From: Marek Safar Date: Tue, 27 Apr 2010 08:01:17 +0000 (-0000) Subject: New tests. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=2d23bfcbce7a3f7e54dcd5911adb88b244baca35;hp=c29282519b48d5fbfd73dd2bd1306a7844174f29;p=mono.git New tests. svn path=/trunk/mcs/; revision=156162 --- diff --git a/COPYING.LIB b/COPYING.LIB index ee8f329b8e3..0247f818a69 100644 --- a/COPYING.LIB +++ b/COPYING.LIB @@ -1,6 +1,16 @@ The Mono runtime is licensed under the terms of the GNU Library General Public License, version 2. + +The eglib directory is licensed under the terms of the MIT +X11 license and is a drop-in replacement for Mono's use of +glib 2.0 (which was LGPL). + +The Boehm licensing information is in the libgc directory + +The SGen Garbage Collector is under the terms of the MIT X11 +license + GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 diff --git a/ChangeLog b/ChangeLog index 5043ae6eaac..74e224a6e60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,175 @@ +2010-04-26 Geoff Norton + + * configure.in: Allow cross compiling osx for 64-bit + +2010-04-26 Zoltan Varga + + * configure.in: Applied patch from Robert Nagy (robert@openbsd.org). Add + sys/param.h dependencies to a few checks. + +2010-04-25 Mark Probst + + * tools/sgen/sgen-grep-binprot.c: Support for major Mark&Sweep + collector. + +2010-04-20 Jonathan Pryor + + * configure.in: Check for the asm/sigcontext.h header. + +2010-04-20 Andrés G. Aragoneses + + * README: Replace --with-profile2 with --with-profile4. + +2010-04-20 Jonathan Pryor + + * configure.in: On OpenBSD, remove duplicate -pthread options in + libmono_ldflags. Change from Robert Nagy . + +2010-04-20 Jonathan Pryor + + * configure.in: For Linux hosts, remove libmono_ldflags="-lpthread". + It's unnecessary (for !target_win32, pthreads are checked again + later in configure.in), and it breaks Android (which doesn't have + libpthread, but DOES have pthreads in libc). + +2010-04-19 Jonathan Pryor + + * configure.in: Disable AC_CHECK_LIB() for pthread, as this breaks + autoconf on BSD platforms. (Why? Who knows -- it's AutoConf!) + +2010-04-19 Jonathan Pryor + + * configure.in: Use AC_CHECK_LIB() to check for pthread instead of + just blindly linking to -lpthread, as Android includes pthread + support within libc and doesn't provide a separate libpthread. + Android's pulls in (unlike glibc), resulting + in a build error in mono/utils/mono-codeman.c due to + `struct mallinfo` re-declaration. Define HAVE_USR_INCLUDE_MALLOC_H + if /usr/include/malloc.h is present to avoid this. + +2010-04-19 Jonathan Pryor + + * configure.in: Add header, structure member, and function checks as + Android doesn't provide all the headers, structure members, and + functions that a "full" Linux distro includes. + +2010-04-19 Zoltan Varga + + * configure.in: Add a --enable-minimal=normalization option to disable support + for string normalization. + +2010-04-16 Marek Habersack + + * configure.in: added a check for sysconf(3) + +2010-04-14 Miguel de Icaza + + * configure.in: turn the AC_MSG_ERROR into a AC_MSG_WARN since in + Andrew's configuration this aborts the build: + + host=i686-pc-linux-gnu != target=i586-suse-linux + + And I no longer remember why I added that error in the first + place (we need to determine perhaps the arch/OS but it is + difficult with those strings). + +2010-04-08 Andreia Gaita + + * configure.in: Add an extra "only" option to --with-moonlight. This + will configure mono to only build moonlight-specific stuff and + nothing else. --with-moonlight=yes now just adds the moon profile to + the build + + * Makefile.am: Add moonlight-specific rules that only build what + moon needs. These are called directly from moon, to do fast + moon+mono+mcs builds + + * runtime/Makefile.am: Change the build rules to have a moonlight-only + build configuration, as well as a normal build that optionally includes + it + +2010-04-07 Raja R Harinath + + * runtime/Makefile.am ($(tmpinst)/bin/dmcs): Add. + +2010-04-06 Andreia Gaita + + * configure.in: add --with-mcs-path option to specify where the mcs + source can be found, if not on ./mcs or ../mcs. + Only touch the mcs and/or olive dirs and config files if we're + actually building them + +2010-04-05 Zoltan Varga + + * configure.in: Append -lgc to libmono_ldflags if using an external libgc. + +2010-04-04 Andreas Färber + + * configure.in: Fix typo. + Set default for with_moonlight to fix "Moon Profile:" output. + + Contributed under MIT/X11 license. + +2010-04-03 Zoltan Varga + + * configure.in: Applied some openbsd changes from Robert Nagy + . + +2010-04-03 Marek Habersack + + * configure.in: TARGET_WIN32 and MINGW_CROSS_COMPILE are defined + when cross-compiling with MinGW + + * build-mingw32.sh: include the 4.0 profile in the zip. + Remove cross-compilation environment bin path from PATH before + compiling native Mono. + Remove autotools cache directory before each compilation phase. + +2010-04-02 Marek Habersack + + * configure.in: include -lkernel32 in LDFLAGS when cross-compiling + with MINGW or compiling on Cygwin. + + * build-mingw32.sh: some changes to make the compilation work + better on non-SuSE systems. + +2010-04-01 Mark Probst + + * scripts/mono-heapviz: Process and output detailed pinning + statistics. + +2010-03-29 Andreas Färber + + * configure.in: Add support for Haiku + + Contributed under MIT/X11 license. + +2010-03-26 Zoltan Varga + + * configure.in: Add a --enable-system-aot option to control the generation of + AOT images during the build. + +2010-03-26 Zoltan Varga + + * configure.in: Apply some openbsd changes from openbsd ports. + +2010-03-23 Neale Ferguson + + * configure.in: Change ACCESS_UNALINGED to "yes" for s390/s390x. + +2010-03-22 Andreia Gaita + + * configure.in: fix build when doing with-mcs-docs=no on a clean tree + +2010-03-19 Zoltan Varga + + * autogen.sh: Pass -Wno-portability to automake to quiet some warnings. + +2010-03-16 Jb Evain + + * runtime/Makefile.am, build-mingw32.sh: rename + the net_2_1 profile to moonlight. + 2010-03-10 Andrew Jorgensen * configure.in: configure eglib even when we are not building diff --git a/LICENSE b/LICENSE index 6177891cdc0..e9655394176 100644 --- a/LICENSE +++ b/LICENSE @@ -54,6 +54,13 @@ For comments, corrections and updates, please contact mono@novell.com the terms of the MIT X11, this means that this code can be used for any purposes by anyone. +** mono/metadata/sgen*: Mono's Copying Collector + + This new garbage collector is licensed under the terms of + the MIT X11 license, in hopes that the GC could be reused + by third party projects, follows the same spirit than the + Boehm GC. + ** mcs/mcs, mcs/gmcs The C# Compilers (1.0 and 2.0) diff --git a/Makefile.am b/Makefile.am index 93fcdee32cb..17c95137b57 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,14 +1,16 @@ AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I . +MOONLIGHT_SUBDIRS = $(libgc_dir) $(eglib_dir) mono $(ikvm_native_dir) data + if CROSS_COMPILING SUBDIRS = po $(libgc_dir) $(eglib_dir) mono $(ikvm_native_dir) data runtime scripts man samples web msvc $(docs_dir) # Keep in sync with SUBDIRS ## 'tools' is not normally built DIST_SUBDIRS = po libgc eglib mono ikvm-native data runtime scripts man samples web tools msvc docs else -if MOONLIGHT -SUBDIRS = $(libgc_dir) $(eglib_dir) mono $(ikvm_native_dir) data runtime +if ONLY_MOONLIGHT +SUBDIRS = $(MOONLIGHT_SUBDIRS) runtime else SUBDIRS = po $(libgc_dir) $(eglib_dir) mono $(ikvm_native_dir) support data runtime scripts man samples web msvc $(docs_dir) # Keep in sync with SUBDIRS @@ -30,12 +32,11 @@ pkgconfigdir = $(libdir)/pkgconfig noinst_DATA = mono-uninstalled.pc DISTCLEANFILES= mono-uninstalled.pc -.PHONY: get-monolite-latest mcs-do-compiler-tests compiler-tests bootstrap-world - # building with monolite mcslib = $(mcs_topdir)/class/lib monolite = $(mcslib)/monolite monolite_url = http://mono.ximian.com/daily/monolite-latest.tar.gz +.PHONY: get-monolite-latest get-monolite-latest: -rm -fr $(mcslib)/monolite-* -mkdir -p $(mcslib) @@ -44,43 +45,44 @@ get-monolite-latest: cd $(mcslib) && { (wget -O- $(monolite_url) || curl $(monolite_url)) | gzip -d | tar xf - ; } cd $(mcslib) && mv -f monolite-* monolite -compiler-tests: build-test-mono-mcs-moon - -compiler-tests-net_2_0: - -rm -f $(mcs_topdir)/build/common/Consts.cs.save - -mv -f $(mcs_topdir)/build/common/Consts.cs $(mcs_topdir)/build/common/Consts.cs.save - cd $(mcs_topdir) && $(MAKE) PROFILE=net_2_0_bootstrap clean - cd $(mcs_topdir) && $(MAKE) PROFILE=net_2_0 clean - -mv -f $(mcs_topdir)/build/common/Consts.cs.save $(mcs_topdir)/build/common/Consts.cs - $(MAKE) all - $(MAKE) test_profiles=net_2_0 mcs-do-compiler-tests - -bootstrap-world: compiler-tests - $(MAKE) install - -bootstrap-world-net_2_0: compiler-tests-net_2_0 - $(MAKE) install - -# internal targets -.PHONY: build-test-mono-mcs-moon -build-test-mono-mcs-moon: do-build-moon-maybe - $(MAKE) mcs-do-compiler-tests - -.PHONY: do-build-mono-mcs +.PHONY: validate do-build-mono-mcs mcs-do-clean mcs-do-tests +validate: do-build-mono-mcs + $(MAKE) mcs-do-tests do-build-mono-mcs: mcs-do-clean $(MAKE) all - -.PHONY: do-build-moon-maybe -do-build-moon-maybe: do-build-mono-mcs - cd runtime && $(MAKE) moon-do-build - mcs-do-clean: cd runtime && $(MAKE) clean-local cd mono/tests && $(MAKE) clean -mcs-do-compiler-tests: - cd runtime && $(MAKE) test_select='TEST_SUBDIRS="tests errors"' check-local +mcs-do-tests: + cd runtime && $(MAKE) check-local cd mono/tests && $(MAKE) check +.PHONY: compiler-tests mcs-do-compiler-tests +compiler-tests: + $(MAKE) test_select='TEST_SUBDIRS="tests errors"' validate +mcs-do-compiler-tests: + $(MAKE) test_select='TEST_SUBDIRS="tests errors"' mcs-do-tests + +.PHONY: bootstrap-world +bootstrap-world: compiler-tests + $(MAKE) install + +if MOONLIGHT +moon-do-build: config.h + @list='$(MOONLIGHT_SUBDIRS)'; for subdir in $$list; do \ + echo "Making all in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) all); \ + done; + cd $(mcs_topdir) && NO_DIR_CHECK=1 $(MAKE) PROFILE=moonlight_raw all + +moon-do-clean: + @list='$(MOONLIGHT_SUBDIRS)'; for subdir in $$list; do \ + echo "Making clean in $$subdir"; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) clean); \ + done; + cd $(mcs_topdir) && NO_DIR_CHECK=1 $(MAKE) PROFILE=moonlight_raw clean +endif + win32getdeps: wget http://www.go-mono.com/archive/pkgconfig-0.11-20020310.zip wget http://www.go-mono.com/archive/glib-2.0.4-20020703.zip @@ -98,10 +100,6 @@ win32getdeps: win32setup: makensis /DMILESTONE=$(VERSION) /DSOURCE_INSTALL_DIR=$(SOURCE_INSTALL_DIR) /DBUILDNUM=$(BUILDNUM) monowiz.win32.nsi -bootstrap: all - @echo "*** 'make bootstrap' is obsolete. Just run 'make' to perform a combined mono+mcs build" - exit 1 - patch-quiet: find mono -name Makefile -exec scripts/patch-quiet.sh {} \; find libgc -name Makefile -exec scripts/patch-quiet.sh {} \; diff --git a/README b/README index 9115a434983..abb03144188 100644 --- a/README +++ b/README @@ -278,10 +278,10 @@ This is Mono. This defaults to `yes'. - --with-profile2=yes,no + --with-profile4=yes,no - Whether you want to build the 2.x libraries (support - for Generics and the 2.0/3.5 APIS). + Whether you want to build the 4.x profile libraries + and runtime. It defaults to `yes'. diff --git a/autogen.sh b/autogen.sh index eba9274a8fa..898b2d80beb 100755 --- a/autogen.sh +++ b/autogen.sh @@ -119,7 +119,7 @@ if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then fi echo "Running automake --gnu $am_opt ..." -automake --add-missing --gnu $am_opt || +automake --add-missing --gnu -Wno-portability $am_opt || { echo "**Error**: automake failed."; exit 1; } echo "Running autoconf ..." autoconf || { echo "**Error**: autoconf failed."; exit 1; } diff --git a/build-mingw32.sh b/build-mingw32.sh index 200c5fa7188..16b91cefe6d 100755 --- a/build-mingw32.sh +++ b/build-mingw32.sh @@ -1,19 +1,32 @@ #!/bin/bash -e CURDIR="`pwd`" -CROSS_DIR=${1:-/opt/cross/} -MINGW=${1:-i386-mingw32msvc} -CROSS_BIN_DIR="$CROSS_DIR/bin" -CROSS_DLL_DIR="$CROSS_DIR/$MINGW/bin" -CROSS_PKG_CONFIG_DIR=$CROSS_DIR/$MINGW/lib/pkgconfig +MINGW=i386-mingw32msvc +CROSS_DIR=/opt/cross/$MINGW COPY_DLLS="libgio*.dll libglib*.dll libgmodule*.dll libgthread*.dll libgobject*.dll" -PATH=$CROSS_BIN_DIR:$PATH INSTALL_DESTDIR="$CURDIR/mono-win32" -PROFILES="default net_2_0 net_2_1 net_3_5" +PROFILES="default net_2_0 net_3_5 net_4_0 moonlight" +TEMPORARY_PKG_CONFIG_DIR=/tmp/$RANDOM-pkg-config-$RANDOM +ORIGINAL_PATH="$PATH" -export PATH +export CPPFLAGS_FOR_EGLIB CFLAGS_FOR_EGLIB CPPFLAGS_FOR_LIBGC CFLAGS_FOR_LIBGC + +function cleanup () +{ + if [ -d "$TEMPORARY_PKG_CONFIG_DIR" ]; then + rm -rf "$TEMPORARY_PKG_CONFIG_DIR" + fi +} function setup () { + local pcname + + CROSS_BIN_DIR="$CROSS_DIR/bin" + CROSS_DLL_DIR="$CROSS_DIR/bin" + CROSS_PKG_CONFIG_DIR=$CROSS_DIR/lib/pkgconfig + PATH=$CROSS_BIN_DIR:$PATH + + export PATH if [ -d ./.git/svn ]; then SVN_INFO='git svn info' elif [ -d ./.svn ]; then @@ -37,6 +50,15 @@ function setup () NOCONFIGURE=yes export NOCONFIGURE + if [ -d "$CROSS_PKG_CONFIG_DIR" ]; then + install -d -m 755 "$TEMPORARY_PKG_CONFIG_DIR" + for pc in "$CROSS_PKG_CONFIG_DIR"/*.pc; do + pcname="`basename $pc`" + sed -e "s;^prefix=.*;prefix=$CROSS_DIR;g" < $pc > "$TEMPORARY_PKG_CONFIG_DIR"/$pcname + done + CROSS_PKG_CONFIG_DIR="$TEMPORARY_PKG_CONFIG_DIR" + fi + echo Mono Win32 installation prefix: $MONO_PREFIX } @@ -44,8 +66,11 @@ function build () { ./autogen.sh + BUILD="`./config.guess`" + if [ -f ./Makefile ]; then make distclean + rm -rf autom4te.cache fi if [ ! -d "$CURDIR/build-cross-windows" ]; then @@ -54,13 +79,18 @@ function build () cd "$CURDIR/build-cross-windows" rm -rf * - ../configure --prefix=$MONO_PREFIX --with-crosspkgdir=$CROSS_PKG_CONFIG_DIR --target=$MINGW --host=$MINGW --enable-parallel-mark --program-transform-name="" + ../configure --prefix=$MONO_PREFIX --with-crosspkgdir=$CROSS_PKG_CONFIG_DIR --build=$BUILD --target=$MINGW --host=$MINGW --enable-parallel-mark --program-transform-name="" --with-tls=none --disable-mcs-build --disable-embed-check --enable-win32-dllmain=yes --with-libgc-threads=win32 --with-profile4=yes make cd "$CURDIR" if [ ! -d "$CURDIR/build-cross-windows-mcs" ]; then mkdir "$CURDIR/build-cross-windows-mcs" fi + + rm -rf autom4te.cache + unset PATH + PATH="$ORIGINAL_PATH" + export PATH cd "$CURDIR/build-cross-windows-mcs" rm -rf * ../configure --prefix=$MONO_PREFIX --enable-parallel-mark @@ -101,8 +131,32 @@ function doinstall () } +function usage () +{ + cat < /dev/null +while getopts "d:m:h" opt; do + case "$opt" in + d) CROSS_DIR="$OPTARG" ;; + m) MINGW="$OPTARG" ;; + *) usage ;; + esac +done + setup build doinstall diff --git a/configure.in b/configure.in index 723850e1c76..acca772bfd7 100644 --- a/configure.in +++ b/configure.in @@ -77,7 +77,7 @@ esac host_win32=no target_win32=no case "$host" in - *-*-mingw*|*-*-cygwin*) + *-mingw*|*-*-cygwin*) AC_DEFINE(HOST_WIN32,1,[Host Platform is Win32]) AC_DEFINE(DISABLE_PORTABILITY,1,[Disable the io-portability layer]) AC_DEFINE(PLATFORM_NO_SYMLINKS,1,[This platform does not support symlinks]) @@ -92,11 +92,15 @@ case "$host" in # So libgc configure gets -mno-cygwin export CC export CXX + else + target_win32=yes + AC_DEFINE(TARGET_WIN32,1,[Target OS is Win32/MinGW]) + AC_DEFINE(MINGW_CROSS_COMPILE,1,[Cross-compiling using MinGW]) fi HOST_CC="gcc" # Windows 2000 is required that includes Internet Explorer 5.01 CPPFLAGS="$CPPFLAGS -DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0501 -D_UNICODE -DUNICODE -DWIN32_THREADS -DFD_SETSIZE=1024" - LDFLAGS="$LDFLAGS -lmswsock -lws2_32 -lole32 -loleaut32 -lpsapi -lversion -ladvapi32 -lwinmm" + LDFLAGS="$LDFLAGS -lmswsock -lws2_32 -lole32 -loleaut32 -lpsapi -lversion -ladvapi32 -lwinmm -lkernel32" libmono_cflags="-mno-cygwin -mms-bitfields -mwindows" libmono_ldflags="-mno-cygwin -mms-bitfields -mwindows" libdl= @@ -151,14 +155,18 @@ case "$host" in ;; *-*-*openbsd*) host_win32=no - CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_FREEBSD_THREADS -DPLATFORM_BSD" - libmono_cflags="-D_THREAD_SAFE" + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_OPENBSD_THREADS -DPLATFORM_BSD -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP" + if test "x$disable_munmap" != "xyes"; then + CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP" + fi + libmono_cflags="-D_THREAD_SAFE -D_REENTRANT" LDFLAGS="$LDFLAGS -pthread" - libmono_ldflags="-pthread" need_link_unlink=yes AC_DEFINE(PTHREAD_POINTER_ID) libdl= + gc_default=boehm libgc_threads=pthreads + with_sigaltstack=no use_sigposix=yes ;; *-*-linux*) @@ -168,7 +176,6 @@ case "$host" in CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP" fi libmono_cflags="-D_REENTRANT" - libmono_ldflags="-lpthread" libdl="-ldl" libgc_threads=pthreads AOT_SUPPORTED="yes" @@ -228,18 +235,6 @@ case "$host" in dnl its gcc defaults to 64-bit mode. They have also deprecated the usage of ucontext dnl we need to set some flags to build our 32-bit binaries on 10.6 properly case "$host" in - dnl MacPorts config.guess reports as this - x86_64-*-darwin10*) - BROKEN_DARWIN_FLAGS="-arch i386 -D_XOPEN_SOURCE -mmacosx-version-min=10.5" - CPPFLAGS="$CPPFLAGS $BROKEN_DARWIN_FLAGS" - CFLAGS="$CFLAGS $BROKEN_DARWIN_FLAGS" - CXXFLAGS="$CXXFLAGS $BROKEN_DARWIN_FLAGS" - CCASFLAGS="$CCASFLAGS $BROKEN_DARWIN_FLAGS" - CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC $BROKEN_DARWIN_FLAGS" - CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC $BROKEN_DARWIN_FLAGS" - CPPFLAGS_FOR_EGLIB="$CPPFLAGS_FOR_EGLIB $BROKEN_DARWIN_FLAGS" - CFLAGS_FOR_EGLIB="$CFLAGS_FOR_EGLIB $BROKEN_DARWIN_FLAGS" - ;; dnl Snow Leopard config.guess reports as this i*86-*-darwin10*) BROKEN_DARWIN_FLAGS="-arch i386 -D_XOPEN_SOURCE -mmacosx-version-min=10.5" @@ -254,6 +249,17 @@ case "$host" in ;; esac ;; + *-*-haiku*) + host_win32=no + CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_THREAD_SAFE" + libmono_cflags="-D_REENTRANT -D_THREAD_SAFE" + libdl= + LIBS="$LIBS -lnetwork" + need_link_unlink=yes + AC_DEFINE(PTHREAD_POINTER_ID) + libgc_threads=pthreads + use_sigposix=yes + ;; *) AC_MSG_WARN([*** Please add $host to configure.in checks!]) host_win32=no @@ -344,8 +350,14 @@ fi AM_CONDITIONAL(NO_VERSION_SCRIPT, test x$no_version_script = xyes) AC_CHECK_HEADERS(sys/filio.h sys/sockio.h netdb.h utime.h sys/utime.h semaphore.h sys/un.h linux/rtc.h sys/syscall.h sys/mkdev.h sys/uio.h) -AC_CHECK_HEADERS(sys/user.h sys/socket.h sys/ipc.h sys/sem.h sys/utsname.h alloca.h ucontext.h pwd.h sys/select.h netinet/tcp.h netinet/in.h unistd.h sys/types.h link.h) +AC_CHECK_HEADERS(sys/param.h sys/socket.h sys/ipc.h sys/sem.h sys/utsname.h alloca.h ucontext.h pwd.h sys/select.h netinet/tcp.h netinet/in.h unistd.h sys/types.h link.h asm/sigcontext.h) +AC_CHECK_HEADERS(sys/user.h, [], [], +[ +#ifdef HAVE_SYS_PARAM_H +# include +#endif +]) AC_CHECK_HEADER(zlib.h, [have_zlib=yes], [have_zlib=no]) if test x$have_zlib = xyes; then @@ -433,6 +445,12 @@ else mcsdir=../mcs fi +AC_ARG_WITH(mcs-path, [ --with-mcs-path=/path/to/mcs Specify an alternate mcs source tree], + if test x$with_mcs_path != "x" -a -d $with_mcs_path ; then + mcsdir=$with_mcs_path + fi +) + # # A sanity check to catch cases where the package was unpacked # with an ancient tar program (Solaris) @@ -443,7 +461,7 @@ AC_ARG_ENABLE(solaris-tar-check, if test x"$do_solaris_tar_check" = xyes -a x"$enable_solaris_tar_check" = xyes; then AC_MSG_CHECKING(integrity of package) - if test -f $srcdir/$mcsdir/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapTypeMapper.cs + if test -f $mcsdir/class/System.Runtime.Serialization.Formatters.Soap/System.Runtime.Serialization.Formatters.Soap/SoapTypeMapper.cs then AC_MSG_RESULT(ok) else @@ -452,8 +470,13 @@ if test x"$do_solaris_tar_check" = xyes -a x"$enable_solaris_tar_check" = xyes; fi fi -mcs_topdir='$(top_srcdir)/'$mcsdir -mcs_topdir_from_srcdir='$(top_builddir)/'$mcsdir +if test "x$with_mcs_path" != "x"; then +mcs_topdir=$(cd "$mcsdir" && pwd) +mcs_topdir_from_srcdir=$mcs_topdir +else +mcs_topdir=$(cd "$srcdir/$mcsdir" && pwd) +mcs_topdir_from_srcdir='$(top_builddir)'/$mcsdir +fi ## Maybe should also disable if mcsdir is invalid. Let's punt the issue for now. AM_CONDITIONAL(BUILD_MCS, [test x$cross_compiling = xno && test x$enable_mcs_build != xno]) @@ -496,8 +519,8 @@ yes|sibling) libgdiplus_loc=`cd ../libgdiplus && pwd`/src/libgdiplus.la ;; esac AC_SUBST([libgdiplus_loc]) -AC_PATH_PROG(PKG_CONFIG, pkg-config, no) -if test "x$PKG_CONFIG" = "xno"; then +PKG_PROG_PKG_CONFIG() +if test "x$PKG_CONFIG" = "x"; then AC_MSG_ERROR([You need to install pkg-config]) fi @@ -534,16 +557,10 @@ embedded) eglib_dir=eglib ;; system) - if test "x$cross_compiling" = "xyes"; then - pkg_config_path="$PKG_CONFIG_PATH" - unset PKG_CONFIG_PATH - fi + echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH" + echo "cross_compiling=$cross_compiling" BUILD_GLIB_CFLAGS=`$PKG_CONFIG --cflags glib-2.0 gthread-2.0` BUILD_GLIB_LIBS=`$PKG_CONFIG --libs glib-2.0 gthread-2.0` - if test "x$cross_compiling" = "xyes"; then - PKG_CONFIG_PATH=$pkg_config_path - export PKG_CONFIG_PATH - fi ## Versions of dependencies GLIB_REQUIRED_VERSION=2.4.0 @@ -644,11 +661,17 @@ if test x$enable_small_config = xyes; then CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DSMALL_CONFIG" fi +if test x$AOT_SUPPORTED != xyes; then + AOT_SUPPORTED=no +fi + +AC_ARG_ENABLE(system-aot, [ --enable-system-aot Enable the Ahead-Of-Time compilation of system assemblies during the build (on by default on some platforms)], enable_system_aot=$enableval, enable_system_aot=$AOT_SUPPORTED) + DISABLED_FEATURES=none AC_ARG_ENABLE(minimal, [ --enable-minimal=LIST drop support for LIST subsystems. LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug, - reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd,soft_debug.], + reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, simd, soft_debug, normalization.], [ for feature in `echo "$enable_minimal" | sed -e "s/,/ /g"`; do eval "mono_feature_disable_$feature='yes'" @@ -763,6 +786,11 @@ if test "x$mono_feature_disable_soft_debug" = "xyes"; then AC_MSG_NOTICE([Disabled Soft Debugger.]) fi +if test "x$mono_feature_disable_normalization" = "xyes"; then + AC_DEFINE(DISABLE_NORMALIZATION, 1, [Disable String normalization support.]) + AC_MSG_NOTICE([Disabled String normalization support.]) +fi + AC_MSG_CHECKING(for visibility __attribute__) AC_TRY_COMPILE([], [ void __attribute__ ((visibility ("hidden"))) doit (void) {} @@ -814,6 +842,7 @@ case "x$gc" in AC_SUBST(HAVE_BOEHM_GC) LIBGC_LIBS="-lgc $libdl" LIBGC_STATIC_LIBS="$LIBGC_LIBS" + libmono_ldflags="$libmono_ldflags -lgc" # AC_CHECK_FUNCS does not work for some reason... AC_CHECK_LIB(gc, GC_gcj_malloc, found_gcj_malloc="yes",,$libdl) @@ -978,6 +1007,7 @@ if test x$target_win32 = xno; then AC_CHECK_FUNCS(getpriority) AC_CHECK_FUNCS(setpriority) AC_CHECK_FUNCS(dl_iterate_phdr) + AC_CHECK_FUNCS(sysconf) AC_CHECK_FUNCS(sched_setaffinity) @@ -1279,6 +1309,9 @@ if test x$target_win32 = xno; then *-*-*freebsd*) AC_CHECK_LIB(pthread, main, LIBS="$LIBS -pthread") ;; + *-*-*openbsd*) + AC_CHECK_LIB(pthread, main, LIBS="$LIBS -pthread") + ;; *) AC_CHECK_LIB(pthread, main, LIBS="$LIBS -lpthread") ;; @@ -1539,7 +1572,15 @@ if test x$target_win32 = xno; then dnl *** Checks for SIOCGIFCONF *** dnl ****************************** AC_CHECK_HEADERS(sys/ioctl.h) - AC_CHECK_HEADERS(net/if.h) + AC_CHECK_HEADERS(net/if.h, [], [], + [ + #ifdef HAVE_SYS_TYPES_H + # include + #endif + #ifdef HAVE_SYS_SOCKET_H + # include + #endif + ]) AC_MSG_CHECKING(for ifreq) AC_TRY_COMPILE([ #include @@ -1592,6 +1633,7 @@ if test x$target_win32 = xno; then dnl *** Checks for MonoPosixHelper *** dnl ********************************** AC_CHECK_HEADERS(checklist.h) + AC_CHECK_HEADERS(pathconf.h) AC_CHECK_HEADERS(fstab.h) AC_CHECK_HEADERS(attr/xattr.h) AC_CHECK_HEADERS(sys/extattr.h) @@ -1602,14 +1644,22 @@ if test x$target_win32 = xno; then AC_CHECK_HEADERS(sys/xattr.h) AC_CHECK_HEADERS(sys/mman.h) AC_CHECK_HEADERS(sys/param.h) + AC_CHECK_HEADERS(sys/mount.h, [], [], + [ + #ifdef HAVE_SYS_PARAM_H + # include + #endif + ]) AC_CHECK_HEADERS(sys/mount.h) + AC_CHECK_FUNCS(confstr) + AC_CHECK_FUNCS(seekdir telldir) AC_CHECK_FUNCS(getdomainname) AC_CHECK_FUNCS(setdomainname) - AC_CHECK_FUNCS(fgetgrent) - AC_CHECK_FUNCS(fgetpwent) - AC_CHECK_FUNCS(fgetpwent) + AC_CHECK_FUNCS(endgrent getgrent fgetgrent setgrent) + AC_CHECK_FUNCS(setgroups) + AC_CHECK_FUNCS(endpwent getpwent fgetpwent setpwent) AC_CHECK_FUNCS(getfsstat) - AC_CHECK_FUNCS(lutimes) + AC_CHECK_FUNCS(lutimes futimes) AC_CHECK_FUNCS(mremap) AC_CHECK_FUNCS(remap_file_pages) AC_CHECK_FUNCS(posix_fadvise) @@ -1617,7 +1667,8 @@ if test x$target_win32 = xno; then AC_CHECK_FUNCS(posix_madvise) AC_CHECK_FUNCS(vsnprintf) AC_CHECK_FUNCS(sendfile) - AC_CHECK_FUNCS(sethostid) + AC_CHECK_FUNCS(gethostid sethostid) + AC_CHECK_FUNCS(sethostname) AC_CHECK_FUNCS(statfs) AC_CHECK_FUNCS(fstatfs) AC_CHECK_FUNCS(statvfs) @@ -1625,6 +1676,11 @@ if test x$target_win32 = xno; then AC_CHECK_FUNCS(stime) AC_CHECK_FUNCS(strerror_r) AC_CHECK_FUNCS(ttyname_r) + AC_CHECK_FUNCS(psignal) + AC_CHECK_FUNCS(getlogin_r) + AC_CHECK_FUNCS(lockf) + AC_CHECK_FUNCS(swab) + AC_CHECK_FUNCS(setusershell endusershell) AC_CHECK_SIZEOF(size_t) AC_CHECK_TYPES([blksize_t], [AC_DEFINE(HAVE_BLKSIZE_T)], , [#include @@ -1660,6 +1716,14 @@ if test x$target_win32 = xno; then [struct dirent.d_off, struct dirent.d_reclen, struct dirent.d_type],,, [#include #include ]) + AC_CHECK_MEMBERS( + [struct passwd.pw_gecos],,, + [#include + #include ]) + AC_CHECK_MEMBERS( + [struct statfs.f_flags],,, + [#include + #include ]) dnl Favour xattr through glibc, but use libattr if we have to AC_CHECK_FUNC(lsetxattr, , @@ -1671,6 +1735,7 @@ if test x$target_win32 = xno; then AC_CHECK_MEMBERS( [struct kinfo_proc.kp_proc],,, [#include + #include #include #include ]) @@ -1751,7 +1816,7 @@ ac_cv_c_socklen_t=yes AC_MSG_RESULT(no) ]) -AC_MSG_CHECKING(for array element initalizer support) +AC_MSG_CHECKING(for array element initializer support) AC_TRY_COMPILE([#include ], [ const int array[] = {[1] = 2,}; ], [ @@ -1799,7 +1864,7 @@ case "{$target}" in dnl Win32 does not have /dev/random, they have their own method... - *-*-mingw*|*-*-cygwin*) + *-mingw*|*-*-cygwin*) ac_cv_have_dev_random=no ;; @@ -2041,6 +2106,10 @@ case "$host" in ;; cygwin*) have_visibility_hidden=no + ;; + haiku*) + LIBC=libroot.so + ;; esac ;; x86_64-*-* | amd64-*-*) @@ -2097,7 +2166,7 @@ case "$host" in INTL="libc.so.6.1" esac ;; - *-*-mingw*|*-*-cygwin*) + *-mingw*|*-*-cygwin*) # When this is enabled, it leads to very strange crashes at runtime (gcc-3.4.4) have_visibility_hidden=no INTL="intl" @@ -2149,7 +2218,7 @@ case "$host" in s390-*-linux*) TARGET=S390; arch_target=s390; - ACCESS_UNALIGNED="no" + ACCESS_UNALIGNED="yes" JIT_SUPPORTED=yes jit_wanted=true # Required CFLAGS for s390[x]. USE_STRING_INLINES is automatic with gcc 4.1 @@ -2158,7 +2227,7 @@ case "$host" in s390x-*-linux*) TARGET=S390x; arch_target=s390x; - ACCESS_UNALIGNED="no" + ACCESS_UNALIGNED="yes" JIT_SUPPORTED=yes jit_wanted=true CFLAGS="$CFLAGS -mbackchain -D__USE_STRING_INLINES" @@ -2191,7 +2260,7 @@ if test "x$host" != "x$target"; then target_byte_order=G_BIG_ENDIAN ;; *) - AC_MSG_ERROR([Cross compiling is only supported for targets matching 'powerpc64-{ps3,xbox360}-linux-gnu']) + AC_MSG_WARN([Cross compiling is only supported for targets matching 'powerpc64-{ps3,xbox360}-linux-gnu']) esac fi @@ -2454,21 +2523,28 @@ AC_ARG_WITH(mcs_docs,[ --with-mcs-docs=yes,no If you want to build the fi ]) -MOONLIGHT=no -AC_ARG_WITH(moonlight, [ --with-moonlight=yes,no If you want to build Mono for Moonlight (defaults to no - the resulting mono build is useless for anything but moonlight)],[ - if test x$with_moonlight = xyes; then - MOONLIGHT=yes +AC_ARG_WITH(moonlight, [ --with-moonlight=yes|no|only If you want to build Mono for Moonlight (defaults to no)],[ + if test "x$with_moonlight" = "xyes"; then + AC_DEFINE(MOONLIGHT,1,[Building for Moonlight]) + elif test "x$with_moonlight" = "xonly"; then AC_DEFINE(MOONLIGHT,1,[Building for Moonlight]) fi -]) +], [with_moonlight=no]) +AC_CHECK_HEADER([malloc.h], + [AC_DEFINE([HAVE_USR_INCLUDE_MALLOC_H], [1], + [Define to 1 if you have /usr/include/malloc.h.])],,) + dnl dnl Consistency settings dnl if test x$cross_compiling = xyes -o x$enable_mcs_build = xno; then DISABLE_MCS_DOCS=yes +fi + +if test x$DISABLE_MCS_DOCS = xyes; then docs_dir="" else docs_dir=docs @@ -2481,7 +2557,8 @@ AC_SUBST(OPROFILE_LIBS) libmono_ldflags="$libmono_ldflags $LIBS" -AM_CONDITIONAL(MOONLIGHT, [test "x$with_moonlight" = xyes]) +AM_CONDITIONAL(MOONLIGHT, [test "x$with_moonlight" != "xno"]) +AM_CONDITIONAL(ONLY_MOONLIGHT, [test "x$with_moonlight" = "xonly"]) AM_CONDITIONAL(INSTALL_4_0, [test "x$with_profile4" = xyes]) AM_CONDITIONAL(INSTALL_MONOTOUCH, [test "x$with_monotouch" = xyes]) @@ -2696,6 +2773,7 @@ data/net_4_0/Makefile data/net_2_0/Browsers/Makefile data/mint.pc data/mono-2.pc +data/mono.pc data/mono-cairo.pc data/mono-nunit.pc data/mono-options.pc @@ -2709,6 +2787,7 @@ data/cecil.pc data/system.web.extensions_1.0.pc data/system.web.extensions.design_1.0.pc data/system.web.mvc.pc +data/system.web.mvc2.pc samples/Makefile support/Makefile data/config @@ -2737,28 +2816,30 @@ fi NONE) exec_prefix='${prefix}' ;; esac - test -w $srcdir/$mcsdir/build || chmod +w $srcdir/$mcsdir/build - # # If we are cross compiling, we don't build in the mcs/ tree. Let us not clobber # any existing config.make. This allows people to share the same source tree # with different build directories, one native and one cross # if test x$cross_compiling = xno && test x$enable_mcs_build != xno; then - echo "prefix=$prefix" > $srcdir/$mcsdir/build/config.make - echo "exec_prefix=$exec_prefix" >> $srcdir/$mcsdir/build/config.make - echo "sysconfdir=$sysconfdir" >> $srcdir/$mcsdir/build/config.make - echo 'mono_libdir=${exec_prefix}/lib' >> $srcdir/$mcsdir/build/config.make - echo 'MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS)' >> $srcdir/$mcsdir/build/config.make - echo 'IL_FLAGS = /debug' >> $srcdir/$mcsdir/build/config.make - echo "RUNTIME = $mono_build_root/runtime/mono-wrapper" >> $srcdir/$mcsdir/build/config.make - echo "ILDISASM = $mono_build_root/runtime/monodis-wrapper" >> $srcdir/$mcsdir/build/config.make + + test -w $mcs_topdir/build || chmod +w $mcs_topdir/build + + echo "prefix=$prefix" > $mcs_topdir/build/config.make + echo "exec_prefix=$exec_prefix" >> $mcs_topdir/build/config.make + echo "sysconfdir=$sysconfdir" >> $mcs_topdir/build/config.make + echo 'mono_libdir=${exec_prefix}/lib' >> $mcs_topdir/build/config.make + echo 'MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS)' >> $mcs_topdir/build/config.make + echo 'IL_FLAGS = /debug' >> $mcs_topdir/build/config.make + echo "RUNTIME = $mono_build_root/runtime/mono-wrapper" >> $mcs_topdir/build/config.make + echo "ILDISASM = $mono_build_root/runtime/monodis-wrapper" >> $mcs_topdir/build/config.make + case $INSTALL in [[\\/$]]* | ?:[[\\/]]* ) mcs_INSTALL=$INSTALL ;; *) mcs_INSTALL=$mono_build_root/$INSTALL ;; esac - echo "INSTALL = $mcs_INSTALL" >> $srcdir/$mcsdir/build/config.make + echo "INSTALL = $mcs_INSTALL" >> $mcs_topdir/build/config.make export VERSION [myver=$($AWK 'BEGIN { @@ -2769,23 +2850,33 @@ fi print vsplit [1] "." vsplit [2] "." vsplit [3] "." vsplit [4] }')] - echo "MONO_VERSION = $myver" >> $srcdir/$mcsdir/build/config.make - fi + echo "MONO_VERSION = $myver" >> $mcs_topdir/build/config.make - if test x$platform_darwin = xyes; then - echo "PLATFORM = darwin" >> $srcdir/$mcsdir/build/config.make - fi + if test x$platform_darwin = xyes; then + echo "PLATFORM = darwin" >> $mcs_topdir/build/config.make + fi + + if test x$TARGET = xAMD64 -a x$host_win32 = xno -a "x$AOT_SUPPORTED" = "xyes" -a x$enable_system_aot = xyes; then + echo "ENABLE_AOT = 1" >> $mcs_topdir/build/config.make + fi + + if test x$DISABLE_MCS_DOCS = xyes; then + echo "DISABLE_MCS_DOCS = yes" >> $mcs_topdir/build/config.make + fi + + if test x$with_moonlight != xno; then + echo "MOONLIGHT = 1" >> $srcdir/$mcsdir/build/config.make + fi - if test x$TARGET = xAMD64 -a x$host_win32 = xno -a "x$AOT_SUPPORTED" = "xyes"; then - echo "ENABLE_AOT = 1" >> $srcdir/$mcsdir/build/config.make fi # if we have an olive folder, override the default settings if test -d $olivedir; then - test -w $srcdir/$olivedir/build || chmod +w $srcdir/$olivedir/build - if test x$cross_compiling = xno && test x$enable_olive_build != xno; then + + test -w $srcdir/$olivedir/build || chmod +w $srcdir/$olivedir/build + echo "prefix=$prefix" > $srcdir/$olivedir/build/config.make echo "exec_prefix=$exec_prefix" >> $srcdir/$olivedir/build/config.make echo 'mono_libdir=${exec_prefix}/lib' >> $srcdir/$olivedir/build/config.make @@ -2795,19 +2886,12 @@ fi fi fi - if test x$DISABLE_MCS_DOCS = xyes; then - echo "DISABLE_MCS_DOCS = yes" >> $srcdir/$mcsdir/build/config.make - fi - - if test x$with_moonlight = xyes; then - echo "MOONLIGHT = 1" >> $srcdir/$mcsdir/build/config.make - fi ) libgdiplus_msg=${libgdiplus_loc:-assumed to be installed} echo " - mcs source: $mcs_topdir + mcs source: $mcsdir olive source: $olive_topdir Engine: diff --git a/data/ChangeLog b/data/ChangeLog index 9401dba5809..0fcb14f40c3 100644 --- a/data/ChangeLog +++ b/data/ChangeLog @@ -1,3 +1,7 @@ +2010-04-02 Jb Evain + + * dotnet35.pc.in: add System.Data.Services.dll. + 2010-03-08 Rodrigo Kumpera * mono.supp: Add hazard pointers supressions. diff --git a/data/Makefile.am b/data/Makefile.am index 3ae35a43747..14ef47b9d9a 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -9,10 +9,10 @@ monodir = $(sysconfdir)/mono EXTRA_DIST = \ config.in \ browscap.ini mono.supp mono.d README ChangeLog \ - mono-2.pc.in mint.pc.in dotnet.pc.in dotnet35.pc.in wcf.pc.in monodoc.pc.in \ + mono.pc.in mono-2.pc.in mint.pc.in dotnet.pc.in dotnet35.pc.in wcf.pc.in monodoc.pc.in \ mono-nunit.pc.in mono-cairo.pc.in mono-options.pc.in cecil.pc.in \ mono-lineeditor.pc.in system.web.extensions_1.0.pc.in system.web.extensions.design_1.0.pc.in\ - dtrace-prelink.sh mono.web.pc.in system.web.mvc.pc.in \ + dtrace-prelink.sh mono.web.pc.in system.web.mvc.pc.in system.web.mvc2.pc.in \ net_1_1/machine.config \ gdb/mono-gdb.py \ gdb/gdb-python.diff @@ -21,18 +21,18 @@ pkgconfigdir = $(libdir)/pkgconfig if JIT_SUPPORTED if INTERP_SUPPORTED -pkgconfig_DATA= mono-2.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ - system.web.extensions.design_1.0.pc mono.web.pc system.web.mvc.pc +pkgconfig_DATA= mono.pc mono-2.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ + system.web.extensions.design_1.0.pc mono.web.pc system.web.mvc.pc system.web.mvc2.pc else -pkgconfig_DATA= mono-2.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ - system.web.extensions.design_1.0.pc mono.web.pc system.web.mvc.pc +pkgconfig_DATA= mono.pc mono-2.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ + system.web.extensions.design_1.0.pc mono.web.pc system.web.mvc.pc system.web.mvc2.pc endif else pkgconfig_DATA= mint.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc endif -DISTCLEANFILES= mono-2.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ - system.web.extensions.design_1.0.pc mono.web.pc system.web.mvc.pc +DISTCLEANFILES= mono-2.pc mono.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ + system.web.extensions.design_1.0.pc mono.web.pc system.web.mvc.pc system.web.mvc2.pc mono_DATA = config \ browscap.ini diff --git a/data/dotnet.pc.in b/data/dotnet.pc.in index e9b2b76dfc7..0983102bffd 100644 --- a/data/dotnet.pc.in +++ b/data/dotnet.pc.in @@ -2,4 +2,4 @@ Name: Standard libraries in a .NET setup Description: References all the standard .NET libraries for compilation Version: @VERSION@ -Libs: -r:Accessibility.dll -r:cscompmgd.dll -r:Microsoft.JScript.dll -r:Microsoft.VisualC.dll -r:Microsoft.Vsa.dll -r:System.Configuration.Install.dll -r:System.Data.dll -r:System.Data.OracleClient.dll -r:System.Design.dll -r:System.DirectoryServices.dll -r:System.dll -r:System.Drawing.Design.dll -r:System.Drawing.dll -r:System.EnterpriseServices.dll -r:System.Management.dll -r:System.Messaging.dll -r:System.Runtime.Remoting.dll -r:System.Runtime.Serialization.Formatters.Soap.dll -r:System.Security.dll -r:System.ServiceProcess.dll -r:System.Web.dll -r:System.Web.Services.dll -r:System.Windows.Forms.dll -r:System.Xml.dll +Libs: -r:Accessibility.dll -r:cscompmgd.dll -r:Microsoft.VisualC.dll -r:System.Configuration.Install.dll -r:System.Data.dll -r:System.Data.OracleClient.dll -r:System.Design.dll -r:System.DirectoryServices.dll -r:System.dll -r:System.Drawing.Design.dll -r:System.Drawing.dll -r:System.EnterpriseServices.dll -r:System.Management.dll -r:System.Messaging.dll -r:System.Runtime.Remoting.dll -r:System.Runtime.Serialization.Formatters.Soap.dll -r:System.Security.dll -r:System.ServiceProcess.dll -r:System.Web.dll -r:System.Web.Services.dll -r:System.Windows.Forms.dll -r:System.Xml.dll diff --git a/data/dotnet35.pc.in b/data/dotnet35.pc.in index 7e2f6e1641b..9db3647aafb 100644 --- a/data/dotnet35.pc.in +++ b/data/dotnet35.pc.in @@ -2,4 +2,4 @@ Name: Standard libraries in a .NET setup Description: References all the standard .NET libraries for compilation (.NET Framework 3.5 compatibility) Version: @VERSION@ -Libs: -r:Accessibility.dll -r:cscompmgd.dll -r:Microsoft.JScript.dll -r:Microsoft.VisualC.dll -r:Microsoft.Vsa.dll -r:System.Configuration.Install.dll -r:System.Data.dll -r:System.Data.OracleClient.dll -r:System.Design.dll -r:System.DirectoryServices.dll -r:System.dll -r:System.Drawing.Design.dll -r:System.Drawing.dll -r:System.EnterpriseServices.dll -r:System.Management.dll -r:System.Messaging.dll -r:System.Runtime.Remoting.dll -r:System.Runtime.Serialization.Formatters.Soap.dll -r:System.Security.dll -r:System.ServiceProcess.dll -r:System.Web.dll -r:System.Web.Services.dll -r:System.Windows.Forms.dll -r:System.Xml.dll -r:System.Configuration.dll -r:System.Core.dll -r:System.Xml.Linq.dll -r:System.Data.DataSetExtensions.dll -r:System.Data.Linq.dll -r:System.Web.Abstractions.dll -r:System.Web.Routing.dll -r:System.Web.DynamicData.dll -r:System.ComponentModel.DataAnnotations.dll +Libs: -r:Accessibility.dll -r:cscompmgd.dll -r:Microsoft.JScript.dll -r:Microsoft.VisualC.dll -r:Microsoft.Vsa.dll -r:System.Configuration.Install.dll -r:System.Data.dll -r:System.Data.OracleClient.dll -r:System.Design.dll -r:System.DirectoryServices.dll -r:System.dll -r:System.Drawing.Design.dll -r:System.Drawing.dll -r:System.EnterpriseServices.dll -r:System.Management.dll -r:System.Messaging.dll -r:System.Runtime.Remoting.dll -r:System.Runtime.Serialization.Formatters.Soap.dll -r:System.Security.dll -r:System.ServiceProcess.dll -r:System.Web.dll -r:System.Web.Services.dll -r:System.Windows.Forms.dll -r:System.Xml.dll -r:System.Configuration.dll -r:System.Core.dll -r:System.Xml.Linq.dll -r:System.Data.DataSetExtensions.dll -r:System.Data.Linq.dll -r:System.Data.Services.dll -r:System.Web.Abstractions.dll -r:System.Web.Routing.dll -r:System.Web.DynamicData.dll -r:System.ComponentModel.DataAnnotations.dll diff --git a/data/mono.pc.in b/data/mono.pc.in new file mode 100644 index 00000000000..0e8727e8e34 --- /dev/null +++ b/data/mono.pc.in @@ -0,0 +1,9 @@ +prefix=${pcfiledir}/../.. +exec_prefix=${pcfiledir}/../.. +libdir=${prefix}/@reloc_libdir@ +includedir=${prefix}/include/mono-@API_VER@ +sysconfdir=@sysconfdir@ + +Name: Mono +Description: Mono Runtime +Version: @VERSION@ diff --git a/data/net_4_0/machine.config b/data/net_4_0/machine.config index 550068cf109..f007af7bdb7 100644 --- a/data/net_4_0/machine.config +++ b/data/net_4_0/machine.config @@ -86,6 +86,9 @@
+ +
+ diff --git a/data/system.web.mvc2.pc.in b/data/system.web.mvc2.pc.in new file mode 100644 index 00000000000..8b173697aa2 --- /dev/null +++ b/data/system.web.mvc2.pc.in @@ -0,0 +1,4 @@ +Name: System.Web.Mvc2 +Description: System.Web.Mvc - ASP.NET MVC v2 +Version: 2.0.0.0 +Libs: -r:@prefix@/lib/mono/gac/System.Web.Mvc/2.0.0.0__31bf3856ad364e35/System.Web.Mvc.dll diff --git a/docs/ChangeLog b/docs/ChangeLog index b78903a7cb4..04f9755dd27 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -1,3 +1,9 @@ +2010-04-06 Andreia Gaita + + * Makefile.am: fix distcheck - several targets get built on the + srcdir, which has no write permissions on make distcheck, so make + sure permissions are set + 2009-12-22 Jo Shields * HtmlAgilityPack/LICENSE: Include upstream license (Ms-PL) since the file headers don't specify it diff --git a/docs/Makefile.am b/docs/Makefile.am index 639b7537d26..c0450027cfd 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -79,21 +79,21 @@ clean-local: monoapi.zip: monoapi.tree @test -f $@ || { rm -f $(srcdir)/monoapi.tree && $(MAKE) monoapi.tree; } -monoapi.tree: docs.make Makefile.am toc.xml $(srcdir)/deploy/.stamp - cd $(srcdir) && cp api-style.css deploy +monoapi.tree: docs.make Makefile.am toc.xml $(srcdir)/deploy/.stamp perms + cd $(srcdir) && cp -f api-style.css deploy cd $(srcdir) && $(MAKE) -f docs.make topdir=$(mcs_topdir_from_srcdir) $@ mono-tools.zip: mono-tools.tree @test -f $@ || { rm -f $(srcdir)/mono-tools.tree && $(MAKE) mono-tools.tree; } -mono-tools.tree: docs.make Makefile.am $(srcdir)/deploy/.stamp +mono-tools.tree: docs.make Makefile.am $(srcdir)/deploy/.stamp perms cd $(srcdir) && $(MAKE) -f docs.make topdir=$(mcs_topdir_from_srcdir) $@ -mono-file-formats.zip: mono-file-formats.tree +mono-file-formats.zip: mono-file-formats.tree perms @test -f $@ || { rm -f $(srcdir)/mono-file-formats.tree && $(MAKE) mono-file-formats.tree; } mono-file-formats.tree: docs.make Makefile.am $(srcdir)/deploy/.stamp cd $(srcdir) && $(MAKE) -f docs.make topdir=$(mcs_topdir_from_srcdir) $@ -$(srcdir)/deploy/.stamp: convert.exe Makefile.am +$(srcdir)/deploy/.stamp: convert.exe Makefile.am perms $(mkdir_p) $(srcdir)/html runtimedir=`cd ../runtime && pwd`; export runtimedir; \ cd $(srcdir) && MONO_PATH=$(mcs_topdir_from_srcdir)/class/lib/net_2_0 perl ./exdoc -h . ../mono/*/*.c @@ -101,8 +101,13 @@ $(srcdir)/deploy/.stamp: convert.exe Makefile.am extract: $(srcdir)/deploy/.stamp -convert.exe: convert.cs AgilityPack.dll +convert.exe: convert.cs AgilityPack.dll perms cd $(srcdir) && $(MAKE) PROFILE=net_2_0 -f docs.make topdir=$(mcs_topdir_from_srcdir) convert.exe -AgilityPack.dll: +AgilityPack.dll: perms cd $(srcdir) && $(MAKE) PROFILE=net_2_0 -f docs.make topdir=$(mcs_topdir_from_srcdir) AgilityPack.dll + +.PHONY: perms +perms: + -@test -w $(srcdir) || chmod a+w $(srcdir) + diff --git a/docs/jit-imt b/docs/jit-imt index 1a2f51733cd..f7751e2e3b6 100644 --- a/docs/jit-imt +++ b/docs/jit-imt @@ -24,7 +24,7 @@ A small note on the choice of magic_reg for different JIT backends: the IMT method identifier doesn't necessarily need to be stored in a register, though doing so is fast and the JIT code has already the infrastructure to handle this case in an arch-independent way. A JIT porter just needs to #define -MONO_ARCH_IMT_REG to the choosen register. Note that this register should be +MONO_ARCH_IMT_REG to the chosen register. Note that this register should be part of the MONO_ARCH_CALLEE_REGS set as it will be handled by the local register allocator (see mini/inssel.brg) and it must not be part of the registers used for argument passing as you'd overwrite an argument in that case. @@ -72,7 +72,7 @@ the IMT slot was asked to execute an interface method that the type doesn't impl In the future we might want to handle this case not with a breakpoint or assert, but by either throwing an InvalidCast exception or by going into the runtime and adding support for the interface automagically to the type/vtable: this could be used -both for tranparent proxies and for the implicit interfaces that vectors in 2.0 +both for transparent proxies and for the implicit interfaces that vectors in 2.0 provide. For a bisect check the code is even simpler: @@ -131,7 +131,7 @@ called the magic trampoline will fill-in the IMT slot with the proper thunk or trampoline, so later calls will use the fast path. This single-instance trampoline will use MONO_FAKE_IMT_METHOD as the method it's asking to be compiled and executed: the trampoline code does recognize -this special value and retrives the interface method to call from the usual +this special value and retrieves the interface method to call from the usual MONO_ARCH_IMT_REG saved by the trampoline code. Given that only the IMT slots that are actually used will be initialized, this saves quite a bit of memory, as it's unlikely that all the interface methods are called on diff --git a/eglib/ChangeLog b/eglib/ChangeLog index 5db80e94e36..60bdd94f906 100644 --- a/eglib/ChangeLog +++ b/eglib/ChangeLog @@ -1,3 +1,35 @@ +2010-04-25 Andreas Faerber + + * configure.ac: The iconv function may be libiconv_open. + Fixes linking with GNU libiconv. + + Contributed under MIT/X11 license. + +2010-04-23 Geoff Norton + + * configure.ac: The iconv function is iconv_open. + +2010-04-19 Jonathan Pryor + + * src/glib.h: Rebase g_return_if_fail(), g_return_val_if_fail() in + terms of g_critical() instead of printf, and turn g_printerr() into + an actual function instead of a macro. + * src/goutput.c: Add Android support, sending g_print(), g_printerr(), + and g_log() messages to the Android system log. + +2010-04-16 Gonzalo Paniagua Javier + + * test/ptrarray.c: new tests + * src/gptrarray.c: implemented g_ptr_array_remove_fast(). + +2010-04-10 Andreas Faerber + + * configure.ac: Add checks for libm and libdl. + * {src,test}/Makefile.am: Remove hardcoded library dependencies. + Fixes compilation on Haiku. + + Contributed under MIT/X11 license. + 2010-03-05 Zoltan Varga * test/test.c (_GNU_SOURCE): Fix compilation if _GNU_SOURCE is already defined. diff --git a/eglib/configure.ac b/eglib/configure.ac index f075d785747..3014d264690 100644 --- a/eglib/configure.ac +++ b/eglib/configure.ac @@ -69,7 +69,10 @@ AM_CONDITIONAL(TARGET_WIN32, test x$OS = xWIN32) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(void *) AC_CHECK_FUNCS(strndup strlcpy getpwent_r strtok_r rewinddir) +AC_CHECK_LIB(iconv, iconv_open, LIBS="$LIBS -liconv") AC_CHECK_LIB(iconv, libiconv_open, LIBS="$LIBS -liconv") +AC_SEARCH_LIBS(sqrtf, m) +AC_SEARCH_LIBS(dlopen, dl) old_ldflags="${LDFLAGS}" LDFLAGS="${LDFLAGS} -Wl,-export-dynamic" AC_TRY_LINK(, [int i;], found_export_dynamic=yes, found_export_dynamic=no) diff --git a/eglib/src/.gitignore b/eglib/src/.gitignore index 53dec7825ac..8d7d614d5ea 100644 --- a/eglib/src/.gitignore +++ b/eglib/src/.gitignore @@ -1,6 +1,10 @@ -/ /Makefile /Makefile.in /.libs /.deps -/eglib-config.h +/*.lo +/*.la +/*.o +/semantic.cache +/.project +/.cproject diff --git a/eglib/src/Makefile.am b/eglib/src/Makefile.am index 337c9886c08..8cd29dc293b 100644 --- a/eglib/src/Makefile.am +++ b/eglib/src/Makefile.am @@ -51,8 +51,6 @@ INCLUDES = -I$(srcdir) if HOST_WIN32 libeglib_la_LIBADD = -lm -liconv -lpsapi -else -libeglib_la_LIBADD = -lm -ldl endif libeglib_static_la_LIBADD = $(libeglib_la_LIBADD) diff --git a/eglib/src/glib.h b/eglib/src/glib.h index ec78f6d2d08..8920d18f26b 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -164,8 +164,8 @@ gchar* g_win32_getlocale(void); /* * Precondition macros */ -#define g_return_if_fail(x) G_STMT_START { if (!(x)) { printf ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return; } } G_STMT_END -#define g_return_val_if_fail(x,e) G_STMT_START { if (!(x)) { printf ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return (e); } } G_STMT_END +#define g_return_if_fail(x) G_STMT_START { if (!(x)) { g_critical ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return; } } G_STMT_END +#define g_return_val_if_fail(x,e) G_STMT_START { if (!(x)) { g_critical ("%s:%d: assertion '%s' failed", __FILE__, __LINE__, #x); return (e); } } G_STMT_END /* * Hashtables @@ -510,6 +510,7 @@ typedef enum { } GLogLevelFlags; void g_print (const gchar *format, ...); +void g_printerr (const gchar *format, ...); GLogLevelFlags g_log_set_always_fatal (GLogLevelFlags fatal_mask); GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain, GLogLevelFlags fatal_mask); void g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args); @@ -522,17 +523,13 @@ void g_assertion_message (const gchar *format, ...) G_GNUC_NORETURN #define g_warning(format, ...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, __VA_ARGS__) #define g_message(format, ...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, __VA_ARGS__) #define g_debug(format, ...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, __VA_ARGS__) - -#define g_printerr(format, ...) fprintf (stderr, format, __VA_ARGS__) -#else +#else /* HAVE_C99_SUPPORT */ #define g_error(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, __VA_ARGS__) #define g_critical(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, __VA_ARGS__) #define g_warning(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, __VA_ARGS__) #define g_message(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__) #define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__) - -#define g_printerr(...) fprintf (stderr, __VA_ARGS__) -#endif +#endif /* ndef HAVE_C99_SUPPORT */ #define g_log_set_handler(a,b,c,d) /* diff --git a/eglib/src/goutput.c b/eglib/src/goutput.c index 3a12201735e..3ed6c91a275 100644 --- a/eglib/src/goutput.c +++ b/eglib/src/goutput.c @@ -31,13 +31,59 @@ /* The current fatal levels, error is always fatal */ static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR; +#if PLATFORM_ANDROID +#include + +static android_LogPriority +to_android_priority (GLogLevelFlags log_level) +{ + switch (log_level & G_LOG_LEVEL_MASK) + { + case G_LOG_LEVEL_ERROR: return ANDROID_LOG_FATAL; + case G_LOG_LEVEL_CRITICAL: return ANDROID_LOG_ERROR; + case G_LOG_LEVEL_WARNING: return ANDROID_LOG_WARN; + case G_LOG_LEVEL_MESSAGE: return ANDROID_LOG_INFO; + case G_LOG_LEVEL_INFO: return ANDROID_LOG_DEBUG; + case G_LOG_LEVEL_DEBUG: return ANDROID_LOG_VERBOSE; + } + return ANDROID_LOG_UNKNOWN; +} + +static void +out_vfprintf (FILE *ignore, const gchar *format, va_list args) +{ + /* TODO: provide a proper app name */ + __android_log_vprint (ANDROID_LOG_ERROR, "mono", format, args); +} +#else +static void +out_vfprintf (FILE *file, const gchar *format, va_list args) +{ + vfprintf (file, format, args); +} +#endif + void g_print (const gchar *format, ...) { va_list args; va_start (args, format); - vprintf (format, args); + + out_vfprintf (stdout, format, args); + + va_end (args); +} + +void +g_printerr (const gchar *format, ...) +{ + va_list args; + + va_start (args, format); + + out_vfprintf (stderr, format, args); + va_end (args); } @@ -68,10 +114,19 @@ g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, char *msg; vasprintf (&msg, format, args); +#if PLATFORM_ANDROID + __android_log_print (to_android_priority (log_level), + /* TODO: provide a proper app name */ + "mono", "%s%s%s", + log_domain != NULL ? log_domain : "", + log_domain != NULL ? ": " : "", + msg); +#else printf ("%s%s%s", log_domain != NULL ? log_domain : "", log_domain != NULL ? ": " : "", msg); +#endif free (msg); if (log_level & fatal){ fflush (stdout); diff --git a/eglib/src/gptrarray.c b/eglib/src/gptrarray.c index 656c7884066..bfde7152255 100644 --- a/eglib/src/gptrarray.c +++ b/eglib/src/gptrarray.c @@ -177,6 +177,27 @@ g_ptr_array_remove(GPtrArray *array, gpointer data) return FALSE; } +gboolean +g_ptr_array_remove_fast(GPtrArray *array, gpointer data) +{ + guint i; + + g_return_val_if_fail(array != NULL, FALSE); + + for(i = 0; i < array->len; i++) { + if(array->pdata[i] == data) { + array->len--; + if (array->len > 0) + array->pdata [i] = array->pdata [array->len]; + else + array->pdata [i] = NULL; + return TRUE; + } + } + + return FALSE; +} + void g_ptr_array_foreach(GPtrArray *array, GFunc func, gpointer user_data) { diff --git a/eglib/src/gshell.c b/eglib/src/gshell.c index f2ccf94093a..1d0c956d17d 100644 --- a/eglib/src/gshell.c +++ b/eglib/src/gshell.c @@ -136,15 +136,145 @@ g_shell_parse_argv (const gchar *command_line, gint *argcp, gchar ***argvp, GErr gchar * g_shell_quote (const gchar *unquoted_string) { - //g_error ("%s", "Not implemented"); - return g_strdup (unquoted_string); -// return NULL; + GString *result = g_string_new ("'"); + const gchar *p; + + for (p = unquoted_string; *p; p++){ + if (*p == '\'') + g_string_append (result, "'\\'"); + g_string_append_c (result, *p); + } + g_string_append_c (result, '\''); + return g_string_free (result, FALSE); } gchar * g_shell_unquote (const gchar *quoted_string, GError **error) { -// g_error ("%s", "Not implemented"); - return g_strdup (quoted_string); -// return NULL; + GString *result; + const char *p; + int do_unquote = 0; + + if (quoted_string == NULL) + return NULL; + + /* Quickly try to determine if we need to unquote or not */ + for (p = quoted_string; *p; p++){ + if (*p == '\'' || *p == '"' || *p == '\\'){ + do_unquote = 1; + break; + } + } + + if (!do_unquote) + return g_strdup (quoted_string); + + /* We do need to unquote */ + result = g_string_new (""); + for (p = quoted_string; *p; p++){ + + if (*p == '\''){ + /* Process single quote, not even \ is processed by glib's version */ + for (p++; *p; p++){ + if (*p == '\'') + break; + g_string_append_c (result, *p); + } + if (!*p){ + g_set_error (error, 0, 0, "Open quote"); + return NULL; + } + } else if (*p == '"'){ + /* Process double quote, allows some escaping */ + for (p++; *p; p++){ + if (*p == '"') + break; + if (*p == '\\'){ + p++; + if (*p == 0){ + g_set_error (error, 0, 0, "Open quote"); + return NULL; + } + switch (*p){ + case '$': + case '"': + case '\\': + case '`': + break; + default: + g_string_append_c (result, '\\'); + break; + } + } + g_string_append_c (result, *p); + } + if (!*p){ + g_set_error (error, 0, 0, "Open quote"); + return NULL; + } + } else if (*p == '\\'){ + char c = *(++p); + if (!(c == '$' || c == '"' || c == '\\' || c == '`' || c == 0)) + g_string_append_c (result, '\\'); + if (c == 0) + break; + else + g_string_append_c (result, c); + } else + g_string_append_c (result, *p); + } + return g_string_free (result, FALSE); +} + +#if JOINT_TEST +/* + * This test is designed to be built with the 2 glib/eglib to compare + */ + +char *args [] = { + "\\", + "\"Foo'bar\"", + "'foo'", + "'fo\'b'", + "'foo\"bar'", + "'foo' dingus bar", + "'foo' 'bar' 'baz'", + "\"foo\" 'bar' \"baz\"", + "\"f\\$\\\'", + "\"\\", + "\\\\", + "'\\\\'", + "\"f\\$\"\\\"\\\\", // /\\\"\\\\" + "'f\\$'\\\"\\\\", + "'f\\$\\\\'", + NULL +}; + + +int +main () +{ + char **s = args; + int i; + + while (*s){ + char *r1 = g_shell_unquote (*s, NULL); + char *r2 = g2_shell_unquote (*s, NULL); + char *ok = r1 == r2 ? "ok" : (r1 != NULL && r2 != NULL && strcmp (r1, r2) == 0) ? "ok" : "fail"; + + printf ("%s [%s] -> [%s] - [%s]\n", ok, *s, r1, r2); + s++; + } + return; + char buffer [10]; + buffer [0] = '\"'; + buffer [1] = '\\'; + buffer [3] = '\"'; + buffer [4] = 0; + + for (i = 32; i < 255; i++){ + buffer [2] = i; + printf ("%d [%s] -> [%s]\n", i, buffer, g_shell_unquote (buffer, NULL)); + } } +#endif diff --git a/eglib/test/.gitignore b/eglib/test/.gitignore index 39e5739e7e2..8d7d614d5ea 100644 --- a/eglib/test/.gitignore +++ b/eglib/test/.gitignore @@ -1,17 +1,10 @@ -/ -/Makefile.in -/configure -/libtool -/aclocal.m4 /Makefile -/config.h -/config.h.in -/config.status -/stamp-h1 -/autom4te.cache +/Makefile.in /.libs /.deps -/test-glib -/test-eglib -/test-glib.exe -/test-eglib.exe +/*.lo +/*.la +/*.o +/semantic.cache +/.project +/.cproject diff --git a/eglib/test/Makefile.am b/eglib/test/Makefile.am index 4f825b3cc61..3411ef90b4a 100644 --- a/eglib/test/Makefile.am +++ b/eglib/test/Makefile.am @@ -30,7 +30,7 @@ SOURCES = \ test_eglib_SOURCES = $(SOURCES) test_eglib_CFLAGS = -Wall -Werror -D_FORTIFY_SOURCE=2 -I$(srcdir)/../src -I../src -DDRIVER_NAME=\"EGlib\" -test_eglib_LDADD = ../src/libeglib.la -ldl +test_eglib_LDADD = ../src/libeglib.la run-eglib: all ./test-eglib diff --git a/eglib/test/ptrarray.c b/eglib/test/ptrarray.c index 1b2cc58c354..a823dd76555 100644 --- a/eglib/test/ptrarray.c +++ b/eglib/test/ptrarray.c @@ -253,6 +253,46 @@ RESULT ptrarray_sort() return OK; } +RESULT ptrarray_remove_fast() +{ + GPtrArray *array = g_ptr_array_new(); + gchar *letters [] = { "A", "B", "C", "D", "E" }; + + if (g_ptr_array_remove_fast (array, NULL)) + return FAILED ("Removing NULL succeeded"); + + g_ptr_array_add(array, letters[0]); + if (!g_ptr_array_remove_fast (array, letters[0]) || array->len != 0) + return FAILED ("Removing last element failed"); + + g_ptr_array_add(array, letters[0]); + g_ptr_array_add(array, letters[1]); + g_ptr_array_add(array, letters[2]); + g_ptr_array_add(array, letters[3]); + g_ptr_array_add(array, letters[4]); + + if (!g_ptr_array_remove_fast (array, letters[0]) || array->len != 4) + return FAILED ("Removing first element failed"); + + if (array->pdata [0] != letters [4]) + return FAILED ("First element wasn't replaced with last upon removal"); + + if (g_ptr_array_remove_fast (array, letters[0])) + return FAILED ("Succedeed removing a non-existing element"); + + if (!g_ptr_array_remove_fast (array, letters[3]) || array->len != 3) + return FAILED ("Failed removing \"D\""); + + if (!g_ptr_array_remove_fast (array, letters[1]) || array->len != 2) + return FAILED ("Failed removing \"B\""); + + if (array->pdata [0] != letters [4] || array->pdata [1] != letters [2]) + return FAILED ("Last two elements are wrong"); + g_ptr_array_free(array, TRUE); + + return OK; +} + static Test ptrarray_tests [] = { {"alloc", ptrarray_alloc}, {"for_iterate", ptrarray_for_iterate}, @@ -262,6 +302,7 @@ static Test ptrarray_tests [] = { {"remove_index_fast", ptrarray_remove_index_fast}, {"remove", ptrarray_remove}, {"sort", ptrarray_sort}, + {"remove_fast", ptrarray_remove_fast}, {NULL, NULL} }; diff --git a/eglib/test/shell.c b/eglib/test/shell.c index 9178625397b..38252cd2e0e 100644 --- a/eglib/test/shell.c +++ b/eglib/test/shell.c @@ -226,10 +226,25 @@ test_shell_argv3 () return OK; } +RESULT +test_quote () +{ + if (strcmp (g_shell_quote ("foo"), "'foo'")) + return FAILED ("Should return 'foo'"); + + if (strcmp (g_shell_quote ("foo'bar"), "'foo'\\''bar'")) + return FAILED ("Should return 'foo'\\''bar'"); + + if (strcmp (g_shell_quote ("foo bar"), "'foo bar'")) + return FAILED ("Should return 'foo bar'"); + return OK; +} + static Test shell_tests [] = { {"g_shell_parse_argv1", test_shell_argv1}, {"g_shell_parse_argv2", test_shell_argv2}, {"g_shell_parse_argv3", test_shell_argv3}, + {"g_shell_quote", test_quote}, {NULL, NULL} }; diff --git a/libgc/ChangeLog b/libgc/ChangeLog index b6235a28389..114a3b27551 100644 --- a/libgc/ChangeLog +++ b/libgc/ChangeLog @@ -1,3 +1,16 @@ +2010-04-23 Geoff Norton + + * include/private/gcconfig.h: Darwin x86-64 bit support. + * darwin_stop_world.c: Ditto + +2010-04-19 Jonathan Pryor + + * include/private/gcconfig.h: Android platforms are built atop Linux, + don't use glibc, and uses `environ` instead of `__environ`. + * configure.in: Use AC_CHECK_LIB() to check for pthread instead of + just blindly linking to -lpthread, as Android includes pthread + support within libc and doesn't provide a separate libpthread. + 2010-03-09 Zoltan Varga * include/private/gc_locks.h: Fix amd64 build with newer gcc's. diff --git a/libgc/configure.in b/libgc/configure.in index 2749d08b13b..2f7e173189b 100644 --- a/libgc/configure.in +++ b/libgc/configure.in @@ -84,7 +84,7 @@ case "$THREADS" in ;; posix | pthreads) THREADS=posix - THREADDLLIBS=-lpthread + AC_CHECK_LIB(pthread, pthread_self, THREADDLLIBS="-lpthread",,) case "$host" in x86-*-linux* | ia64-*-linux* | i386-*-linux* | i486-*-linux* | i586-*-linux* | i686-*-linux* | x86_64-*-linux* | alpha*-*-linux* | s390*-*-linux* | sparc*-*-linux* | powerpc-*-linux*) AC_DEFINE(GC_LINUX_THREADS) diff --git a/libgc/darwin_stop_world.c b/libgc/darwin_stop_world.c index 0c85c005729..7e60fe790f5 100644 --- a/libgc/darwin_stop_world.c +++ b/libgc/darwin_stop_world.c @@ -89,6 +89,9 @@ void GC_push_all_stacks() { #elif defined(ARM) arm_thread_state_t state; mach_msg_type_number_t thread_state_count = ARM_THREAD_STATE_COUNT; +#elif defined(X86_64) + x86_thread_state64_t state; + mach_msg_type_number_t thread_state_count = x86_THREAD_STATE64_COUNT; #else # error FIXME for non-x86 || ppc architectures mach_msg_type_number_t thread_state_count = MACHINE_THREAD_STATE_COUNT; @@ -109,7 +112,7 @@ void GC_push_all_stacks() { GC_MACH_THREAD_STATE_FLAVOR, (natural_t*)&state, &thread_state_count); - if(r != KERN_SUCCESS) ABORT("thread_get_state failed"); + if(r != KERN_SUCCESS) continue; #if defined(I386) #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 @@ -134,6 +137,29 @@ void GC_push_all_stacks() { GC_push_one(state.esi); GC_push_one(state.ebp); #endif +#elif defined(X86_64) + lo = state.__rsp; + GC_push_one(state.__rax); + GC_push_one(state.__rbx); + GC_push_one(state.__rcx); + GC_push_one(state.__rdx); + GC_push_one(state.__rdi); + GC_push_one(state.__rsi); + GC_push_one(state.__rbp); + GC_push_one(state.__rsp); + GC_push_one(state.__r8); + GC_push_one(state.__r9); + GC_push_one(state.__r10); + GC_push_one(state.__r11); + GC_push_one(state.__r12); + GC_push_one(state.__r13); + GC_push_one(state.__r14); + GC_push_one(state.__r15); + GC_push_one(state.__rip); + GC_push_one(state.__rflags); + GC_push_one(state.__cs); + GC_push_one(state.__fs); + GC_push_one(state.__gs); #elif defined(POWERPC) #if defined(_STRUCT_PPC_EXCEPTION_STATE) lo = (void*)(state.__r1 - PPC_RED_ZONE_SIZE); diff --git a/libgc/include/private/gcconfig.h b/libgc/include/private/gcconfig.h index 860195c857f..10ffed63755 100644 --- a/libgc/include/private/gcconfig.h +++ b/libgc/include/private/gcconfig.h @@ -332,6 +332,9 @@ # define mach_type_known # define DARWIN_DONT_PARSE_STACK # define GC_DONT_REGISTER_MAIN_STATIC_DATA +# elif defined(__x86_64) +# define X86_64 +# define mach_type_known # endif # endif # if defined(NeXT) && defined(mc68000) @@ -710,6 +713,9 @@ # if defined(__GLIBC__)&& __GLIBC__>=2 # define SEARCH_FOR_DATA_START # else /* !GLIBC2 */ +# if defined(PLATFORM_ANDROID) +# define __environ environ +# endif extern char **__environ; # define DATASTART ((ptr_t)(&__environ)) /* hideous kludge: __environ is the first */ @@ -2034,6 +2040,27 @@ # define PREFETCH_FOR_WRITE(x) __builtin_prefetch((x), 1) # endif # endif +# ifdef DARWIN +# define OS_TYPE "DARWIN" +# define DARWIN_DONT_PARSE_STACK +# define DYNAMIC_LOADING + /* XXX: see get_end(3), get_etext() and get_end() should not be used. + These aren't used when dyld support is enabled (it is by default) */ +# define DATASTART ((ptr_t) get_etext()) +# define DATAEND ((ptr_t) get_end()) +# define STACKBOTTOM ((ptr_t) 0x7fff5fc00000) +# ifndef USE_MMAP +# define USE_MMAP +# endif +# define USE_MMAP_ANON +# ifdef GC_DARWIN_THREADS +# define MPROTECT_VDB +# endif +# include +# define GETPAGESIZE() getpagesize() + /* There seems to be some issues with trylock hanging on darwin. This + should be looked into some more */ +# endif # ifdef FREEBSD # define OS_TYPE "FREEBSD" # ifndef GC_FREEBSD_THREADS diff --git a/man/ChangeLog b/man/ChangeLog index e0a3ab437ab..f5feb5061a7 100644 --- a/man/ChangeLog +++ b/man/ChangeLog @@ -1,3 +1,19 @@ +2010-04-23 Miguel de Icaza + + * mono.1: Sort environment variables, update a couple of docs. + +2010-04-07 Andrés G. Aragoneses + + * monolinker.1: Fix typo. + +2010-04-01 Sebastien Pouliot + + * mono.1: Document the new "security" option for logging + +2010-03-26 Zoltan Varga + + * mono.1: Document the MONO_ENABLE_SHM env variable. + 2010-03-03 Rolf Bjarne Kvinge * mono.1: Document exception tracing. diff --git a/man/mono.1 b/man/mono.1 index ea99ab88a70..dca52985d3f 100644 --- a/man/mono.1 +++ b/man/mono.1 @@ -237,6 +237,14 @@ collection a bit. \fB--help\fR, \fB-h\fR Displays usage instructions. .TP +\fB--llvm\fR +If the Mono runtime has been compiled with LLVM support (not available +in all configurations), Mono will use the LLVM optimization and code +generation engine to JIT or AOT compile. You can also use the +\fBMONO_USE_LLVM\fR environment variable to turn this on +.Sp +For more information, consult: http://www.mono-project.com/Mono_LLVM +.TP \fB--optimize=MODE\fR, \fB-O=MODE\fR MODE is a comma separated list of optimizations. They also allow optimizations to be turned off by prefixing the optimization name with @@ -1131,7 +1139,8 @@ Use the environment variable to limit the extent of the messages you get: If set, the log mask is changed to the set value. Possible values are "asm" (assembly loader), "type", "dll" (native library loader), "gc" -(garbage collector), "cfg" (config file loader), "aot" (precompiler) and "all". +(garbage collector), "cfg" (config file loader), "aot" (precompiler), +"security" (e.g. Moonlight CoreCLR support) and "all". The default value is "all". Changing the mask value allows you to display only messages for a certain component. You can use multiple masks by comma separating them. For example to see config file messages and assembly loader @@ -1186,6 +1195,16 @@ If set, this variable will instruct Mono to ahead-of-time compile new assemblies on demand and store the result into a cache in ~/.mono/aot-cache. .TP +\fBMONO_ASPNET_INHIBIT_SETTINGSMAP\fR +Mono contains a feature which allows modifying settings in the .config files shipped +with Mono by using config section mappers. The mappers and the mapping rules are +defined in the $prefix/etc/mono/2.0/settings.map file and, optionally, in the +settings.map file found in the top-level directory of your ASP.NET application. +Both files are read by System.Web on application startup, if they are found at the +above locations. If you don't want the mapping to be performed you can set this +variable in your environment before starting the application and no action will +be taken. +.TP \fBMONO_CFG_DIR\fR If set, this variable overrides the default system configuration directory ($PREFIX/etc). It's used to locate machine.config file. @@ -1201,61 +1220,21 @@ If set, this variable overrides the default runtime configuration file ($PREFIX/etc/mono/config). The --config command line options overrides the environment variable. .TP -\fBMONO_DEBUG\fR -If set, enables some features of the runtime useful for debugging. -This variable should contain a comma separated list of debugging options. -Currently, the following options are supported: -.RS -.ne 8 -.TP -\fBbreak-on-unverified\fR -If this variable is set, when the Mono VM runs into a verification -problem, instead of throwing an exception it will break into the -debugger. This is useful when debugging verifier problems -.TP -\fBcollect-pagefault-stats\fR -Collects information about pagefaults. This is used internally to -track the number of page faults produced to load metadata. To display -this information you must use this option with "--stats" command line -option. -.TP -\fBdont-free-domains\fR -This is an Optimization for multi-AppDomain applications (most -commonly ASP.NET applications). Due to internal limitations Mono, -Mono by default does not use typed allocations on multi-appDomain -applications as they could leak memory when a domain is unloaded. -.Sp -Although this is a fine default, for applications that use more than -on AppDomain heavily (for example, ASP.NET applications) it is worth -trading off the small leaks for the increased performance -(additionally, since ASP.NET applications are not likely going to -unload the application domains on production systems, it is worth -using this feature). -.TP -\fBhandle-sigint\fR -Captures the interrupt signal (Control-C) and displays a stack trace -when pressed. Useful to find out where the program is executing at a -given point. This only displays the stack trace of a single thread. -.TP -\fBkeep-delegates\fR -This option will leak delegate trampolines that are no longer -referenced as to present the user with more information about a -delegate misuse. Basically a delegate instance might be created, -passed to unmanaged code, and no references kept in managed code, -which will garbage collect the code. With this option it is possible -to track down the source of the problems. -.TP -\fBno-gdb-backtrace\fR -This option will disable the GDB backtrace emitted by the runtime -after a SIGSEGV or SIGABRT in unmanaged code. -.TP -\fBsuspend-on-sigsegv\fR +\fBMONO_CPU_ARCH\fR +Override the automatic cpu detection mechanism. Currently used only on arm. +The format of the value is as follows: +.nf -This option will suspend the program when a native SIGSEGV is received. -This is useful for debugging crashes which do not happen under gdb, -since a live process contains more information than a core file. -.ne -.RE + "armvV [thumb]" + +.fi +where V is the architecture number 4, 5, 6, 7 and the options can be currently be +"thunb". Example: +.nf + + MONO_CPU_ARCH="armv4 thumb" mono ... + +.fi .TP \fBMONO_DISABLE_AIO\fR If set, tells mono NOT to attempt using native asynchronous I/O services. In @@ -1269,11 +1248,28 @@ internally disables managed collation functionality invoked via the members of System.Globalization.CompareInfo class. Collation is enabled by default. .TP +\fBMONO_DISABLE_SHM\fR +Unix only: If set, disables the shared memory files used for +cross-process handles: process have only private handles. This means +that process and thread handles are not available to other processes, +and named mutexes, named events and named semaphores are not visible +between processes. +.Sp +This is can also be enabled by default by passing the +"--disable-shared-handles" option to configure. +.Sp +This is the default from mono 2.8 onwards. +.TP \fBMONO_EGD_SOCKET\fR For platforms that do not otherwise have a way of obtaining random bytes this can be set to the name of a file system socket on which an egd or prngd daemon is listening. .TP +\fBMONO_ENABLE_SHM\fR +Unix only: Enable support for cross-process handles. Cross-process +handles are used to expose process handles, thread handles, named +mutexes, named events and named semaphores across Unix processes. +.TP \fBMONO_EVENTLOG_TYPE\fR Sets the type of event log provider to use (for System.Diagnostics.EventLog). .Sp @@ -1393,10 +1389,24 @@ managed implementation (slow). If unset, mono will try to use inotify, FAM, Gamin, kevent under Unix systems and native API calls on Windows, falling back to the managed implementation on error. .TP +\fBMONO_MESSAGING_PROVIDER\fR +Mono supports a plugin model for its implementation of System.Messaging making +it possible to support a variety of messaging implementations (e.g. AMQP, ActiveMQ). +To specify which messaging implementation is to be used the evironement variable +needs to be set to the full class name for the provider. E.g. to use the RabbitMQ based +AMQP implementation the variable should be set to: + +.nf +Mono.Messaging.RabbitMQ.RabbitMQMessagingProvider,Mono.Messaging.RabbitMQ +.TP \fBMONO_NO_SMP\fR If set causes the mono process to be bound to a single processor. This may be useful when debugging or working around race conditions. .TP +\fBMONO_NO_TLS\fR +Disable inlining of thread local accesses. Try setting this if you get a segfault +early on in the execution of mono. +.TP \fBMONO_PATH\fR Provides a search path to the runtime where to look for library files. This is a tool convenient for debugging applications, but @@ -1430,26 +1440,6 @@ For example: MONO_RTC=4096 mono --profiler=default:stat program.exe -.fi -.TP -\fBMONO_NO_TLS\fR -Disable inlining of thread local accesses. Try setting this if you get a segfault -early on in the execution of mono. -.TP -\fBMONO_CPU_ARCH\fR -Override the automatic cpu detection mechanism. Currently used only on arm. -The format of the value is as follows: -.nf - - "armvV [thumb]" - -.fi -where V is the architecture number 4, 5, 6, 7 and the options can be currently be -"thunb". Example: -.nf - - MONO_CPU_ARCH="armv4 thumb" mono ... - .fi .TP \fBMONO_SHARED_DIR\fR @@ -1472,16 +1462,6 @@ home directories that might be shared over the network. If set, extra checks are made during IO operations. Currently, this includes only advisory locks around file writes. .TP -\fBMONO_DISABLE_SHM\fR -If set, disables the shared memory files used for cross-process -handles: process have only private handles. This means that process -and thread handles are not available to other processes, and named -mutexes, named events and named semaphores are not visible between -processes. -.Sp -This is can also be enabled by default by passing the -"--disable-shared-handles" option to configure. -.TP \fBMONO_THEME\fR The name of the theme to be used by Windows.Forms. Available themes today include "clearlooks", "nice" and "win32". @@ -1501,6 +1481,13 @@ The maximum number of threads in the general threadpool will be 20 + (MONO_THREADS_PER_CPU * number of CPUs). The default value for this variable is 10. .TP +\fBMONO_USE_LLVM\fR +If the Mono runtime has been compiled with LLVM support (not available +in all configurations), Mono will use the LLVM optimization and code +generation engine to JIT or AOT compile. This is equivalent to +using the \-\-llvm command line option, but is useful for global +configurations. +.TP \fBMONO_XMLSERIALIZER_THS\fR Controls the threshold for the XmlSerializer to produce a custom serializer for a given class instead of using the Reflection-based @@ -1508,31 +1495,6 @@ interpreter. The possible values are `no' to disable the use of a custom serializer or a number to indicate when the XmlSerializer should start serializing. The default value is 50, which means that the a custom serializer will be produced on the 50th use. -.TP -\fBMONO_XMLSERIALIZER_DEBUG\fR -Set this value to 1 to prevent the serializer from removing the -temporary files that are created for fast serialization; This might -be useful when debugging. -.TP -\fBMONO_ASPNET_INHIBIT_SETTINGSMAP\fR -Mono contains a feature which allows modifying settings in the .config files shipped -with Mono by using config section mappers. The mappers and the mapping rules are -defined in the $prefix/etc/mono/2.0/settings.map file and, optionally, in the -settings.map file found in the top-level directory of your ASP.NET application. -Both files are read by System.Web on application startup, if they are found at the -above locations. If you don't want the mapping to be performed you can set this -variable in your environment before starting the application and no action will -be taken. -.TP -\fBMONO_MESSAGING_PROVIDER\fR -Mono supports a plugin model for its implementation of System.Messaging making -it possible to support a variety of messaging implementations (e.g. AMQP, ActiveMQ). -To specify which messaging implementation is to be used the evironement variable -needs to be set to the full class name for the provider. E.g. to use the RabbitMQ based -AMQP implementation the variable should be set to: - -.nf -Mono.Messaging.RabbitMQ.RabbitMQMessagingProvider,Mono.Messaging.RabbitMQ .SH ENVIRONMENT VARIABLES FOR DEBUGGING .TP \fBMONO_ASPNET_NODELETE\fR @@ -1540,6 +1502,62 @@ If set to any value, temporary source files generated by ASP.NET support classes will not be removed. They will be kept in the user's temporary directory. .TP +\fBMONO_DEBUG\fR +If set, enables some features of the runtime useful for debugging. +This variable should contain a comma separated list of debugging options. +Currently, the following options are supported: +.RS +.ne 8 +.TP +\fBbreak-on-unverified\fR +If this variable is set, when the Mono VM runs into a verification +problem, instead of throwing an exception it will break into the +debugger. This is useful when debugging verifier problems +.TP +\fBcollect-pagefault-stats\fR +Collects information about pagefaults. This is used internally to +track the number of page faults produced to load metadata. To display +this information you must use this option with "--stats" command line +option. +.TP +\fBdont-free-domains\fR +This is an Optimization for multi-AppDomain applications (most +commonly ASP.NET applications). Due to internal limitations Mono, +Mono by default does not use typed allocations on multi-appDomain +applications as they could leak memory when a domain is unloaded. +.Sp +Although this is a fine default, for applications that use more than +on AppDomain heavily (for example, ASP.NET applications) it is worth +trading off the small leaks for the increased performance +(additionally, since ASP.NET applications are not likely going to +unload the application domains on production systems, it is worth +using this feature). +.TP +\fBhandle-sigint\fR +Captures the interrupt signal (Control-C) and displays a stack trace +when pressed. Useful to find out where the program is executing at a +given point. This only displays the stack trace of a single thread. +.TP +\fBkeep-delegates\fR +This option will leak delegate trampolines that are no longer +referenced as to present the user with more information about a +delegate misuse. Basically a delegate instance might be created, +passed to unmanaged code, and no references kept in managed code, +which will garbage collect the code. With this option it is possible +to track down the source of the problems. +.TP +\fBno-gdb-backtrace\fR +This option will disable the GDB backtrace emitted by the runtime +after a SIGSEGV or SIGABRT in unmanaged code. +.TP +\fBsuspend-on-sigsegv\fR + +This option will suspend the program when a native SIGSEGV is received. +This is useful for debugging crashes which do not happen under gdb, +since a live process contains more information than a core file. +.ne +.RE +.TP \fBMONO_LOG_LEVEL\fR The logging level, possible values are `error', `critical', `warning', `message', `info' and `debug'. See the DEBUGGING section for more @@ -1549,7 +1567,8 @@ details. Controls the domain of the Mono runtime that logging will apply to. If set, the log mask is changed to the set value. Possible values are "asm" (assembly loader), "type", "dll" (native library loader), "gc" -(garbage collector), "cfg" (config file loader), "aot" (precompiler) and "all". +(garbage collector), "cfg" (config file loader), "aot" (precompiler), +"security" (e.g. Moonlight CoreCLR support) and "all". The default value is "all". Changing the mask value allows you to display only messages for a certain component. You can use multiple masks by comma separating them. For example to see config file messages and assembly loader @@ -1584,6 +1603,11 @@ information. This throws an exception when a X11 error is encountered; by default a message is displayed but execution continues .TP +\fBMONO_XMLSERIALIZER_DEBUG\fR +Set this value to 1 to prevent the serializer from removing the +temporary files that are created for fast serialization; This might +be useful when debugging. +.TP \fBMONO_XSYNC\fR This is used in the System.Windows.Forms implementation when running with the X11 backend. This is used to debug problems in Windows.Forms diff --git a/man/monolinker.1 b/man/monolinker.1 index ed207770aa9..f8baa8b3819 100644 --- a/man/monolinker.1 +++ b/man/monolinker.1 @@ -142,7 +142,7 @@ is necessary for this assembly to run. use a .info xml file as a source for the linker. .Sp An info file is a file produced by the tool mono-api-info. The linker will use it to -generate an assembly that contains only what the public API defined in he info file +generate an assembly that contains only what the public API defined in the info file needs. .TP .I "-s [StepBefore:]StepFullName,StepAssembly[:StepAfter]" diff --git a/man/monop.1 b/man/monop.1 index 2d7df2093ed..fa913978dc0 100644 --- a/man/monop.1 +++ b/man/monop.1 @@ -9,6 +9,9 @@ monop, monop2 \- Mono Class Outline Viewer .I \-r:assembly Specifies the assembly to use for looking up the type .TP +.I \-a +Renders all of the types in the specified assembly. +.TP .I \-\-search, \-s, \-k Searches through all known assemblies for types containing `class'. .TP diff --git a/mcs/ChangeLog b/mcs/ChangeLog index e4e31b255d4..3111e81a8d6 100644 --- a/mcs/ChangeLog +++ b/mcs/ChangeLog @@ -1,3 +1,11 @@ +2010-04-03 Ankit Jain + + * Makefile: Process tools/xbuild for 3.5 also. + +2010-03-16 Jb Evain + + * Makefile: rename the net_2_1 profile to moonlight. + 2010-03-03 Rolf Bjarne Kvinge * Makefile: Make basic the bootstrapping profile for net_2_1_bootstrap. diff --git a/mcs/Makefile b/mcs/Makefile index b30f44ec5df..3c04be99c3d 100644 --- a/mcs/Makefile +++ b/mcs/Makefile @@ -5,12 +5,12 @@ SUBDIRS := build jay mcs class nunit24 ilasm tools tests errors docs basic_SUBDIRS := build jay mcs class tools net_2_0_bootstrap_SUBDIRS := build tools net_2_0_SUBDIRS := build mcs class nunit24 ilasm tools tests errors -net_2_1_bootstrap_SUBDIRS := build mcs class -net_2_1_raw_SUBDIRS := build mcs class tools -net_2_1_SUBDIRS := tools tests errors +moonlight_bootstrap_SUBDIRS := build mcs class +moonlight_raw_SUBDIRS := build mcs class tools +moonlight_SUBDIRS := tools tests errors monotouch_SUBDIRS := build mcs class monotouch_bootstrap_SUBDIRS := build mcs class -net_3_5_SUBDIRS := build class +net_3_5_SUBDIRS := build class tools/xbuild net_4_0_bootstrap_SUBDIRS := build mcs class tools net_4_0_SUBDIRS := build mcs class nunit24 ilasm tools tests errors docs @@ -106,11 +106,11 @@ _boot_ = all clean install $(_boot_:%=profile-do--net_4_0--%): profile-do--net_4_0--%: profile-do--net_4_0_bootstrap--% $(_boot_:%=profile-do--net_4_0_bootstrap--%): profile-do--net_4_0_bootstrap--%: profile-do--net_2_0--% $(_boot_:%=profile-do--net_3_5--%): profile-do--net_3_5--%: profile-do--net_2_0--% -$(_boot_:%=profile-do--net_2_1--%): profile-do--net_2_1--%: profile-do--net_2_1_raw--% +$(_boot_:%=profile-do--moonlight--%): profile-do--moonlight--%: profile-do--moonlight_raw--% $(_boot_:%=profile-do--monotouch--%): profile-do--monotouch--%: profile-do--monotouch_bootstrap--% $(_boot_:%=profile-do--monotouch_bootstrap--%): profile-do--monotouch_bootstrap--%: profile-do--net_2_0--% -$(_boot_:%=profile-do--net_2_1_raw--%): profile-do--net_2_1_raw--%: profile-do--net_2_1_bootstrap--% -$(_boot_:%=profile-do--net_2_1_bootstrap--%): profile-do--net_2_1_bootstrap--%: profile-do--basic--% +$(_boot_:%=profile-do--moonlight_raw--%): profile-do--moonlight_raw--%: profile-do--moonlight_bootstrap--% +$(_boot_:%=profile-do--moonlight_bootstrap--%): profile-do--moonlight_bootstrap--%: profile-do--basic--% $(_boot_:%=profile-do--net_2_0--%): profile-do--net_2_0--%: profile-do--net_2_0_bootstrap--% $(_boot_:%=profile-do--net_2_0_bootstrap--%): profile-do--net_2_0_bootstrap--%: profile-do--basic--% diff --git a/mcs/build/ChangeLog b/mcs/build/ChangeLog index 2b6610dd975..c60dbb3aa17 100644 --- a/mcs/build/ChangeLog +++ b/mcs/build/ChangeLog @@ -1,3 +1,39 @@ +2010-04-16 Raja R Harinath + + * profiles/net_4_0_bootstrap.make (PROFILE_MCS_HAS_BOOTSTRAP_FALLBACK): + New. Can be set if we have BOOTSTRAP_PROFILE listed in the + MONO_PATH of MCS, and the profile's System.dll depends features + the profile's mscorlib.dll. + +2010-04-07 Raja R Harinath + + * Makefile (DISTFILES): Add gensources.sh. + * gensources.sh: New, improved version of tools/gensources.sh. + * library.make ($(sourcefile)): Use the new gensources.sh. + ($(makefrag)): Update to handle the optional makefrag generated by + gensources.sh. + +2010-04-01 Zoltan Varga + + * config-default.make (LIBRARY_FLAGS): Applied patch from Laurent Etiemble + (laurent.etiemble@gmail.com). Use CFLAGS in the environment if defined. + +2010-03-31 Zoltan Varga + + * library.make ($(the_lib)$(PLATFORM_AOT_SUFFIX)): Pass --debug to the aot + compiler. Fixes #592545. + +2010-03-16 Jonathan Pryor + + * library.make (MDOC_UP): Set MONO_PATH to find monodoc.dll. + * rules.make (MDOC): MONO_PATH needs to include + $(topdir)/class/lib/net_2_0 so that monodoc.dll can be found. + +2010-03-16 Jb Evain + + * profiles/net_2_1_*.make: rename to moonlight_*.make and + define the MOONLIGHT symbol. + 2010-03-03 Jonathan Pryor * library.make: Add the generated per-profile .source file to diff --git a/mcs/build/Makefile b/mcs/build/Makefile index 08640a9f4ac..69721f73b68 100644 --- a/mcs/build/Makefile +++ b/mcs/build/Makefile @@ -19,9 +19,9 @@ PROFILES = \ basic \ net_2_0_bootstrap \ net_2_0 \ - net_2_1_bootstrap \ - net_2_1_raw \ - net_2_1 \ + moonlight_bootstrap \ + moonlight_raw \ + moonlight \ net_3_5 \ net_4_0_bootstrap \ net_4_0 @@ -40,6 +40,7 @@ DISTFILES = \ corcompare.make \ corcompare-api.xsl \ executable.make \ + gensources.sh \ library.make \ nunit-summary.xsl \ rules.make \ diff --git a/mcs/build/common/ChangeLog b/mcs/build/common/ChangeLog index 6f4b0776438..df647834d2e 100644 --- a/mcs/build/common/ChangeLog +++ b/mcs/build/common/ChangeLog @@ -1,3 +1,17 @@ +2010-04-16 Raja R Harinath + + * basic-profile-check.cs: Add use of 'var' keyword. + +2010-04-15 Atsushi Enomoto + + * Consts.cs.in : Add AssemblyWindowsBase, AssemblyPresentationCore_3_5 + and AssemblyPresentationFramework_3_5. + +2010-04-06 Jb Evain + + * Consts.cs.in: define Assembly_System_2_0 for TypeForwardedFrom + attributes in NET_4_0. + 2010-01-07 Sebastien Pouliot * Consts.cs.in: Update FX version for SL3 latest released version diff --git a/mcs/build/common/Consts.cs.in b/mcs/build/common/Consts.cs.in index 31750ed2f9c..671043b9cd1 100644 --- a/mcs/build/common/Consts.cs.in +++ b/mcs/build/common/Consts.cs.in @@ -41,7 +41,7 @@ static class Consts #if NET_4_0 || BOOTSTRAP_NET_4_0 public const string FxVersion = "4.0.0.0"; - public const string FxFileVersion = "4.0.21006.1"; + public const string FxFileVersion = "4.0.30319.1"; public const string VsVersion = "0.0.0.0"; // Useless ? public const string VsFileVersion = "10.0.0.0"; // TODO: @@ -103,9 +103,13 @@ static class Consts public const string AssemblySystem_Web = "System.Web, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"; public const string AssemblySystem_Windows_Forms = "System.Windows.Forms, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089"; #if NET_4_0 || BOOTSTRAP_NET_4_0 + public const string AssemblySystem_2_0 = "System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystemCore_3_5 = "System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string AssemblySystem_Core = "System.Core, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089"; public const string WindowsBase_3_0 = "WindowsBase, Version=3.0.0.0, PublicKeyToken=31bf3856ad364e35"; + public const string AssemblyWindowsBase = "WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + public const string AssemblyPresentationCore_3_5 = "PresentationCore, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; + public const string AssemblyPresentationFramework_3_5 = "PresentationFramework, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"; #elif NET_2_1 public const string AssemblySystem_Core = "System.Core, Version=" + FxVersion + ", Culture=neutral, PublicKeyToken=b77a5c561934e089"; #elif NET_2_0 diff --git a/mcs/build/common/basic-profile-check.cs b/mcs/build/common/basic-profile-check.cs index dd104e32fa3..a945efb220d 100644 --- a/mcs/build/common/basic-profile-check.cs +++ b/mcs/build/common/basic-profile-check.cs @@ -1,6 +1,10 @@ class X { // Check installed compiler - static void Generic () { } + static void Generic () + { + // we use 'var' all around in the compiler sources + var x = new X (); + } static int Main () { diff --git a/mcs/build/config-default.make b/mcs/build/config-default.make index c556006cfc5..a6969592c55 100644 --- a/mcs/build/config-default.make +++ b/mcs/build/config-default.make @@ -14,7 +14,9 @@ TEST_HARNESS = $(topdir)/class/lib/$(PROFILE)/nunit-console.exe MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS) MBAS_FLAGS = $(PLATFORM_DEBUG_FLAGS) LIBRARY_FLAGS = /noconfig +ifndef CFLAGS CFLAGS = -g -O2 +endif prefix = /usr/local exec_prefix = $(prefix) mono_libdir = $(exec_prefix)/lib diff --git a/mcs/build/gensources.sh b/mcs/build/gensources.sh new file mode 100644 index 00000000000..61639e54a29 --- /dev/null +++ b/mcs/build/gensources.sh @@ -0,0 +1,49 @@ +#! /bin/sh + +outfile=$1 +incfile=$2 +excfile=$3 + +process_includes_1() { + sed -e '/^[ \t]*$/d' -e '/^[ \t]*#/d' $1 > $2 + if cmp -s $1 $2; then + false + else + sed -n 's,^[ \t]*#include ,,p' $1 | + while read inc; do + cat $inc >> $2 + echo $outfile: $inc >> $outfile.makefrag + echo $inc: >> $outfile.makefrag + done + fi +} + +process_includes() { + i=$1; o=$2; t=${2}.tmp + while process_includes_1 $i $o; do + mv $o $t + i=$t + done + rm -f $t +} + +rm -f $outfile.makefrag + +process_includes $incfile $outfile.inc + +sort -u $outfile.inc > $outfile.inc_s +rm -f $outfile.inc + +if test -z "$excfile"; then + mv $outfile.inc_s $outfile +else + process_includes $excfile $outfile.exc + + sort -u $outfile.exc > $outfile.exc_s + rm -f $outfile.exc + + sort -m $outfile.inc_s $outfile.exc_s | uniq -u > $outfile + rm -f $outfile.inc_s $outfile.exc_s +fi + + diff --git a/mcs/build/library.make b/mcs/build/library.make index f5844153850..7bf697ed1c7 100644 --- a/mcs/build/library.make +++ b/mcs/build/library.make @@ -11,15 +11,17 @@ sourcefile = $(LIBRARY).sources # If the directory contains the per profile include file, generate list file. -PROFILE_sources = $(PROFILE)_$(LIBRARY).sources -ifeq ($(wildcard $(PROFILE_sources)), $(PROFILE_sources)) +PROFILE_sources := $(wildcard $(PROFILE)_$(LIBRARY).sources) +ifdef PROFILE_sources PROFILE_excludes = $(wildcard $(PROFILE)_$(LIBRARY).exclude.sources) -COMMON_sourcefile := $(sourcefile) sourcefile = $(depsdir)/$(PROFILE)_$(LIBRARY).sources -$(sourcefile): $(PROFILE_sources) $(PROFILE_excludes) $(COMMON_sourcefile) - @echo Creating the per profile list $@ ... - $(topdir)/tools/gensources.sh $(PROFILE_sources) $(PROFILE_excludes) > $@ library_CLEAN_FILES += $(sourcefile) + +# Note, gensources.sh can create a $(sourcefile).makefrag if it sees any '#include's +# We don't include it in the dependencies since it isn't always created +$(sourcefile): $(PROFILE_sources) $(PROFILE_excludes) $(topdir)/build/gensources.sh + @echo Creating the per profile list $@ ... + $(SHELL) $(topdir)/build/gensources.sh $@ $(PROFILE_sources) $(PROFILE_excludes) endif PLATFORM_excludes := $(wildcard $(LIBRARY).$(PLATFORM)-excludes) @@ -32,7 +34,7 @@ endif ifndef response response = $(depsdir)/$(PROFILE)_$(LIBRARY).response -library_CLEAN_FILES += $(response) $(LIBRARY).mdb $(BUILT_SOURCES) +library_CLEAN_FILES += $(response) endif ifndef LIBRARY_NAME @@ -45,13 +47,7 @@ else lib_dir = lib endif -makefrag = $(depsdir)/$(PROFILE)_$(LIBRARY).makefrag the_libdir = $(topdir)/class/$(lib_dir)/$(PROFILE)/ -the_lib = $(the_libdir)$(LIBRARY_NAME) -the_pdb = $(the_lib:.dll=.pdb) -the_mdb = $(the_lib).mdb -library_CLEAN_FILES += $(makefrag) $(the_lib) $(the_lib).so $(the_pdb) $(the_mdb) - ifdef LIBRARY_NEEDS_POSTPROCESSING build_libdir = fixup/$(PROFILE)/ else @@ -62,8 +58,10 @@ build_libdir = $(the_libdir) endif endif +the_lib = $(the_libdir)$(LIBRARY_NAME) build_lib = $(build_libdir)$(LIBRARY_NAME) -library_CLEAN_FILES += $(build_lib) $(build_lib:.dll=.pdb) +library_CLEAN_FILES += $(the_lib) $(the_lib).so $(the_lib).mdb $(the_lib:.dll=.pdb) +library_CLEAN_FILES += $(build_lib) $(build_lib).so $(build_lib).mdb $(build_lib:.dll=.pdb) ifdef NO_SIGN_ASSEMBLY SN = : @@ -211,6 +209,7 @@ LIBRARY_SNK = $(topdir)/class/mono.snk endif ifdef BUILT_SOURCES +library_CLEAN_FILES += $(BUILT_SOURCES) ifeq (cat, $(PLATFORM_CHANGE_SEPARATOR_CMD)) BUILT_SOURCES_cmdline = $(BUILT_SOURCES) else @@ -237,7 +236,7 @@ endif ifdef PLATFORM_AOT_SUFFIX Q_AOT=$(if $(V),,@echo "AOT [$(PROFILE)] $(notdir $(@))";) $(the_lib)$(PLATFORM_AOT_SUFFIX): $(the_lib) - $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version $(the_lib) + $(Q_AOT) MONO_PATH='$(the_libdir)' > $(PROFILE)_aot.log 2>&1 $(RUNTIME) --aot=bind-to-runtime-version --debug $(the_lib) endif ifdef ENABLE_AOT @@ -248,9 +247,15 @@ all-local: $(the_lib)$(PLATFORM_AOT_SUFFIX) endif endif +makefrag = $(depsdir)/$(PROFILE)_$(LIBRARY).makefrag +library_CLEAN_FILES += $(makefrag) $(makefrag): $(sourcefile) @echo Creating $@ ... @sed 's,^,$(build_lib): ,' $< >$@ + @if test ! -f $(sourcefile).makefrag; then :; else \ + cat $(sourcefile).makefrag >> $@ ; \ + echo '$@: $(sourcefile).makefrag' >> $@; \ + echo '$(sourcefile).makefrag:' >> $@; fi ifneq ($(response),$(sourcefile)) $(response): $(sourcefile) $(PLATFORM_excludes) @@ -276,6 +281,7 @@ $(makefrag) $(test_response) $(test_makefrag) $(btest_response) $(btest_makefrag Q_MDOC_UP=$(if $(V),,@echo "MDOC-UP [$(PROFILE)] $(notdir $(@))";) MDOC_UP =$(Q_MDOC_UP) \ + MONO_PATH="$(topdir)/class/lib/net_4_0$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/net_2_0$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" \ $(RUNTIME) $(topdir)/tools/mdoc/mdoc.exe update --delete \ -o Documentation/en $(the_lib) diff --git a/mcs/build/profiles/monotouch_bootstrap.make b/mcs/build/profiles/monotouch_bootstrap.make index 1ac6af0ef58..a280c2bf513 100644 --- a/mcs/build/profiles/monotouch_bootstrap.make +++ b/mcs/build/profiles/monotouch_bootstrap.make @@ -6,6 +6,9 @@ BOOTSTRAP_PROFILE = net_2_0 BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_GMCS) MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_SMCS) +# We can enable this if System.dll depends on features of the mscorlib.dll from this profile +#PROFILE_MCS_HAS_BOOTSTRAP_FALLBACK = yes + profile-check: @: diff --git a/mcs/build/profiles/moonlight.make b/mcs/build/profiles/moonlight.make new file mode 100644 index 00000000000..f3aba438b8f --- /dev/null +++ b/mcs/build/profiles/moonlight.make @@ -0,0 +1,19 @@ +#! -*- makefile -*- + +my_runtime = $(RUNTIME) $(RUNTIME_FLAGS) --security=temporary-smcs-hack +INTERNAL_SMCS = $(my_runtime) $(topdir)/class/lib/$(PROFILE)/smcs.exe + +BOOTSTRAP_PROFILE = moonlight_bootstrap + +BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(my_runtime) $(topdir)/class/lib/$(BOOTSTRAP_PROFILE)/smcs.exe +MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_SMCS) + +profile-check: + @: + +PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:MOONLIGHT +FRAMEWORK_VERSION = 2.1 +NO_TEST = yes + +# the tuner takes care of the install +NO_INSTALL = yes diff --git a/mcs/build/profiles/moonlight_bootstrap.make b/mcs/build/profiles/moonlight_bootstrap.make new file mode 100644 index 00000000000..243fc6518f5 --- /dev/null +++ b/mcs/build/profiles/moonlight_bootstrap.make @@ -0,0 +1,20 @@ +#! -*- makefile -*- + +INTERNAL_SMCS = $(RUNTIME) $(RUNTIME_FLAGS) --security=temporary-smcs-hack $(topdir)/class/lib/$(PROFILE)/smcs.exe + +BOOTSTRAP_PROFILE = basic +BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_GMCS) +MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_SMCS) + +# We can enable this if System.dll depends new features of the mscorlib.dll from this profile +#PROFILE_MCS_HAS_BOOTSTRAP_FALLBACK = yes + +profile-check: + @: + +PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:MOONLIGHT +FRAMEWORK_VERSION = 2.1 +NO_TEST = yes + +# the tuner takes care of the install +NO_INSTALL = yes diff --git a/mcs/build/profiles/moonlight_raw.make b/mcs/build/profiles/moonlight_raw.make new file mode 100644 index 00000000000..f3aba438b8f --- /dev/null +++ b/mcs/build/profiles/moonlight_raw.make @@ -0,0 +1,19 @@ +#! -*- makefile -*- + +my_runtime = $(RUNTIME) $(RUNTIME_FLAGS) --security=temporary-smcs-hack +INTERNAL_SMCS = $(my_runtime) $(topdir)/class/lib/$(PROFILE)/smcs.exe + +BOOTSTRAP_PROFILE = moonlight_bootstrap + +BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(my_runtime) $(topdir)/class/lib/$(BOOTSTRAP_PROFILE)/smcs.exe +MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_SMCS) + +profile-check: + @: + +PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -d:MOONLIGHT +FRAMEWORK_VERSION = 2.1 +NO_TEST = yes + +# the tuner takes care of the install +NO_INSTALL = yes diff --git a/mcs/build/profiles/net_2_1.make b/mcs/build/profiles/net_2_1.make deleted file mode 100644 index f6a58a5c348..00000000000 --- a/mcs/build/profiles/net_2_1.make +++ /dev/null @@ -1,19 +0,0 @@ -#! -*- makefile -*- - -my_runtime = $(RUNTIME) $(RUNTIME_FLAGS) --security=temporary-smcs-hack -INTERNAL_SMCS = $(my_runtime) $(topdir)/class/lib/$(PROFILE)/smcs.exe - -BOOTSTRAP_PROFILE = net_2_1_bootstrap - -BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(my_runtime) $(topdir)/class/lib/$(BOOTSTRAP_PROFILE)/smcs.exe -MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_SMCS) - -profile-check: - @: - -PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -FRAMEWORK_VERSION = 2.1 -NO_TEST = yes - -# the tuner takes care of the install -NO_INSTALL = yes diff --git a/mcs/build/profiles/net_2_1_bootstrap.make b/mcs/build/profiles/net_2_1_bootstrap.make deleted file mode 100644 index 230c3918983..00000000000 --- a/mcs/build/profiles/net_2_1_bootstrap.make +++ /dev/null @@ -1,17 +0,0 @@ -#! -*- makefile -*- - -INTERNAL_SMCS = $(RUNTIME) $(RUNTIME_FLAGS) --security=temporary-smcs-hack $(topdir)/class/lib/$(PROFILE)/smcs.exe - -BOOTSTRAP_PROFILE = basic -BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_GMCS) -MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_SMCS) - -profile-check: - @: - -PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -FRAMEWORK_VERSION = 2.1 -NO_TEST = yes - -# the tuner takes care of the install -NO_INSTALL = yes diff --git a/mcs/build/profiles/net_2_1_raw.make b/mcs/build/profiles/net_2_1_raw.make deleted file mode 100644 index f6a58a5c348..00000000000 --- a/mcs/build/profiles/net_2_1_raw.make +++ /dev/null @@ -1,19 +0,0 @@ -#! -*- makefile -*- - -my_runtime = $(RUNTIME) $(RUNTIME_FLAGS) --security=temporary-smcs-hack -INTERNAL_SMCS = $(my_runtime) $(topdir)/class/lib/$(PROFILE)/smcs.exe - -BOOTSTRAP_PROFILE = net_2_1_bootstrap - -BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(my_runtime) $(topdir)/class/lib/$(BOOTSTRAP_PROFILE)/smcs.exe -MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_SMCS) - -profile-check: - @: - -PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:NET_2_1 -FRAMEWORK_VERSION = 2.1 -NO_TEST = yes - -# the tuner takes care of the install -NO_INSTALL = yes diff --git a/mcs/build/profiles/net_4_0_bootstrap.make b/mcs/build/profiles/net_4_0_bootstrap.make index 77645a18d0b..d74036604eb 100644 --- a/mcs/build/profiles/net_4_0_bootstrap.make +++ b/mcs/build/profiles/net_4_0_bootstrap.make @@ -4,6 +4,9 @@ BOOTSTRAP_PROFILE = net_2_0 BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(BOOTSTRAP_PROFILE)/gmcs.exe MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/$(BOOTSTRAP_PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(RUNTIME_FLAGS) $(topdir)/class/lib/$(PROFILE)/dmcs.exe +# we have BOOTSTRAP_PROFILE listed in the MONO_PATH of MCS +PROFILE_MCS_HAS_BOOTSTRAP_FALLBACK = yes + profile-check: PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -d:BOOTSTRAP_NET_4_0 diff --git a/mcs/build/rules.make b/mcs/build/rules.make index 5f34ce865d5..08bdc227483 100644 --- a/mcs/build/rules.make +++ b/mcs/build/rules.make @@ -205,5 +205,6 @@ withmcs: ## Documentation stuff Q_MDOC =$(if $(V),,@echo "MDOC [$(PROFILE)] $(notdir $(@))";) -MDOC =$(Q_MDOC) MONO_PATH="$(topdir)/class/lib/net_4_0$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(topdir)/tools/mdoc/mdoc.exe +MDOC =$(Q_MDOC) MONO_PATH="$(topdir)/class/lib/net_4_0$(PLATFORM_PATH_SEPARATOR)$(topdir)/class/lib/net_2_0$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" \ + $(RUNTIME) $(topdir)/tools/mdoc/mdoc.exe diff --git a/mcs/class/ChangeLog b/mcs/class/ChangeLog index 44fb1d7a4a4..c0362ed44ee 100644 --- a/mcs/class/ChangeLog +++ b/mcs/class/ChangeLog @@ -1,3 +1,25 @@ +2010-04-14 Ankit Jain + + * Makefile: Add Moonlight.Build.Tasks to net_2_0_dirs and + net_3_5_dirs. + * Moonlight.Build.Tasks: New. + +2010-04-08 Atsushi Enomoto + + * Makefile : add 4.0 System.Xaml. + +2010-03-16 Rolf Bjarne Kvinge + + * Makefile: Add System.Xml.Serialization to the Moonlight build. + +2010-03-16 Jb Evain + + * Makefile: rename the net_2_1 profile to moonlight. + +2010-03-15 Marek Habersack + + * Makefile (net_2_0_dirs): added System.Web.Mvc2 + 2010-03-11 Atsushi Enomoto * Makefile : build Sys.Json after Sys.SM.Web. diff --git a/mcs/class/Makefile b/mcs/class/Makefile index c61e7fee132..f776bd9af58 100644 --- a/mcs/class/Makefile +++ b/mcs/class/Makefile @@ -106,12 +106,14 @@ net_2_0_dirs := \ System.Web.DynamicData \ System.ServiceModel.Web \ System.Web.Mvc \ + System.Web.Mvc2 \ Mono.C5 \ Mono.Management \ Mono.Options \ Mono.Simd \ Mono.Tasklets \ Mono.CSharp \ + Moonlight.Build.Tasks \ WindowsBase \ System.Data.Services @@ -119,7 +121,7 @@ net_2_0_only_dirs := \ System.Web.Extensions_1.0 \ System.Web.Extensions.Design_1.0 -net_2_1_dirs := \ +moonlight_dirs := \ corlib \ Mono.CompilerServices.SymbolWriter \ System.Core \ @@ -127,6 +129,7 @@ net_2_1_dirs := \ System.XML \ System.Net \ System.Xml.Linq \ + System.Xml.Serialization \ System.Runtime.Serialization \ System.ServiceModel \ System.ServiceModel.Web @@ -157,6 +160,7 @@ net_3_5_dirs := \ Microsoft.Build.Utilities \ Microsoft.Build.Engine \ Microsoft.Build.Tasks \ + Moonlight.Build.Tasks \ System.Web.Extensions.Design net_4_0_dirs := \ @@ -165,12 +169,14 @@ net_4_0_dirs := \ Microsoft.CSharp \ System.Windows.Forms.DataVisualization \ System.ComponentModel.Composition \ - System.ServiceModel.Routing + System.Xaml \ + System.ServiceModel.Routing \ + System.Runtime.Caching net_2_0_bootstrap_SUBDIRS := $(bootstrap_dirs) net_2_0_SUBDIRS := $(common_dirs) $(net_2_0_dirs) $(net_2_0_only_dirs) -net_2_1_bootstrap_SUBDIRS := corlib System Mono.CompilerServices.SymbolWriter System.Core -net_2_1_raw_SUBDIRS := $(net_2_1_dirs) +moonlight_bootstrap_SUBDIRS := corlib System Mono.CompilerServices.SymbolWriter System.Core +moonlight_raw_SUBDIRS := $(moonlight_dirs) monotouch_bootstrap_SUBDIRS := corlib System Mono.CompilerServices.SymbolWriter System.Core monotouch_SUBDIRS := $(monotouch_dirs) net_3_5_SUBDIRS := $(net_3_5_dirs) @@ -179,7 +185,7 @@ net_4_0_SUBDIRS := $(common_dirs) $(net_2_0_dirs) $(net_4_0_dirs) include ../build/rules.make -SUBDIRS = $(common_dirs) $(net_2_0_dirs) $(net_2_0_only_dirs) $(net_2_1_dirs) $(net_3_5_dirs) $(net_4_0_dirs) +SUBDIRS = $(common_dirs) $(net_2_0_dirs) $(net_2_0_only_dirs) $(moonlight_dirs) $(monotouch_dirs) $(net_3_5_dirs) $(net_4_0_dirs) DIST_ONLY_SUBDIRS = dlr diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog index 4b8a485f504..828cca2da53 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog @@ -1,3 +1,125 @@ +2010-04-27 Carlos Alberto Cortez + + * ToolStripSplitButton.cs: + * ToolStripDropDownItem.cs: + * ToolStripMenuItem.cs: Update overrides. + * ToolStripItem.cs: Pass the number of clicks to HandleClick when + firing OnMouseUp, so we can later fire either OnClick or + OnDoubleClick. + + Fixes #558632. + +2010-04-26 Carlos Alberto Cortez + + * RichTextBox.cs: When emitting the complete RTF value escape chars + above 0x80, at .Net seems to do. This way we are able to make + round-trip assignations between the setter and getter of the + RichTextBox.Rtf property. + Fixes part of #586901. + +2010-04-26 Ivan Zlatev + + * DataGridView.cs: Handle all possible cases for when a new column is + added and there are existing rows with existing cells both in the + non-databound and the databound scenario. + [Fixes bug #583387] + +2010-04-26 Carlos Alberto Cortez + + * XplatUIX11.cs: When retrieving data from the x11 clipboard and we + are using either XA_STRING or OEMTEXT try to detect if we have escaped + unicode chars, and unescape them as needed. This us used by some + (gnome) applications to pass unicode chars in a non-unicode context. + Fixes #596402. + +2010-04-25 Ivan Zlatev + + * DataGridViewCellCollection.cs, DataGridView.cs: + Ensure column cell templates are properly applied. + [Fixes bug #583404] + +2010-04-24 Ivan Zlatev + + * DataGridViewColumnCollection.cs: When adding a column also + set the DisplayIndex if its now set by the user already. + [Fixes bug #583387] + +2010-04-19 Carlos Alberto Cortez + + * NotifyIcon.cs: Make BalloonWindow expose the owner's Handle. + * Theme.cs: + * ThemeWin32Classic.cs: Add a HideBalloonWindow method to force to + close an active balloon window. + * XplatUIX11.cs: When removing from the system tray try to close + the balloon window. This is important when we hide a NotifyIcon and + thus need to close its related balloon window as well. + Fixes bits of #590093. + +2010-04-19 Carlos Alberto Cortez + + * XplatUIX11.cs: When adding a NotifyIcon to the system tray, mark its + Hwnd.mapped as true, since its handle is going to be mapped later by + the tray (not us), but we need to know it's alive and can later properly unmap + it. + Fixes part of #590093. + +2010-04-16 Carlos Alberto Cortez + + * TreeNodeCollection.cs: When adding/inserting/setting a new node call + TreeView.Sort if needed, and update/recalculate this entire + collection in that case. + * TreeView.cs: Make 'sorted' internal, instead of directly using + Sorted, as this one could trigger a complete Sort() operation. + +2010-04-14 Carlos Alberto Cortez + + * TreeView.cs: We must use the comparer supplied by TreeViewNodeSorter + *always*, since it is used recursively, so checking for a number of + top level nodes is useless. This should fix a case where we were not + sorting any node with a single root node. + +2010-04-14 Carlos Alberto Cortez + + * DataGridView.cs: Call the base Paint impl last, instead of do that + at the beginning, to let handlers draw on top of us. + Fixes the remaining bits of #587563. + +2010-04-14 Carlos Alberto Cortez + + * ToolStripItem.cs: Separate the background rendering from the Paint + routine, so we can both make sure the background stuff is done first, + and we also let our items fire the OnPaint event handlers before or + after their own routines. + * ToolStripLabel.cs: Move the base call to OnPaint to the end, so any + user's Paint handler can draw on top of us, like .Net does. + Fixes #587563. + +2010-04-13 Carlos Alberto Cortez + + * XplatUIX11.cs: When checking for the values returned by + _NET_WORKAREA, use current_desktop+1 instead of current_desktop, since + we need the actual value, instead of the index (which is 0 based, and + is not working in this case). Patch by Andy Stühr + (andysmuell@hammerhartes.de). + Fixes #494234. + +2010-04-04 Carlos Alberto Cortez + + * ToolTip.cs: Make TipState internal. + * ToolStrip.cs: Use the same idea of ToolTip'state to have our + internal timer close the tooltip window after a delay, instead of + waiting for the mouse to move to a different item. Also, hide the + tooltip window when the handle is destroyed, and also when the control + is getting hidden. + Fixes #581273. + +2010-03-31 Carlos Alberto Cortez + + * ListView.cs: Selection should be available after the first time the + handle has been created, even if later the handle is destroyed or + temporary invalidated. + Fixes #584070. + 2010-03-01 Carlos Alberto Cortez * TreeView.cs: When receiving a double click on a node, toggle it only diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs index a583d7cb3a8..6e811bfe84b 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridView.cs @@ -3794,8 +3794,16 @@ namespace System.Windows.Forms { // if (!is_autogenerating_columns && columns.Count == 1) ReBind (); - foreach (DataGridViewRow row in Rows) - row.Cells.Add ((DataGridViewCell)e.Column.CellTemplate.Clone ()); + + foreach (DataGridViewRow row in Rows) { + DataGridViewCell newCell = (DataGridViewCell)e.Column.CellTemplate.Clone (); + if (row.Cells.Count == columns.Count) + row.Cells.Replace (e.Column.Index, newCell); + else if (e.Column.Index >= row.Cells.Count) + row.Cells.Add (newCell); + else + row.Cells.Insert (e.Column.Index, newCell); + } } e.Column.DataColumnIndex = FindDataColumnIndex (e.Column); @@ -4675,8 +4683,6 @@ namespace System.Windows.Forms { protected override void OnPaint (PaintEventArgs e) { - base.OnPaint(e); - Graphics g = e.Graphics; Rectangle bounds = ClientRectangle; @@ -4783,6 +4789,9 @@ namespace System.Windows.Forms { ControlPaint.DrawBorder3D (g, bounds, Border3DStyle.Sunken); break; } + + // Call the base impl at the end. + base.OnPaint(e); } private void RefreshScrollBars () diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewCellCollection.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewCellCollection.cs index 7574f286599..eacce0b0ef5 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewCellCollection.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewCellCollection.cs @@ -123,6 +123,12 @@ namespace System.Windows.Forms return result; } + internal void Replace (int columnIndex, DataGridViewCell dataGridViewCell) + { + RemoveAt (columnIndex); + Insert (columnIndex, dataGridViewCell); + } + [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public virtual void AddRange (params DataGridViewCell[] dataGridViewCells) { diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumn.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumn.cs index b7b3295acba..159714b9e05 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumn.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumn.cs @@ -184,6 +184,11 @@ namespace System.Windows.Forms { } } + internal int DisplayIndexInternal { + get { return DisplayIndex; } + set { displayIndex = value; } + } + internal int DataColumnIndex { get { return dataColumnIndex; } set { dataColumnIndex = value; } diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumnCollection.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumnCollection.cs index cf5b7929c27..29bc09dd61e 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumnCollection.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/DataGridViewColumnCollection.cs @@ -78,6 +78,8 @@ namespace System.Windows.Forms public virtual int Add (DataGridViewColumn dataGridViewColumn) { int result = base.List.Add(dataGridViewColumn); + if (dataGridViewColumn.DisplayIndex == -1) + dataGridViewColumn.DisplayIndexInternal = result; dataGridViewColumn.SetIndex(result); dataGridViewColumn.SetDataGridView(dataGridView); OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, dataGridViewColumn)); @@ -188,6 +190,8 @@ namespace System.Windows.Forms public virtual void Insert (int columnIndex, DataGridViewColumn dataGridViewColumn) { base.List.Insert (columnIndex, dataGridViewColumn); + if (dataGridViewColumn.DisplayIndex == -1) + dataGridViewColumn.DisplayIndexInternal = columnIndex; dataGridViewColumn.SetIndex (columnIndex); dataGridViewColumn.SetDataGridView (dataGridView); OnCollectionChanged (new CollectionChangeEventArgs (CollectionChangeAction.Add, dataGridViewColumn)); @@ -253,9 +257,8 @@ namespace System.Windows.Forms List result = new List (array); result.Sort (new ColumnDisplayIndexComparator ()); - for (int i = 0; i < result.Count; i++) - result[i].DisplayIndex = i; + result[i].DisplayIndexInternal = i; display_index_sorted = result; } @@ -271,7 +274,12 @@ namespace System.Windows.Forms { public int Compare (DataGridViewColumn o1, DataGridViewColumn o2) { - return o1.DisplayIndex - o2.DisplayIndex; + if (o1.DisplayIndex == o2.DisplayIndex) + // Here we avoid the equal value swapping that both Array.Sort and ArrayList.Sort + // do occasionally and preserve the user column insertation order. + return 1; + else + return o1.DisplayIndex - o2.DisplayIndex; } } } diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs index 10e19812c62..6a981d6c963 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs @@ -113,6 +113,9 @@ namespace System.Windows.Forms private int virtual_list_size; private bool right_to_left_layout; #endif + // selection is available after the first time the handle is created, *even* if later + // the handle is either recreated or destroyed - so keep this info around. + private bool is_selection_available; // internal variables internal ImageList large_image_list; @@ -1207,7 +1210,7 @@ namespace System.Windows.Forms internal void OnSelectedIndexChanged () { - if (IsHandleCreated) + if (is_selection_available) OnSelectedIndexChanged (EventArgs.Empty); } @@ -3506,6 +3509,7 @@ namespace System.Windows.Forms protected override void CreateHandle () { base.CreateHandle (); + is_selection_available = true; for (int i = 0; i < SelectedItems.Count; i++) OnSelectedIndexChanged (EventArgs.Empty); } @@ -5901,7 +5905,7 @@ namespace System.Windows.Forms [Browsable (false)] public int Count { get { - if (!owner.IsHandleCreated) + if (!owner.is_selection_available) return 0; return List.Count; @@ -5920,7 +5924,7 @@ namespace System.Windows.Forms public int this [int index] { get { - if (!owner.IsHandleCreated || index < 0 || index >= List.Count) + if (!owner.is_selection_available || index < 0 || index >= List.Count) throw new ArgumentOutOfRangeException ("index"); return (int) List [index]; @@ -5958,12 +5962,12 @@ namespace System.Windows.Forms if (itemIndex < 0 || itemIndex >= owner.Items.Count) throw new ArgumentOutOfRangeException ("index"); - if (owner.virtual_mode && !owner.IsHandleCreated) + if (owner.virtual_mode && !owner.is_selection_available) return -1; owner.Items [itemIndex].Selected = true; - if (!owner.IsHandleCreated) + if (!owner.is_selection_available) return 0; return List.Count; @@ -5977,7 +5981,7 @@ namespace System.Windows.Forms #endif void Clear () { - if (!owner.IsHandleCreated) + if (!owner.is_selection_available) return; int [] indexes = (int []) List.ToArray (typeof (int)); @@ -6041,7 +6045,7 @@ namespace System.Windows.Forms public int IndexOf (int selectedIndex) { - if (!owner.IsHandleCreated) + if (!owner.is_selection_available) return -1; return List.IndexOf (selectedIndex); @@ -6145,7 +6149,7 @@ namespace System.Windows.Forms public ListViewItem this [int index] { get { - if (!owner.IsHandleCreated || index < 0 || index >= Count) + if (!owner.is_selection_available || index < 0 || index >= Count) throw new ArgumentOutOfRangeException ("index"); int item_index = owner.SelectedIndices [index]; @@ -6203,7 +6207,7 @@ namespace System.Windows.Forms public void CopyTo (Array dest, int index) { - if (!owner.IsHandleCreated) + if (!owner.is_selection_available) return; if (index > Count) // Throws ArgumentException instead of IOOR exception throw new ArgumentException ("index"); @@ -6214,7 +6218,7 @@ namespace System.Windows.Forms public IEnumerator GetEnumerator () { - if (!owner.IsHandleCreated) + if (!owner.is_selection_available) return (new ListViewItem [0]).GetEnumerator (); ListViewItem [] items = new ListViewItem [Count]; @@ -6260,7 +6264,7 @@ namespace System.Windows.Forms public int IndexOf (ListViewItem item) { - if (!owner.IsHandleCreated) + if (!owner.is_selection_available) return -1; for (int i = 0; i < Count; i++) @@ -6273,7 +6277,7 @@ namespace System.Windows.Forms #if NET_2_0 public virtual int IndexOfKey (string key) { - if (!owner.IsHandleCreated || key == null || key.Length == 0) + if (!owner.is_selection_available || key == null || key.Length == 0) return -1; for (int i = 0; i < Count; i++) { diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NotifyIcon.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NotifyIcon.cs index b45922574f1..0a71465d762 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NotifyIcon.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/NotifyIcon.cs @@ -263,6 +263,12 @@ namespace System.Windows.Forms { timer.Enabled = false; timer.Tick += new EventHandler (HandleTimer); } + + public IntPtr OwnerHandle { + get { + return owner; + } + } protected override void Dispose (bool disposing) { diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/RichTextBox.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/RichTextBox.cs index f9842135226..1db7f29a519 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/RichTextBox.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/RichTextBox.cs @@ -1950,12 +1950,12 @@ namespace System.Windows.Forms { static readonly char [] ReservedRTFChars = new char [] { '\\', '{', '}' }; - [MonoInternalNote ("Emit unicode and other special characters properly")] private void EmitRTFText(StringBuilder rtf, string text) { int start = rtf.Length; int count = text.Length; - rtf.Append(text); + // First emit simple unicode chars as escaped + EmitEscapedUnicode (rtf, text); // This method emits user text *only*, so it's safe to escape any reserved rtf chars // Escape '\' first, since it is used later to escape the other chars @@ -1966,6 +1966,39 @@ namespace System.Windows.Forms { } } + // The chars to be escaped use "\'" + its hexadecimal value. + private void EmitEscapedUnicode (StringBuilder sb, string text) + { + int pos; + int start = 0; + + while ((pos = IndexOfNonAscii (text, start)) > -1) { + sb.Append (text, start, pos - start); + + int n = (int)text [pos]; + sb.Append ("\\'"); + sb.Append (n.ToString ("X")); + + start = pos + 1; + } + + // Append remaining (maybe all) the text value. + if (start < text.Length) + sb.Append (text, start, text.Length - start); + } + + // MS seems to be escaping values larger than 0x80 + private int IndexOfNonAscii (string text, int startIndex) + { + for (int i = startIndex; i < text.Length; i++) { + int n = (int)text [i]; + if (n < 0 || n >= 0x80) + return i; + } + + return -1; + } + // start_pos and end_pos are 0-based private StringBuilder GenerateRTF(Line start_line, int start_pos, Line end_line, int end_pos) { StringBuilder sb; diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs index 599ae0f33b2..e4154e726f1 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs @@ -984,6 +984,7 @@ namespace System.Windows.Forms #region BalloonWindow #if NET_2_0 public abstract void ShowBalloonWindow (IntPtr handle, int timeout, string title, string text, ToolTipIcon icon); + public abstract void HideBalloonWindow (IntPtr handle); public abstract void DrawBalloonWindow (Graphics dc, Rectangle clip, NotifyIcon.BalloonWindow control); public abstract Rectangle BalloonWindowRect (NotifyIcon.BalloonWindow control); #endif diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs index 0bd84de71b0..42a533043ed 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs @@ -5529,6 +5529,16 @@ namespace System.Windows.Forms balloon_window.Show (); } + public override void HideBalloonWindow (IntPtr handle) + { + if (balloon_window == null || balloon_window.OwnerHandle != handle) + return; + + balloon_window.Close (); + balloon_window.Dispose (); + balloon_window = null; + } + private const int balloon_iconsize = 16; private const int balloon_bordersize = 8; diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs index fd6500af68c..d6dc5f19e5e 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStrip.cs @@ -79,6 +79,10 @@ namespace System.Windows.Forms private ToolStripItem mouse_currently_over; internal bool menu_selected; private ToolStripItem tooltip_currently_showing; + private ToolTip.TipState tooltip_state; + + const int InitialToolTipDelay = 500; + const int ToolTipDelay = 5000; #endregion #region Public Constructors @@ -723,6 +727,7 @@ namespace System.Windows.Forms protected override void Dispose (bool disposing) { if (!IsDisposed) { + CloseToolTip (null); // ToolStripItem.Dispose modifes the collection, // so we iterate it in reverse order for (int i = Items.Count - 1; i >= 0; i--) @@ -1060,6 +1065,9 @@ namespace System.Windows.Forms protected override void OnVisibleChanged (EventArgs e) { + if (!Visible) + CloseToolTip (null); + base.OnVisibleChanged (e); } @@ -1597,24 +1605,32 @@ namespace System.Windows.Forms private void MouseEnteredItem (ToolStripItem item) { if (this.show_item_tool_tips && !(item is ToolStripTextBox)) { + ToolTipTimer.Interval = InitialToolTipDelay; + tooltip_state = ToolTip.TipState.Initial; tooltip_currently_showing = item; ToolTipTimer.Start (); } } - - private void MouseLeftItem (ToolStripItem item) + + private void CloseToolTip (ToolStripItem item) { ToolTipTimer.Stop (); ToolTipWindow.Hide (this); tooltip_currently_showing = null; + tooltip_state = ToolTip.TipState.Down; } - + + private void MouseLeftItem (ToolStripItem item) + { + CloseToolTip (item); + } + private Timer ToolTipTimer { get { if (tooltip_timer == null) { tooltip_timer = new Timer (); tooltip_timer.Enabled = false; - tooltip_timer.Interval = 500; + tooltip_timer.Interval = InitialToolTipDelay; tooltip_timer.Tick += new EventHandler (ToolTipTimer_Tick); } @@ -1631,16 +1647,32 @@ namespace System.Windows.Forms } } - private void ToolTipTimer_Tick (object o, EventArgs args) + private void ShowToolTip () { string tooltip = tooltip_currently_showing.GetToolTip (); - if (!string.IsNullOrEmpty (tooltip)) + if (!string.IsNullOrEmpty (tooltip)) { ToolTipWindow.Present (this, tooltip); + ToolTipTimer.Interval = ToolTipDelay; + ToolTipTimer.Start (); + tooltip_state = ToolTip.TipState.Show; + } tooltip_currently_showing.FireEvent (EventArgs.Empty, ToolStripItemEventType.MouseHover); + } + private void ToolTipTimer_Tick (object o, EventArgs args) + { ToolTipTimer.Stop (); + + switch (tooltip_state) { + case ToolTip.TipState.Initial: + ShowToolTip (); + break; + case ToolTip.TipState.Show: + CloseToolTip (null); + break; + } } #endregion diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripDropDownItem.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripDropDownItem.cs index 5465739ab1e..3d9a76c2bfb 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripDropDownItem.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripDropDownItem.cs @@ -322,7 +322,7 @@ namespace System.Windows.Forms base.Dismiss (reason); } - internal override void HandleClick (EventArgs e) + internal override void HandleClick (int mouse_clicks, EventArgs e) { OnClick (e); } diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripItem.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripItem.cs index 9ccbff04001..3e5e051e1f6 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripItem.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripItem.cs @@ -1015,9 +1015,6 @@ namespace System.Windows.Forms EventHandler eh = (EventHandler)(Events [DoubleClickEvent]); if (eh != null) eh (this, e); - - if (!double_click_enabled) - OnClick (e); } [EditorBrowsable (EditorBrowsableState.Advanced)] @@ -1178,12 +1175,18 @@ namespace System.Windows.Forms this.CalculateAutoSize (); OnFontChanged (EventArgs.Empty); } - - protected virtual void OnPaint (PaintEventArgs e) + + void OnPaintInternal (PaintEventArgs e) { + // Have the background rendered independently from OnPaint if (this.parent != null) this.parent.Renderer.DrawItemBackground (new ToolStripItemRenderEventArgs (e.Graphics, this)); - + + OnPaint (e); + } + + protected virtual void OnPaint (PaintEventArgs e) + { PaintEventHandler eh = (PaintEventHandler)(Events [PaintEvent]); if (eh != null) eh (this, e); @@ -1773,7 +1776,7 @@ namespace System.Windows.Forms switch (met) { case ToolStripItemEventType.MouseUp: - this.HandleClick (e); + this.HandleClick (((MouseEventArgs)e).Clicks, e); this.OnMouseUp ((MouseEventArgs)e); break; case ToolStripItemEventType.MouseDown: @@ -1792,18 +1795,21 @@ namespace System.Windows.Forms this.OnMouseMove ((MouseEventArgs)e); break; case ToolStripItemEventType.Paint: - this.OnPaint ((PaintEventArgs)e); + this.OnPaintInternal ((PaintEventArgs)e); break; case ToolStripItemEventType.Click: - this.HandleClick (e); + this.HandleClick (1, e); break; } } - internal virtual void HandleClick (EventArgs e) + internal virtual void HandleClick (int mouse_clicks, EventArgs e) { this.Parent.HandleItemClick (this); - this.OnClick (e); + if (mouse_clicks == 2 && double_click_enabled) + this.OnDoubleClick (e); + else + this.OnClick (e); } internal virtual void SetPlacement (ToolStripItemPlacement placement) diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripLabel.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripLabel.cs index ff4524fa3ae..59c73bd0532 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripLabel.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripLabel.cs @@ -193,8 +193,6 @@ namespace System.Windows.Forms protected override void OnPaint (System.Windows.Forms.PaintEventArgs e) { - base.OnPaint (e); - if (this.Owner != null) { Color font_color = this.Enabled ? this.ForeColor : SystemColors.GrayText; Image draw_image = this.Enabled ? this.Image : ToolStripRenderer.CreateDisabledImage (this.Image); @@ -278,6 +276,9 @@ namespace System.Windows.Forms } else this.Owner.Renderer.DrawItemText (new System.Windows.Forms.ToolStripItemTextRenderEventArgs (e.Graphics, this, this.Text, text_layout_rect, font_color, this.Font, this.TextAlign)); } + + // call Paint handlers last. + base.OnPaint (e); } protected internal override bool ProcessMnemonic (char charCode) diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs index de4a6ff17c5..326a3c81247 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs @@ -534,7 +534,7 @@ namespace System.Windows.Forms } } - internal override void HandleClick (EventArgs e) + internal override void HandleClick (int mouse_clicks, EventArgs e) { this.OnClick (e); diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripSplitButton.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripSplitButton.cs index 832fb235363..9737dc37367 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripSplitButton.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolStripSplitButton.cs @@ -321,9 +321,9 @@ namespace System.Windows.Forms #endregion #region Internal Methods - internal override void HandleClick (EventArgs e) + internal override void HandleClick (int mouse_clicks, EventArgs e) { - base.HandleClick (e); + base.HandleClick (mouse_clicks, e); MouseEventArgs mea = e as MouseEventArgs; diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolTip.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolTip.cs index 1a1c4f51f6e..a5d4a7fea11 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolTip.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ToolTip.cs @@ -803,7 +803,7 @@ namespace System.Windows.Forms { #endif #endregion // Protected Instance Methods - enum TipState { + internal enum TipState { Initial, Show, Down diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeNodeCollection.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeNodeCollection.cs index 318a0fcdb10..007fb1ef029 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeNodeCollection.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeNodeCollection.cs @@ -434,7 +434,14 @@ namespace System.Windows.Forms { tree_view = owner.TreeView; if (tree_view != null) { - TreeNode prev = GetPrevNode (node); + bool sorted = false; + if (tree_view.Sorted || tree_view.TreeViewNodeSorter != null) { + owner.Nodes.Sort (tree_view.TreeViewNodeSorter); + tree_view.sorted = sorted = true; + } + + // We may need to invalidate this entire node collection if sorted. + TreeNode prev = sorted ? owner : GetPrevNode (node); if (tree_view.IsHandleCreated && node.ArePreviousNodesExpanded) tree_view.RecalculateVisibleOrder (prev); diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeView.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeView.cs index 313d67f5b05..be73ec2d400 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeView.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TreeView.cs @@ -44,7 +44,7 @@ namespace System.Windows.Forms { #region Fields private string path_separator = "\\"; private int item_height = -1; - private bool sorted; + internal bool sorted; internal TreeNode root_node; internal bool nodes_added; private TreeNodeCollection nodes; @@ -751,7 +751,7 @@ namespace System.Windows.Forms { #if NET_2_0 public void Sort () { - Sort (Nodes.Count >= 2 ? tree_view_node_sorter : null); + Sort (tree_view_node_sorter); } #endif diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs index 4b085346c10..78ae994a6a3 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs @@ -1252,13 +1252,15 @@ namespace System.Windows.Forms { if ((long)nitems > 0) { if (property == (IntPtr)Atom.XA_STRING) { - Clipboard.Item = Marshal.PtrToStringAnsi(prop); + // Some X managers/apps pass unicode chars as escaped strings, so + // we may need to unescape them. + Clipboard.Item = UnescapeUnicodeFromAnsi (Marshal.PtrToStringAnsi(prop)); } else if (property == (IntPtr)Atom.XA_BITMAP) { // FIXME - convert bitmap to image } else if (property == (IntPtr)Atom.XA_PIXMAP) { // FIXME - convert pixmap to image } else if (property == OEMTEXT) { - Clipboard.Item = Marshal.PtrToStringAnsi(prop); + Clipboard.Item = UnescapeUnicodeFromAnsi (Marshal.PtrToStringAnsi(prop)); } else if (property == UTF8_STRING) { byte [] buffer = new byte [(int)nitems]; for (int i = 0; i < (int)nitems; i++) @@ -1285,6 +1287,48 @@ namespace System.Windows.Forms { } } + private string UnescapeUnicodeFromAnsi (string value) + { + if (value == null || value.IndexOf ("\\u") == -1) + return value; + + StringBuilder sb = new StringBuilder (value.Length); + int start, pos; + + start = pos = 0; + while (start < value.Length) { + pos = value.IndexOf ("\\u", start); + if (pos == -1) + break; + + sb.Append (value, start, pos - start); + pos += 2; + start = pos; + + int length = 0; + while (pos < value.Length) { + if (!Char.IsLetterOrDigit (value [pos])) + break; + length++; + pos++; + } + + int res; + if (!Int32.TryParse (value.Substring (start, length), System.Globalization.NumberStyles.HexNumber, + null, out res)) + return value; // Error, return the unescaped original value. + + sb.Append ((char)res); + start = pos; + } + + // Append any remaining data. + if (start < value.Length) + sb.Append (value, start, value.Length - start); + + return sb.ToString (); + } + private void AddExpose (Hwnd hwnd, bool client, int x, int y, int width, int height) { // Don't waste time if ((hwnd == null) || (x > hwnd.Width) || (y > hwnd.Height) || ((x + width) < 0) || ((y + height) < 0)) { @@ -2486,7 +2530,7 @@ namespace System.Windows.Forms { XFree(prop); XGetWindowProperty(DisplayHandle, RootWindow, _NET_WORKAREA, IntPtr.Zero, new IntPtr (256), false, (IntPtr)Atom.XA_CARDINAL, out actual_atom, out actual_format, out nitems, out bytes_after, ref prop); - if ((long)nitems < 4 * current_desktop) { + if ((long)nitems < 4 * (current_desktop + 1)) { goto failsafe; } @@ -6017,6 +6061,10 @@ namespace System.Windows.Forms { hwnd.Queue.Paint.Remove (hwnd); } + // We are going to be directly mapped by the system tray, so mark as mapped + // so we can later properly unmap it. + hwnd.mapped = true; + size_hints = new XSizeHints(); size_hints.flags = (IntPtr)(XSizeHintsFlags.PMinSize | XSizeHintsFlags.PMaxSize | XSizeHintsFlags.PBaseSize); @@ -6082,6 +6130,10 @@ namespace System.Windows.Forms { tt.Dispose(); tt = null; } +#if NET_2_0 + // Close any balloon window *we* fired. + ThemeEngine.Current.HideBalloonWindow (handle); +#endif } #if NET_2_0 diff --git a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/ChangeLog b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/ChangeLog index 1df2086be24..6dc092ebe83 100644 --- a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/ChangeLog +++ b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/ChangeLog @@ -1,3 +1,19 @@ +2010-04-24 Ivan Zlatev + + * DataGridViewColumnCollectionTest.cs: Add tests for bug #583387. + +2010-04-17 Carlos Alberto Cortez + + * TreeViewTest.cs: New test for Sorted and BeginUpdate interaction. + +2010-04-16 Carlos Alberto Cortez + + * TreeViewTest.cs: New test for automatical sorting. + +2010-04-14 Carlos Alberto Cortez + + * TreeViewTest.cs: New test for TreeViewNodeSorter used recursively. + 2010-01-18 Carlos Alberto Cortez * RichTextBoxTest.cs: New test for the Modified property. diff --git a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewColumnCollectionTest.cs b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewColumnCollectionTest.cs index aaf87d7db1e..e239b5d7678 100644 --- a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewColumnCollectionTest.cs +++ b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/DataGridViewColumnCollectionTest.cs @@ -107,22 +107,31 @@ namespace MonoTests.System.Windows.Forms dgv.Columns.Add ("A1", "A1"); Assert.AreEqual (0, dgv.Columns[0].Index, "A1"); + Assert.AreEqual (0, dgv.Columns[0].DisplayIndex, "B1"); dgv.Columns.Add ("A2", "A2"); Assert.AreEqual (0, dgv.Columns[0].Index, "A2"); + Assert.AreEqual (0, dgv.Columns[0].DisplayIndex, "B2"); Assert.AreEqual (1, dgv.Columns[1].Index, "A3"); + Assert.AreEqual (1, dgv.Columns[1].DisplayIndex, "B3"); dgv.Columns.Insert (0, new DataGridViewTextBoxColumn ()); Assert.AreEqual (0, dgv.Columns[0].Index, "A4"); + Assert.AreEqual (0, dgv.Columns[0].DisplayIndex, "B4"); Assert.AreEqual (1, dgv.Columns[1].Index, "A5"); + Assert.AreEqual (1, dgv.Columns[1].DisplayIndex, "B5"); Assert.AreEqual (2, dgv.Columns[2].Index, "A6"); + Assert.AreEqual (2, dgv.Columns[2].DisplayIndex, "B6"); dgv.Columns.RemoveAt (1); Assert.AreEqual (0, dgv.Columns[0].Index, "A7"); + Assert.AreEqual (0, dgv.Columns[0].DisplayIndex, "B7"); Assert.AreEqual (1, dgv.Columns[1].Index, "A8"); + Assert.AreEqual (1, dgv.Columns[1].DisplayIndex, "B8"); dgv.Columns.RemoveAt (0); Assert.AreEqual (0, dgv.Columns[0].Index, "A9"); + Assert.AreEqual (0, dgv.Columns[0].DisplayIndex, "B9"); f.Close (); f.Dispose (); diff --git a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeViewTest.cs b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeViewTest.cs index 838126fb33a..27d4a267370 100644 --- a/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeViewTest.cs +++ b/mcs/class/Managed.Windows.Forms/Test/System.Windows.Forms/TreeViewTest.cs @@ -330,6 +330,22 @@ namespace MonoTests.System.Windows.Forms Assert.AreEqual ("aaa", tv.Nodes[0].Text, "A1"); } + + [Test] + public void SortBeginUpdate () + { + TreeView tv = new TreeView (); + tv.Sorted = true; + tv.BeginUpdate (); + tv.Nodes.Add ("x"); + tv.Nodes.Add ("f"); + tv.Nodes.Add ("a"); + + // Even if BeginUpdate was called, Sort is called. + Assert.AreEqual ("a", tv.Nodes [0].Text, "#A1"); + Assert.AreEqual ("f", tv.Nodes [1].Text, "#A2"); + Assert.AreEqual ("x", tv.Nodes [2].Text, "#A3"); + } #endif [Test] @@ -686,6 +702,124 @@ namespace MonoTests.System.Windows.Forms return ((TreeNode)x).Text == "2" ? -1 : 1; } } + + [Test] + public void SortedRecursive () + { + TreeView tv = new TreeView (); + tv.TreeViewNodeSorter = new InverseNodeSorter (); + tv.BeginUpdate (); + TreeNode root_node = tv.Nodes.Add ("Root"); + for (char c = 'a'; c <= 'f'; c++) { + TreeNode node = new TreeNode (c.ToString ()); + for (int i = 0; i < 3; i++) + node.Nodes.Add (i.ToString ()); + + root_node.Nodes.Add (node); + } + tv.EndUpdate (); + + // Make sure we are sorted + tv.Sort (); + + Assert.AreEqual ("f", root_node.Nodes [0].Text, "#A1"); + Assert.AreEqual ("e", root_node.Nodes [1].Text, "#A2"); + Assert.AreEqual ("d", root_node.Nodes [2].Text, "#A3"); + Assert.AreEqual ("c", root_node.Nodes [3].Text, "#A4"); + Assert.AreEqual ("b", root_node.Nodes [4].Text, "#A5"); + Assert.AreEqual ("a", root_node.Nodes [5].Text, "#A5"); + + foreach (TreeNode n in root_node.Nodes) { + Assert.AreEqual ("2", n.Nodes [0].Text, "#B1"); + Assert.AreEqual ("1", n.Nodes [1].Text, "#B2"); + Assert.AreEqual ("0", n.Nodes [2].Text, "#B3"); + } + } + + [Test] + public void SortedAutomatically () + { + TreeView tv = new TreeView (); + tv.Nodes.Add ("z"); + tv.Nodes.Add ("a"); + tv.Nodes.Add ("c"); + + // One way to sort them automatically is to set Sorted to true + // and let the TreeView use the default comparer + tv.Sorted = true; + Assert.AreEqual ("a", tv.Nodes [0].Text, "#A1"); + Assert.AreEqual ("c", tv.Nodes [1].Text, "#A2"); + Assert.AreEqual ("z", tv.Nodes [2].Text, "#A3"); + Assert.AreEqual (true, tv.Sorted, "#A4"); + + tv.Nodes.Add ("d"); + Assert.AreEqual ("a", tv.Nodes [0].Text, "#B1"); + Assert.AreEqual ("c", tv.Nodes [1].Text, "#B2"); + Assert.AreEqual ("d", tv.Nodes [2].Text, "#B3"); + Assert.AreEqual ("z", tv.Nodes [3].Text, "#B4"); + + // Another way is to set TreeViewNodeSorter, + // which will set Sorted to true automatically + tv.Sorted = false; + Assert.AreEqual (false, tv.Sorted, "#C0"); + + tv.TreeViewNodeSorter = new InverseNodeSorter (); + Assert.AreEqual ("z", tv.Nodes [0].Text, "#C1"); + Assert.AreEqual ("d", tv.Nodes [1].Text, "#C2"); + Assert.AreEqual ("c", tv.Nodes [2].Text, "#C3"); + Assert.AreEqual ("a", tv.Nodes [3].Text, "#C4"); + Assert.AreEqual (true, tv.Sorted, "#C5"); + + tv.Nodes.Add ("i"); + Assert.AreEqual ("z", tv.Nodes [0].Text, "#D1"); + Assert.AreEqual ("i", tv.Nodes [1].Text, "#D2"); + Assert.AreEqual ("d", tv.Nodes [2].Text, "#D3"); + Assert.AreEqual ("c", tv.Nodes [3].Text, "#D4"); + Assert.AreEqual ("a", tv.Nodes [4].Text, "#D5"); + + tv.Sorted = false; + Assert.AreEqual (false, tv.Sorted, "#E0"); + + // If we have set a TreeViewNodeSorter, + // it will sort the nodes automatically when adding/inserting a new one, + // setting Sorted to true. + tv.Nodes.Add ("f"); + Assert.AreEqual ("z", tv.Nodes [0].Text, "#E1"); + Assert.AreEqual ("i", tv.Nodes [1].Text, "#E2"); + Assert.AreEqual ("f", tv.Nodes [2].Text, "#E3"); + Assert.AreEqual ("d", tv.Nodes [3].Text, "#E4"); + Assert.AreEqual ("c", tv.Nodes [4].Text, "#E5"); + Assert.AreEqual ("a", tv.Nodes [5].Text, "#E6"); + Assert.AreEqual (true, tv.Sorted, "#E7"); + + // After setting the node sorter to null and testing, + // I'm curious about the interaction between Sort and Sorted. + tv.TreeViewNodeSorter = null; + Assert.AreEqual (null, tv.TreeViewNodeSorter, "#F1"); + Assert.AreEqual (true, tv.Sorted, "#F2"); + + // Finally, no NodeSorter to automatically set Sorted to true + tv.Sorted = false; + Assert.AreEqual (false, tv.Sorted, "#F0"); + tv.Nodes.Add ("k"); + Assert.AreEqual ("z", tv.Nodes [0].Text, "#G1"); + Assert.AreEqual ("i", tv.Nodes [1].Text, "#G2"); + Assert.AreEqual ("f", tv.Nodes [2].Text, "#G3"); + Assert.AreEqual ("d", tv.Nodes [3].Text, "#G4"); + Assert.AreEqual ("c", tv.Nodes [4].Text, "#G5"); + Assert.AreEqual ("a", tv.Nodes [5].Text, "#G6"); + Assert.AreEqual ("k", tv.Nodes [6].Text, "#G7"); + } + + class InverseNodeSorter : IComparer + { + public int Compare (object a, object b) + { + TreeNode node_a = (TreeNode)a; + TreeNode node_b = (TreeNode)b; + return String.Compare (node_b.Text, node_a.Text); + } + } } #endif } diff --git a/mcs/class/Microsoft.Build.Engine/ChangeLog b/mcs/class/Microsoft.Build.Engine/ChangeLog index 0052a5560ce..11e68a37062 100644 --- a/mcs/class/Microsoft.Build.Engine/ChangeLog +++ b/mcs/class/Microsoft.Build.Engine/ChangeLog @@ -1,3 +1,20 @@ +2010-04-06 Ankit Jain + + * Makefile (EXTRA_DISTFILES): Remove TestTasks.dll.config . + +2010-04-03 Ankit Jain + + * Makefile: Use the correct assembly name for MS.Build.Utilities* + for 3.5 and 4.0 profiles. Copy the .config files for the test + assembly. + Import tools/xbuild/xbuild_targets.make, which copies the target + and tasks file in the correct place, to allow running tests + with different toolsversion. + * Microsoft.Build.Engine.dll.sources: Add LogExtensions.cs, + Toolset.cs, ToolsetDefinitionLocations.cs and ToolsetCollection.cs . + * Test/test-config-file-net-3.5: New. + * Test/test-config-file-net-4.0: New. + 2010-02-19 Ankit Jain * Microsoft.Build.Engine.dll.sources: Add ProjectLoadSettings.cs . diff --git a/mcs/class/Microsoft.Build.Engine/Makefile b/mcs/class/Microsoft.Build.Engine/Makefile index d46bf87bf13..07f9e6fc299 100644 --- a/mcs/class/Microsoft.Build.Engine/Makefile +++ b/mcs/class/Microsoft.Build.Engine/Makefile @@ -11,23 +11,56 @@ NO_TEST = yes NO_SIGN_ASSEMBLY = yes endif +ifeq (3.5, $(FRAMEWORK_VERSION)) +NAME_SUFFIX = .v3.5 +else +ifeq (4.0, $(FRAMEWORK_VERSION)) +NAME_SUFFIX = .v4.0 +endif +endif + LIB_MCS_FLAGS = \ /r:$(corlib) \ /r:System.dll \ + /r:System.Core.dll \ /r:System.Xml.dll \ /r:Microsoft.Build.Framework.dll \ - /r:Microsoft.Build.Utilities.dll + /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll TEST_MCS_FLAGS = \ /r:Microsoft.Build.Framework.dll \ - /r:Microsoft.Build.Utilities.dll + /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll EXTRA_DISTFILES = \ Test/resources/TestTasks.cs \ - Test/resources/*.*proj + Test/resources/*.*proj \ + Test/test-config-file* Test/resources/TestTasks.dll: Test/resources/TestTasks.cs - $(CSCOMPILE) Test/resources/TestTasks.cs /r:Microsoft.Build.Framework.dll /r:Microsoft.Build.Utilities.dll /target:library + $(CSCOMPILE) Test/resources/TestTasks.cs /r:Microsoft.Build.Framework.dll /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll /target:library + +clean-local: clean-test-tasks + +clean-test-tasks: + rm -f Test/resources/TestTasks.dll + +test-local: copy-config + +ifeq (net_4_0, $(PROFILE)) +copy-config: + cp Test/test-config-file-net-4.0 $(test_lib).config +else +ifeq (net_3_5, $(PROFILE)) +copy-config: + cp Test/test-config-file-net-3.5 $(test_lib).config +else +copy-config: +endif +endif + +export TESTING_MONO=a +XBUILD_DIR=../../tools/xbuild +include $(XBUILD_DIR)/xbuild_targets.make test-local: Test/resources/TestTasks.dll diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs index 0200f6f2a87..1d48f922501 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildEngine.cs @@ -32,7 +32,7 @@ using System.Collections; using Microsoft.Build.Framework; namespace Microsoft.Build.BuildEngine { - internal class BuildEngine : IBuildEngine { + internal class BuildEngine : IBuildEngine2 { Engine engine; int columnNumberOfTaskNode; @@ -59,8 +59,17 @@ namespace Microsoft.Build.BuildEngine { string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs) + { + return BuildProjectFile (projectFileName, targetNames, globalProperties, targetOutputs, null); + } + + public bool BuildProjectFile (string projectFileName, + string[] targetNames, + IDictionary globalProperties, + IDictionary targetOutputs, string toolsVersion) { if (String.IsNullOrEmpty (projectFileName)) { + project.ToolsVersion = toolsVersion; return engine.BuildProject (project, targetNames, targetOutputs, BuildSettings.DoNotResetPreviouslyBuiltTargets); } else { @@ -71,10 +80,21 @@ namespace Microsoft.Build.BuildEngine { (string) de.Key, (string) de.Value, PropertyType.Global)); return engine.BuildProjectFile (projectFileName, - targetNames, bpg, targetOutputs, BuildSettings.DoNotResetPreviouslyBuiltTargets); + targetNames, bpg, targetOutputs, BuildSettings.DoNotResetPreviouslyBuiltTargets, toolsVersion); } } + public bool BuildProjectFilesInParallel (string[] projectFileNames, + string [] targetNames, + IDictionary[] globalProperties, + IDictionary[] targetOutputsPerProject, + string[] toolsVersion, + bool useResultsCache, + bool unloadProjectsOnCompletion) + { + throw new NotImplementedException (); + } + // Raises a custom event to all registered loggers. public void LogCustomEvent (CustomBuildEventArgs e) { @@ -128,6 +148,10 @@ namespace Microsoft.Build.BuildEngine { public string ProjectFileOfTaskNode { get { return taskfile; } } + + public bool IsRunningMultipleNodes { + get { return false; } + } } } diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs index 9edeeb5a820..38bdad84bfa 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs @@ -176,27 +176,31 @@ namespace Microsoft.Build.BuildEngine { void LogError (string message, params object[] messageArgs) { - BuildErrorEventArgs beea = new BuildErrorEventArgs ( - null, null, null, 0, 0, 0, 0, String.Format (message, messageArgs), - null, null); - parentTarget.Project.ParentEngine.EventSource.FireErrorRaised (this, beea); + parentTarget.Project.ParentEngine.LogError (message, messageArgs); } void LogMessage (MessageImportance importance, string message, params object[] messageArgs) { - BuildMessageEventArgs bmea = new BuildMessageEventArgs ( - String.Format (message, messageArgs), null, - null, importance); - parentTarget.Project.ParentEngine.EventSource.FireMessageRaised (this, bmea); + parentTarget.Project.ParentEngine.LogMessage (importance, message, messageArgs); } ITask InitializeTask () { ITask task; - task = (ITask)Activator.CreateInstance (this.Type); + try { + task = (ITask)Activator.CreateInstance (this.Type); + } catch (InvalidCastException) { + LogMessage (MessageImportance.Low, "InvalidCastException, ITask: {0} Task type: {1}", + typeof (ITask).AssemblyQualifiedName, this.Type.AssemblyQualifiedName); + throw; + } + parentTarget.Project.ParentEngine.LogMessage ( + MessageImportance.Low, + "Using task {0} from {1}", Name, this.Type.AssemblyQualifiedName); + task.BuildEngine = new BuildEngine (parentTarget.Project.ParentEngine, parentTarget.Project, parentTarget.TargetFile, 0, 0, ContinueOnError); task_logger = new TaskLoggingHelper (task); diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog index adf15516ddf..7b43f792701 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ChangeLog @@ -1,3 +1,55 @@ +2010-04-10 Ankit Jain + + * Project.cs (InitializeProperties): Set MSBuildBinPath to the current + tools path. + +2010-04-10 Ankit Jain + + * TaskEngine.cs (Prepare): Throw InvalidProjectFileException instead of a generic + Exception. + +2010-04-10 Ankit Jain + + * ConsoleLogger.cs (EventsToString): If the target being executed is + from an imported file, then show that. + +2010-04-10 Ankit Jain + + * Project.cs: Add property MSBuildExtensionsPath32, used by silverlight + projects. + +2010-04-07 Ankit Jain + + * ConsoleLogger.cs: Dump items and properties when a project starts + to build. Useful for debugging. + * Engine.cs (LogProjectStarted): Set the properties and items also, + for the project started event. + * Project.cs (EvaluatedPropertiesAsDictionaryEntries): New. + (EvaluatedItemsByNameAsDictionaryEntries): New. Required for + ProjectStartedEvent . + +2010-04-03 Ankit Jain + + * BuildEngine.cs: Implement IBuildEngine2 instead of + IBuildEngine. + * BuildTasks.cs: Use the new extension methods for logging. + (InitializeTask): Emit a message informing about the assembly + from which the task is being loaded. Emit a useful debug message + incase of a InvalidCastException. + * Engine.cs: Add missing methods, constructors and properties related + to ToolsVersion support. Setup a default set of Toolsets. + Keep separate taskdbs' per ToolsVersion. The common tasks + would come from different *.tasks file, and use different + task assemblies. + (DefaultToolsVersion): Correctly set this based on the profile. + * LogExtensions.cs: New. Extension methods on Engine, for logging. + * Project.cs: Add missing methods/contructors/properties related + to ToolsVersion support. Add reserved properties - + MSBuildToolsPath and MSBuildToolsVersion . + * Toolset.cs: New. + * ToolsetCollection.cs: New. + * ToolsetDefinitionLocations.cs: New. + 2010-03-04 Ankit Jain * BuildEngine.cs (LogErrorEvent): Log as warning, if diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs index 8114c79c6c3..02d0179fb3f 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs @@ -29,6 +29,7 @@ using System; using System.Runtime.InteropServices; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Security; @@ -283,6 +284,8 @@ namespace Microsoft.Build.BuildEngine { String.IsNullOrEmpty (args.TargetNames) ? "default" : args.TargetNames)); ResetColor (); WriteLine (String.Empty); + DumpProperties (args.Properties); + DumpItems (args.Items); PushEvent (args); } @@ -405,7 +408,7 @@ namespace Microsoft.Build.BuildEngine { public void CustomEventHandler (object sender, CustomBuildEventArgs args) { } - + private void WriteLine (string message) { if (indent > 0) { @@ -436,6 +439,7 @@ namespace Microsoft.Build.BuildEngine { { StringBuilder sb = new StringBuilder (); + string last_imported_target_file = String.Empty; for (int i = 0; i < events.Count; i ++) { BuildStatusEventArgs args = events [i]; ProjectStartedEventArgs pargs = args as ProjectStartedEventArgs; @@ -444,12 +448,20 @@ namespace Microsoft.Build.BuildEngine { String.IsNullOrEmpty (pargs.TargetNames) ? "default targets" : pargs.TargetNames); + last_imported_target_file = String.Empty; continue; } TargetStartedEventArgs targs = args as TargetStartedEventArgs; - if (targs != null) + if (targs != null) { + if (targs.TargetFile != targs.ProjectFile && targs.TargetFile != last_imported_target_file) + // target from an imported file, + // and it hasn't been mentioned as yet + sb.AppendFormat ("{0} ", targs.TargetFile); + + last_imported_target_file = targs.TargetFile; sb.AppendFormat ("({0} target) ->\n", targs.TargetName); + } } return sb.ToString (); @@ -572,6 +584,59 @@ namespace Microsoft.Build.BuildEngine { return false; } + void DumpProperties (IEnumerable properties) + { + if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic)) + return; + + SetColor (eventColor); + WriteLine ("\n"); + WriteLine ("Initial Properties:"); + ResetColor (); + + if (properties == null) + return; + + var dict = new SortedDictionary (); + foreach (DictionaryEntry de in properties) + dict [(string)de.Key] = (string)de.Value; + + foreach (KeyValuePair pair in dict) + WriteLine (String.Format ("{0} = {1}", pair.Key, pair.Value)); + WriteLine ("\n"); + } + + void DumpItems (IEnumerable items) + { + if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic) || items == null) + return; + + SetColor (eventColor); + WriteLine ("\n"); + WriteLine ("Initial Items:"); + ResetColor (); + if (items == null) + return; + + var items_table = new SortedDictionary> (); + foreach (DictionaryEntry de in items) { + string key = (string)de.Key; + if (!items_table.ContainsKey (key)) + items_table [key] = new List (); + + items_table [key].Add ((ITaskItem) de.Value); + } + + foreach (string name in items_table.Keys) { + WriteLine (name); + indent ++; + foreach (ITaskItem item in items_table [name]) + WriteLine (item.ItemSpec); + indent--; + } + WriteLine ("\n"); + } + public string Parameters { get { return parameters; diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs index a8f6a067a2c..b6fe05eb2c6 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs @@ -40,16 +40,17 @@ namespace Microsoft.Build.BuildEngine { string binPath; bool buildEnabled; - TaskDatabase defaultTasks; - bool defaultTasksRegistered; + Dictionary defaultTasksTableByToolsVersion; const string defaultTasksProjectName = "Microsoft.Common.tasks"; EventSource eventSource; bool buildStarted; + ToolsetDefinitionLocations toolsetLocations; BuildPropertyGroup global_properties; //IDictionary importedProjects; List loggers; //bool onlyLogCriticalEvents; Dictionary projects; + string defaultToolsVersion; // the key here represents the project+target+global_properties set Dictionary builtTargetsOutputByName; @@ -68,6 +69,25 @@ namespace Microsoft.Build.BuildEngine { { } + public Engine (ToolsetDefinitionLocations locations) + : this (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20)) + { + toolsetLocations = locations; + } + + public Engine (BuildPropertyGroup globalProperties) + : this (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20)) + { + this.global_properties = globalProperties; + } + + public Engine (BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations) + : this (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20)) + { + this.global_properties = globalProperties; + toolsetLocations = locations; + } + // engine should be invoked with path where binary files are // to find microsoft.build.tasks public Engine (string binPath) @@ -81,8 +101,25 @@ namespace Microsoft.Build.BuildEngine { this.global_properties = new BuildPropertyGroup (); this.builtTargetsOutputByName = new Dictionary (); this.currentlyBuildingProjectsStack = new Stack (); - - RegisterDefaultTasks (); + this.Toolsets = new ToolsetCollection (); + LoadDefaultToolsets (); + defaultTasksTableByToolsVersion = new Dictionary (); + GetDefaultTasks (DefaultToolsVersion); + } + + //FIXME: should be loaded from config file + void LoadDefaultToolsets () + { + Toolsets.Add (new Toolset ("2.0", + ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20))); + Toolsets.Add (new Toolset ("3.0", + ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version30))); + Toolsets.Add (new Toolset ("3.5", + ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version35))); +#if NET_4_0 + Toolsets.Add (new Toolset ("4.0", + ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version40))); +#endif } [MonoTODO] @@ -128,27 +165,31 @@ namespace Microsoft.Build.BuildEngine { if (targetNames == null) return false; + if (defaultToolsVersion != null) + // it has been explicitly set, xbuild does this.. + project.ToolsVersion = defaultToolsVersion; return project.Build (targetNames, targetOutputs, buildFlags); } [MonoTODO] public bool BuildProjectFile (string projectFile) { - throw new NotImplementedException (); + return BuildProjectFile (projectFile, new string [0]); } [MonoTODO] public bool BuildProjectFile (string projectFile, string targetName) { - throw new NotImplementedException (); + return BuildProjectFile (projectFile, + targetName == null ? new string [0] : new string [] {targetName}); } [MonoTODO] public bool BuildProjectFile (string projectFile, string[] targetNames) { - throw new NotImplementedException (); + return BuildProjectFile (projectFile, targetNames, null); } [MonoTODO] @@ -173,6 +214,16 @@ namespace Microsoft.Build.BuildEngine { BuildPropertyGroup globalProperties, IDictionary targetOutputs, BuildSettings buildFlags) + { + return BuildProjectFile (projectFile, targetNames, globalProperties, targetOutputs, buildFlags, null); + } + + //FIXME: add a test for null @toolsVersion + public bool BuildProjectFile (string projectFile, + string[] targetNames, + BuildPropertyGroup globalProperties, + IDictionary targetOutputs, + BuildSettings buildFlags, string toolsVersion) { Project project; @@ -197,6 +248,13 @@ namespace Microsoft.Build.BuildEngine { } try { + if (String.IsNullOrEmpty (toolsVersion) && defaultToolsVersion != null) + // it has been explicitly set, xbuild does this.. + //FIXME: should this be cleared after building? + project.ToolsVersion = defaultToolsVersion; + else + project.ToolsVersion = toolsVersion; + return project.Build (targetNames, targetOutputs, buildFlags); } finally { if (globalProperties != null) { @@ -217,8 +275,6 @@ namespace Microsoft.Build.BuildEngine { public Project CreateNewProject () { - if (defaultTasksRegistered) - CheckBinPath (); return new Project (this); } @@ -328,13 +384,15 @@ namespace Microsoft.Build.BuildEngine { void LogProjectStarted (Project project, string [] target_names) { - ProjectStartedEventArgs psea; + string targets; if (target_names == null || target_names.Length == 0) - psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, - String.Empty, null, null); + targets = String.Empty; else - psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, - String.Join (";", target_names), null, null); + targets = String.Join (";", target_names); + + ProjectStartedEventArgs psea = new ProjectStartedEventArgs ("Project started.", null, project.FullFileName, targets, + project.EvaluatedPropertiesAsDictionaryEntries, project.EvaluatedItemsByNameAsDictionaryEntries); + eventSource.FireProjectStarted (this, psea); } @@ -358,23 +416,44 @@ namespace Microsoft.Build.BuildEngine { bfea = new BuildFinishedEventArgs ("Build finished.", null, succeeded); eventSource.FireBuildFinished (this, bfea); } + + internal TaskDatabase GetDefaultTasks (string toolsVersion) + { + TaskDatabase db; + if (defaultTasksTableByToolsVersion.TryGetValue (toolsVersion, out db)) + return db; + + var toolset = Toolsets [toolsVersion]; + if (toolset == null) + throw new Exception ("Unknown toolsversion: " + toolsVersion); + + string toolsPath = toolset.ToolsPath; + string tasksFile = Path.Combine (toolsPath, defaultTasksProjectName); + this.LogMessage (MessageImportance.Low, "Loading default tasks for ToolsVersion: {0} from {1}", toolsVersion, tasksFile); + + // set a empty taskdb here, because the project loading the tasks + // file will try to get the default task db + defaultTasksTableByToolsVersion [toolsVersion] = new TaskDatabase (); + + db = defaultTasksTableByToolsVersion [toolsVersion] = RegisterDefaultTasks (tasksFile); + + return db; + } - void RegisterDefaultTasks () + TaskDatabase RegisterDefaultTasks (string tasksFile) { - this.defaultTasksRegistered = false; - Project defaultTasksProject = CreateNewProject (); + TaskDatabase db; - if (binPath != null) { - if (File.Exists (Path.Combine (binPath, defaultTasksProjectName))) { - defaultTasksProject.Load (Path.Combine (binPath, defaultTasksProjectName)); - defaultTasks = defaultTasksProject.TaskDatabase; - } else - defaultTasks = new TaskDatabase (); - } else - defaultTasks = new TaskDatabase (); - - this.defaultTasksRegistered = true; + if (File.Exists (tasksFile)) { + defaultTasksProject.Load (tasksFile); + db = defaultTasksProject.TaskDatabase; + } else { + this.LogWarning ("Default tasks file {0} not found, ignoring.", tasksFile); + db = new TaskDatabase (); + } + + return db; } public string BinPath { @@ -403,7 +482,31 @@ namespace Microsoft.Build.BuildEngine { get { return global_properties; } set { global_properties = value; } } + + public ToolsetCollection Toolsets { + get; private set; + } + public string DefaultToolsVersion { + get { + if (String.IsNullOrEmpty (defaultToolsVersion)) +#if NET_4_0 + return "4.0"; +#elif NET_3_5 + return "3.5"; +#else + return "2.0"; +#endif + + return defaultToolsVersion; + } + set { defaultToolsVersion = value; } + } + + public bool IsBuilding { + get { return buildStarted; } + } + public bool OnlyLogCriticalEvents { get { return eventSource.OnlyLogCriticalEvents; } set { eventSource.OnlyLogCriticalEvents = value; } @@ -413,14 +516,6 @@ namespace Microsoft.Build.BuildEngine { get { return eventSource; } } - internal bool DefaultTasksRegistered { - get { return defaultTasksRegistered; } - } - - internal TaskDatabase DefaultTasks { - get { return defaultTasks; } - } - internal Dictionary BuiltTargetsOutputByName { get { return builtTargetsOutputByName; } } diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/LogExtensions.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/LogExtensions.cs new file mode 100644 index 00000000000..030ea8aa86a --- /dev/null +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/LogExtensions.cs @@ -0,0 +1,183 @@ +// +// LogExtensions.cs: Extension methods for logging on Engine +// +// Author: +// Ankit Jain (jankit@novell.com) +// +// Copyright 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#if NET_2_0 + +using System; +using System.IO; +using System.Text; +using Microsoft.Build.Framework; + +namespace Microsoft.Build.BuildEngine +{ + static class LogExtensions + { + public static string FormatString (string unformatted, + params object[] args) + { + if (unformatted == null) + throw new ArgumentNullException ("unformatted"); + + if (args == null || args.Length == 0) + return unformatted; + else + return String.Format (unformatted, args); + } + + public static void LogError (this Engine engine, string message, + params object[] messageArgs) + { + if (message == null) + throw new ArgumentNullException ("message"); + + BuildErrorEventArgs beea = new BuildErrorEventArgs ( + null, null, null, 0, 0, 0, 0, FormatString (message, messageArgs), + null, null); + engine.EventSource.FireErrorRaised (engine, beea); + } + + public static void LogError (this Engine engine, string subcategory, string errorCode, + string helpKeyword, string file, + int lineNumber, int columnNumber, + int endLineNumber, int endColumnNumber, + string message, + params object[] messageArgs) + { + if (message == null) + throw new ArgumentNullException ("message"); + + BuildErrorEventArgs beea = new BuildErrorEventArgs ( + subcategory, errorCode, file, lineNumber, + columnNumber, endLineNumber, endColumnNumber, + FormatString (message, messageArgs), helpKeyword /*it's helpKeyword*/, + null /*it's senderName*/); + + engine.EventSource.FireErrorRaised (engine, beea); + } + + public static void LogErrorFromException (this Engine engine, Exception e) + { + LogErrorFromException (engine, e, true); + } + + public static void LogErrorFromException (this Engine engine, Exception e, + bool showStackTrace) + { + LogErrorFromException (engine, e, showStackTrace, true, String.Empty); + } + + [MonoTODO ("Arguments @showDetail and @file are not honored")] + public static void LogErrorFromException (this Engine engine, Exception e, + bool showStackTrace, bool showDetail, string file) + { + if (e == null) + throw new ArgumentNullException ("e"); + + StringBuilder sb = new StringBuilder (); + sb.Append (e.Message); + if (showStackTrace == true) + sb.Append (e.StackTrace); + BuildErrorEventArgs beea = new BuildErrorEventArgs ( + null, null, null, 0, 0, 0, 0, sb.ToString (), + e.HelpLink, e.Source); + engine.EventSource.FireErrorRaised (engine, beea); + } + + public static void LogMessage (this Engine engine, string message, + params object[] messageArgs) + { + LogMessage (engine, MessageImportance.Normal, message, messageArgs); + } + + public static void LogMessage (this Engine engine, MessageImportance importance, + string message, + params object[] messageArgs) + { + if (message == null) + throw new ArgumentNullException ("message"); + + LogMessageFromText (engine, FormatString (message, messageArgs), importance); + } + + public static bool LogMessageFromText (this Engine engine, string lineOfText, + MessageImportance importance) + { + if (lineOfText == null) + throw new ArgumentNullException ("lineOfText"); + + BuildMessageEventArgs bmea = new BuildMessageEventArgs ( + lineOfText, null, + null, importance); + + engine.EventSource.FireMessageRaised (engine, bmea); + + return true; + } + + public static void LogWarning (this Engine engine, string message, + params object[] messageArgs) + { + // FIXME: what about all the parameters? + BuildWarningEventArgs bwea = new BuildWarningEventArgs ( + null, null, null, 0, 0, 0, 0, FormatString (message, messageArgs), + null, null); + engine.EventSource.FireWarningRaised (engine, bwea); + } + + public static void LogWarning (this Engine engine, string subcategory, string warningCode, + string helpKeyword, string file, + int lineNumber, int columnNumber, + int endLineNumber, int endColumnNumber, + string message, + params object[] messageArgs) + { + BuildWarningEventArgs bwea = new BuildWarningEventArgs ( + subcategory, warningCode, file, lineNumber, + columnNumber, endLineNumber, endColumnNumber, + FormatString (message, messageArgs), helpKeyword, null); + engine.EventSource.FireWarningRaised (engine, bwea); + } + + public static void LogWarningFromException (this Engine engine, Exception e) + { + LogWarningFromException (engine, e, false); + } + + public static void LogWarningFromException (this Engine engine, Exception e, + bool showStackTrace) + { + StringBuilder sb = new StringBuilder (); + sb.Append (e.Message); + if (showStackTrace) + sb.Append (e.StackTrace); + LogWarning (engine, null, null, null, null, 0, 0, 0, 0, + sb.ToString (), null); + } + } +} + +#endif diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs index b5b0b1aa811..0bda5abba45 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Project.cs @@ -89,9 +89,14 @@ namespace Microsoft.Build.BuildEngine { { } - public Project (Engine engine) + public Project (Engine engine) : this (engine, null) + { + } + + public Project (Engine engine, string toolsVersion) { parentEngine = engine; + ToolsVersion = toolsVersion; buildEnabled = ParentEngine.BuildEnabled; xmlDocument = new XmlDocument (); @@ -116,6 +121,7 @@ namespace Microsoft.Build.BuildEngine { GlobalProperties.AddProperty (bp.Clone (true)); ProcessXml (); + } [MonoTODO ("Not tested")] @@ -793,8 +799,7 @@ namespace Microsoft.Build.BuildEngine { last_item_group_containing = new Dictionary (); taskDatabase = new TaskDatabase (); - if (ParentEngine.DefaultTasksRegistered) - taskDatabase.CopyTasks (ParentEngine.DefaultTasks); + taskDatabase.CopyTasks (ParentEngine.GetDefaultTasks (GetToolsVersionToUse ())); initialTargets = new List (); defaultTargets = new string [0]; @@ -860,7 +865,7 @@ namespace Microsoft.Build.BuildEngine { AddChoose (xe); break; default: - throw new InvalidProjectFileException ("Invalid element in project file."); + throw new InvalidProjectFileException (String.Format ("Invalid element '{0}' in project file.", xe.Name)); } } } @@ -927,9 +932,15 @@ namespace Microsoft.Build.BuildEngine { EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildProjectName", Path.GetFileNameWithoutExtension (fullFileName), PropertyType.Reserved)); - EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildBinPath", parentEngine.BinPath, PropertyType.Reserved)); - EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildToolsPath", parentEngine.BinPath, PropertyType.Reserved)); + string toolsVersionToUse = GetToolsVersionToUse (); + string toolsPath = parentEngine.Toolsets [toolsVersionToUse].ToolsPath; + if (toolsPath == null) + throw new Exception ("Unknown toolsVersion: " + toolsVersionToUse); + EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildBinPath", toolsPath, PropertyType.Reserved)); + EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildToolsPath", toolsPath, PropertyType.Reserved)); + EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildToolsVersion", toolsVersionToUse, PropertyType.Reserved)); EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildExtensionsPath", ExtensionsPath, PropertyType.Reserved)); + EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildExtensionsPath32", ExtensionsPath, PropertyType.Reserved)); EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildProjectDefaultTargets", DefaultTargets, PropertyType.Reserved)); EvaluatedProperties.AddProperty (new BuildProperty ("OS", OS, PropertyType.Environment)); @@ -942,6 +953,18 @@ namespace Microsoft.Build.BuildEngine { EvaluatedProperties.AddProperty (new BuildProperty ("MSBuildProjectDirectory", projectDir, PropertyType.Reserved)); } + + string GetToolsVersionToUse () + { + if (String.IsNullOrEmpty (ToolsVersion)) { + if (HasToolsVersionAttribute) + return DefaultToolsVersion; + else + return parentEngine.DefaultToolsVersion; + } else { + return ToolsVersion; + } + } void AddProjectExtensions (XmlElement xmlElement) { @@ -1077,7 +1100,19 @@ namespace Microsoft.Build.BuildEngine { return evaluatedItemsByName; } } - + + internal IEnumerable EvaluatedItemsByNameAsDictionaryEntries { + get { + if (EvaluatedItemsByName.Count == 0) + yield break; + + foreach (KeyValuePair pair in EvaluatedItemsByName) { + foreach (BuildItem bi in pair.Value) + yield return new DictionaryEntry (pair.Key, bi.ConvertToITaskItem (null, ExpressionOptions.ExpandItemRefs)); + } + } + } + internal IDictionary EvaluatedItemsByNameIgnoringCondition { get { // FIXME: do we need to do this here? @@ -1238,6 +1273,13 @@ namespace Microsoft.Build.BuildEngine { } } + internal IEnumerable EvaluatedPropertiesAsDictionaryEntries { + get { + foreach (BuildProperty bp in EvaluatedProperties) + yield return new DictionaryEntry (bp.Name, bp.Value); + } + } + public string FullFileName { get { return fullFileName; } set { fullFileName = value; } @@ -1316,6 +1358,29 @@ namespace Microsoft.Build.BuildEngine { get { return xmlDocument.InnerXml; } } + // corresponds to the xml attribute + public string DefaultToolsVersion { + get { + if (xmlDocument != null) + return xmlDocument.DocumentElement.GetAttribute ("ToolsVersion"); + return null; + } + set { + if (xmlDocument != null) + xmlDocument.DocumentElement.SetAttribute ("ToolsVersion", value); + } + } + + public bool HasToolsVersionAttribute { + get { + return xmlDocument != null && xmlDocument.DocumentElement.HasAttribute ("ToolsVersion"); + } + } + + public string ToolsVersion { + get; internal set; + } + internal List BuiltTargetKeys { get { return builtTargetKeys; } } diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs index 485771de492..696ffbeedfb 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs @@ -95,7 +95,7 @@ namespace Microsoft.Build.BuildEngine { if (TryGetObjectFromString (de.Value, currentProperty.PropertyType, out value)) values.Add (de.Key, value); } catch (Exception e) { - throw new Exception (String.Format ( + throw new InvalidProjectFileException (String.Format ( "Error converting Property named '{0}' with value '{1}' to type {2}: {3}", de.Key, de.Value, currentProperty.PropertyType, e.Message), e); } @@ -171,10 +171,10 @@ namespace Microsoft.Build.BuildEngine { propertyInfo = taskType.GetProperty (taskParameter, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); if (propertyInfo == null) - throw new Exception (String.Format ( + throw new InvalidProjectFileException (String.Format ( "The parameter '{0}' was not found for the '{1}' task.", taskParameter, taskElement.Name)); if (!propertyInfo.IsDefined (outputAttribute, false)) - throw new Exception ("This is not output property."); + throw new InvalidProjectFileException ("This is not output property."); o = propertyInfo.GetValue (task, null); // FIXME: maybe we should throw an exception here? diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Toolset.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Toolset.cs new file mode 100644 index 00000000000..d7955176a4a --- /dev/null +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Toolset.cs @@ -0,0 +1,53 @@ +// +// Toolset.cs +// +// Author: +// Ankit Jain (jankit@novell.com) +// +// Copyright 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#if NET_2_0 +using System; + +namespace Microsoft.Build.BuildEngine +{ + public class Toolset + { + public Toolset (string toolsVersion, string toolsPath, BuildPropertyGroup buildProperties) + { + ToolsVersion = toolsVersion; + ToolsPath = toolsPath; + BuildProperties = buildProperties; + } + + public Toolset (string toolsVersion, string toolsPath) + : this (toolsVersion, toolsPath, null) + { + } + + public BuildPropertyGroup BuildProperties { get; private set; } + + public string ToolsVersion { get; private set; } + public string ToolsPath { get; private set; } + } +} +#endif diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetCollection.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetCollection.cs new file mode 100644 index 00000000000..0c332d45d53 --- /dev/null +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetCollection.cs @@ -0,0 +1,99 @@ +// +// ToolsetCollection.cs +// +// Author: +// Ankit Jain (jankit@novell.com) +// +// Copyright 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#if NET_2_0 + +using System; +using System.Collections.Generic; +using System.Collections; + +namespace Microsoft.Build.BuildEngine +{ + + public class ToolsetCollection : ICollection, IEnumerable, IEnumerable + { + List toolsets; + + internal ToolsetCollection () + { + toolsets = new List (); + } + + public int Count + { + get { return toolsets.Count; } + } + + public bool IsReadOnly { get { return false; } } + + public Toolset this [string toolsVersion] + { + get { return toolsets.Find (item => item.ToolsVersion == toolsVersion); } + } + + public void Add (Toolset item) + { + toolsets.Add (item); + } + + public void Clear () + { + toolsets.Clear (); + } + + public bool Contains (string toolsVersion) + { + return toolsets.Exists (item => item.ToolsVersion == toolsVersion); + } + + public bool Contains (Toolset item) + { + return toolsets.Contains (item); + } + + public void CopyTo (Toolset[] array, int arrayIndex) + { + toolsets.CopyTo (array, arrayIndex); + } + + public IEnumerator GetEnumerator () + { + return toolsets.GetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return toolsets.GetEnumerator (); + } + + public bool Remove (Toolset item) + { + return toolsets.Remove (item); + } + } +} +#endif diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs new file mode 100644 index 00000000000..6f5e106b8e9 --- /dev/null +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs @@ -0,0 +1,39 @@ +// +// ToolsetDefinitionLocations.cs +// +// Author: +// Ankit Jain (jankit@novell.com) +// +// Copyright 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#if NET_2_0 + +namespace Microsoft.Build.BuildEngine +{ + public enum ToolsetDefinitionLocations + { + None, + ConfigurationFile, + Registry + } +} +#endif diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources index 8f429b31a78..02bc4c2002f 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.Engine.dll.sources @@ -46,6 +46,7 @@ Microsoft.Build.BuildEngine/InternalLoggerException.cs Microsoft.Build.BuildEngine/InvalidProjectFileException.cs Microsoft.Build.BuildEngine/IReference.cs Microsoft.Build.BuildEngine/ItemReference.cs +Microsoft.Build.BuildEngine/LogExtensions.cs Microsoft.Build.BuildEngine/MetadataReference.cs Microsoft.Build.BuildEngine/Project.cs Microsoft.Build.BuildEngine/ProjectLoadSettings.cs @@ -56,6 +57,9 @@ Microsoft.Build.BuildEngine/Target.cs Microsoft.Build.BuildEngine/TaskDatabase.cs Microsoft.Build.BuildEngine/TaskEngine.cs Microsoft.Build.BuildEngine/Token.cs +Microsoft.Build.BuildEngine/Toolset.cs +Microsoft.Build.BuildEngine/ToolsetCollection.cs +Microsoft.Build.BuildEngine/ToolsetDefinitionLocations.cs Microsoft.Build.BuildEngine/UsingTask.cs Microsoft.Build.BuildEngine/UsingTaskCollection.cs Microsoft.Build.BuildEngine/Utilities.cs diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog index 7a11426c773..c6084a139c6 100644 --- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog +++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ChangeLog @@ -1,3 +1,11 @@ +2010-04-06 Ankit Jain + + * Consts.cs (ToolsVersionString): New. + (GetTasksAsmPath): New. + * EngineTest.cs: Use the direct path to the tasks assembly + in the UsingTasks. + * ProjectTest.cs: Set ToolsVersion to the current profile. + 2010-02-19 Ankit Jain * ImportTest.cs (TestMissingImport*): Add new tests for missing diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs index bae9a32d6e5..31a160850a1 100644 --- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs +++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System; +using System.IO; using Microsoft.Build.Utilities; public static class Consts { @@ -43,4 +44,27 @@ public static class Consts { return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20); } } + + public static string ToolsVersionString { + get { +#if NET_4_0 + return " ToolsVersion='4.0'"; +#elif NET_3_5 + return " ToolsVersion='3.5'"; +#else + return String.Empty; +#endif + } + } + + public static string GetTasksAsmPath () + { +#if NET_4_0 + return Path.Combine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version40), "Microsoft.Build.Tasks.v4.0.dll"); +#elif NET_3_5 + return Path.Combine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version35), "Microsoft.Build.Tasks.v3.5.dll"); +#else + return Path.Combine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20), "Microsoft.Build.Tasks.dll"); +#endif + } } diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs index e18e464cb91..b64c1f5bcf1 100644 --- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs +++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/EngineTest.cs @@ -324,8 +324,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties1 () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -333,9 +334,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -363,8 +364,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { public void TestGlobalProperties1a () { Directory.CreateDirectory ("Test/resources/foo"); - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -372,9 +374,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -401,8 +403,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties1b () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -410,9 +413,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -439,8 +442,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties2 () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -449,9 +453,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -478,8 +482,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties3 () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -491,9 +496,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -521,8 +526,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties4 () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -534,9 +540,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -568,8 +574,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties4a () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -581,9 +588,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -615,8 +622,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties4b () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -628,9 +636,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -666,8 +674,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestGlobalProperties4c () { - string mainProject = @" - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -679,9 +688,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { "; - string firstProject = @" - + string firstProject = @"" + + GetUsingTask ("MSBuild") + + @" @@ -714,10 +723,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestMSBuildOutputs () { - string mainProject = @" - - + string mainProject = @"" + + GetUsingTask ("MSBuild") + + @" value @@ -889,6 +897,9 @@ namespace MonoTests.Microsoft.Build.BuildEngine { } } - + public static string GetUsingTask (string taskName) + { + return ""; + } } } diff --git a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs index cce13c6af67..5d92a43f5a5 100644 --- a/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs +++ b/mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/ProjectTest.cs @@ -1779,7 +1779,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine { Engine engine = new Engine (Consts.BinPath); Project project = engine.CreateNewProject (); - string second = @" + string second = @" InitialVal @@ -1797,7 +1797,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine { sw.Write (second); } - string third = @" + string third = @" Third Value @@ -1972,7 +1972,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine { [Test] public void TestCaseSensitivityOfProjectElements () { - string projectXml = @" + string projectXml = @" md1 diff --git a/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-3.5 b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-3.5 new file mode 100644 index 00000000000..7756bca8df1 --- /dev/null +++ b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-3.5 @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-4.0 b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-4.0 new file mode 100644 index 00000000000..3c78f3b4ec8 --- /dev/null +++ b/mcs/class/Microsoft.Build.Engine/Test/test-config-file-net-4.0 @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mcs/class/Microsoft.Build.Framework/ChangeLog b/mcs/class/Microsoft.Build.Framework/ChangeLog index 74073fb0652..dea06412ca5 100644 --- a/mcs/class/Microsoft.Build.Framework/ChangeLog +++ b/mcs/class/Microsoft.Build.Framework/ChangeLog @@ -1,3 +1,10 @@ +2010-04-03 Ankit Jain + + * Makefile: Import tools/xbuild/xbuild_targets.make, which copies + the target and tasks file in the correct place, to allow running + tests with different toolsversion. + * Microsoft.Build.Framework.dll.sources: Add IBuildEngine2.cs . + 2006-04-19 Marek Sieradzki * Microsoft.Build.Framework.targets: Removed. diff --git a/mcs/class/Microsoft.Build.Framework/Makefile b/mcs/class/Microsoft.Build.Framework/Makefile index 74043402bbc..0cb68bfac6c 100644 --- a/mcs/class/Microsoft.Build.Framework/Makefile +++ b/mcs/class/Microsoft.Build.Framework/Makefile @@ -17,5 +17,9 @@ LIB_MCS_FLAGS = \ include ../../build/library.make +export TESTING_MONO=a +XBUILD_DIR=../../tools/xbuild +include $(XBUILD_DIR)/xbuild_targets.make + EXTRA_DISTFILES = \ Mono.XBuild.Framework/AssemblyLoadInfo.cs diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources index 5be4904c10f..7e7d3a57db2 100644 --- a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources +++ b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources @@ -20,6 +20,7 @@ Microsoft.Build.Framework/CustomBuildEventHandler.cs Microsoft.Build.Framework/ExternalProjectFinishedEventArgs.cs Microsoft.Build.Framework/ExternalProjectStartedEventArgs.cs Microsoft.Build.Framework/IBuildEngine.cs +Microsoft.Build.Framework/IBuildEngine2.cs Microsoft.Build.Framework/IEventSource.cs Microsoft.Build.Framework/ILogger.cs Microsoft.Build.Framework/ITask.cs diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog index 47cfed8525e..0f14e7b1420 100644 --- a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog +++ b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ChangeLog @@ -1,3 +1,7 @@ +2010-04-03 Ankit Jain + + * IBuildEngine2.cs: New. + 2006-12-19 Marek Sieradzki * LoggerException.cs: Changed serialization names. diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine2.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine2.cs new file mode 100644 index 00000000000..42b456c3a0c --- /dev/null +++ b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine2.cs @@ -0,0 +1,59 @@ +// +// IBuildEngine2.cs: Provides a way for task authors to use the functionality +// of the MSBuild engine. +// +// Author: +// Ankit Jain (jankit@novell.com) +// +// Copyright 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +#if NET_2_0 + +using System; +using System.Collections; + +namespace Microsoft.Build.Framework +{ + public interface IBuildEngine2 : IBuildEngine + { + // Initiates a build of a project file. If the build is + // successful, the outputs (if any) of the specified targets + // are returned. + bool BuildProjectFile (string projectFileName, + string[] targetNames, + IDictionary globalProperties, + IDictionary targetOutputs, string toolsVersion); + + bool BuildProjectFilesInParallel (string[] projectFileNames, + string [] targetNames, + IDictionary[] globalProperties, + IDictionary[] targetOutputsPerProject, + string[] toolsVersion, + bool useResultsCache, + bool unloadProjectsOnCompletion); + + bool IsRunningMultipleNodes { get; } + + } +} + +#endif diff --git a/mcs/class/Microsoft.Build.Tasks/ChangeLog b/mcs/class/Microsoft.Build.Tasks/ChangeLog index 7e8c05ac911..ff531ad0138 100644 --- a/mcs/class/Microsoft.Build.Tasks/ChangeLog +++ b/mcs/class/Microsoft.Build.Tasks/ChangeLog @@ -1,3 +1,14 @@ +2010-04-03 Ankit Jain + + * Makefile: Import tools/xbuild/xbuild_targets.make, which copies + the target and tasks file in the correct place, to allow running + tests with different toolsversion. Copy the config file for the + test assembly. Clean the generated test.dll . + Use the correct target assembly name for 4.0 profile + (ms.build.tasks.v4.0.dll), and for Utilities assembly. + * Microsoft.Build.Tasks_test.dll.sources: Use Consts.cs from Engine + instead of maintaining a copy here. + 2010-03-02 Ankit Jain Fix tests. diff --git a/mcs/class/Microsoft.Build.Tasks/Makefile b/mcs/class/Microsoft.Build.Tasks/Makefile index 70d2cb67752..34a542a1e1b 100644 --- a/mcs/class/Microsoft.Build.Tasks/Makefile +++ b/mcs/class/Microsoft.Build.Tasks/Makefile @@ -14,6 +14,10 @@ else ifeq (3.5, $(FRAMEWORK_VERSION)) NAME_SUFFIX = .v3.5 +else +ifeq (4.0, $(FRAMEWORK_VERSION)) +NAME_SUFFIX = .v4.0 +endif endif LIBRARY_NAME = Microsoft.Build.Tasks$(NAME_SUFFIX).dll @@ -26,7 +30,7 @@ LIB_MCS_FLAGS = \ /r:System.Core.dll \ /r:System.Xml.dll \ /r:System.Windows.Forms.dll \ - /r:Microsoft.Build.Utilities.dll \ + /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll \ /r:Microsoft.Build.Framework.dll \ /r:Microsoft.Build.Engine.dll @@ -39,11 +43,35 @@ EXTRA_DISTFILES = \ Test/resources/test.cs \ Test/resources/Sample.cs \ Test/resources/Sample.vb \ - Test/resources/junk.txt + Test/resources/junk.txt \ + Test/test-config-file* test-local: Test/resources/test.dll Test/resources/test.dll: Test/resources/test.cs $(CSCOMPILE) -target:library Test/resources/test.cs +clean-local: clean-test-dll + +clean-test-dll: + rm -f Test/resources/test.dll + +test-local: copy-config + +ifeq (net_4_0, $(PROFILE)) +copy-config: + cp Test/test-config-file-net-4.0 $(test_lib).config +else +ifeq (net_3_5, $(PROFILE)) +copy-config: + cp Test/test-config-file-net-3.5 $(test_lib).config +else +copy-config: +endif +endif + +export TESTING_MONO=a +XBUILD_DIR=../../tools/xbuild +include $(XBUILD_DIR)/xbuild_targets.make + include ../../build/library.make diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog index 3104cf56732..354d0dc1f90 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/ChangeLog @@ -1,3 +1,42 @@ +2010-04-10 Ankit Jain + + * GetFrameworkPath.cs (FrameworkVersion40Path): New. + +2010-04-10 Ankit Jain + + * Copy.cs: Cleanly log errors, instead of throwing exceptions. + +2010-04-10 Ankit Jain + + * Vbc.cs (LogEventsFromTextOutput): + * ToolTask.cs (LogEventsFromTextOutput): Emit the messages + that don't match the error regex, as is. + +2010-04-08 Ankit Jain + + * Copy.cs: Handle non-existant source files. + +2010-04-08 Ankit Jain + + Fix bug #594541 + * Vbc.cs (LogEventsFromTextOutput): Override and correctly parse + output. Taken regex from monodevelop for this. + +2010-04-08 Ankit Jain + + * Vbc.cs (ValidateParameters): Always return true, dummy implementation. + +2010-04-07 Ankit Jain + + * MSBuild.cs: Emit global properties, if any. Sort the property + list. + +2010-04-03 Ankit Jain + + * Csc.cs: Use dmcs as the compiler for 4.0 profile. + * MSBuild.cs (ToolsVersion): New. + Use toolsVersion for building. + 2010-02-10 Ankit Jain * GenerateResource.cs (CompileResourceFile): Check File.Exists diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs index f704bceb446..a090e4716d4 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Copy.cs @@ -57,10 +57,16 @@ namespace Microsoft.Build.Tasks { List temporaryCopiedFiles = new List (); if (sourceFiles != null && destinationFiles != null && - sourceFiles.Length != destinationFiles.Length) - throw new Exception ("Number of source files is different than number of destination files."); - if (destinationFiles != null && destinationFolder != null) - throw new Exception ("You must specify only one attribute from DestinationFiles and DestinationFolder"); + sourceFiles.Length != destinationFiles.Length) { + Log.LogError ("Number of source files is different than number of destination files."); + return false; + } + + if (destinationFiles != null && destinationFolder != null) { + Log.LogError ("You must specify only one attribute from DestinationFiles and DestinationFolder"); + return false; + } + if (destinationFiles != null && destinationFiles.Length > 0) { for (int i = 0; i < sourceFiles.Length; i ++) { ITaskItem sourceItem = sourceFiles [i]; @@ -68,6 +74,11 @@ namespace Microsoft.Build.Tasks { string sourceFile = sourceItem.GetMetadata ("FullPath"); string destinationFile = destinationItem.GetMetadata ("FullPath"); + if (!File.Exists (sourceFile)) { + Log.LogError ("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile); + continue; + } + if (!skipUnchangedFiles || HasFileChanged (sourceFile, destinationFile)) CopyFile (sourceFile, destinationFile, true); @@ -85,6 +96,11 @@ namespace Microsoft.Build.Tasks { string filename = sourceItem.GetMetadata ("Filename") + sourceItem.GetMetadata ("Extension"); string destinationFile = Path.Combine (destinationDirectory,filename); + if (!File.Exists (sourceFile)) { + Log.LogError ("Cannot copy {0} to {1}, as the source file doesn't exist.", sourceFile, destinationFile); + continue; + } + if (!skipUnchangedFiles || directoryCreated || HasFileChanged (sourceFile, destinationFile)) CopyFile (sourceFile, destinationFile, false); @@ -99,7 +115,8 @@ namespace Microsoft.Build.Tasks { } destinationFiles = temporaryDestinationFiles.ToArray (); } else { - throw new Exception ("You must specify DestinationFolder or DestinationFiles attribute."); + Log.LogError ("You must specify DestinationFolder or DestinationFiles attribute."); + return false; } copiedFiles = temporaryCopiedFiles.ToArray (); diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs index 8b4217ab327..98399663276 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Csc.cs @@ -187,7 +187,11 @@ namespace Microsoft.Build.Tasks { protected override string ToolName { get { +#if NET_4_0 + return Utilities.RunningOnWindows ? "dmcs.bat" : "dmcs"; +#else return Utilities.RunningOnWindows ? "gmcs.bat" : "gmcs"; +#endif } } diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs index f32d5279133..07e6169fc5a 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/GetFrameworkPath.cs @@ -87,6 +87,15 @@ namespace Microsoft.Build.Tasks { } } +#if NET_4_0 + [Output] + public string FrameworkVersion40Path { + get { + return ToolLocationHelper.GetPathToDotNetFramework ( + TargetDotNetFrameworkVersion.Version40); + } + } +#endif } } diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs index 592a4122123..90c54cd38c5 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/MSBuild.cs @@ -65,9 +65,14 @@ namespace Microsoft.Build.Tasks { string currentDirectory = Environment.CurrentDirectory; Hashtable outputs; - Dictionary global_properties = SplitPropertiesToDictionary (); + var global_properties = SplitPropertiesToDictionary (); Dictionary projectsByFileName = new Dictionary (); + Log.LogMessage (MessageImportance.Low, "Global Properties:"); + if (global_properties != null) + foreach (KeyValuePair pair in global_properties) + Log.LogMessage (MessageImportance.Low, "\t{0} = {1}", pair.Key, pair.Value); + foreach (ITaskItem project in projects) { filename = project.GetMetadata ("FullPath"); if (!File.Exists (filename)) { @@ -82,7 +87,14 @@ namespace Microsoft.Build.Tasks { outputs = new Hashtable (); try { - result = BuildEngine.BuildProjectFile (filename, targets, global_properties, outputs); + // Order of precedence: + // %(Project.ToolsVersion) , ToolsVersion property + string tv = project.GetMetadata ("ToolsVersion"); + if (String.IsNullOrEmpty (tv)) + tv = ToolsVersion; + ThrowIfNotValidToolsVersion (tv); + + result = BuildEngine2.BuildProjectFile (filename, targets, global_properties, outputs, tv); } catch (InvalidProjectFileException e) { Log.LogError ("Error building project {0}: {1}", filename, e.Message); result = false; @@ -127,6 +139,12 @@ namespace Microsoft.Build.Tasks { return result; } + void ThrowIfNotValidToolsVersion (string toolsVersion) + { + if (!String.IsNullOrEmpty (toolsVersion) && Engine.GlobalEngine.Toolsets [toolsVersion] == null) + throw new Exception (String.Format ("Unknown ToolsVersion : {0}", toolsVersion)); + } + [Required] public ITaskItem [] Projects { get { return projects; } @@ -170,12 +188,16 @@ namespace Microsoft.Build.Tasks { set { buildInParallel = value; } } - Dictionary SplitPropertiesToDictionary () + public string ToolsVersion { + get; set; + } + + SortedDictionary SplitPropertiesToDictionary () { if (properties == null) return null; - Dictionary global_properties = new Dictionary (); + var global_properties = new SortedDictionary (); foreach (string kvpair in properties) { if (String.IsNullOrEmpty (kvpair)) continue; diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs index 66c0889ce9c..52a8da8f978 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Vbc.cs @@ -31,6 +31,7 @@ using System; using System.IO; using System.Text; +using System.Text.RegularExpressions; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -151,9 +152,53 @@ namespace Microsoft.Build.Tasks { [MonoTODO] protected override bool ValidateParameters () { - throw new NotImplementedException (); + return true; } - + + protected override void LogEventsFromTextOutput (string singleLine, MessageImportance importance) + { + singleLine = singleLine.Trim (); + if (singleLine.Length == 0) + return; + + // When IncludeDebugInformation is true, prevents the debug symbols stats from braeking this. + if (singleLine.StartsWith ("WROTE SYMFILE") || + singleLine.StartsWith ("OffsetTable") || + singleLine.StartsWith ("Compilation succeeded") || + singleLine.StartsWith ("Compilation failed")) + return; + + Match match = ErrorRegex.Match (singleLine); + if (!match.Success) { + Log.LogMessage (importance, singleLine); + return; + } + + string filename = match.Result ("${file}") ?? ""; + + string line = match.Result ("${line}"); + int lineNumber = !string.IsNullOrEmpty (line) ? Int32.Parse (line) : 0; + + string col = match.Result ("${column}"); + int columnNumber = 0; + if (!string.IsNullOrEmpty (col)) + columnNumber = col == "255+" ? -1 : Int32.Parse (col); + + string category = match.Result ("${level}"); + string code = match.Result ("${number}"); + string text = match.Result ("${message}"); + + if (String.Compare (category, "warning", StringComparison.OrdinalIgnoreCase) == 0) { + Log.LogWarning (null, code, null, filename, lineNumber, columnNumber, -1, + -1, text, null); + } else if (String.Compare (category, "error", StringComparison.OrdinalIgnoreCase) == 0) { + Log.LogError (null, code, null, filename, lineNumber, columnNumber, -1, + -1, text, null); + } else { + Log.LogMessage (importance, singleLine); + } + } + [MonoTODO] public string BaseAddress { get { return (string) Bag ["BaseAddress"]; } @@ -284,6 +329,20 @@ namespace Microsoft.Build.Tasks { get { return (string) Bag ["WarningsNotAsErrors"]; } set { Bag ["WarningsNotAsErrors"] = value; } } + + // from md's VBBindingCompilerServices.cs + //matches "/home/path/Default.aspx.vb (40,31) : Error VBNC30205: Expected end of statement." + //and "Error : VBNC99999: vbnc crashed nearby this location in the source code." + //and "Error : VBNC99999: Unexpected error: Object reference not set to an instance of an object" + static Regex errorRegex; + static Regex ErrorRegex { + get { + if (errorRegex == null) + errorRegex = new Regex (@"^\s*((?.*)\s?\((?\d*)(,(?\d*))?\) : )?(?\w+) :? ?(?[^:]*): (?.*)$", RegexOptions.Compiled | RegexOptions.ExplicitCapture); + return errorRegex; + } + } + } } diff --git a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources index 4cbc3917c3a..0b678d1795c 100644 --- a/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources +++ b/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks_test.dll.sources @@ -4,7 +4,7 @@ Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs Microsoft.Build.Tasks/AssignTargetPathTest.cs Microsoft.Build.Tasks/CombinePathTest.cs Microsoft.Build.Tasks/CopyTest.cs -Microsoft.Build.Tasks/Consts.cs +../../Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs Microsoft.Build.Tasks/CreateItemTest.cs diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs index 1458c999c6b..3673526ed70 100644 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/AssignProjectConfigurationTest.cs @@ -136,7 +136,7 @@ namespace MonoTests.Microsoft.Build.Tasks { StringBuilder sb = new StringBuilder (); sb.Append (@""); - sb.Append ("\n\n"); + sb.Append ("\n" + GetUsingTask ("AssignProjectConfiguration")); sb.AppendFormat (@"{0}", CreateSolutionConfigurationProperty (guids, "Release|AnyCPU")); sb.Append (CreateProjectReferencesItemGroup (project_ref_guids)); @@ -179,5 +179,11 @@ namespace MonoTests.Microsoft.Build.Tasks sb.Append ("\n"); return sb.ToString (); } + + string GetUsingTask (string taskName) + { + return ""; + } + } } diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog index 8ce07f826a3..73c326e93e6 100644 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/ChangeLog @@ -1,3 +1,17 @@ +2010-04-06 Ankit Jain + + * Consts.cs: Remove. + * AssignProjectConfigurationTest.cs: + * CreateCSharpManifestResourceNameTest.cs: + * CreateVisualBasicManifestResourceNameTest.cs: + * CreateItemTest.cs: + * FindAppConfigFileTest.cs: + * RemoveDuplicatesTest.cs: + * TaskBatchingTest.cs: + * WriteLinesToFileTest.cs: + Set the ToolsVersion to match the profile. Use the + full path to the tasks assembly for UsingTasks. + 2010-03-04 Ankit Jain * AssignTargetPathTest.cs (CreateProjectString): Remove the diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/Consts.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/Consts.cs deleted file mode 100644 index 2f41a67c3d9..00000000000 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/Consts.cs +++ /dev/null @@ -1,46 +0,0 @@ -// -// Consts.cs -// -// Author: -// Marek Sieradzki (marek.sieradzki@gmail.com) -// -// (C) 2006 Marek Sieradzki -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -using System; -using Microsoft.Build.Utilities; - -public static class Consts { - - static bool RunningOnMono () - { - return Type.GetType ("Mono.Runtime") != null; - } - - public static string BinPath { - get { - if (RunningOnMono ()) - return "../../tools/xbuild/xbuild"; - else - return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20); - } - } -} diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs index 150104c662a..47f2b75e14f 100755 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateCSharpManifestResourceNameTest.cs @@ -235,9 +235,9 @@ namespace MonoTests.Microsoft.Build.Tasks Project project = engine.CreateNewProject (); TestMessageLogger logger = new TestMessageLogger (); engine.RegisterLogger (logger); - Console.WriteLine (projectText); project.LoadXml (projectText); if (!project.Build ("1")) { + Console.WriteLine (projectText); logger.DumpMessages (); Assert.Fail ("Build failed"); } @@ -283,11 +283,16 @@ namespace MonoTests.Microsoft.Build.Tasks sb.AppendFormat (" RootNamespace = \"{0}\"", rootNamespace); sb.Append (">\n \t\t\t\n"); sb.Append ("\t\t\n\t\n"); - sb.Append ("\t\n"); + sb.Append ("\t" + GetUsingTask ("CreateCSharpManifestResourceName")); sb.Append (""); return sb.ToString (); } + + string GetUsingTask (string taskName) + { + return ""; + } + } } diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs index d16c54572a1..cfe90118c38 100755 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateItemTest.cs @@ -252,6 +252,7 @@ namespace MonoTests.Microsoft.Build.Tasks { } +#if NET_3_5 || NET_4_0 [Test] public void TestItemsWithWildcards () { Engine engine = new Engine (Consts.BinPath); @@ -274,7 +275,7 @@ namespace MonoTests.Microsoft.Build.Tasks { }; string documentString = @" - + dir\**\*.dll *\x*.dll @@ -318,6 +319,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Directory.Delete (basedir, true); } } +#endif void CreateDirectoriesAndFiles (string basedir, string[] dirs, string[] files) { foreach (string dir in dirs) diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs index bb94c5c3af2..b5b4b18b87f 100755 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/CreateVisualBasicManifestResourceNameTest.cs @@ -235,9 +235,9 @@ namespace MonoTests.Microsoft.Build.Tasks Project project = engine.CreateNewProject (); TestMessageLogger logger = new TestMessageLogger (); engine.RegisterLogger (logger); - Console.WriteLine (projectText); project.LoadXml (projectText); if (!project.Build ("1")) { + Console.WriteLine (projectText); logger.DumpMessages (); Assert.Fail ("Build failed"); } @@ -283,11 +283,16 @@ namespace MonoTests.Microsoft.Build.Tasks sb.AppendFormat (" RootNamespace = \"{0}\"", rootNamespace); sb.Append (">\n \t\t\t\n"); sb.Append ("\t\t\n\t\n"); - sb.Append ("\t\n"); + sb.Append ("\t" + GetUsingTask ("CreateVisualBasicManifestResourceName")); sb.Append (""); return sb.ToString (); } + + string GetUsingTask (string taskName) + { + return ""; + } + } } diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs index d6b9d0aa4d8..5aaa23086b9 100644 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/FindAppConfigFileTest.cs @@ -25,6 +25,8 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +#if NET_3_5 + using System; using System.Collections; using Microsoft.Build.BuildEngine; @@ -85,7 +87,7 @@ namespace MonoTests.Microsoft.Build.Tasks { void CheckOutput (string[] primary_list, string[] secondary_list, string expected) { StringBuilder sb = new StringBuilder (); - sb.Append (@""); + sb.Append (@""); sb.Append ("\t"); if (primary_list != null) foreach (string s in primary_list) @@ -124,4 +126,4 @@ namespace MonoTests.Microsoft.Build.Tasks { } } } - +#endif diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs index b4c17a8f371..6c1975c804c 100644 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/RemoveDuplicatesTest.cs @@ -44,7 +44,7 @@ namespace MonoTests.Microsoft.Build.Tasks public void Test1 () { string documentString = @" - + diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs index 6bfaae755e9..e854812b76b 100755 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs @@ -40,6 +40,12 @@ namespace MonoTests.Microsoft.Build.Tasks [TestFixture] public class TaskBatchingTest { + string projectHeader; + public TaskBatchingTest () + { + projectHeader = @""; + } + [Test] public void Test1 () { @@ -548,7 +554,7 @@ namespace MonoTests.Microsoft.Build.Tasks // batching should happen only on basis of the task attributes, // and not the resolved expression values public void TestBatching1 () { - string projectString = @" + string projectString = projectHeader + @" @@ -584,7 +590,7 @@ namespace MonoTests.Microsoft.Build.Tasks // batching should happen only on basis of the task attributes, // and not the resolved expression values public void TestConditionalBatching2 () { - string projectString = @" + string projectString = projectHeader + @" @@ -614,7 +620,7 @@ namespace MonoTests.Microsoft.Build.Tasks [Test] public void TestBatchingWithUnbatchedItems () { - string projectString = @" + string projectString = projectHeader + @" @@ -651,7 +657,7 @@ namespace MonoTests.Microsoft.Build.Tasks [Test] public void TestPropertiesWithBatchedReferences () { - string projectString = @" + string projectString = projectHeader + @" @@ -693,7 +699,7 @@ namespace MonoTests.Microsoft.Build.Tasks [Test] public void TestPropertiesWithDynamicItems () { - string projectString = @" + string projectString = projectHeader + @" @@ -748,7 +754,7 @@ namespace MonoTests.Microsoft.Build.Tasks [Test] public void TestTargetInvocationFromBatchedTask () { - string projectString = @" + string projectString = projectHeader + @" @@ -799,7 +805,7 @@ namespace MonoTests.Microsoft.Build.Tasks [Test] public void TestTargetInvocationFromBatchedTarget () { - string projectString = @" + string projectString = projectHeader + @" @@ -864,7 +870,7 @@ namespace MonoTests.Microsoft.Build.Tasks [Test] public void TestBatchingWithUnqualifiedMetadataReference () { - string projectString = @" + string projectString = projectHeader + @" 1 2 diff --git a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs index 62c03ac7e6b..82d4471a53a 100755 --- a/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs +++ b/mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/WriteLinesToFileTest.cs @@ -159,7 +159,7 @@ namespace MonoTests.Microsoft.Build.Tasks { Project project; StringBuilder sb = new StringBuilder (); - sb.Append (@" + sb.Append (@" "); diff --git a/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-3.5 b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-3.5 new file mode 100644 index 00000000000..7756bca8df1 --- /dev/null +++ b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-3.5 @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0 b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0 new file mode 100644 index 00000000000..3c78f3b4ec8 --- /dev/null +++ b/mcs/class/Microsoft.Build.Tasks/Test/test-config-file-net-4.0 @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/mcs/class/Microsoft.Build.Utilities/ChangeLog b/mcs/class/Microsoft.Build.Utilities/ChangeLog index d82c0037907..19ffbef5c9f 100644 --- a/mcs/class/Microsoft.Build.Utilities/ChangeLog +++ b/mcs/class/Microsoft.Build.Utilities/ChangeLog @@ -1,3 +1,10 @@ +2010-04-03 Ankit Jain + + * Makefile: Import tools/xbuild/xbuild_targets.make, which copies + the target and tasks file in the correct place, to allow running + tests with different toolsversion. + Use the correct target assembly name for 4.0 profile. + 2010-02-10 Ankit Jain * Microsoft.Build.Utilities.dll.sources: Add ProcessStringDictionary.cs diff --git a/mcs/class/Microsoft.Build.Utilities/Makefile b/mcs/class/Microsoft.Build.Utilities/Makefile index bbfc0a9f1ae..a600ff9b67e 100644 --- a/mcs/class/Microsoft.Build.Utilities/Makefile +++ b/mcs/class/Microsoft.Build.Utilities/Makefile @@ -12,6 +12,10 @@ endif ifeq (3.5, $(FRAMEWORK_VERSION)) LIBRARY_NAME = Microsoft.Build.Utilities.v3.5.dll +else +ifeq (4.0, $(FRAMEWORK_VERSION)) +LIBRARY_NAME = Microsoft.Build.Utilities.v4.0.dll +endif endif LIB_MCS_FLAGS = \ @@ -21,4 +25,8 @@ LIB_MCS_FLAGS = \ TEST_MCS_FLAGS = /r:Microsoft.Build.Framework.dll +export TESTING_MONO=a +XBUILD_DIR=../../tools/xbuild +include $(XBUILD_DIR)/xbuild_targets.make + include ../../build/library.make diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog index d7f994b30d9..9b48a6ebad1 100644 --- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog +++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ChangeLog @@ -1,3 +1,24 @@ +2010-04-10 Ankit Jain + + * ReservedNameUtils.cs (GetReservedMetadata): Handle empty item. + +2010-04-08 Ankit Jain + + * ToolTask.cs: Use regex to parse output. Regex is from monodevelop. + +2010-04-08 Ankit Jain + + * ToolTask.cs (ExecuteTool): Check that the tool exists. + +2010-04-03 Ankit Jain + + * TargetDotNetFrameworkVersion.cs: Add Version40 . + * Task.cs (BuildEngine2): New. + * ToolLocationHelper.cs: Use class/lib/net_* as the path + for the assemblies and targets when running tests. + Environment variable TESTING_MONO is set for testing. + This allows a 4.0 xbuild to build 2.0/3.5 projects. + 2010-02-19 Ankit Jain * TaskItem.cs: Track api changes. diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs index 451e40ef145..60cd2dba3dc 100644 --- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs +++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs @@ -37,7 +37,12 @@ namespace Microsoft.Build.Utilities Version20, Version30, Version35, +#if NET_4_0 + Version40, + VersionLatest = Version40 +#else VersionLatest = Version35 +#endif } } diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs index 62276342051..a529e1fafab 100644 --- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs +++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/Task.cs @@ -70,6 +70,10 @@ namespace Microsoft.Build.Utilities } } + public IBuildEngine2 BuildEngine2 { + get { return buildEngine as IBuildEngine2; } + } + protected string HelpKeywordPrefix { get { return helpKeywordPrefix; diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs index 3c132076022..a6c807cfbdf 100644 --- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs +++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs @@ -50,13 +50,24 @@ namespace Microsoft.Build.Utilities t2 = t1.Parent; lib_mono_dir = t2.FullName; + if (Environment.GetEnvironmentVariable ("TESTING_MONO") != null) { + mono_dir = new string [] { + Path.Combine (lib_mono_dir, "net_1_0"), + Path.Combine (lib_mono_dir, "net_2_0"), + Path.Combine (lib_mono_dir, "net_2_0"), + Path.Combine (lib_mono_dir, "net_3_5"), + Path.Combine (lib_mono_dir, "net_4_0") + }; + } else { + mono_dir = new string [] { + Path.Combine (lib_mono_dir, "1.0"), + Path.Combine (lib_mono_dir, "2.0"), + Path.Combine (lib_mono_dir, "2.0"), + Path.Combine (lib_mono_dir, "3.5"), + Path.Combine (lib_mono_dir, "4.0") + }; + } - mono_dir = new string [] { - Path.Combine (lib_mono_dir, "1.0"), - Path.Combine (lib_mono_dir, "2.0"), - Path.Combine (lib_mono_dir, "2.0"), - Path.Combine (lib_mono_dir, "3.5") - }; } [MonoTODO] diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs index 2af0265325b..eed5e7a2760 100644 --- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs +++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs @@ -56,8 +56,6 @@ namespace Microsoft.Build.Utilities StringBuilder toolOutput; bool typeLoadException; - static Regex regex; - protected ToolTask () : this (null, null) { @@ -81,19 +79,6 @@ namespace Microsoft.Build.Utilities this.environmentOverride = new SCS.ProcessStringDictionary (); } - static ToolTask () - { - regex = new Regex ( - @"^\s*" - + @"(((?(((\d+>)?[a-zA-Z]?:[^:]*)|([^:]*))):)" - + "|())" - + "(?(()|([^:]*? )))" - + "(?(error|warning)) " - + "(?[^:]*):" - + "(?.*)$", - RegexOptions.IgnoreCase); - } - [MonoTODO] protected virtual bool CallHostObjectToExecute () { @@ -126,6 +111,11 @@ namespace Microsoft.Build.Utilities if (pathToTool == null) throw new ArgumentNullException ("pathToTool"); + if (!File.Exists (pathToTool)) { + Log.LogError ("Tool not found at {0}", pathToTool); + return -1; + } + string output, error, responseFileName; StreamWriter outwr, errwr; @@ -233,80 +223,33 @@ namespace Microsoft.Build.Utilities singleLine.StartsWith ("Compilation failed")) return; - string filename, origin, category, code, subcategory, text; - int lineNumber, columnNumber, endLineNumber, endColumnNumber; - - Match m = regex.Match (singleLine); - origin = m.Groups [regex.GroupNumberFromName ("ORIGIN")].Value; - category = m.Groups [regex.GroupNumberFromName ("CATEGORY")].Value; - code = m.Groups [regex.GroupNumberFromName ("CODE")].Value; - subcategory = m.Groups [regex.GroupNumberFromName ("SUBCATEGORY")].Value; - text = m.Groups [regex.GroupNumberFromName ("TEXT")].Value; - - ParseOrigin (origin, out filename, out lineNumber, out columnNumber, out endLineNumber, out endColumnNumber); - - if (category == "warning") { - Log.LogWarning (subcategory, code, null, filename, lineNumber, columnNumber, endLineNumber, - endColumnNumber, text, null); - } else if (category == "error") { - Log.LogError (subcategory, code, null, filename, lineNumber, columnNumber, endLineNumber, - endColumnNumber, text, null); - } else { + Match match = CscErrorRegex.Match (singleLine); + if (!match.Success) { Log.LogMessage (importance, singleLine); + return; } - } - - private void ParseOrigin (string origin, out string filename, - out int lineNumber, out int columnNumber, - out int endLineNumber, out int endColumnNumber) - { - int lParen; - string[] temp; - string[] left, right; - - if (origin.IndexOf ('(') != -1 ) { - lParen = origin.IndexOf ('('); - filename = origin.Substring (0, lParen); - temp = origin.Substring (lParen + 1, origin.Length - lParen - 2).Split (','); - if (temp.Length == 1) { - left = temp [0].Split ('-'); - if (left.Length == 1) { - lineNumber = Int32.Parse (left [0]); - columnNumber = 0; - endLineNumber = 0; - endColumnNumber = 0; - } else if (left.Length == 2) { - lineNumber = Int32.Parse (left [0]); - columnNumber = 0; - endLineNumber = Int32.Parse (left [1]); - endColumnNumber = 0; - } else - throw new Exception ("Invalid line/column format."); - } else if (temp.Length == 2) { - right = temp [1].Split ('-'); - lineNumber = Int32.Parse (temp [0]); - endLineNumber = 0; - if (right.Length == 1) { - columnNumber = Int32.Parse (right [0]); - endColumnNumber = 0; - } else if (right.Length == 2) { - columnNumber = Int32.Parse (right [0]); - endColumnNumber = Int32.Parse (right [0]); - } else - throw new Exception ("Invalid line/column format."); - } else if (temp.Length == 4) { - lineNumber = Int32.Parse (temp [0]); - endLineNumber = Int32.Parse (temp [2]); - columnNumber = Int32.Parse (temp [1]); - endColumnNumber = Int32.Parse (temp [3]); - } else - throw new Exception ("Invalid line/column format."); + + string filename = match.Result ("${file}") ?? ""; + string line = match.Result ("${line}"); + int lineNumber = !string.IsNullOrEmpty (line) ? Int32.Parse (line) : 0; + + string col = match.Result ("${column}"); + int columnNumber = 0; + if (!string.IsNullOrEmpty (col)) + columnNumber = col == "255+" ? -1 : Int32.Parse (col); + + string category = match.Result ("${level}"); + string code = match.Result ("${number}"); + string text = match.Result ("${message}"); + + if (String.Compare (category, "warning", StringComparison.OrdinalIgnoreCase) == 0) { + Log.LogWarning (null, code, null, filename, lineNumber, columnNumber, -1, + -1, text, null); + } else if (String.Compare (category, "error", StringComparison.OrdinalIgnoreCase) == 0) { + Log.LogError (null, code, null, filename, lineNumber, columnNumber, -1, + -1, text, null); } else { - filename = origin; - lineNumber = 0; - columnNumber = 0; - endLineNumber = 0; - endColumnNumber = 0; + Log.LogMessage (importance, singleLine); } } @@ -447,6 +390,17 @@ namespace Microsoft.Build.Utilities toolPath = value; } } + + // Snatched from our codedom code, with some changes to make it compatible with csc + // (the line+column group is optional is csc) + static Regex errorRegex; + static Regex CscErrorRegex { + get { + if (errorRegex == null) + errorRegex = new Regex (@"^(\s*(?[^\(]+)(\((?\d*)(,(?\d*[\+]*))?\))?:\s+)*(?\w+)\s+(?.*\d):\s*(?.*)", RegexOptions.Compiled | RegexOptions.ExplicitCapture); + return errorRegex; + } + } } } diff --git a/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs b/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs index 49f489948e7..e8379f00be0 100644 --- a/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs +++ b/mcs/class/Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs @@ -72,6 +72,9 @@ namespace Mono.XBuild.Utilities { { if (metadataName == null) throw new ArgumentNullException (); + + if (String.IsNullOrEmpty (itemSpec)) + return String.Empty; switch (metadataName.ToLower ()) { case "fullpath": diff --git a/mcs/class/Mono.Cecil.Mdb/Makefile b/mcs/class/Mono.Cecil.Mdb/Makefile index ff34f3afb7a..689f5d03ddf 100644 --- a/mcs/class/Mono.Cecil.Mdb/Makefile +++ b/mcs/class/Mono.Cecil.Mdb/Makefile @@ -11,7 +11,7 @@ LIB_MCS_FLAGS = /r:$(corlib) /r:$(CECIL) /d:CECIL -keyfile:$(LIBRARY_SNK) NO_TEST = yes -ifneq (net_1_1, $(PROFILE)) +ifneq (net_2_0, $(PROFILE)) NO_INSTALL = yes endif diff --git a/mcs/class/Mono.Cecil/ChangeLog b/mcs/class/Mono.Cecil/ChangeLog index 8570089c59d..140b0ea1290 100644 --- a/mcs/class/Mono.Cecil/ChangeLog +++ b/mcs/class/Mono.Cecil/ChangeLog @@ -1,3 +1,20 @@ +2010-04-23 Jb Evain + + * Mono.Cecil/ReflectionWriter.cs: fix writing of exported types. + +2010-04-19 Sebastien Pouliot + + * Mono.Cecil/ReflectionWriter.cs: Partial (forwarders) fix for + writing ExternTypes (needed for tuning ML4 correctly) + +2010-04-11 Jb Evain + + * Mono.Cecil/GenericParameter.cs: override Module properly. + +2010-03-29 Jb Evain + + * Mono.Cecil/AssemblyStripper.cs: optimize. + 2010-02-13 Jb Evain * Mono.Cecil/ReflectionReader.cs: don't cache everything diff --git a/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyStripper.cs b/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyStripper.cs index 77e72e181d8..4bd08e9342d 100644 --- a/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyStripper.cs +++ b/mcs/class/Mono.Cecil/Mono.Cecil/AssemblyStripper.cs @@ -85,10 +85,10 @@ namespace Mono.Cecil { if (!method.HasBody) continue; - method.Body.ExceptionHandlers.Clear(); - method.Body.Variables.Clear (); - method.Body.Instructions.Clear (); - method.Body.CilWorker.Emit (OpCodes.Ret); + MethodBody body = new MethodBody (method); + body.CilWorker.Emit (OpCodes.Ret); + + method.Body = body; } } diff --git a/mcs/class/Mono.Cecil/Mono.Cecil/BaseAssemblyResolver.cs b/mcs/class/Mono.Cecil/Mono.Cecil/BaseAssemblyResolver.cs index 04f2e20aebc..99b518201ea 100644 --- a/mcs/class/Mono.Cecil/Mono.Cecil/BaseAssemblyResolver.cs +++ b/mcs/class/Mono.Cecil/Mono.Cecil/BaseAssemblyResolver.cs @@ -155,7 +155,7 @@ namespace Mono.Cecil { runtime_path = "v2.0.50727"; break; case "4.0.0.0": - runtime_path = "v4.0.21006"; + runtime_path = "v4.0.30319"; break; } } @@ -180,7 +180,7 @@ namespace Mono.Cecil { get { if (m_monoGacPaths == null) m_monoGacPaths = GetDefaultMonoGacPaths (); - return m_monoGacPaths; + return m_monoGacPaths; } } diff --git a/mcs/class/Mono.Cecil/Mono.Cecil/GenericParameter.cs b/mcs/class/Mono.Cecil/Mono.Cecil/GenericParameter.cs index 559ec5054ad..88a58509dee 100644 --- a/mcs/class/Mono.Cecil/Mono.Cecil/GenericParameter.cs +++ b/mcs/class/Mono.Cecil/Mono.Cecil/GenericParameter.cs @@ -76,6 +76,17 @@ namespace Mono.Cecil { } } + public override ModuleDefinition Module { + get { + if (m_owner is TypeReference) + return ((TypeReference) m_owner).Module; + if (m_owner is MethodReference) + return ((MethodReference) m_owner).DeclaringType.Module; + + throw new InvalidOperationException (); + } + } + public override string Name { get { if (m_name != null) diff --git a/mcs/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs b/mcs/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs index 5008cbd1515..80b0c11d519 100644 --- a/mcs/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs +++ b/mcs/class/Mono.Cecil/Mono.Cecil/NameObjectCollectionBase.cs @@ -1,650 +1,650 @@ -using System; -using System.Collections; -using System.Runtime.Serialization; - -#if NO_SYSTEM_DLL -namespace System.Collections.Specialized -{ - [Serializable] - public abstract class NameObjectCollectionBase : ICollection, IEnumerable, ISerializable, IDeserializationCallback - { - private Hashtable m_ItemsContainer; - /// - /// Extends Hashtable based Items container to support storing null-key pairs - /// - private _Item m_NullKeyItem; - private ArrayList m_ItemsArray; - private IHashCodeProvider m_hashprovider; - private IComparer m_comparer; - private int m_defCapacity; - private bool m_readonly; - SerializationInfo infoCopy; - private KeysCollection keyscoll; -#if NET_2_0 - private IEqualityComparer equality_comparer; - - internal IEqualityComparer EqualityComparer { - get { return equality_comparer; } - } -#endif - internal IComparer Comparer - { - get { return m_comparer; } - } - - internal IHashCodeProvider HashCodeProvider - { - get { return m_hashprovider; } - } - - internal class _Item - { - public string key; - public object value; - public _Item(string key, object value) - { - this.key = key; - this.value = value; - } - } - /// - /// Implements IEnumerable interface for KeysCollection - /// - [Serializable] - internal class _KeysEnumerator : IEnumerator - { - private NameObjectCollectionBase m_collection; - private int m_position; - - internal _KeysEnumerator(NameObjectCollectionBase collection) - { - m_collection = collection; - Reset(); - } - public object Current - { - - get - { - if ((m_position < m_collection.Count) || (m_position < 0)) - return m_collection.BaseGetKey(m_position); - else - throw new InvalidOperationException(); - } - - } - public bool MoveNext() - { - return ((++m_position) < m_collection.Count); - } - public void Reset() - { - m_position = -1; - } - } - - /// - /// SDK: Represents a collection of the String keys of a collection. - /// - [Serializable] - public class KeysCollection : ICollection, IEnumerable - { - private NameObjectCollectionBase m_collection; - - internal KeysCollection(NameObjectCollectionBase collection) - { - this.m_collection = collection; - } - - public virtual string Get(int index) - { - return m_collection.BaseGetKey(index); - } - - // ICollection methods ----------------------------------- - void ICollection.CopyTo(Array array, int arrayIndex) - { - ArrayList items = m_collection.m_ItemsArray; -#if NET_2_0 - if (null == array) - throw new ArgumentNullException ("array"); - - if (arrayIndex < 0) - throw new ArgumentOutOfRangeException ("arrayIndex"); - - if ((array.Length > 0) && (arrayIndex >= array.Length)) - throw new ArgumentException ("arrayIndex is equal to or greater than array.Length"); - - if (arrayIndex + items.Count > array.Length) - throw new ArgumentException ("Not enough room from arrayIndex to end of array for this KeysCollection"); -#endif - - if (array != null && array.Rank > 1) - throw new ArgumentException("array is multidimensional"); - - object[] objArray = (object[])array; - for (int i = 0; i < items.Count; i++, arrayIndex++) - objArray[arrayIndex] = ((_Item)items[i]).key; - } - - bool ICollection.IsSynchronized - { - get - { - return false; - } - } - object ICollection.SyncRoot - { - get - { - return m_collection; - } - } - /// - /// Gets the number of keys in the NameObjectCollectionBase.KeysCollection - /// - public int Count - { - get - { - return m_collection.Count; - } - } - - public string this[int index] - { - get { return Get(index); } - } - - // IEnumerable methods -------------------------------- - /// - /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.KeysCollection. - /// - /// - public IEnumerator GetEnumerator() - { - return new _KeysEnumerator(m_collection); - } - } - - //--------------- Protected Instance Constructors -------------- - - /// - /// SDK: Initializes a new instance of the NameObjectCollectionBase class that is empty. - /// - protected NameObjectCollectionBase() - { - m_readonly = false; -#if NET_1_0 - m_hashprovider = CaseInsensitiveHashCodeProvider.Default; - m_comparer = CaseInsensitiveComparer.Default; -#else - m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; - m_comparer = CaseInsensitiveComparer.DefaultInvariant; -#endif - m_defCapacity = 0; - Init(); - } - - protected NameObjectCollectionBase(int capacity) - { - m_readonly = false; -#if NET_1_0 - m_hashprovider = CaseInsensitiveHashCodeProvider.Default; - m_comparer = CaseInsensitiveComparer.Default; -#else - m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; - m_comparer = CaseInsensitiveComparer.DefaultInvariant; -#endif - m_defCapacity = capacity; - Init(); - } - -#if NET_2_0 - - internal NameObjectCollectionBase (IEqualityComparer equalityComparer, IComparer comparer, IHashCodeProvider hcp) - { - equality_comparer = equalityComparer; - m_comparer = comparer; - m_hashprovider = hcp; - m_readonly = false; - m_defCapacity = 0; - Init (); - } - - protected NameObjectCollectionBase (IEqualityComparer equalityComparer) : this( (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer), null, null) - { - } - - [Obsolete ("Use NameObjectCollectionBase(IEqualityComparer)")] -#endif - protected NameObjectCollectionBase(IHashCodeProvider hashProvider, IComparer comparer) - { - m_comparer = comparer; - m_hashprovider = hashProvider; - m_readonly = false; - m_defCapacity = 0; - Init(); - } - - protected NameObjectCollectionBase(SerializationInfo info, StreamingContext context) - { - infoCopy = info; - } - -#if NET_2_0 - protected NameObjectCollectionBase (int capacity, IEqualityComparer equalityComparer) - { - m_readonly = false; - equality_comparer = (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer); - m_defCapacity = capacity; - Init(); - } - - [Obsolete ("Use NameObjectCollectionBase(int,IEqualityComparer)")] -#endif - protected NameObjectCollectionBase(int capacity, IHashCodeProvider hashProvider, IComparer comparer) - { - m_readonly = false; - - m_hashprovider = hashProvider; - m_comparer = comparer; - m_defCapacity = capacity; - Init(); - } - - private void Init() - { -#if NET_2_0 - if (equality_comparer != null) - m_ItemsContainer = new Hashtable (m_defCapacity, equality_comparer); - else - m_ItemsContainer = new Hashtable (m_defCapacity, m_hashprovider, m_comparer); -#else - m_ItemsContainer = new Hashtable(m_defCapacity, m_hashprovider, m_comparer); -#endif - m_ItemsArray = new ArrayList(); - m_NullKeyItem = null; - } - - //--------------- Public Instance Properties ------------------- - - public virtual NameObjectCollectionBase.KeysCollection Keys - { - get - { - if (keyscoll == null) - keyscoll = new KeysCollection(this); - return keyscoll; - } - } - - //--------------- Public Instance Methods ---------------------- - // - /// - /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase. - /// - /// This enumerator returns the keys of the collection as strings. - /// - /// - public -#if NET_2_0 - virtual -#endif - IEnumerator GetEnumerator() - { - return new _KeysEnumerator(this); - } - - // ISerializable - public virtual void GetObjectData(SerializationInfo info, StreamingContext context) - { - if (info == null) - throw new ArgumentNullException("info"); - - int count = Count; - string[] keys = new string[count]; - object[] values = new object[count]; - int i = 0; - foreach (_Item item in m_ItemsArray) - { - keys[i] = item.key; - values[i] = item.value; - i++; - } - -#if NET_2_0 - if (equality_comparer != null) { - info.AddValue ("KeyComparer", equality_comparer, typeof (IEqualityComparer)); - info.AddValue ("Version", 4, typeof (int)); - } else { - info.AddValue ("HashProvider", m_hashprovider, typeof (IHashCodeProvider)); - info.AddValue ("Comparer", m_comparer, typeof (IComparer)); - info.AddValue ("Version", 2, typeof (int)); - } -#else - info.AddValue("HashProvider", m_hashprovider, typeof(IHashCodeProvider)); - info.AddValue("Comparer", m_comparer, typeof(IComparer)); -#endif - info.AddValue("ReadOnly", m_readonly); - info.AddValue("Count", count); - info.AddValue("Keys", keys, typeof(string[])); - info.AddValue("Values", values, typeof(object[])); - } - - // ICollection - public virtual int Count - { - get - { - return m_ItemsArray.Count; - } - } - - bool ICollection.IsSynchronized - { - get { return false; } - } - - object ICollection.SyncRoot - { - get { return this; } - } - - void ICollection.CopyTo(Array array, int index) - { - ((ICollection)Keys).CopyTo(array, index); - } - - // IDeserializationCallback - public virtual void OnDeserialization(object sender) - { - SerializationInfo info = infoCopy; - - // If a subclass overrides the serialization constructor - // and inplements its own serialization process, infoCopy will - // be null and we can ignore this callback. - if (info == null) - return; - - infoCopy = null; - m_hashprovider = (IHashCodeProvider)info.GetValue("HashProvider", - typeof(IHashCodeProvider)); -#if NET_2_0 - if (m_hashprovider == null) { - equality_comparer = (IEqualityComparer) info.GetValue ("KeyComparer", typeof (IEqualityComparer)); - } else { - m_comparer = (IComparer) info.GetValue ("Comparer", typeof (IComparer)); - if (m_comparer == null) - throw new SerializationException ("The comparer is null"); - } -#else - if (m_hashprovider == null) - throw new SerializationException("The hash provider is null"); - - m_comparer = (IComparer)info.GetValue("Comparer", typeof(IComparer)); - if (m_comparer == null) - throw new SerializationException("The comparer is null"); -#endif - m_readonly = info.GetBoolean("ReadOnly"); - string[] keys = (string[])info.GetValue("Keys", typeof(string[])); - if (keys == null) - throw new SerializationException("keys is null"); - - object[] values = (object[])info.GetValue("Values", typeof(object[])); - if (values == null) - throw new SerializationException("values is null"); - - Init(); - int count = keys.Length; - for (int i = 0; i < count; i++) - BaseAdd(keys[i], values[i]); - } - - //--------------- Protected Instance Properties ---------------- - /// - /// SDK: Gets or sets a value indicating whether the NameObjectCollectionBase instance is read-only. - /// - protected bool IsReadOnly - { - get - { - return m_readonly; - } - set - { - m_readonly = value; - } - } - - //--------------- Protected Instance Methods ------------------- - /// - /// Adds an Item with the specified key and value into the NameObjectCollectionBase instance. - /// - /// - /// - protected void BaseAdd(string name, object value) - { - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - - _Item newitem = new _Item(name, value); - - if (name == null) - { - //todo: consider nullkey entry - if (m_NullKeyItem == null) - m_NullKeyItem = newitem; - } - else - if (m_ItemsContainer[name] == null) - { - m_ItemsContainer.Add(name, newitem); - } - m_ItemsArray.Add(newitem); - } - - protected void BaseClear() - { - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - Init(); - } - - /// - /// SDK: Gets the value of the entry at the specified index of the NameObjectCollectionBase instance. - /// - /// - /// - protected object BaseGet(int index) - { - return ((_Item)m_ItemsArray[index]).value; - } - - /// - /// SDK: Gets the value of the first entry with the specified key from the NameObjectCollectionBase instance. - /// - /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. - /// - /// - protected object BaseGet(string name) - { - _Item item = FindFirstMatchedItem(name); - /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. - if (item == null) - return null; - else - return item.value; - } - - /// - /// SDK:Returns a String array that contains all the keys in the NameObjectCollectionBase instance. - /// - /// A String array that contains all the keys in the NameObjectCollectionBase instance. - protected string[] BaseGetAllKeys() - { - int cnt = m_ItemsArray.Count; - string[] allKeys = new string[cnt]; - for (int i = 0; i < cnt; i++) - allKeys[i] = BaseGetKey(i);//((_Item)m_ItemsArray[i]).key; - - return allKeys; - } - - /// - /// SDK: Returns an Object array that contains all the values in the NameObjectCollectionBase instance. - /// - /// An Object array that contains all the values in the NameObjectCollectionBase instance. - protected object[] BaseGetAllValues() - { - int cnt = m_ItemsArray.Count; - object[] allValues = new object[cnt]; - for (int i = 0; i < cnt; i++) - allValues[i] = BaseGet(i); - - return allValues; - } - - protected object[] BaseGetAllValues(Type type) - { - if (type == null) - throw new ArgumentNullException("'type' argument can't be null"); - int cnt = m_ItemsArray.Count; - object[] allValues = (object[])Array.CreateInstance(type, cnt); - for (int i = 0; i < cnt; i++) - allValues[i] = BaseGet(i); - - return allValues; - } - - protected string BaseGetKey(int index) - { - return ((_Item)m_ItemsArray[index]).key; - } - - /// - /// Gets a value indicating whether the NameObjectCollectionBase instance contains entries whose keys are not a null reference - /// - /// true if the NameObjectCollectionBase instance contains entries whose keys are not a null reference otherwise, false. - protected bool BaseHasKeys() - { - return (m_ItemsContainer.Count > 0); - } - - protected void BaseRemove(string name) - { - int cnt = 0; - String key; - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - if (name != null) - { - m_ItemsContainer.Remove(name); - } - else - { - m_NullKeyItem = null; - } - - cnt = m_ItemsArray.Count; - for (int i = 0; i < cnt; ) - { - key = BaseGetKey(i); - if (Equals(key, name)) - { - m_ItemsArray.RemoveAt(i); - cnt--; - } - else - i++; - } - } - - /// - /// - /// - /// - /// This function implemented the way Microsoft implemented it - - /// item is removed from hashtable and array without considering the case when there are two items with the same key but different values in array. - /// E.g. if - /// hashtable is [("Key1","value1")] and array contains [("Key1","value1")("Key1","value2")] then - /// after RemoveAt(1) the collection will be in following state: - /// hashtable:[] - /// array: [("Key1","value1")] - /// It's ok only then the key is uniquely assosiated with the value - /// To fix it a comparsion of objects stored under the same key in the hashtable and in the arraylist should be added - /// > - protected void BaseRemoveAt(int index) - { - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); - string key = BaseGetKey(index); - if (key != null) - { - // TODO: see LAME description above - m_ItemsContainer.Remove(key); - } - else - m_NullKeyItem = null; - m_ItemsArray.RemoveAt(index); - } - - /// - /// SDK: Sets the value of the entry at the specified index of the NameObjectCollectionBase instance. - /// - /// - /// - protected void BaseSet(int index, object value) - { -#if NET_2_0 - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); -#endif - _Item item = (_Item)m_ItemsArray[index]; - item.value = value; - } - - /// - /// Sets the value of the first entry with the specified key in the NameObjectCollectionBase instance, if found; otherwise, adds an entry with the specified key and value into the NameObjectCollectionBase instance. - /// - /// The String key of the entry to set. The key can be a null reference - /// The Object that represents the new value of the entry to set. The value can be a null reference - protected void BaseSet(string name, object value) - { -#if NET_2_0 - if (this.IsReadOnly) - throw new NotSupportedException("Collection is read-only"); -#endif - _Item item = FindFirstMatchedItem(name); - if (item != null) - item.value = value; - else - BaseAdd(name, value); - } - - private _Item FindFirstMatchedItem(string name) - { - if (name != null) - return (_Item)m_ItemsContainer[name]; - else - { - //TODO: consider null key case - return m_NullKeyItem; - } - } - - internal bool Equals(string s1, string s2) - { -#if NET_2_0 - if (m_comparer != null) - return (m_comparer.Compare (s1, s2) == 0); - else - return equality_comparer.Equals (s1, s2); -#else - return (m_comparer.Compare(s1, s2) == 0); -#endif - } - } -} -#endif +using System; +using System.Collections; +using System.Runtime.Serialization; + +#if NO_SYSTEM_DLL +namespace System.Collections.Specialized +{ + [Serializable] + public abstract class NameObjectCollectionBase : ICollection, IEnumerable, ISerializable, IDeserializationCallback + { + private Hashtable m_ItemsContainer; + /// + /// Extends Hashtable based Items container to support storing null-key pairs + /// + private _Item m_NullKeyItem; + private ArrayList m_ItemsArray; + private IHashCodeProvider m_hashprovider; + private IComparer m_comparer; + private int m_defCapacity; + private bool m_readonly; + SerializationInfo infoCopy; + private KeysCollection keyscoll; +#if NET_2_0 + private IEqualityComparer equality_comparer; + + internal IEqualityComparer EqualityComparer { + get { return equality_comparer; } + } +#endif + internal IComparer Comparer + { + get { return m_comparer; } + } + + internal IHashCodeProvider HashCodeProvider + { + get { return m_hashprovider; } + } + + internal class _Item + { + public string key; + public object value; + public _Item(string key, object value) + { + this.key = key; + this.value = value; + } + } + /// + /// Implements IEnumerable interface for KeysCollection + /// + [Serializable] + internal class _KeysEnumerator : IEnumerator + { + private NameObjectCollectionBase m_collection; + private int m_position; + + internal _KeysEnumerator(NameObjectCollectionBase collection) + { + m_collection = collection; + Reset(); + } + public object Current + { + + get + { + if ((m_position < m_collection.Count) || (m_position < 0)) + return m_collection.BaseGetKey(m_position); + else + throw new InvalidOperationException(); + } + + } + public bool MoveNext() + { + return ((++m_position) < m_collection.Count); + } + public void Reset() + { + m_position = -1; + } + } + + /// + /// SDK: Represents a collection of the String keys of a collection. + /// + [Serializable] + public class KeysCollection : ICollection, IEnumerable + { + private NameObjectCollectionBase m_collection; + + internal KeysCollection(NameObjectCollectionBase collection) + { + this.m_collection = collection; + } + + public virtual string Get(int index) + { + return m_collection.BaseGetKey(index); + } + + // ICollection methods ----------------------------------- + void ICollection.CopyTo(Array array, int arrayIndex) + { + ArrayList items = m_collection.m_ItemsArray; +#if NET_2_0 + if (null == array) + throw new ArgumentNullException ("array"); + + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException ("arrayIndex"); + + if ((array.Length > 0) && (arrayIndex >= array.Length)) + throw new ArgumentException ("arrayIndex is equal to or greater than array.Length"); + + if (arrayIndex + items.Count > array.Length) + throw new ArgumentException ("Not enough room from arrayIndex to end of array for this KeysCollection"); +#endif + + if (array != null && array.Rank > 1) + throw new ArgumentException("array is multidimensional"); + + object[] objArray = (object[])array; + for (int i = 0; i < items.Count; i++, arrayIndex++) + objArray[arrayIndex] = ((_Item)items[i]).key; + } + + bool ICollection.IsSynchronized + { + get + { + return false; + } + } + object ICollection.SyncRoot + { + get + { + return m_collection; + } + } + /// + /// Gets the number of keys in the NameObjectCollectionBase.KeysCollection + /// + public int Count + { + get + { + return m_collection.Count; + } + } + + public string this[int index] + { + get { return Get(index); } + } + + // IEnumerable methods -------------------------------- + /// + /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase.KeysCollection. + /// + /// + public IEnumerator GetEnumerator() + { + return new _KeysEnumerator(m_collection); + } + } + + //--------------- Protected Instance Constructors -------------- + + /// + /// SDK: Initializes a new instance of the NameObjectCollectionBase class that is empty. + /// + protected NameObjectCollectionBase() + { + m_readonly = false; +#if NET_1_0 + m_hashprovider = CaseInsensitiveHashCodeProvider.Default; + m_comparer = CaseInsensitiveComparer.Default; +#else + m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; + m_comparer = CaseInsensitiveComparer.DefaultInvariant; +#endif + m_defCapacity = 0; + Init(); + } + + protected NameObjectCollectionBase(int capacity) + { + m_readonly = false; +#if NET_1_0 + m_hashprovider = CaseInsensitiveHashCodeProvider.Default; + m_comparer = CaseInsensitiveComparer.Default; +#else + m_hashprovider = CaseInsensitiveHashCodeProvider.DefaultInvariant; + m_comparer = CaseInsensitiveComparer.DefaultInvariant; +#endif + m_defCapacity = capacity; + Init(); + } + +#if NET_2_0 + + internal NameObjectCollectionBase (IEqualityComparer equalityComparer, IComparer comparer, IHashCodeProvider hcp) + { + equality_comparer = equalityComparer; + m_comparer = comparer; + m_hashprovider = hcp; + m_readonly = false; + m_defCapacity = 0; + Init (); + } + + protected NameObjectCollectionBase (IEqualityComparer equalityComparer) : this( (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer), null, null) + { + } + + [Obsolete ("Use NameObjectCollectionBase(IEqualityComparer)")] +#endif + protected NameObjectCollectionBase(IHashCodeProvider hashProvider, IComparer comparer) + { + m_comparer = comparer; + m_hashprovider = hashProvider; + m_readonly = false; + m_defCapacity = 0; + Init(); + } + + protected NameObjectCollectionBase(SerializationInfo info, StreamingContext context) + { + infoCopy = info; + } + +#if NET_2_0 + protected NameObjectCollectionBase (int capacity, IEqualityComparer equalityComparer) + { + m_readonly = false; + equality_comparer = (equalityComparer == null ? StringComparer.InvariantCultureIgnoreCase : equalityComparer); + m_defCapacity = capacity; + Init(); + } + + [Obsolete ("Use NameObjectCollectionBase(int,IEqualityComparer)")] +#endif + protected NameObjectCollectionBase(int capacity, IHashCodeProvider hashProvider, IComparer comparer) + { + m_readonly = false; + + m_hashprovider = hashProvider; + m_comparer = comparer; + m_defCapacity = capacity; + Init(); + } + + private void Init() + { +#if NET_2_0 + if (equality_comparer != null) + m_ItemsContainer = new Hashtable (m_defCapacity, equality_comparer); + else + m_ItemsContainer = new Hashtable (m_defCapacity, m_hashprovider, m_comparer); +#else + m_ItemsContainer = new Hashtable(m_defCapacity, m_hashprovider, m_comparer); +#endif + m_ItemsArray = new ArrayList(); + m_NullKeyItem = null; + } + + //--------------- Public Instance Properties ------------------- + + public virtual NameObjectCollectionBase.KeysCollection Keys + { + get + { + if (keyscoll == null) + keyscoll = new KeysCollection(this); + return keyscoll; + } + } + + //--------------- Public Instance Methods ---------------------- + // + /// + /// SDK: Returns an enumerator that can iterate through the NameObjectCollectionBase. + /// + /// This enumerator returns the keys of the collection as strings. + /// + /// + public +#if NET_2_0 + virtual +#endif + IEnumerator GetEnumerator() + { + return new _KeysEnumerator(this); + } + + // ISerializable + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + + int count = Count; + string[] keys = new string[count]; + object[] values = new object[count]; + int i = 0; + foreach (_Item item in m_ItemsArray) + { + keys[i] = item.key; + values[i] = item.value; + i++; + } + +#if NET_2_0 + if (equality_comparer != null) { + info.AddValue ("KeyComparer", equality_comparer, typeof (IEqualityComparer)); + info.AddValue ("Version", 4, typeof (int)); + } else { + info.AddValue ("HashProvider", m_hashprovider, typeof (IHashCodeProvider)); + info.AddValue ("Comparer", m_comparer, typeof (IComparer)); + info.AddValue ("Version", 2, typeof (int)); + } +#else + info.AddValue("HashProvider", m_hashprovider, typeof(IHashCodeProvider)); + info.AddValue("Comparer", m_comparer, typeof(IComparer)); +#endif + info.AddValue("ReadOnly", m_readonly); + info.AddValue("Count", count); + info.AddValue("Keys", keys, typeof(string[])); + info.AddValue("Values", values, typeof(object[])); + } + + // ICollection + public virtual int Count + { + get + { + return m_ItemsArray.Count; + } + } + + bool ICollection.IsSynchronized + { + get { return false; } + } + + object ICollection.SyncRoot + { + get { return this; } + } + + void ICollection.CopyTo(Array array, int index) + { + ((ICollection)Keys).CopyTo(array, index); + } + + // IDeserializationCallback + public virtual void OnDeserialization(object sender) + { + SerializationInfo info = infoCopy; + + // If a subclass overrides the serialization constructor + // and inplements its own serialization process, infoCopy will + // be null and we can ignore this callback. + if (info == null) + return; + + infoCopy = null; + m_hashprovider = (IHashCodeProvider)info.GetValue("HashProvider", + typeof(IHashCodeProvider)); +#if NET_2_0 + if (m_hashprovider == null) { + equality_comparer = (IEqualityComparer) info.GetValue ("KeyComparer", typeof (IEqualityComparer)); + } else { + m_comparer = (IComparer) info.GetValue ("Comparer", typeof (IComparer)); + if (m_comparer == null) + throw new SerializationException ("The comparer is null"); + } +#else + if (m_hashprovider == null) + throw new SerializationException("The hash provider is null"); + + m_comparer = (IComparer)info.GetValue("Comparer", typeof(IComparer)); + if (m_comparer == null) + throw new SerializationException("The comparer is null"); +#endif + m_readonly = info.GetBoolean("ReadOnly"); + string[] keys = (string[])info.GetValue("Keys", typeof(string[])); + if (keys == null) + throw new SerializationException("keys is null"); + + object[] values = (object[])info.GetValue("Values", typeof(object[])); + if (values == null) + throw new SerializationException("values is null"); + + Init(); + int count = keys.Length; + for (int i = 0; i < count; i++) + BaseAdd(keys[i], values[i]); + } + + //--------------- Protected Instance Properties ---------------- + /// + /// SDK: Gets or sets a value indicating whether the NameObjectCollectionBase instance is read-only. + /// + protected bool IsReadOnly + { + get + { + return m_readonly; + } + set + { + m_readonly = value; + } + } + + //--------------- Protected Instance Methods ------------------- + /// + /// Adds an Item with the specified key and value into the NameObjectCollectionBase instance. + /// + /// + /// + protected void BaseAdd(string name, object value) + { + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + + _Item newitem = new _Item(name, value); + + if (name == null) + { + //todo: consider nullkey entry + if (m_NullKeyItem == null) + m_NullKeyItem = newitem; + } + else + if (m_ItemsContainer[name] == null) + { + m_ItemsContainer.Add(name, newitem); + } + m_ItemsArray.Add(newitem); + } + + protected void BaseClear() + { + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + Init(); + } + + /// + /// SDK: Gets the value of the entry at the specified index of the NameObjectCollectionBase instance. + /// + /// + /// + protected object BaseGet(int index) + { + return ((_Item)m_ItemsArray[index]).value; + } + + /// + /// SDK: Gets the value of the first entry with the specified key from the NameObjectCollectionBase instance. + /// + /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. + /// + /// + protected object BaseGet(string name) + { + _Item item = FindFirstMatchedItem(name); + /// CAUTION: The BaseGet method does not distinguish between a null reference which is returned because the specified key is not found and a null reference which is returned because the value associated with the key is a null reference. + if (item == null) + return null; + else + return item.value; + } + + /// + /// SDK:Returns a String array that contains all the keys in the NameObjectCollectionBase instance. + /// + /// A String array that contains all the keys in the NameObjectCollectionBase instance. + protected string[] BaseGetAllKeys() + { + int cnt = m_ItemsArray.Count; + string[] allKeys = new string[cnt]; + for (int i = 0; i < cnt; i++) + allKeys[i] = BaseGetKey(i);//((_Item)m_ItemsArray[i]).key; + + return allKeys; + } + + /// + /// SDK: Returns an Object array that contains all the values in the NameObjectCollectionBase instance. + /// + /// An Object array that contains all the values in the NameObjectCollectionBase instance. + protected object[] BaseGetAllValues() + { + int cnt = m_ItemsArray.Count; + object[] allValues = new object[cnt]; + for (int i = 0; i < cnt; i++) + allValues[i] = BaseGet(i); + + return allValues; + } + + protected object[] BaseGetAllValues(Type type) + { + if (type == null) + throw new ArgumentNullException("'type' argument can't be null"); + int cnt = m_ItemsArray.Count; + object[] allValues = (object[])Array.CreateInstance(type, cnt); + for (int i = 0; i < cnt; i++) + allValues[i] = BaseGet(i); + + return allValues; + } + + protected string BaseGetKey(int index) + { + return ((_Item)m_ItemsArray[index]).key; + } + + /// + /// Gets a value indicating whether the NameObjectCollectionBase instance contains entries whose keys are not a null reference + /// + /// true if the NameObjectCollectionBase instance contains entries whose keys are not a null reference otherwise, false. + protected bool BaseHasKeys() + { + return (m_ItemsContainer.Count > 0); + } + + protected void BaseRemove(string name) + { + int cnt = 0; + String key; + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + if (name != null) + { + m_ItemsContainer.Remove(name); + } + else + { + m_NullKeyItem = null; + } + + cnt = m_ItemsArray.Count; + for (int i = 0; i < cnt; ) + { + key = BaseGetKey(i); + if (Equals(key, name)) + { + m_ItemsArray.RemoveAt(i); + cnt--; + } + else + i++; + } + } + + /// + /// + /// + /// + /// This function implemented the way Microsoft implemented it - + /// item is removed from hashtable and array without considering the case when there are two items with the same key but different values in array. + /// E.g. if + /// hashtable is [("Key1","value1")] and array contains [("Key1","value1")("Key1","value2")] then + /// after RemoveAt(1) the collection will be in following state: + /// hashtable:[] + /// array: [("Key1","value1")] + /// It's ok only then the key is uniquely assosiated with the value + /// To fix it a comparsion of objects stored under the same key in the hashtable and in the arraylist should be added + /// > + protected void BaseRemoveAt(int index) + { + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); + string key = BaseGetKey(index); + if (key != null) + { + // TODO: see LAME description above + m_ItemsContainer.Remove(key); + } + else + m_NullKeyItem = null; + m_ItemsArray.RemoveAt(index); + } + + /// + /// SDK: Sets the value of the entry at the specified index of the NameObjectCollectionBase instance. + /// + /// + /// + protected void BaseSet(int index, object value) + { +#if NET_2_0 + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); +#endif + _Item item = (_Item)m_ItemsArray[index]; + item.value = value; + } + + /// + /// Sets the value of the first entry with the specified key in the NameObjectCollectionBase instance, if found; otherwise, adds an entry with the specified key and value into the NameObjectCollectionBase instance. + /// + /// The String key of the entry to set. The key can be a null reference + /// The Object that represents the new value of the entry to set. The value can be a null reference + protected void BaseSet(string name, object value) + { +#if NET_2_0 + if (this.IsReadOnly) + throw new NotSupportedException("Collection is read-only"); +#endif + _Item item = FindFirstMatchedItem(name); + if (item != null) + item.value = value; + else + BaseAdd(name, value); + } + + private _Item FindFirstMatchedItem(string name) + { + if (name != null) + return (_Item)m_ItemsContainer[name]; + else + { + //TODO: consider null key case + return m_NullKeyItem; + } + } + + internal bool Equals(string s1, string s2) + { +#if NET_2_0 + if (m_comparer != null) + return (m_comparer.Compare (s1, s2) == 0); + else + return equality_comparer.Equals (s1, s2); +#else + return (m_comparer.Compare(s1, s2) == 0); +#endif + } + } +} +#endif diff --git a/mcs/class/Mono.Cecil/Mono.Cecil/ReflectionWriter.cs b/mcs/class/Mono.Cecil/Mono.Cecil/ReflectionWriter.cs index ee7f8cb72c5..418b8941c78 100644 --- a/mcs/class/Mono.Cecil/Mono.Cecil/ReflectionWriter.cs +++ b/mcs/class/Mono.Cecil/Mono.Cecil/ReflectionWriter.cs @@ -425,12 +425,41 @@ namespace Mono.Cecil { public override void VisitExternTypeCollection (ExternTypeCollection externs) { - VisitCollection (externs); + if (externs.Count == 0) + return; + + ExportedTypeTable etTable = m_tableWriter.GetExportedTypeTable (); + foreach (TypeReference ext in externs) { + TypeDefinition td = ext.Resolve (); + if (td == null) + continue; + + MetadataToken scope = GetExportedTypeScope (td); + + ExportedTypeRow etRow = m_rowWriter.CreateExportedTypeRow ( + td.Attributes, + 0, + m_mdWriter.AddString (td.Name), + m_mdWriter.AddString (td.Namespace), + scope); + + etTable.Rows.Add (etRow); + ext.MetadataToken = new MetadataToken (TokenType.ExportedType, (uint) etTable.Rows.Count); + } } - public override void VisitExternType (TypeReference externType) + MetadataToken GetExportedTypeScope (TypeDefinition t) { - // TODO + if (t.DeclaringType != null) + return t.DeclaringType.MetadataToken; + + if (t.Scope is AssemblyNameReference) + return new MetadataToken (TokenType.AssemblyRef, GetRidFor ((AssemblyNameReference) t.Scope)); + + if (t.Scope is ModuleDefinition) + return new MetadataToken (TokenType.Module, GetRidFor ((ModuleDefinition) t.Scope)); + + throw new NotImplementedException (); } public override void VisitOverrideCollection (OverrideCollection meths) @@ -860,6 +889,9 @@ namespace Mono.Cecil { if (module.HasCustomAttributes) VisitCustomAttributeCollection (module.CustomAttributes); + if (module.ExternTypes.Count > 0) + VisitExternTypeCollection (module.ExternTypes); + CompleteGenericTables (); SortTables (); diff --git a/mcs/class/Mono.Cecil/Mono.Cecil/StructureReader.cs b/mcs/class/Mono.Cecil/Mono.Cecil/StructureReader.cs index 02f5f2c3868..6085cdb42b9 100644 --- a/mcs/class/Mono.Cecil/Mono.Cecil/StructureReader.cs +++ b/mcs/class/Mono.Cecil/Mono.Cecil/StructureReader.cs @@ -105,7 +105,7 @@ namespace Mono.Cecil { case "v2.0.50727": asm.Runtime = TargetRuntime.NET_2_0; break; - case "v4.0.21006" : + case "v4.0.30319" : asm.Runtime = TargetRuntime.NET_4_0; break; } diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog index 56fda9fcb2c..da081609310 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog @@ -1,3 +1,9 @@ +2010-04-21 Veerapuram Varadhan + + ** Fixes #595918 + * Tds70.cs (WriteParameterInfo): Write updated decimal value according + to specified scale value. + 2009-08-17 Veerapuram Varadhan ** Fixes #381151 NRE diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs index a7c78a0f9e4..57fb0914645 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs @@ -563,6 +563,14 @@ namespace Mono.Data.Tds.Protocol if ( param.TypeName == "decimal" || param.TypeName == "numeric") { Comm.Append ((param.Precision !=0 ) ? param.Precision : (byte) 29); Comm.Append (param.Scale); + // Convert the decimal value according to Scale + if (param.Value != null && param.Value != DBNull.Value && + ((decimal)param.Value) != Decimal.MaxValue && + ((decimal)param.Value) != Decimal.MinValue) { + decimal expo = new Decimal (System.Math.Pow (10, (double)param.Scale)); + int pVal = (int)(((decimal)param.Value) * expo); + param.Value = (decimal)pVal; + } } diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources index 7b066b2243e..cde4e685d64 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft.dll.sources @@ -60,4 +60,5 @@ Mono.Debugger.Soft/TypeLoadEvent.cs Mono.Debugger.Soft/VMDisconnectEvent.cs Mono.Debugger.Soft/InvokeOptions.cs Mono.Debugger.Soft/IInvokeAsyncResult.cs +Mono.Debugger.Soft/IProcess.cs diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog index a2e095eaf19..708bb0276cd 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ChangeLog @@ -1,3 +1,17 @@ +2010-04-26 Lluis Sanchez + + * IProcess.cs: + * VirtualMachine.cs: + * VirtualMachineManager.cs: + Added new IProcess interface which wraps the debugged process. + This abstraction makes it easier to support debugging processes + for which we don't have a direct Process reference (for example, + if the process is remote). + +2010-04-10 Zoltan Varga + + * ThreadMirror.cs: Add a ThreadId property. + 2010-03-05 Martin Baulig Add support for aborting invocations. diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs index 4088fb66715..eace25b3cca 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs @@ -303,7 +303,9 @@ namespace Mono.Debugger.Soft GET_FRAME_INFO = 1, GET_NAME = 2, GET_STATE = 3, - GET_INFO = 4 + GET_INFO = 4, + /* FIXME: Merge into GET_INFO when the major protocol version is increased */ + GET_ID = 5 } enum CmdEventRequest { @@ -1430,6 +1432,10 @@ namespace Mono.Debugger.Soft return res; } + public long Thread_GetId (long id) { + return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_ID, new PacketWriter ().WriteId (id)).ReadLong (); + } + /* * MODULE */ diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/IProcess.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/IProcess.cs new file mode 100644 index 00000000000..ba62ad3ce36 --- /dev/null +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/IProcess.cs @@ -0,0 +1,70 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace Mono.Debugger.Soft +{ + public interface IProcess + { + event System.EventHandler Exited; + StreamReader StandardOutput { get; } + StreamReader StandardError { get; } + bool HasExited { get; } + void Kill (); + int Id { get; } + string ProcessName { get; } + } + + internal class ProcessWrapper: IProcess + { + Process process; + + public ProcessWrapper (Process process) + { + this.process = process; + } + + public event System.EventHandler Exited { + add { process.Exited += value; } + remove { process.Exited -= value; } + } + + public StreamReader StandardOutput { + get { + return process.StandardOutput; + } + } + + public StreamReader StandardError { + get { + return process.StandardError; + } + } + + public bool HasExited { + get { + return process.HasExited; + } + } + + public void Kill () + { + process.Kill (); + } + + public int Id { + get { + return process.Id; + } + } + + public string ProcessName { + get { + return process.ProcessName; + } + } + + + + } +} diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs index 65e0c0f62ac..d18804bd89a 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ThreadMirror.cs @@ -51,5 +51,15 @@ namespace Mono.Debugger.Soft return info.is_thread_pool; } } + + /* + * Return a unique identifier for this thread, multiple ThreadMirror objects + * may have the same ThreadId because of appdomains. + */ + public long ThreadId { + get { + return vm.conn.Thread_GetId (id); + } + } } } diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs index b8160781a94..6570aeb83cf 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs @@ -16,11 +16,11 @@ namespace Mono.Debugger.Soft object startup_monitor; AppDomainMirror root_domain; Dictionary requests; - Process process; + IProcess process; internal Connection conn; - internal VirtualMachine (Process process, Connection conn) : base () { + internal VirtualMachine (IProcess process, Connection conn) : base () { SetVirtualMachine (this); queue = new Queue (); queue_monitor = new Object (); @@ -35,7 +35,7 @@ namespace Mono.Debugger.Soft public StreamReader StandardOutput { get; set; } public StreamReader StandardError { get; set; } - public Process Process { + public IProcess Process { get { return process; } diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs index 932963473e6..17b9032fc25 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachineManager.cs @@ -21,18 +21,18 @@ namespace Mono.Debugger.Soft get; set; } - public delegate Process ProcessLauncher (ProcessStartInfo info); + public delegate IProcess ProcessLauncher (ProcessStartInfo info); } public class VirtualMachineManager { - private delegate VirtualMachine LaunchCallback (Process p, Socket socket); + private delegate VirtualMachine LaunchCallback (IProcess p, ProcessStartInfo info, Socket socket); private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock); internal VirtualMachineManager () { } - public static VirtualMachine LaunchInternal (Process p, Socket socket) { + public static VirtualMachine LaunchInternal (IProcess p, ProcessStartInfo info, Socket socket) { Socket accepted = null; try { accepted = socket.Accept (); @@ -44,10 +44,10 @@ namespace Mono.Debugger.Soft VirtualMachine vm = new VirtualMachine (p, conn); - if (p.StartInfo.RedirectStandardOutput) + if (info.RedirectStandardOutput) vm.StandardOutput = p.StandardOutput; - if (p.StartInfo.RedirectStandardError) + if (info.RedirectStandardError) vm.StandardError = p.StandardError; conn.EventHandler = new EventHandler (vm); @@ -77,18 +77,18 @@ namespace Mono.Debugger.Soft if (options != null && options.Valgrind) info.FileName = "valgrind"; - Process p; + IProcess p; if (options != null && options.CustomProcessLauncher != null) p = options.CustomProcessLauncher (info); else - p = Process.Start (info); + p = new ProcessWrapper (Process.Start (info)); p.Exited += delegate (object sender, EventArgs eargs) { socket.Close (); }; LaunchCallback c = new LaunchCallback (LaunchInternal); - return c.BeginInvoke (p, socket, callback, socket); + return c.BeginInvoke (p, info, socket, callback, socket); } public static VirtualMachine EndLaunch (IAsyncResult asyncResult) { diff --git a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog index 3901ef4f9f6..d1b975c6ce5 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/ChangeLog +++ b/mcs/class/Mono.Posix/Mono.Unix/ChangeLog @@ -1,3 +1,9 @@ +2010-04-15 Jonathan Pryor + + * UnixSignal.cs: Change the native WaitAny() method to accept a + Mono_Posix_RuntimeIsShuttingDown delegate, so that we can prevent an + infinite loop while shutting the process down. Fixes #592981. + 2009-03-23 Jonathan Pryor * UnixDriveInfo.cs: UnixDriveInfo.AvailableFreeSpace needs to return diff --git a/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs b/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs index fc21e5f9bf9..86a855aeecb 100644 --- a/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs +++ b/mcs/class/Mono.Posix/Mono.Unix/UnixSignal.cs @@ -94,9 +94,12 @@ namespace Mono.Unix { EntryPoint="Mono_Unix_UnixSignal_uninstall")] private static extern int uninstall (IntPtr info); + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + delegate int Mono_Posix_RuntimeIsShuttingDown (); + [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl, EntryPoint="Mono_Unix_UnixSignal_WaitAny")] - private static extern int WaitAny (IntPtr[] infos, int count, int timeout); + private static extern int WaitAny (IntPtr[] infos, int count, int timeout, Mono_Posix_RuntimeIsShuttingDown shutting_down); [DllImport (Stdlib.MPH, CallingConvention=CallingConvention.Cdecl, EntryPoint="Mono_Posix_SIGRTMIN")] @@ -199,7 +202,7 @@ namespace Mono.Unix { if (infos [i] == IntPtr.Zero) throw new InvalidOperationException ("Disposed UnixSignal"); } - return WaitAny (infos, infos.Length, millisecondsTimeout); + return WaitAny (infos, infos.Length, millisecondsTimeout, () => Environment.HasShutdownStarted ? 1 : 0); } } } diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog index e1747f253bd..eda3970564c 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/ChangeLog @@ -1,3 +1,7 @@ +2010-04-07 Gonzalo Paniagua Javier + + * TlsServerCertificate.cs: display the error code. + 2010-03-11 Gonzalo Paniagua Javier * TlsServerCertificate.cs: chain is built and validated in diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs index cf17da1223d..174e0eb5844 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls.Handshake.Client/TlsServerCertificate.cs @@ -214,7 +214,8 @@ namespace Mono.Security.Protocol.Tls.Handshake.Client description = AlertDescription.CertificateUnknown; break; } - throw new TlsException (description, "Invalid certificate received from server."); + string err = String.Format ("0x{0:x}", error); + throw new TlsException (description, "Invalid certificate received from server. Error code: " + err); } #endif // the leaf is the web server certificate diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog index 7c677b39bbd..e6a5442d5ea 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog @@ -1,3 +1,12 @@ +2010-04-23 Gonzalo Paniagua Javier + + * Context.cs: + * SslStreamBase.cs: + * RecordProtocol.cs: differentiate a received 'CloseNotify' alert from + one that we sent. Disposing the stream will try to send the + 'CloseNotify' alert, if it hasn't already, and ignore any errors. This + is needed for FTPS to work. + 2010-03-11 Gonzalo Paniagua Javier * SslStreamBase.cs: diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs index 295eee5e606..792a9970a17 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs @@ -76,7 +76,8 @@ namespace Mono.Security.Protocol.Tls // Misc private bool abbreviatedHandshake; - private bool connectionEnd; + private bool receivedConnectionEnd; + private bool sentConnectionEnd; private bool protocolNegotiated; // Sequence numbers @@ -203,10 +204,16 @@ namespace Mono.Security.Protocol.Tls set { this.handshakeState = value; } } - public bool ConnectionEnd + public bool ReceivedConnectionEnd { - get { return this.connectionEnd; } - set { this.connectionEnd = value; } + get { return this.receivedConnectionEnd; } + set { this.receivedConnectionEnd = value; } + } + + public bool SentConnectionEnd + { + get { return this.sentConnectionEnd; } + set { this.sentConnectionEnd = value; } } public CipherSuiteCollection SupportedCiphers diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs index 6ccced66b85..878233fc95f 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs @@ -311,7 +311,7 @@ namespace Mono.Security.Protocol.Tls public IAsyncResult BeginReceiveRecord(Stream record, AsyncCallback callback, object state) { - if (this.context.ConnectionEnd) + if (this.context.ReceivedConnectionEnd) { throw new TlsException( AlertDescription.InternalError, @@ -580,7 +580,7 @@ namespace Mono.Security.Protocol.Tls switch (alertDesc) { case AlertDescription.CloseNotify: - this.context.ConnectionEnd = true; + this.context.ReceivedConnectionEnd = true; break; } break; @@ -624,9 +624,8 @@ namespace Mono.Security.Protocol.Tls // Write record this.SendRecord (ContentType.Alert, new byte[2] { (byte) level, (byte) description }); - if (close) - { - this.context.ConnectionEnd = true; + if (close) { + this.context.SentConnectionEnd = true; } } @@ -695,7 +694,7 @@ namespace Mono.Security.Protocol.Tls public IAsyncResult BeginSendRecord(ContentType contentType, byte[] recordData, AsyncCallback callback, object state) { - if (this.context.ConnectionEnd) + if (this.context.SentConnectionEnd) { throw new TlsException( AlertDescription.InternalError, @@ -745,7 +744,7 @@ namespace Mono.Security.Protocol.Tls int offset, int count) { - if (this.context.ConnectionEnd) + if (this.context.SentConnectionEnd) { throw new TlsException( AlertDescription.InternalError, diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs index f347ccb2bdf..646f8d928a4 100644 --- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs +++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslStreamBase.cs @@ -612,7 +612,7 @@ namespace Mono.Security.Protocol.Tls { asyncResult.SetComplete(preReadSize); } - else if (!this.context.ConnectionEnd) + else if (!this.context.ReceivedConnectionEnd) { // this will read data from the network until we have (at least) one // record to send back to the caller @@ -731,11 +731,15 @@ namespace Mono.Security.Protocol.Tls if (!dataToReturn && (n > 0)) { - // there is no record to return to caller and (possibly) more data waiting - // so continue reading from network (and appending to stream) - recordStream.Position = recordStream.Length; - this.innerStream.BeginRead(recbuf, 0, recbuf.Length, - new AsyncCallback(InternalReadCallback), state); + if (context.ReceivedConnectionEnd) { + internalResult.SetComplete (0); + } else { + // there is no record to return to caller and (possibly) more data waiting + // so continue reading from network (and appending to stream) + recordStream.Position = recordStream.Length; + this.innerStream.BeginRead(recbuf, 0, recbuf.Length, + new AsyncCallback(InternalReadCallback), state); + } } else { @@ -1176,10 +1180,13 @@ namespace Mono.Security.Protocol.Tls if (this.innerStream != null) { if (this.context.HandshakeState == HandshakeState.Finished && - !this.context.ConnectionEnd) + !this.context.SentConnectionEnd) { - // Write close notify - this.protocol.SendAlert(AlertDescription.CloseNotify); + // Write close notify + try { + this.protocol.SendAlert(AlertDescription.CloseNotify); + } catch { + } } if (this.ownsStream) diff --git a/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs b/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs index c878a999eac..3a1cf930183 100644 --- a/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs +++ b/mcs/class/Mono.Security/Mono.Security/ASN1Convert.cs @@ -206,7 +206,7 @@ namespace Mono.Security { mask = "yyyyMMddHHmmsszzz"; break; } - return DateTime.ParseExact (t, mask, null, DateTimeStyles.AdjustToUniversal); + return DateTime.ParseExact (t, mask, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); } } } diff --git a/mcs/class/Mono.Security/Mono.Security/ChangeLog b/mcs/class/Mono.Security/Mono.Security/ChangeLog index 56a0e5a2d5f..fba575945bf 100644 --- a/mcs/class/Mono.Security/Mono.Security/ChangeLog +++ b/mcs/class/Mono.Security/Mono.Security/ChangeLog @@ -1,3 +1,8 @@ +2010-03-24 Sebastien Pouliot + + * ASN1Convert.cs: Specify CultureInfo.InvariantCulture (instead of + null) to avoid crash on Windows. Patch by Yoni Shalom. + 2008-09-12 Sebastien Pouliot * ASN1.cs: Use File.Create instead of OpenWrite to make sure nothing diff --git a/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/ChangeLog b/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/ChangeLog index 0b78daf5973..2acb3b1e6d6 100644 --- a/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/ChangeLog +++ b/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/ChangeLog @@ -1,3 +1,8 @@ +2010-04-08 Sebastien Pouliot + + * SubjectAltNameExtensionTest.cs: Add unit tests for multiple + DNSNames entries (#594110 and #591516 certificate test case) + 2008-06-26 Sebastien Pouliot * SubjectAltNameExtensionTest.cs: New. Unit tests for diff --git a/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/SubjectAltNameExtensionTest.cs b/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/SubjectAltNameExtensionTest.cs index 5c453d68d9c..9fe01a623d0 100644 --- a/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/SubjectAltNameExtensionTest.cs +++ b/mcs/class/Mono.Security/Test/Mono.Security.X509.Extensions/SubjectAltNameExtensionTest.cs @@ -92,5 +92,96 @@ namespace MonoTests.Mono.Security.X509.Extensions { Assert.AreEqual (sane_test.UniformResourceIdentifiers.Length, 0, "URI Count"); Assert.AreEqual (sane_test.IPAddresses[0], "192.168.111.111", "IPAddress Test"); } + + static byte [] multiple_entries_cert = new byte [] { + 0x30, 0x82, 0x06, 0x0B, 0x30, 0x82, 0x04, 0xF3, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x01, 0x47, 0x31, 0x5D, 0x40, 0xFA, 0x32, 0x70, 0xE2, + 0x0F, 0x16, 0x2D, 0xCC, 0xA6, 0x46, 0x0E, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, + 0xB5, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, + 0x0E, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x1F, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x04, 0x0B, + 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4E, 0x65, 0x74, 0x77, 0x6F, 0x72, 0x6B, + 0x31, 0x3B, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6D, 0x73, 0x20, 0x6F, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, + 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, 0x77, 0x77, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6E, 0x2E, + 0x63, 0x6F, 0x6D, 0x2F, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x39, 0x31, 0x2F, 0x30, 0x2D, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, + 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6E, 0x20, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2D, 0x20, 0x47, 0x32, 0x30, 0x1E, 0x17, 0x0D, 0x30, 0x39, 0x31, 0x32, 0x33, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5A, 0x17, 0x0D, 0x31, 0x31, 0x31, 0x32, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5A, 0x30, 0x81, + 0xDE, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x1B, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x12, 0x42, 0x61, 0x64, 0x65, 0x6E, 0x2D, 0x57, 0x75, 0x65, 0x72, 0x74, 0x74, 0x65, 0x6D, 0x62, 0x65, 0x72, 0x67, 0x31, 0x11, 0x30, 0x0F, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x14, 0x08, 0x4D, 0x61, 0x6E, 0x6E, 0x68, 0x65, 0x69, 0x6D, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x14, + 0x2D, 0x41, 0x44, 0x47, 0x20, 0x41, 0x70, 0x6F, 0x74, 0x68, 0x65, 0x6B, 0x65, 0x6E, 0x20, 0x44, 0x69, 0x65, 0x6E, 0x73, 0x74, 0x6C, 0x65, 0x69, + 0x73, 0x74, 0x75, 0x6E, 0x67, 0x73, 0x67, 0x65, 0x73, 0x65, 0x6C, 0x6C, 0x73, 0x63, 0x68, 0x61, 0x66, 0x74, 0x20, 0x6D, 0x62, 0x48, 0x31, 0x0C, + 0x30, 0x0A, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x03, 0x45, 0x44, 0x56, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x14, 0x2A, 0x54, + 0x65, 0x72, 0x6D, 0x73, 0x20, 0x6F, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, 0x77, 0x77, 0x77, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, + 0x69, 0x67, 0x6E, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x35, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x14, 0x1B, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x33, 0x30, 0x30, 0x30, 0x2D, 0x66, 0x69, 0x6C, 0x69, 0x61, 0x6C, 0x61, 0x70, 0x6F, 0x74, + 0x68, 0x65, 0x6B, 0x65, 0x2E, 0x64, 0x65, 0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x81, 0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xAE, 0xF3, 0xD4, 0xFE, 0x33, 0x44, 0x0F, 0x68, 0xBB, 0x4C, 0x6D, 0x5F, + 0xAF, 0xE7, 0xBC, 0x20, 0x05, 0xE3, 0xCB, 0xD6, 0x9D, 0x7A, 0x68, 0x8B, 0x3D, 0x63, 0x9B, 0xED, 0x31, 0x4E, 0x7E, 0xE7, 0x0A, 0x80, 0xF5, 0xDD, + 0x29, 0xDE, 0x02, 0x71, 0x82, 0xE7, 0x69, 0x02, 0xBC, 0xAC, 0xA6, 0x09, 0xFF, 0x3A, 0x41, 0xCB, 0x3C, 0x9C, 0x68, 0xB0, 0x80, 0xA6, 0xAF, 0x4C, + 0xED, 0xE7, 0xA7, 0xF1, 0x74, 0x63, 0x3A, 0xF7, 0xC8, 0x66, 0x84, 0x6D, 0xE5, 0x5B, 0x9B, 0x45, 0xBC, 0x78, 0x84, 0x3E, 0x1A, 0x82, 0x84, 0x8C, + 0xB2, 0x06, 0x64, 0x62, 0xB7, 0xB0, 0xE6, 0x9E, 0x5F, 0xAF, 0x58, 0x93, 0xAC, 0xCE, 0x04, 0x71, 0x2A, 0x11, 0xD9, 0xD5, 0x4E, 0xD0, 0x7F, 0x9E, + 0xF7, 0x92, 0x5F, 0x83, 0xAE, 0x32, 0x1F, 0x2E, 0x1B, 0xDD, 0x34, 0xE8, 0x28, 0xC8, 0x4D, 0x97, 0x20, 0xBA, 0xE8, 0x6B, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xA3, 0x82, 0x02, 0x6E, 0x30, 0x82, 0x02, 0x6A, 0x30, 0x81, 0x9A, 0x06, 0x03, 0x55, 0x1D, 0x11, 0x04, 0x81, 0x92, 0x30, 0x81, 0x8F, 0x82, + 0x21, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x72, 0x7A, 0x6E, 0x65, 0x69, 0x6D, 0x69, 0x74, 0x74, 0x65, 0x6C, 0x2D, 0x62, 0x65, 0x73, 0x74, 0x65, 0x6C, + 0x6C, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x64, 0x65, 0x82, 0x26, 0x77, 0x77, 0x77, 0x2E, 0x78, 0x6E, 0x65, 0x74, 0x2D, 0x61, 0x72, 0x7A, + 0x6E, 0x65, 0x69, 0x6D, 0x69, 0x74, 0x74, 0x65, 0x6C, 0x2D, 0x62, 0x65, 0x73, 0x74, 0x65, 0x6C, 0x6C, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x2E, + 0x64, 0x65, 0x82, 0x25, 0x77, 0x77, 0x77, 0x2E, 0x61, 0x64, 0x67, 0x2D, 0x61, 0x72, 0x7A, 0x6E, 0x65, 0x69, 0x6D, 0x69, 0x74, 0x74, 0x65, 0x6C, + 0x2D, 0x62, 0x65, 0x73, 0x74, 0x65, 0x6C, 0x6C, 0x63, 0x65, 0x6E, 0x74, 0x65, 0x72, 0x2E, 0x64, 0x65, 0x82, 0x1B, 0x77, 0x77, 0x77, 0x2E, 0x61, + 0x33, 0x30, 0x30, 0x30, 0x2D, 0x66, 0x69, 0x6C, 0x69, 0x61, 0x6C, 0x61, 0x70, 0x6F, 0x74, 0x68, 0x65, 0x6B, 0x65, 0x2E, 0x64, 0x65, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0B, 0x06, 0x03, 0x55, 0x1D, 0x0F, 0x04, 0x04, 0x03, 0x02, 0x05, 0xA0, 0x30, 0x45, + 0x06, 0x03, 0x55, 0x1D, 0x1F, 0x04, 0x3E, 0x30, 0x3C, 0x30, 0x3A, 0xA0, 0x38, 0xA0, 0x36, 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, + 0x53, 0x56, 0x52, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2D, 0x47, 0x32, 0x2D, 0x63, 0x72, 0x6C, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, + 0x6E, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x53, 0x56, 0x52, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x47, 0x32, 0x2E, 0x63, 0x72, 0x6C, 0x30, 0x44, 0x06, + 0x03, 0x55, 0x1D, 0x20, 0x04, 0x3D, 0x30, 0x3B, 0x30, 0x39, 0x06, 0x0B, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01, 0x07, 0x17, 0x03, 0x30, + 0x2A, 0x30, 0x28, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1C, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3A, 0x2F, 0x2F, 0x77, + 0x77, 0x77, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6E, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x72, 0x70, 0x61, 0x30, 0x1D, 0x06, 0x03, 0x55, + 0x1D, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x02, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x1D, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xA5, 0xEF, 0x0B, 0x11, 0xCE, 0xC0, 0x41, 0x03, 0xA3, + 0x4A, 0x65, 0x90, 0x48, 0xB2, 0x1C, 0xE0, 0x57, 0x2D, 0x7D, 0x47, 0x30, 0x76, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x6A, 0x30, 0x68, 0x30, 0x24, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, + 0x6F, 0x63, 0x73, 0x70, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6E, 0x2E, 0x63, 0x6F, 0x6D, 0x30, 0x40, 0x06, 0x08, 0x2B, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x53, 0x56, 0x52, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2D, + 0x47, 0x32, 0x2D, 0x61, 0x69, 0x61, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6E, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x53, 0x56, 0x52, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x47, 0x32, 0x2E, 0x63, 0x65, 0x72, 0x30, 0x6E, 0x06, 0x08, 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0C, 0x04, + 0x62, 0x30, 0x60, 0xA1, 0x5E, 0xA0, 0x5C, 0x30, 0x5A, 0x30, 0x58, 0x30, 0x56, 0x16, 0x09, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x67, 0x69, 0x66, + 0x30, 0x21, 0x30, 0x1F, 0x30, 0x07, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x04, 0x14, 0x4B, 0x6B, 0xB9, 0x28, 0x96, 0x06, 0x0C, 0xBB, 0xD0, + 0x52, 0x38, 0x9B, 0x29, 0xAC, 0x4B, 0x07, 0x8B, 0x21, 0x05, 0x18, 0x30, 0x26, 0x16, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F, 0x6C, 0x6F, + 0x67, 0x6F, 0x2E, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6E, 0x2E, 0x63, 0x6F, 0x6D, 0x2F, 0x76, 0x73, 0x6C, 0x6F, 0x67, 0x6F, 0x31, 0x2E, + 0x67, 0x69, 0x66, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2F, + 0x1E, 0x71, 0x21, 0xD9, 0xCE, 0xBB, 0x16, 0xEA, 0xA2, 0xD9, 0x5B, 0xA6, 0x0E, 0x1B, 0x9A, 0x32, 0xC2, 0xFA, 0x38, 0xF5, 0x3F, 0xC7, 0xEE, 0xFC, + 0xD7, 0xBE, 0x92, 0x14, 0xAA, 0xBE, 0x94, 0x63, 0xE6, 0xCE, 0x46, 0x9D, 0x28, 0x11, 0x6E, 0x8D, 0x64, 0xDB, 0x4B, 0x7D, 0x03, 0xD2, 0xE7, 0x6B, + 0x23, 0xA4, 0xD2, 0x67, 0xFE, 0x1B, 0xFC, 0x7E, 0x2C, 0xAA, 0xB6, 0x1F, 0x36, 0xD5, 0x65, 0x47, 0xCE, 0xC1, 0x4C, 0xD2, 0x83, 0xBA, 0x1A, 0x8E, + 0x39, 0x74, 0x0E, 0xCC, 0x29, 0x1A, 0x91, 0x09, 0x32, 0x5F, 0x01, 0x14, 0x7A, 0xC8, 0x9C, 0x14, 0x36, 0x78, 0x5F, 0xB0, 0x5E, 0x07, 0xFD, 0x34, + 0xD1, 0x93, 0xD6, 0x79, 0xA0, 0xC1, 0xA0, 0xF2, 0xD7, 0xF0, 0x5E, 0xF7, 0x57, 0xB0, 0xE7, 0x75, 0x60, 0xC5, 0xE6, 0x4F, 0xA9, 0x78, 0x72, 0x47, + 0x72, 0x8F, 0x8A, 0x6B, 0xCD, 0x3D, 0x0D, 0x56, 0xB1, 0x85, 0x5B, 0x2E, 0x1F, 0xF1, 0x00, 0x86, 0x83, 0x72, 0xD4, 0x80, 0x71, 0x1A, 0xBB, 0x08, + 0xCC, 0x6B, 0x67, 0xDA, 0x9B, 0xCB, 0x99, 0xDD, 0xAF, 0x27, 0x0F, 0xCE, 0x30, 0x02, 0x69, 0x74, 0x64, 0x3C, 0x68, 0xB5, 0xFF, 0x60, 0x5F, 0x1D, + 0x6A, 0xBB, 0xF5, 0x0D, 0xC5, 0x96, 0x85, 0xDA, 0x36, 0x4E, 0xF3, 0x84, 0x97, 0x62, 0x9E, 0x18, 0x6E, 0xA9, 0x8D, 0xFD, 0x54, 0x9E, 0x39, 0xFA, + 0x4A, 0x38, 0xF6, 0xF1, 0x1C, 0x63, 0x5D, 0x09, 0x09, 0xC4, 0x18, 0xA9, 0x8C, 0x96, 0x75, 0xEB, 0x0D, 0x91, 0xA5, 0xE8, 0x7E, 0x08, 0x38, 0x49, + 0x77, 0x10, 0x05, 0xF0, 0xD9, 0x57, 0x5A, 0xE2, 0xA0, 0x0C, 0x10, 0x03, 0x46, 0xA2, 0xD1, 0x6A, 0x12, 0x21, 0x81, 0x24, 0x35, 0x94, 0x51, 0x93, + 0x2E, 0x5D, 0x91, 0x2D, 0xAE, 0xB6, 0xBE, 0xFA, 0x26, 0x12, 0xB5, 0x38, 0x9A, 0xAD, 0x6E + }; + + [Test] + public void MultipleEntriesInExtension () + { + X509Certificate cert = new X509Certificate (multiple_entries_cert); + SubjectAltNameExtension sane = new SubjectAltNameExtension (cert.Extensions ["2.5.29.17"]); + Assert.AreEqual (4, sane.DNSNames.Length, "Count"); + Assert.AreEqual ("www.arzneimittel-bestellcenter.de", sane.DNSNames [0], "0"); + Assert.AreEqual ("www.xnet-arzneimittel-bestellcenter.de", sane.DNSNames [1], "1"); + Assert.AreEqual ("www.adg-arzneimittel-bestellcenter.de", sane.DNSNames [2], "2"); + Assert.AreEqual ("www.a3000-filialapotheke.de", sane.DNSNames [3], "3"); + } + + [Test] + public void MultipleEntriesInExtension_AsASN1 () + { + X509Certificate cert = new X509Certificate (multiple_entries_cert); + SubjectAltNameExtension sane = new SubjectAltNameExtension (cert.Extensions ["2.5.29.17"].ASN1); + Assert.AreEqual ("www.arzneimittel-bestellcenter.de", sane.DNSNames [0], "0"); + Assert.AreEqual ("www.xnet-arzneimittel-bestellcenter.de", sane.DNSNames [1], "1"); + Assert.AreEqual ("www.adg-arzneimittel-bestellcenter.de", sane.DNSNames [2], "2"); + Assert.AreEqual ("www.a3000-filialapotheke.de", sane.DNSNames [3], "3"); + } } } diff --git a/mcs/class/Mono.Simd/Mono.Simd/ChangeLog b/mcs/class/Mono.Simd/Mono.Simd/ChangeLog index 8ab1729a9e2..e508f043319 100644 --- a/mcs/class/Mono.Simd/Mono.Simd/ChangeLog +++ b/mcs/class/Mono.Simd/Mono.Simd/ChangeLog @@ -1,3 +1,7 @@ +2010-03-24 Rodrigo Kumpera + + * Vector4f.cs: Add vector x scalar multiply. + 2009-09-18 Rodrigo Kumpera * SimdRuntime.cs: Raise an exception if the method been queried diff --git a/mcs/class/Mono.Simd/Mono.Simd/Vector4f.cs b/mcs/class/Mono.Simd/Mono.Simd/Vector4f.cs index 77ba2cd6def..db7143b9b49 100644 --- a/mcs/class/Mono.Simd/Mono.Simd/Vector4f.cs +++ b/mcs/class/Mono.Simd/Mono.Simd/Vector4f.cs @@ -80,9 +80,7 @@ namespace Mono.Simd Abs (implemented as pand [7fffffff,...] ) Comparison functions Mask extraction function - Setters vector x float ops - Single float constructor (expand it to the 4 positions) Replace Shuffle with less bug prone methods */ @@ -223,6 +221,18 @@ namespace Mono.Simd return new Vector4f (v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w); } + [Acceleration (AccelMode.SSE1)] + public static Vector4f operator * (float scalar, Vector4f v) + { + return new Vector4f (scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.w); + } + + [Acceleration (AccelMode.SSE1)] + public static Vector4f operator * (Vector4f v, float scalar) + { + return new Vector4f (scalar * v.x, scalar * v.y, scalar * v.z, scalar * v.w); + } + [Acceleration (AccelMode.SSE1)] public static Vector4f operator / (Vector4f v1, Vector4f v2) { diff --git a/mcs/class/Moonlight.Build.Tasks/ChangeLog b/mcs/class/Moonlight.Build.Tasks/ChangeLog new file mode 100644 index 00000000000..7e630808bab --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/ChangeLog @@ -0,0 +1,3 @@ +2010-04-13 Ankit Jain + + * Initial commit. diff --git a/mcs/class/Moonlight.Build.Tasks/Makefile b/mcs/class/Moonlight.Build.Tasks/Makefile new file mode 100644 index 00000000000..7c3511c9066 --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Makefile @@ -0,0 +1,61 @@ +thisdir = class/Moonlight.Build.Tasks +SUBDIRS = +include ../../build/rules.make + +LIBRARY = Moonlight.Build.Tasks.dll +LIBRARY_NAME = Moonlight.Build.Tasks.dll + +ifeq (1.0, $(FRAMEWORK_VERSION)) +LIBRARY_NAME = dummy-Moonlight.Build.Tasks.dll +endif + +ifeq (3.5, $(FRAMEWORK_VERSION)) +NAME_SUFFIX = .v3.5 +else +ifeq (4.0, $(FRAMEWORK_VERSION)) +NAME_SUFFIX = .v4.0 +endif +endif + +NO_INSTALL = yes +NO_TEST = yes +NO_SIGN_ASSEMBLY = yes + +REFERENCES = \ + /r:$(corlib) \ + /r:System.dll \ + /r:System.Xml.dll \ + /r:Microsoft.Build.Engine.dll \ + /r:Microsoft.Build.Framework.dll \ + /r:Microsoft.Build.Utilities$(NAME_SUFFIX).dll \ + /r:Microsoft.Build.Tasks$(NAME_SUFFIX).dll \ + /r:ICSharpCode.SharpZipLib.dll + +LIB_MCS_FLAGS = \ + $(REFERENCES) \ + $(RESOURCE_FILES:%=-resource:%) + +RESOURCE_FILES = Moonlight.Build.Tasks/PreviewTemplate.html + +EXTRA_DISTFILES = $(RESOURCE_FILES) + +XBUILD_DIR=../../tools/xbuild +include $(XBUILD_DIR)/xbuild_targets.make + +include ../../build/library.make + +SILVERLIGHT_DIR = $(DESTDIR)$(mono_libdir)/mono/xbuild/Microsoft/Silverlight + +install-local: install-lib + +install-lib: $(the_lib) + -$(MKINSTALLDIRS) $(SILVERLIGHT_DIR)/v2.0 + -$(MKINSTALLDIRS) $(SILVERLIGHT_DIR)/v3.0 + $(INSTALL_DATA) $(topdir)/class/lib/$(PROFILE)/$(LIBRARY_NAME) $(SILVERLIGHT_DIR)/v2.0 + $(INSTALL_DATA) $(topdir)/class/lib/$(PROFILE)/$(LIBRARY_NAME) $(SILVERLIGHT_DIR)/v3.0 + +uninstall-local: uninstall-lib + +uninstall-lib: + -rm -f $(SILVERLIGHT_DIR)/v2.0/$(LIBRARY_NAME) + -rm -f $(SILVERLIGHT_DIR)/v3.0/$(LIBRARY_NAME) diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks.dll.sources b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks.dll.sources new file mode 100644 index 00000000000..74c3a27a725 --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks.dll.sources @@ -0,0 +1,6 @@ +Moonlight.Build.Tasks/GenerateXap.cs +Moonlight.Build.Tasks/XamlG.cs +Moonlight.Build.Tasks/GetMoonlightFrameworkPath.cs +Moonlight.Build.Tasks/GenerateMoonlightManifest.cs +Moonlight.Build.Tasks/CreateTestPage.cs +Moonlight.Build.Tasks/Respack.cs diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/ChangeLog b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/ChangeLog new file mode 100644 index 00000000000..8851010c370 --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/ChangeLog @@ -0,0 +1,9 @@ +2010-04-13 Ankit Jain + + * CreateTestPage.cs: + * GenerateMoonlightManifest.cs: + * GetMoonlightFrameworkPath.cs: + * GenerateXap.cs: + * Respack.cs: + * XamlG.cs: + MSBuild tasks for building silverlight projects. diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/CreateTestPage.cs b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/CreateTestPage.cs new file mode 100644 index 00000000000..28051694eed --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/CreateTestPage.cs @@ -0,0 +1,79 @@ +// +// CreateTestPage.cs: Generates test page for moonlight app +// +// Author: +// Michael Hutchinson +// Ankit Jain +// +// Copyright (c) 2009 Novell, Inc. (http://www.novell.com) +// Copyright (c) 2010 Novell, Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.IO; +using System.Reflection; +using System.Text; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Moonlight.Build.Tasks { + public class CreateTestPage : Task { + + public override bool Execute () + { + Log.LogMessage (MessageImportance.Low, "Generating test page {0}", XapFilename); + + var sb = new StringBuilder (); + using (var sr = new StreamReader (Assembly.GetExecutingAssembly ().GetManifestResourceStream ("PreviewTemplate.html"))) + sb.Append (sr.ReadToEnd ()); + + sb.Replace ("@TITLE@", Title); + sb.Replace ("@XAP_FILE@", XapFilename); + + try{ + File.WriteAllText (TestPageFilename, sb.ToString ()); + } catch (IOException e) { + Log.LogError (String.Format ( + "Error generating test page file {0}: {1}", TestPageFilename, e.Message)); + return false; + } + + return true; + } + + [Required] + public string XapFilename { + get; set; + } + + [Required] + public string Title { + get; set; + } + + [Required] + [Output] + public string TestPageFilename { + get; set; + } + } +} diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GenerateMoonlightManifest.cs b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GenerateMoonlightManifest.cs new file mode 100644 index 00000000000..4b7e7a30dfa --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GenerateMoonlightManifest.cs @@ -0,0 +1,179 @@ +// +// GenerateMoonlightManifest.cs +// +// Author: +// Michael Hutchinson +// Ankit Jain +// +// Copyright (c) 2009 Novell, Inc. (http://www.novell.com) +// Copyright (c) 2010 Novell, Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Xml; + +using Microsoft.CSharp; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Moonlight.Build.Tasks { + public class GenerateMoonlightManifest : Task { + + public override bool Execute () + { + return GenerateManifest (); + } + + bool GenerateManifest () + { + const string depNS = "http://schemas.microsoft.com/client/2007/deployment"; + + string template = null; + var manifest = ManifestFile.ItemSpec; + Log.LogMessage (MessageImportance.Normal, "Generating manifest file {0}", manifest); + + if (SilverlightManifestTemplate != null) + template = String.IsNullOrEmpty (SilverlightManifestTemplate.ItemSpec) ? + null : + SilverlightManifestTemplate.GetMetadata ("FullPath"); + + XmlDocument doc = new XmlDocument (); + if (template != null) { + if (!File.Exists (template)) { + Log.LogError ("Could not find manifest template '" + template + "'."); + return false; + } + + try { + doc.Load (template); + } catch (XmlException ex) { + Log.LogError (null, null, null, template, ex.LineNumber, ex.LinePosition, 0, 0, + "Error loading manifest template '" + ex.Source); + return false; + } catch (Exception ex) { + Log.LogError ("Could not load manifest template '" + template + "'."); + Log.LogMessage (MessageImportance.Low, "Could not load manifest template '" + template + "': " + ex.ToString ()); + return false; + } + + } else { + doc.LoadXml (@""); + } + + try { + XmlNode deploymentNode = doc.DocumentElement; + if (deploymentNode == null || deploymentNode.Name != "Deployment" || deploymentNode.NamespaceURI != depNS) { + Log.LogError ("Missing or invalid root element in manifest template '" + template + "'."); + return false; + } + if (deploymentNode.Attributes["EntryPointAssembly"] == null) + deploymentNode.Attributes.Append (doc.CreateAttribute ("EntryPointAssembly")).Value = + EntryPointAssembly.GetMetadata ("Filename"); + + if (!String.IsNullOrEmpty (SilverlightAppEntry) && deploymentNode.Attributes["EntryPointType"] == null) + deploymentNode.Attributes.Append (doc.CreateAttribute ("EntryPointType")).Value = SilverlightAppEntry; + + if (deploymentNode.Attributes["RuntimeVersion"] == null) { + //FIXME: + /*string fxVersion = MoonlightFrameworkBackend.GetFxVersion (proj.TargetFramework); + + if (proj.TargetRuntime is MonoDevelop.Core.Assemblies.MonoTargetRuntime) { + var package = proj.TargetRuntime.RuntimeAssemblyContext.GetPackage ("moonlight-web-" + fxVersion); + if (package != null && package.IsFrameworkPackage) { + runtimeVersion = package.Version; + } else { + LoggingService.LogWarning ("Moonlight core framework package not found, cannot determine " + + "runtime version string. Falling back to default value."); + } + }*/ + + deploymentNode.Attributes.Append (doc.CreateAttribute ("RuntimeVersion")).Value = + String.IsNullOrEmpty (RuntimeVersion) ? "2.0.31005.0" : RuntimeVersion; + } + + XmlNamespaceManager mgr = new XmlNamespaceManager (doc.NameTable); + mgr.AddNamespace ("dep", depNS); + XmlNode partsNode = deploymentNode.SelectSingleNode ("dep:Deployment.Parts", mgr); + if (partsNode == null) + partsNode = deploymentNode.AppendChild (doc.CreateElement ("Deployment.Parts", depNS)); + + AddAssemblyPart (doc, partsNode, EntryPointAssembly); + + foreach (ITaskItem ref_item in References) + AddAssemblyPart (doc, partsNode, ref_item); + } catch (XmlException ex) { + Log.LogError (null, null, null, template, ex.LineNumber, ex.LinePosition, 0, 0, + "Error processing manifest template: '" + ex.Source); + return false; + } + + doc.Save (manifest); + + return true; + } + + static void AddAssemblyPart (XmlDocument doc, XmlNode partsNode, ITaskItem filename) + { + XmlNode child = doc.CreateElement ("AssemblyPart", "http://schemas.microsoft.com/client/2007/deployment"); + child.Attributes.Append (doc.CreateAttribute ( + "Name", "http://schemas.microsoft.com/winfx/2006/xaml")).Value = filename.GetMetadata ("Filename"); + string subdir = filename.GetMetadata ("DestinationSubdirectory"); + child.Attributes.Append (doc.CreateAttribute ("Source")).Value = Path.Combine (subdir ?? String.Empty, Path.GetFileName (filename.ItemSpec)); + partsNode.AppendChild (child); + } + + [Required] + [Output] + public ITaskItem ManifestFile { + get; set; + } + + [Required] + // with extension + public ITaskItem EntryPointAssembly { + get; set; + } + + [Required] + public ITaskItem[] References { + get; set; + } + + public ITaskItem SilverlightManifestTemplate { + get; set; + } + + public string SilverlightAppEntry { + get; set; + } + + public string RuntimeVersion { + get; set; + } + } + +} diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GenerateXap.cs b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GenerateXap.cs new file mode 100644 index 00000000000..92082ac0efb --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GenerateXap.cs @@ -0,0 +1,140 @@ +// +// GenerateXap.cs +// +// Author: +// Michael Hutchinson +// Ankit Jain +// +// Copyright (c) 2009 Novell, Inc. (http://www.novell.com) +// Copyright (c) 2010 Novell, Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Xml; + +using Microsoft.CSharp; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Moonlight.Build.Tasks { + public class GenerateXap : Task { + + public override bool Execute () + { + if (InputFiles.Length == 0) + return true; + + return Zip (); + } + + bool Zip () + { + var xapName = XapFilename.ItemSpec; + if (File.Exists (xapName)) { + DateTime lastMod = File.GetLastWriteTime (xapName); + bool needsWrite = false; + foreach (ITaskItem file_item in InputFiles) { + if (File.GetLastWriteTime (file_item.ItemSpec) > lastMod) { + needsWrite = true; + break; + } + } + if (!needsWrite) { + Log.LogMessage (MessageImportance.Low, "Skipping xap file {0} generation, its up-to date"); + return true; + } + } + + Log.LogMessage (MessageImportance.Normal, "Generating compressed xap file {0}", xapName); + try { + using (FileStream fs = new FileStream (xapName, FileMode.Create)) { + var zip_stream = new ICSharpCode.SharpZipLib.Zip.ZipOutputStream (fs); + zip_stream.SetLevel (9); + + AddFilesToZip (InputFiles, zip_stream); + AddFilesToZip (LocalCopyReferences, zip_stream); + + zip_stream.Finish (); + zip_stream.Close (); + } + } catch (IOException ex) { + Log.LogError ("Error writing xap file.", ex); + Log.LogMessage (MessageImportance.Low, "Error writing xap file:" + ex.ToString ()); + + try { + if (File.Exists (xapName)) + File.Delete (xapName); + } catch {} + + return false; + } + + return true; + } + + void AddFilesToZip (ITaskItem [] files, ICSharpCode.SharpZipLib.Zip.ZipOutputStream zipStream) + { + if (files == null) + return; + + foreach (ITaskItem item in files) { + string target_path = item.GetMetadata ("TargetPath"); + if (String.IsNullOrEmpty (target_path)) + target_path = Path.GetFileName (item.ItemSpec); + + zipStream.PutNextEntry (new ICSharpCode.SharpZipLib.Zip.ZipEntry (target_path)); + using (FileStream inStream = File.OpenRead (item.ItemSpec)) { + int readCount; + byte[] buffer = new byte[4096]; + + do { + readCount = inStream.Read (buffer, 0, buffer.Length); + zipStream.Write (buffer, 0, readCount); + } while (readCount > 0); + } + } + } + + [Output] + [Required] + public ITaskItem XapFilename { + get; set; + } + + [Required] + public ITaskItem[] InputFiles { + get; set; + } + + public ITaskItem[] LocalCopyReferences { + get; set; + } + + } + + +} diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GetMoonlightFrameworkPath.cs b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GetMoonlightFrameworkPath.cs new file mode 100644 index 00000000000..65072db4237 --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/GetMoonlightFrameworkPath.cs @@ -0,0 +1,89 @@ +// +// GetMoonlightFrameworkPath.cs +// +// Author: +// Michael Hutchinson +// Ankit Jain +// +// Copyright (c) 2009 Novell, Inc. (http://www.novell.com) +// Copyright (c) 2010 Novell, Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using SI = System.IO; + +using System; +using System.Text; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Moonlight.Build.Tasks { + public class GetMoonlightFrameworkPath : Task { + + public override bool Execute () + { + return true; + } + + [Required] + public string SilverlightVersion { + get; set; + } + + [Output] + public string FrameworkPath { + get { + if (SilverlightVersion == "3.0") + return FrameworkVersion30Path; + else + return FrameworkVersion20Path; + } + } + + [Output] + public string FrameworkVersion20Path { + get { + return SI.Path.GetFullPath ( + PathCombine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20), + "..", "..", "moonlight", "2.0")); + } + } + + [Output] + public string FrameworkVersion30Path { + get { + return SI.Path.GetFullPath ( + PathCombine (ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20), + "..", "..", "moonlight", "3.0")); + } + } + + static string PathCombine (string path1, params string[] parts) + { + StringBuilder sb = new StringBuilder (); + sb.Append (path1); + foreach (string part in parts) + sb.AppendFormat ("{0}{1}", SI.Path.DirectorySeparatorChar, part); + + return sb.ToString (); + } + } +} diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/PreviewTemplate.html b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/PreviewTemplate.html new file mode 100644 index 00000000000..2be05759952 --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/PreviewTemplate.html @@ -0,0 +1,76 @@ + + + + @TITLE@ + + + + + + + + +
+ +
+ + + + + + + + Get Microsoft Silverlight + + + +
+ + diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/Respack.cs b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/Respack.cs new file mode 100644 index 00000000000..4f7a5448d9e --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/Respack.cs @@ -0,0 +1,105 @@ +// +// Respack.cs +// +// Author: +// Ankit Jain (jankit@novell.com) +// +// Copyright 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHRespackL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DERespackINGS IN THE SOFTWARE. + +using System; +using System.Diagnostics; +using System.IO; +using Microsoft.Build.Framework; +using Microsoft.Build.Tasks; +using Microsoft.Build.Utilities; +using Mono.XBuild.Utilities; + +namespace Moonlight.Build.Tasks { + public class Respack : ToolTask + { + public override bool Execute () + { + if (!ValidateParameters ()) { + // not generating any resource file + OutputFile = null; + return true; + } + + return base.Execute (); + } + + void AddCommandLineCommands (CommandLineBuilderExtension commandLine) + { + if (Resources.Length == 0) + return; + + commandLine.AppendFileNameIfNotNull (OutputFile); + + commandLine.AppendFileNamesIfNotNull (Resources, " "); + } + + protected override string GenerateCommandLineCommands () + { + CommandLineBuilderExtension clbe = new CommandLineBuilderExtension (); + AddCommandLineCommands (clbe); + return clbe.ToString (); + } + + protected override string GenerateFullPathToTool () + { + return Path.Combine (ToolPath, ToolExe); + } + + protected override bool ValidateParameters() + { + return Resources.Length > 0; + } + + [Required] + [Output] + public ITaskItem OutputFile { + get; set; + } + + [Required] + public ITaskItem[] Resources { + get; set; + } + + protected override string ToolName { + get { + return RunningOnWindows ? "respack.bat" : "respack"; + } + } + + static bool RunningOnWindows { + get { + // Code from Mono.GetOptions/Options.cs + // check for non-Unix platforms - see FAQ for more details + // http://www.mono-project.com/FAQ:_Technical#How_to_detect_the_execution_platform_.3F + int platform = (int) Environment.OSVersion.Platform; + return ((platform != 4) && (platform != 128)); + } + + } + } +} diff --git a/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/XamlG.cs b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/XamlG.cs new file mode 100644 index 00000000000..63bea8af800 --- /dev/null +++ b/mcs/class/Moonlight.Build.Tasks/Moonlight.Build.Tasks/XamlG.cs @@ -0,0 +1,375 @@ +// +// XamlG.cs +// +// Author: +// Michael Hutchinson +// Ankit Jain +// +// Copyright (c) 2009 Novell, Inc. (http://www.novell.com) +// Copyright (c) 2010 Novell, Inc. (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Xml; + +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace Moonlight.Build.Tasks { + public class XamlG : Task { + + public override bool Execute () + { + if (Sources.Length == 0) + return true; + + if (OutputFiles == null || Sources.Length != OutputFiles.Length) { + Log.LogError ("Number of OutputFiles must match the number of Source files"); + return false; + } + + var codedom_provider = GetCodeDomProviderForLanguage (Language); + if (codedom_provider == null) { + Log.LogError ("Language {0} not supported for code generation.", Language); + return false; + } + + for (int i = 0; i < Sources.Length; i ++) { + ITaskItem source_item = Sources [i]; + ITaskItem dest_item = OutputFiles [i]; + if (!File.Exists (dest_item.ItemSpec) || + File.GetLastWriteTime (dest_item.ItemSpec) < File.GetLastWriteTime (source_item.ItemSpec)) { + Log.LogMessage (MessageImportance.Low, "Generating codebehind accessors for {0}...", source_item.ItemSpec); + + string full_source_path = source_item.GetMetadata ("FullPath"); + try { + if (!XamlGCompiler.GenerateFile (codedom_provider, AssemblyName, full_source_path, full_source_path, dest_item.ItemSpec, Log)) { + Log.LogError ("Error generating {0} from {1}", full_source_path, dest_item.ItemSpec); + return false; + } + } catch (Exception e) { + Log.LogError ("Error generating {0} from {1}: {2}", full_source_path, dest_item.ItemSpec, e.Message); + Log.LogMessage (MessageImportance.Low, "Error generating {0} from {1}: {2}", + full_source_path, dest_item.ItemSpec, e.ToString ()); + return false; + } + } + } + + return true; + } + + CodeDomProvider GetCodeDomProviderForLanguage (string lang) + { + switch (lang.ToLower ()) { + case "c#": return new Microsoft.CSharp.CSharpCodeProvider (); + case "vb": return new Microsoft.VisualBasic.VBCodeProvider (); + } + + return null; + } + + [Required] + public ITaskItem [] Sources { + get; set; + } + + [Required] + public string Language { + get; set; + } + + [Required] + public string AssemblyName { + get; set; + } + + [Output] + public ITaskItem [] OutputFiles { + get; set; + } + + bool HasFileChanged (string source, string dest) + { + if (!File.Exists (dest)) + return true; + + FileInfo sourceInfo = new FileInfo (source); + FileInfo destinationInfo = new FileInfo (dest); + + return !(sourceInfo.Length == destinationInfo.Length && + File.GetLastWriteTime(source) <= File.GetLastWriteTime (dest)); + } + + } + + static class XamlGCompiler + { + private static bool sl2 = true; + + public static bool GenerateFile (CodeDomProvider provider, string app_name, + string xaml_file, string xaml_path_in_project, string out_file, TaskLoggingHelper log) + { + XmlDocument xmldoc = new XmlDocument (); + xmldoc.Load (xaml_file); + + XmlNamespaceManager nsmgr = new XmlNamespaceManager (xmldoc.NameTable); + nsmgr.AddNamespace("x", "http://schemas.microsoft.com/winfx/2006/xaml"); + + XmlNode root = xmldoc.SelectSingleNode ("/*", nsmgr); + if (root == null) { + log.LogError ("{0}: No root node found.", xaml_file); + return false; + } + + XmlAttribute root_class = root.Attributes ["x:Class"]; + if (root_class == null) { + File.WriteAllText (out_file, ""); + return true; + } + + bool is_application = root.LocalName == "Application"; + string root_ns; + string root_type; + string root_asm; + + ParseXmlns (root_class.Value, out root_type, out root_ns, out root_asm); + + Hashtable names_and_types = GetNamesAndTypes (root, nsmgr); +// Hashtable keys_and_types = GetKeysAndTypes (root, nsmgr); + + CodeCompileUnit ccu = new CodeCompileUnit (); + CodeNamespace decl_ns = new CodeNamespace (root_ns); + ccu.Namespaces.Add (decl_ns); + + decl_ns.Imports.Add (new CodeNamespaceImport ("System")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Controls")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Documents")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Input")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Media")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Media.Animation")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Shapes")); + decl_ns.Imports.Add (new CodeNamespaceImport ("System.Windows.Controls.Primitives")); + + CodeTypeDeclaration decl_type = new CodeTypeDeclaration (root_type); + decl_type.IsPartial = true; + + decl_ns.Types.Add (decl_type); + + CodeMemberMethod initcomp = new CodeMemberMethod (); + initcomp.Name = "InitializeComponent"; + decl_type.Members.Add (initcomp); + + if (sl2) { + CodeMemberField field = new CodeMemberField (); + field.Name = "_contentLoaded"; + field.Type = new CodeTypeReference (typeof (bool)); + + decl_type.Members.Add (field); + + CodeConditionStatement is_content_loaded = new CodeConditionStatement (new CodeVariableReferenceExpression ("_contentLoaded"), + new CodeStatement [] { new CodeMethodReturnStatement () }); + initcomp.Statements.Add (is_content_loaded); + + CodeAssignStatement set_content_loaded = new CodeAssignStatement (new CodeVariableReferenceExpression ("_contentLoaded"), + new CodePrimitiveExpression (true)); + + initcomp.Statements.Add (set_content_loaded); + + string component_path = String.Format ("/{0};component/{1}", app_name, xaml_path_in_project); + CodeMethodInvokeExpression load_component = new CodeMethodInvokeExpression ( + new CodeTypeReferenceExpression ("System.Windows.Application"), "LoadComponent", + new CodeExpression [] { new CodeThisReferenceExpression (), + new CodeObjectCreateExpression (new CodeTypeReference ("System.Uri"), new CodeExpression [] { + new CodePrimitiveExpression (component_path), + new CodeFieldReferenceExpression (new CodeTypeReferenceExpression ("System.UriKind"), "Relative") }) + }); + initcomp.Statements.Add (load_component); + } + + if (!is_application) { + foreach (DictionaryEntry entry in names_and_types) { + string name = (string) entry.Key; + CodeTypeReference type = (CodeTypeReference) entry.Value; + + CodeMemberField field = new CodeMemberField (); + + if (sl2) + field.Attributes = MemberAttributes.Assembly; + + field.Name = name; + field.Type = type; + + decl_type.Members.Add (field); + + CodeMethodInvokeExpression find_invoke = new CodeMethodInvokeExpression ( + new CodeThisReferenceExpression(), "FindName", + new CodeExpression[] { new CodePrimitiveExpression (name) } ); + + CodeCastExpression cast = new CodeCastExpression (type, find_invoke); + + CodeAssignStatement assign = new CodeAssignStatement ( + new CodeVariableReferenceExpression (name), cast); + + initcomp.Statements.Add (assign); + } + } + + + using (StreamWriter writer = new StreamWriter (out_file)) { + provider.GenerateCodeFromCompileUnit (ccu, writer, new CodeGeneratorOptions ()); + } + + return true; + } + + private static Hashtable GetNamesAndTypes (XmlNode root, XmlNamespaceManager nsmgr) + { + Hashtable res = new Hashtable (); + + XmlNodeList names = root.SelectNodes ("//*[@x:Name]", nsmgr); + foreach (XmlNode node in names) { + + // Don't take the root canvas + if (node == root) + continue; + + XmlAttribute attr = node.Attributes ["x:Name"]; + string name = attr.Value; + string ns = GetNamespace (node); + string member_type = node.LocalName; + + if (ns != null) + member_type = String.Concat (ns, ".", member_type); + + CodeTypeReference type = new CodeTypeReference (member_type); + if (ns != null) + type.Options |= CodeTypeReferenceOptions.GlobalReference; + + res [name] = type; + } + + return res; + } + + /* + private static Hashtable GetKeysAndTypes (XmlNode root, XmlNamespaceManager nsmgr) + { + Hashtable res = new Hashtable (); + + XmlNodeList keys = root.SelectNodes ("//*[@x:Key]", nsmgr); + foreach (XmlNode node in keys) { + + // Don't take the root canvas + if (node == root) + continue; + + XmlAttribute attr = node.Attributes ["x:Key"]; + string key = attr.Value; + string ns = GetNamespace (node); + string member_type = node.LocalName; + + if (ns != null) + member_type = String.Concat (ns, ".", member_type); + + res [key] = member_type; + } + + return res; + } + */ + + internal static string GetNamespace (XmlNode node) + { + if (!IsCustom (node.NamespaceURI)) + return null; + + return ParseNamespaceFromXmlns (node.NamespaceURI); + } + + private static bool IsCustom (string ns) + { + switch (ns) { + case "http://schemas.microsoft.com/winfx/2006/xaml": + case "http://schemas.microsoft.com/winfx/2006/xaml/presentation": + case "http://schemas.microsoft.com/client/2007": + return false; + } + + return true; + } + + private static string ParseNamespaceFromXmlns (string xmlns) + { + string type_name = null; + string ns = null; + string asm = null; + + ParseXmlns (xmlns, out type_name, out ns, out asm); + + return ns; + } + +// private static string ParseTypeFromXmlns (string xmlns) +// { +// string type_name = null; +// string ns = null; +// string asm = null; +// +// ParseXmlns (xmlns, out type_name, out ns, out asm); +// +// return type_name; +// } + + internal static void ParseXmlns (string xmlns, out string type_name, out string ns, out string asm) + { + type_name = null; + ns = null; + asm = null; + + string [] decls = xmlns.Split (';'); + foreach (string decl in decls) { + if (decl.StartsWith ("clr-namespace:")) { + ns = decl.Substring (14, decl.Length - 14); + continue; + } + if (decl.StartsWith ("assembly=")) { + asm = decl.Substring (9, decl.Length - 9); + continue; + } + int nsind = decl.LastIndexOf ("."); + if (nsind > 0) { + ns = decl.Substring (0, nsind); + type_name = decl.Substring (nsind + 1, decl.Length - nsind - 1); + } else { + type_name = decl; + } + } + } + } + +} diff --git a/mcs/class/System.ComponentModel.Composition/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs b/mcs/class/System.ComponentModel.Composition/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs index ae15ef4b290..616ef4577a4 100644 --- a/mcs/class/System.ComponentModel.Composition/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs +++ b/mcs/class/System.ComponentModel.Composition/src/ComponentModel/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs @@ -468,7 +468,7 @@ namespace System.ComponentModel.Composition.Hosting private string[] GetFiles() { string[] files = Directory.GetFiles(this._fullPath, this._searchPattern); - return Array.ConvertAll(files, (file) => file.ToUpperInvariant()); + return Array.ConvertAll(files, (file) => file); } private static string GetFullPath(string path) @@ -478,7 +478,7 @@ namespace System.ComponentModel.Composition.Hosting path = IOPath.Combine(AppDomain.CurrentDomain.BaseDirectory, path); } - return IOPath.GetFullPath(path).ToUpperInvariant(); + return IOPath.GetFullPath(path); } private void Initialize(string path, string searchPattern) diff --git a/mcs/class/System.Core/Assembly/AssemblyInfo.cs b/mcs/class/System.Core/Assembly/AssemblyInfo.cs index 0ccc1d0801e..d2adf2ccf02 100644 --- a/mcs/class/System.Core/Assembly/AssemblyInfo.cs +++ b/mcs/class/System.Core/Assembly/AssemblyInfo.cs @@ -73,3 +73,8 @@ using System.Runtime.InteropServices; // Extension attribute should be added by compiler [assembly: SecurityPermission (SecurityAction.RequestMinimum, SkipVerification = true)] + +#if NET_4_0 +[assembly: TypeForwardedTo (typeof (System.Security.Cryptography.Aes))] +#endif + diff --git a/mcs/class/System.Core/Assembly/ChangeLog b/mcs/class/System.Core/Assembly/ChangeLog index 02c2a5d0dfa..640ce64edd9 100644 --- a/mcs/class/System.Core/Assembly/ChangeLog +++ b/mcs/class/System.Core/Assembly/ChangeLog @@ -1,3 +1,7 @@ +2010-03-18 Sebastien Pouliot + + * AssemblyInfo.cs: Add TypeForwardTo for Aes on NET_4_0 + 2008-08-08 Sebastien Pouliot * AssemblyInfo.cs: Remove a few attributes for SL2 diff --git a/mcs/class/System.Core/ChangeLog b/mcs/class/System.Core/ChangeLog index 5bddef0064e..69b587d7847 100644 --- a/mcs/class/System.Core/ChangeLog +++ b/mcs/class/System.Core/ChangeLog @@ -1,3 +1,24 @@ +2010-04-23 Rolf Bjarne Kvinge + + * moonlight_raw_System.Core.dll.sources: Include Lazy.cs and + LazyThreadSafetyMode.cs from corlib in here. + +2010-04-15 Jérémie Laval + + * System.Core_test.dll.sources: Add PLinq unit tests + +2010-04-15 Jérémie Laval + + * net_4_0_System.Core.dll.sources: add PLinq sources + +2010-04-06 Jb Evain + + * net_4_0_System.Core.dll.sources: add files to support ToQueryable. + +2010-03-16 Jb Evain + + * net_2_1_*.dll.sources: rename to moonlight_*.dll.sources. + 2009-12-17 Marek Safar * Makefile: Compile itself using bootstrap System.Core. diff --git a/mcs/class/System.Core/Makefile b/mcs/class/System.Core/Makefile index dde17448c70..893de76b60b 100644 --- a/mcs/class/System.Core/Makefile +++ b/mcs/class/System.Core/Makefile @@ -14,7 +14,7 @@ ifeq (4.0, $(FRAMEWORK_VERSION)) LIB_MCS_FLAGS += -d:CODEPLEX_40 endif -FULL_PROFILE := $(filter net_2_0 net_4_0 net_2_1_raw monotouch, $(PROFILE)) +FULL_PROFILE := $(filter net_2_0 net_4_0 moonlight_raw monotouch, $(PROFILE)) ifdef FULL_PROFILE LIBRARY_COMPILE = $(BOOT_COMPILE) endif diff --git a/mcs/class/System.Core/System.Collections.Generic/ChangeLog b/mcs/class/System.Core/System.Collections.Generic/ChangeLog index d89d3739964..95a52e75441 100644 --- a/mcs/class/System.Core/System.Collections.Generic/ChangeLog +++ b/mcs/class/System.Core/System.Collections.Generic/ChangeLog @@ -1,3 +1,7 @@ +2010-04-16 Sebastien Pouliot + + * HashSet.cs: Implement ISet in MOONLIGHT too + 2010-02-13 Gonzalo Paniagua Javier * HashSet.cs: fix and test for bug #579791. Patch from Tiaan diff --git a/mcs/class/System.Core/System.Collections.Generic/HashSet.cs b/mcs/class/System.Core/System.Collections.Generic/HashSet.cs index 5a382c1df63..157ca51fcb7 100644 --- a/mcs/class/System.Core/System.Collections.Generic/HashSet.cs +++ b/mcs/class/System.Core/System.Collections.Generic/HashSet.cs @@ -44,7 +44,7 @@ namespace System.Collections.Generic { [DebuggerDisplay ("Count={Count}")] [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))] public class HashSet : ICollection, ISerializable, IDeserializationCallback -#if NET_4_0 +#if NET_4_0 || MOONLIGHT , ISet #endif { diff --git a/mcs/class/System.Core/System.Core_test.dll.sources b/mcs/class/System.Core/System.Core_test.dll.sources index dffaf5eb7a9..58a8fac036f 100644 --- a/mcs/class/System.Core/System.Core_test.dll.sources +++ b/mcs/class/System.Core/System.Core_test.dll.sources @@ -78,3 +78,5 @@ System.Security.Cryptography/SHA384CryptoServiceProviderTest.cs System.Security.Cryptography/SHA512CngTest.cs System.Security.Cryptography/SHA512CryptoServiceProviderTest.cs System.Runtime.CompilerServices/DynamicAttributeTest.cs +System.Linq/ParallelEnumerableTests.cs +System.Linq/ParallelTestHelper.cs diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/ChangeLog b/mcs/class/System.Core/System.IO.MemoryMappedFiles/ChangeLog index 1466f2eb6cc..461c74fddc7 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/ChangeLog +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/ChangeLog @@ -1,3 +1,15 @@ +2010-04-15 Jb Evain + + * MemoryMappedFile.cs: implement CreateOrOpen. + +2010-04-14 Jb Evain + + * MemoryMappedViewAccessor.cs + * MemoryMappedFile.cs + * MemoryMappedViewStream.cs: + Properly retrieve the size of the mmapped file. Fixes the + unit tests. + 2009-12-14 Miguel de Icaza * MemoryMappedFile.cs: Make this by default use the native diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs index 7376bc5ae06..346ca16c311 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs @@ -69,7 +69,6 @@ namespace System.IO.MemoryMappedFiles return CreateFromFile (path, FileMode.Open, null, 0, MemoryMappedFileAccess.ReadWrite); } - public static MemoryMappedFile CreateFromFile (string path, FileMode mode) { return CreateFromFile (path, mode, null, 0, MemoryMappedFileAccess.ReadWrite); @@ -224,14 +223,16 @@ namespace System.IO.MemoryMappedFiles return CreateFromFile (mapName, FileMode.CreateNew, mapName, capacity, access); } - [MonoTODO] - public static MemoryMappedFile CreateOrOpen (string mapName, long capacity) { - throw new NotImplementedException (); + [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")] + public static MemoryMappedFile CreateOrOpen (string mapName, long capacity) + { + return CreateOrOpen (mapName, capacity, MemoryMappedFileAccess.ReadWrite); } - [MonoTODO] - public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access) { - throw new NotImplementedException (); + [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")] + public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access) + { + return CreateFromFile (mapName, FileMode.OpenOrCreate, mapName, capacity, access); } /* @@ -333,7 +334,7 @@ namespace System.IO.MemoryMappedFiles } } - internal static unsafe void MapPosix (int file_handle, long offset, long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff) + internal static unsafe void MapPosix (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff) { if (pagesize == 0) pagesize = Syscall.getpagesize (); diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs index e1fc156c2a3..ae9b4541575 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs @@ -73,7 +73,7 @@ namespace System.IO.MemoryMappedFiles { int offset_diff; - MemoryMappedFile.MapPosix (file_handle, offset, size, access, out mmap_addr, out offset_diff); + MemoryMappedFile.MapPosix (file_handle, offset, ref size, access, out mmap_addr, out offset_diff); handle = new SafeMemoryMappedViewHandle ((IntPtr)((long)mmap_addr + offset_diff), size); Initialize (handle, 0, size, ToFileAccess (access)); diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs index 2bf2f8a0084..3abd26cb3d4 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs @@ -53,8 +53,7 @@ namespace System.IO.MemoryMappedFiles { int offset_diff; mmap_size = (ulong) size; - MemoryMappedFile.MapPosix (fd, offset, size, access, out mmap_addr, out offset_diff); - + MemoryMappedFile.MapPosix (fd, offset, ref size, access, out mmap_addr, out offset_diff); FileAccess faccess; switch (access) { @@ -94,4 +93,4 @@ namespace System.IO.MemoryMappedFiles } } -#endif \ No newline at end of file +#endif diff --git a/mcs/class/System.Core/System.Linq/ChangeLog b/mcs/class/System.Core/System.Linq/ChangeLog index a7c2221dc4c..09221b2afb3 100644 --- a/mcs/class/System.Core/System.Linq/ChangeLog +++ b/mcs/class/System.Core/System.Linq/ChangeLog @@ -1,3 +1,57 @@ +2010-04-15 Jérémie Laval + + * OrderedParallelQuery.cs: + * ParallelEnumerable.cs: + * ParallelExecuter.cs: + * ParallelPartitioner.cs: + * ParallelQuery.cs: + * ParallelQueryEnumerator.cs: First check-in of PLinq + +2010-04-15 Jérémie Laval + + * ParallelExecutionMode.cs: + * ParallelMergeOptions.cs: Initial check-in of PLinq (enum) + +2010-04-12 Miguel de Icaza + + * Enumerable.cs: Jumbo patch that inlines code, mainly for the AOT + scenario where we our compiler cant infer the extra layer of + indirection of a lambda function. + + But additionally, since we lack support for our JIT to inline + intermediate delegate calls, it should save memory and run + faster. + +2010-04-07 Jb Evain + + * EnumerableExecutor.cs: make ctor protected. + +2010-04-07 Jb Evain + + * EnumerableQuery_T.cs: implement. + +2010-04-07 Jb Evain + + * EnumerableQuery.cs: make ctor protected. + +2010-04-06 Jb Evain + + * QueryableEnumerable.cs: make TransformQueryable work on net_4_0. + +2010-04-06 Jb Evain + + * QueryableTransformer.cs: use factory method that work for all + ET implementations. + +2010-03-30 Jb Evain + + * Queryable.cs: implement Zip for net_4_0. + +2010-03-24 Jb Evain + + * SortSequenceContext.cs: Fix OrderByDescending stability. + Based on a patch by Richard Kiene . + 2010-02-23 Marek Safar * Enumerable.cs: Implement Zip. diff --git a/mcs/class/System.Core/System.Linq/Enumerable.cs b/mcs/class/System.Core/System.Linq/Enumerable.cs index bda1c0551d6..56018f49d7d 100644 --- a/mcs/class/System.Core/System.Linq/Enumerable.cs +++ b/mcs/class/System.Core/System.Linq/Enumerable.cs @@ -162,48 +162,77 @@ namespace System.Linq public static double Average (this IEnumerable source) { - return Average (source, (a, b) => a + b, (a, b) => (double) a / (double) b); + Check.Source (source); + + long total = 0; + int count = 0; + foreach (var element in source){ + total = checked (total + element); + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / (double) count; } public static double Average (this IEnumerable source) { - return Average (source, (a, b) => a + b, (a, b) => (double) a / (double) b); + Check.Source (source); + + long total = 0; + long count = 0; + foreach (var element in source){ + total += element; + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / (double) count; } public static double Average (this IEnumerable source) { - return Average (source, (a, b) => a + b, (a, b) => a / b); + Check.Source (source); + + double total = 0; + long count = 0; + foreach (var element in source){ + total += element; + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / count; } public static float Average (this IEnumerable source) { - return Average (source, (a, b) => a + b, (a, b) => (float) a / (float) b); - } + Check.Source (source); - public static decimal Average (this IEnumerable source) - { - return Average (source, (a, b) => a + b, (a, b) => a / b); + float total = 0; + long count = 0; + foreach (var element in source){ + total += element; + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / count; } - static TResult Average (this IEnumerable source, - Func func, Func result) - where TElement : struct - where TAggregate : struct - where TResult : struct + public static decimal Average (this IEnumerable source) { Check.Source (source); - var total = default (TAggregate); - long counter = 0; - foreach (var element in source) { - total = func (total, element); - ++counter; + decimal total = 0; + long count = 0; + foreach (var element in source){ + total += element; + count++; } - - if (counter == 0) + if (count == 0) throw new InvalidOperationException (); - - return result (total, counter); + return total / count; } static TResult? AverageNullable (this IEnumerable source, @@ -234,105 +263,297 @@ namespace System.Linq { Check.Source (source); - return source.AverageNullable ((a, b) => a + b, (a, b) => (double) a / (double) b); + long total = 0; + long counter = 0; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + total = total + element.Value; + counter++; + } + + if (counter == 0) + return null; + + return new double? (total / (double) counter); } public static double? Average (this IEnumerable source) { Check.Source (source); - return source.AverageNullable ((a, b) => a + b, (a, b) => (double) a / b); + long total = 0; + long counter = 0; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + total = checked (total + element.Value); + counter++; + } + + if (counter == 0) + return null; + + return new double? (total / (double) counter); + } public static double? Average (this IEnumerable source) { Check.Source (source); - return source.AverageNullable ((a, b) => a + b, (a, b) => a / b); + double total = 0; + long counter = 0; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + total = total + element.Value; + counter++; + } + + if (counter == 0) + return null; + + return new double? (total / counter); + } public static decimal? Average (this IEnumerable source) { Check.Source (source); - return source.AverageNullable ((a, b) => a + b, (a, b) => a / b); + decimal total = 0; + long counter = 0; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + total = total + element.Value; + counter++; + } + + if (counter == 0) + return null; + + return new decimal? (total / counter); + } public static float? Average (this IEnumerable source) { Check.Source (source); - return source.AverageNullable ((a, b) => a + b, (a, b) => (float) a / (float) b); + float total = 0; + long counter = 0; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + total = total + element.Value; + counter++; + } + + if (counter == 0) + return null; + + return new float? (total / counter); + } public static double Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).Average ((a, b) => a + b, (a, b) => (double) a / (double) b); + long total = 0; + long count = 0; + foreach (var element in source){ + total += selector (element); + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / (double) count; } public static double? Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).AverageNullable ((a, b) => a + b, (a, b) => (double) a / (double) b); + long total = 0; + long counter = 0; + + foreach (var element in source) { + var value = selector (element); + if (!value.HasValue) + continue; + + total = total + value.Value; + counter++; + } + + if (counter == 0) + return null; + + return new double? (total / (double) counter); } public static double Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).Average ((a, b) => a + b, (a, b) => (double) a / (double) b); + long total = 0; + long count = 0; + foreach (var element in source){ + total = checked (total + selector (element)); + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / (double) count; + } public static double? Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).AverageNullable ((a, b) => a + b, (a, b) => (double) a / (double) b); + long total = 0; + long counter = 0; + + foreach (var element in source) { + var value = selector (element); + if (!value.HasValue) + continue; + + total = checked (total + value.Value); + counter++; + } + + if (counter == 0) + return null; + + return new double? (total / (double) counter); } public static double Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).Average ((a, b) => a + b, (a, b) => a / b); + double total = 0; + long count = 0; + foreach (var element in source){ + total += selector (element); + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / count; + } public static double? Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).AverageNullable ((a, b) => a + b, (a, b) => a / b); + double total = 0; + long counter = 0; + + foreach (var element in source) { + var value = selector (element); + if (!value.HasValue) + continue; + + total = total + value.Value; + counter++; + } + + if (counter == 0) + return null; + + return new double? (total / counter); + } public static float Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).Average ((a, b) => a + b, (a, b) => (float) a / (float) b); + float total = 0; + long count = 0; + foreach (var element in source){ + total += selector (element); + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / count; } public static float? Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).AverageNullable ((a, b) => a + b, (a, b) => (float) a / (float) b); + float total = 0; + long counter = 0; + + foreach (var element in source) { + var value = selector (element); + if (!value.HasValue) + continue; + + total = total + value.Value; + counter++; + } + + if (counter == 0) + return null; + + return new float? (total / counter); } public static decimal Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).Average ((a, b) => a + b, (a, b) => a / b); + decimal total = 0; + long count = 0; + foreach (var element in source){ + total += selector (element); + count++; + } + if (count == 0) + throw new InvalidOperationException (); + return total / count; } public static decimal? Average (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.Select (selector).AverageNullable ((a, b) => a + b, (a, b) => a / b); + decimal total = 0; + long counter = 0; + + foreach (var element in source) { + var value = selector (element); + if (!value.HasValue) + continue; + + total = total + value.Value; + counter++; + } + + if (counter == 0) + return null; + + return new decimal? (total / counter); } #endregion @@ -1027,200 +1248,289 @@ namespace System.Linq { Check.Source (source); - return Iterate (source, int.MinValue, (a, b) => Math.Max (a, b)); + bool empty = true; + var max = int.MinValue; + foreach (var element in source){ + max = Math.Max (element, max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static long Max (this IEnumerable source) { Check.Source (source); - return Iterate (source, long.MinValue, (a, b) => Math.Max (a, b)); + bool empty = true; + var max = long.MinValue; + foreach (var element in source){ + max = Math.Max (element, max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static double Max (this IEnumerable source) { Check.Source (source); - return Iterate (source, double.MinValue, (a, b) => Math.Max (a, b)); + bool empty = true; + var max = double.MinValue; + foreach (var element in source){ + max = Math.Max (element, max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static float Max (this IEnumerable source) { Check.Source (source); - return Iterate (source, float.MinValue, (a, b) => Math.Max (a, b)); + bool empty = true; + var max = float.MinValue; + foreach (var element in source){ + max = Math.Max (element, max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static decimal Max (this IEnumerable source) { Check.Source (source); - return Iterate (source, decimal.MinValue, (a, b) => Math.Max (a, b)); + bool empty = true; + var max = decimal.MinValue; + foreach (var element in source){ + max = Math.Max (element, max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static int? Max (this IEnumerable source) { Check.Source (source); - return IterateNullable (source, (a, b) => Math.Max (a, b)); - } - - public static long? Max (this IEnumerable source) - { - Check.Source (source); - - return IterateNullable (source, (a, b) => Math.Max (a, b)); - } - - public static double? Max (this IEnumerable source) - { - Check.Source (source); + bool empty = true; + var max = int.MinValue; + + foreach (var element in source) { + if (!element.HasValue) + continue; - return IterateNullable (source, (a, b) => Math.Max (a, b)); - } + max = Math.Max (element.Value, max); + empty = false; + } - public static float? Max (this IEnumerable source) - { - Check.Source (source); + if (empty) + return null; - return IterateNullable (source, (a, b) => Math.Max (a, b)); + return max; } - public static decimal? Max (this IEnumerable source) + public static long? Max (this IEnumerable source) { Check.Source (source); - return IterateNullable (source, (a, b) => Math.Max (a, b)); - } - - static T? IterateNullable (IEnumerable source, Func selector) where T : struct - { bool empty = true; - T? value = null; + var max = long.MinValue; + foreach (var element in source) { if (!element.HasValue) continue; - if (!value.HasValue) - value = element.Value; - else - value = selector (element.Value, value.Value); - + max = Math.Max (element.Value, max); empty = false; } if (empty) return null; - return value; + return max; } - static TRet? IterateNullable ( - IEnumerable source, - Func source_selector, - Func selector) where TRet : struct + public static double? Max (this IEnumerable source) { + Check.Source (source); + bool empty = true; - TRet? value = null; + var max = double.MinValue; + foreach (var element in source) { - TRet? item = source_selector (element); - - if (!value.HasValue) - value = item; - else if (selector (item, value)) - value = item; + if (!element.HasValue) + continue; + max = Math.Max (element.Value, max); empty = false; } if (empty) return null; - return value; + return max; } - static TSource IterateNullable (IEnumerable source, Func selector) + public static float? Max (this IEnumerable source) { - var value = default (TSource); + Check.Source (source); + bool empty = true; + var max = float.MinValue; + foreach (var element in source) { - if (element == null) + if (!element.HasValue) continue; - if (value == null || selector (element, value)) - value = element; + max = Math.Max (element.Value, max); + empty = false; } - return value; + if (empty) + return null; + + return max; } - static TSource IterateNonNullable (IEnumerable source, Func selector) + public static decimal? Max (this IEnumerable source) { - var value = default (TSource); + Check.Source (source); + bool empty = true; + var max = decimal.MinValue; + foreach (var element in source) { - if (empty) { - value = element; - empty = false; + if (!element.HasValue) continue; - } - if (selector (element, value)) - value = element; + max = Math.Max (element.Value, max); + empty = false; } if (empty) - throw new InvalidOperationException (); + return null; - return value; + return max; } + // TODO: test nullable and non-nullable public static TSource Max (this IEnumerable source) { Check.Source (source); var comparer = Comparer.Default; - Func compare = (a, b) => comparer.Compare (a, b) > 0; - if (default (TSource) == null) - return IterateNullable (source, compare); - - return IterateNonNullable (source, compare); - } + TSource max = default (TSource); + + if (default (TSource) == null){ + foreach (var element in source) { + if (element == null) + continue; - public static int Max (this IEnumerable source, Func selector) - { - Check.SourceAndSelector (source, selector); + if (max == null || comparer.Compare (element, max) > 0) + max = element; + } + } else { + bool empty = true; + foreach (var element in source) { + if (empty){ + max = element; + empty = false; + continue; + } + if (comparer.Compare (element, max) > 0) + max = element; + } + if (empty) + throw new InvalidOperationException (); + } + return max; + } + + public static int Max (this IEnumerable source, Func selector) + { + Check.SourceAndSelector (source, selector); - return Iterate (source, int.MinValue, (a, b) => Math.Max (selector (a), b)); + bool empty = true; + var max = int.MinValue; + foreach (var element in source){ + max = Math.Max (selector (element), max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static long Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, long.MinValue, (a, b) => Math.Max (selector (a), b)); + bool empty = true; + var max = long.MinValue; + foreach (var element in source){ + max = Math.Max (selector (element), max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static double Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, double.MinValue, (a, b) => Math.Max (selector (a), b)); + bool empty = true; + var max = double.MinValue; + foreach (var element in source){ + max = Math.Max (selector (element), max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static float Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, float.MinValue, (a, b) => Math.Max (selector (a), b)); + bool empty = true; + var max = float.MinValue; + foreach (var element in source){ + max = Math.Max (selector (element), max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } public static decimal Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, decimal.MinValue, (a, b) => Math.Max (selector (a), b)); + bool empty = true; + var max = decimal.MinValue; + foreach (var element in source){ + max = Math.Max (selector (element), max); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return max; } static U Iterate (IEnumerable source, U initValue, Func selector) @@ -1241,41 +1551,112 @@ namespace System.Linq { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a > b); + bool empty = true; + int? max = null; + foreach (var element in source) { + int? item = selector (element); + + if (!max.HasValue) + max = item; + else if (item > max) + max = item; + empty = false; + } + + if (empty) + return null; + return max; } public static long? Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a > b); + bool empty = true; + long? max = null; + foreach (var element in source) { + long? item = selector (element); + + if (!max.HasValue) + max = item; + else if (item > max) + max = item; + empty = false; + } + + if (empty) + return null; + return max; } public static double? Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a > b); + bool empty = true; + double? max = null; + foreach (var element in source) { + double? item = selector (element); + + if (!max.HasValue) + max = item; + else if (item > max) + max = item; + empty = false; + } + + if (empty) + return null; + return max; } public static float? Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a > b); + bool empty = true; + float? max = null; + foreach (var element in source) { + float? item = selector (element); + + if (!max.HasValue) + max = item; + else if (item > max) + max = item; + empty = false; + } + + if (empty) + return null; + return max; } public static decimal? Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a > b); + bool empty = true; + decimal? max = null; + foreach (var element in source) { + decimal? item = selector (element); + + if (!max.HasValue) + max = item; + else if (item > max) + max = item; + empty = false; + } + + if (empty) + return null; + return max; } public static TResult Max (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); + // TODO: inline return source.Select (selector).Max (); } @@ -1287,70 +1668,180 @@ namespace System.Linq { Check.Source (source); - return Iterate (source, int.MaxValue, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = int.MaxValue; + foreach (var element in source){ + min = Math.Min (element, min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static long Min (this IEnumerable source) { Check.Source (source); - return Iterate (source, long.MaxValue, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = long.MaxValue; + foreach (var element in source){ + min = Math.Min (element, min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static double Min (this IEnumerable source) { Check.Source (source); - return Iterate (source, double.MaxValue, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = double.MaxValue; + foreach (var element in source){ + min = Math.Min (element, min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static float Min (this IEnumerable source) { Check.Source (source); - return Iterate (source, float.MaxValue, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = float.MaxValue; + foreach (var element in source){ + min = Math.Min (element, min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static decimal Min (this IEnumerable source) { Check.Source (source); - return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = decimal.MaxValue; + foreach (var element in source){ + min = Math.Min (element, min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static int? Min (this IEnumerable source) { Check.Source (source); - return IterateNullable (source, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = int.MaxValue; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + min = Math.Min (element.Value, min); + empty = false; + } + + if (empty) + return null; + + return min; } public static long? Min (this IEnumerable source) { Check.Source (source); - return IterateNullable (source, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = long.MaxValue; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + min = Math.Min (element.Value, min); + empty = false; + } + + if (empty) + return null; + + return min; } public static double? Min (this IEnumerable source) { Check.Source (source); - return IterateNullable (source, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = double.MaxValue; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + min = Math.Min (element.Value, min); + empty = false; + } + + if (empty) + return null; + + return min; } public static float? Min (this IEnumerable source) { Check.Source (source); - return IterateNullable (source, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = float.MaxValue; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + min = Math.Min (element.Value, min); + empty = false; + } + + if (empty) + return null; + + return min; } public static decimal? Min (this IEnumerable source) { Check.Source (source); - return IterateNullable (source, (a, b) => Math.Min (a, b)); + bool empty = true; + var min = decimal.MaxValue; + + foreach (var element in source) { + if (!element.HasValue) + continue; + + min = Math.Min (element.Value, min); + empty = false; + } + + if (empty) + return null; + + return min; } public static TSource Min (this IEnumerable source) @@ -1358,88 +1849,219 @@ namespace System.Linq Check.Source (source); var comparer = Comparer.Default; - Func compare = (a, b) => comparer.Compare (a, b) < 0; - if (default (TSource) == null) - return IterateNullable (source, compare); + TSource min = default (TSource); + + if (default (TSource) == null){ + foreach (var element in source) { + if (element == null) + continue; - return IterateNonNullable (source, compare); + if (min == null || comparer.Compare (element, min) < 0) + min = element; + } + } else { + bool empty = true; + foreach (var element in source) { + if (empty){ + min = element; + empty = false; + continue; + } + if (comparer.Compare (element, min) < 0) + min = element; + } + if (empty) + throw new InvalidOperationException (); + } + return min; } public static int Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, int.MaxValue, (a, b) => Math.Min (selector (a), b)); + bool empty = true; + var min = int.MaxValue; + foreach (var element in source){ + min = Math.Min (selector (element), min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static long Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, long.MaxValue, (a, b) => Math.Min (selector (a), b)); + bool empty = true; + var min = long.MaxValue; + foreach (var element in source){ + min = Math.Min (selector (element), min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static double Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, double.MaxValue, (a, b) => Math.Min (selector (a), b)); + bool empty = true; + var min = double.MaxValue; + foreach (var element in source){ + min = Math.Min (selector (element), min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static float Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, float.MaxValue, (a, b) => Math.Min (selector (a), b)); + bool empty = true; + var min = float.MaxValue; + foreach (var element in source){ + min = Math.Min (selector (element), min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static decimal Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Iterate (source, decimal.MaxValue, (a, b) => Math.Min (selector (a), b)); + bool empty = true; + var min = decimal.MaxValue; + foreach (var element in source){ + min = Math.Min (selector (element), min); + empty = false; + } + if (empty) + throw new InvalidOperationException (); + return min; } public static int? Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a < b); + bool empty = true; + int? min = null; + foreach (var element in source) { + int? item = selector (element); + + if (!min.HasValue) + min = item; + else if (item < min) + min = item; + empty = false; + } + + if (empty) + return null; + return min; } public static long? Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a < b); + bool empty = true; + long? min = null; + foreach (var element in source) { + long? item = selector (element); + + if (!min.HasValue) + min = item; + else if (item < min) + min = item; + empty = false; + } + + if (empty) + return null; + return min; } public static float? Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a < b); + bool empty = true; + float? min = null; + foreach (var element in source) { + float? item = selector (element); + + if (!min.HasValue) + min = item; + else if (item < min) + min = item; + empty = false; + } + + if (empty) + return null; + return min; } public static double? Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a < b); + bool empty = true; + double? min = null; + foreach (var element in source) { + double? item = selector (element); + + if (!min.HasValue) + min = item; + else if (item < min) + min = item; + empty = false; + } + + if (empty) + return null; + return min; } public static decimal? Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return IterateNullable (source, selector, (a, b) => a < b); + bool empty = true; + decimal? min = null; + foreach (var element in source) { + decimal? item = selector (element); + + if (!min.HasValue) + min = item; + else if (item < min) + min = item; + empty = false; + } + + if (empty) + return null; + return min; } public static TResult Min (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); + // TODO: inline return source.Select (selector).Min (); } @@ -1803,175 +2425,231 @@ namespace System.Linq public static int Sum (this IEnumerable source) { Check.Source (source); - - return Sum (source, (a, b) => checked (a + b)); + int total = 0; + + foreach (var element in source) + total = checked (total + element); + return total; } public static int? Sum (this IEnumerable source) { Check.Source (source); - return source.SumNullable (0, (total, element) => element.HasValue ? checked (total + element) : total); + int total = 0; + foreach (var element in source) { + if (element.HasValue) + total = checked (total + element.Value); + } + return total; } public static int Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); + int total = 0; + + foreach (var element in source) + total = checked (total + selector (element)); - return Sum (source, (a, b) => checked (a + selector (b))); + return total; } public static int? Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.SumNullable (0, (a, b) => { - var value = selector (b); - return value.HasValue ? checked (a + value.Value) : a; - }); + int total = 0; + foreach (var element in source) { + var value = selector (element); + if (value.HasValue) + total = checked (total + value.Value); + } + return total; } public static long Sum (this IEnumerable source) { Check.Source (source); - return Sum (source, (a, b) => checked (a + b)); + long total = 0; + + foreach (var element in source) + total = checked (total + element); + return total; } public static long? Sum (this IEnumerable source) { Check.Source (source); - return source.SumNullable (0, (total, element) => element.HasValue ? checked (total + element) : total); + long total = 0; + foreach (var element in source) { + if (element.HasValue) + total = checked (total + element.Value); + } + return total; } public static long Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Sum (source, (a, b) => checked (a + selector (b))); + long total = 0; + foreach (var element in source) + total = checked (total + selector (element)); + return total; } public static long? Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.SumNullable (0, (a, b) => { - var value = selector (b); - return value.HasValue ? checked (a + value.Value) : a; - }); + long total = 0; + foreach (var element in source) { + var value = selector (element); + if (value.HasValue) + total = checked (total + value.Value); + } + return total; } public static double Sum (this IEnumerable source) { Check.Source (source); - return Sum (source, (a, b) => checked (a + b)); + double total = 0; + + foreach (var element in source) + total = checked (total + element); + return total; } public static double? Sum (this IEnumerable source) { Check.Source (source); - return source.SumNullable (0, (total, element) => element.HasValue ? checked (total + element) : total); + double total = 0; + foreach (var element in source) { + if (element.HasValue) + total = checked (total + element.Value); + } + return total; } public static double Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return Sum (source, (a, b) => checked (a + selector (b))); + double total = 0; + + foreach (var element in source) + total = checked (total + selector (element)); + return total; } public static double? Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.SumNullable (0, (a, b) => { - var value = selector (b); - return value.HasValue ? checked (a + value.Value) : a; - }); + double total = 0; + foreach (var element in source) { + var value = selector (element); + if (value.HasValue) + total = checked (total + value.Value); + } + return total; } public static float Sum (this IEnumerable source) { Check.Source (source); - return Sum (source, (a, b) => checked (a + b)); + float total = 0; + + foreach (var element in source) + total = checked (total + element); + return total; } public static float? Sum (this IEnumerable source) { Check.Source (source); - return source.SumNullable (0, (total, element) => element.HasValue ? checked (total + element) : total); + float total = 0; + foreach (var element in source) { + if (element.HasValue) + total = checked (total + element.Value); + } + return total; + } public static float Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - - return Sum (source, (a, b) => checked (a + selector (b))); + float total = 0; + foreach (var element in source) + total = checked (total + selector (element)); + return total; } public static float? Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.SumNullable (0, (a, b) => { - var value = selector (b); - return value.HasValue ? checked (a + value.Value) : a; - }); + float total = 0; + foreach (var element in source) { + var value = selector (element); + if (value.HasValue) + total = checked (total + value.Value); + } + return total; } public static decimal Sum (this IEnumerable source) { Check.Source (source); - - return Sum (source, (a, b) => checked (a + b)); + decimal total = 0; + + foreach (var element in source) + total = checked (total + element); + return total; } public static decimal? Sum (this IEnumerable source) { Check.Source (source); - return source.SumNullable (0, (total, element) => element.HasValue ? checked (total + element) : total); + decimal total = 0; + foreach (var element in source) { + if (element.HasValue) + total = checked (total + element.Value); + } + return total; + } public static decimal Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - - return Sum (source, (a, b) => checked (a + selector (b))); + decimal total = 0; + + foreach (var element in source) + total = checked (total + selector (element)); + return total; } public static decimal? Sum (this IEnumerable source, Func selector) { Check.SourceAndSelector (source, selector); - return source.SumNullable (0, (a, b) => { - var value = selector (b); - return value.HasValue ? checked (a + value.Value) : a; - }); - } - - static TR Sum (this IEnumerable source, Func selector) - { - TR total = default (TR); + decimal total = 0; foreach (var element in source) { - total = selector (total, element); + var value = selector (element); + if (value.HasValue) + total = checked (total + value.Value); } - - return total; - } - - static TR SumNullable (this IEnumerable source, TR zero, Func selector) - { - TR total = zero; - foreach (var element in source) { - total = selector (total, element); - } - return total; } diff --git a/mcs/class/System.Core/System.Linq/EnumerableExecutor.cs b/mcs/class/System.Core/System.Linq/EnumerableExecutor.cs index 836fe1e0d3c..7d7b16abbf0 100644 --- a/mcs/class/System.Core/System.Linq/EnumerableExecutor.cs +++ b/mcs/class/System.Core/System.Linq/EnumerableExecutor.cs @@ -32,6 +32,9 @@ namespace System.Linq { public abstract class EnumerableExecutor { + protected EnumerableExecutor () + { + } } } diff --git a/mcs/class/System.Core/System.Linq/EnumerableQuery.cs b/mcs/class/System.Core/System.Linq/EnumerableQuery.cs index beb420ab0c7..3ead6e60bad 100644 --- a/mcs/class/System.Core/System.Linq/EnumerableQuery.cs +++ b/mcs/class/System.Core/System.Linq/EnumerableQuery.cs @@ -32,6 +32,9 @@ namespace System.Linq { public abstract class EnumerableQuery { + protected EnumerableQuery () + { + } } } diff --git a/mcs/class/System.Core/System.Linq/EnumerableQuery_T.cs b/mcs/class/System.Core/System.Linq/EnumerableQuery_T.cs index 8120f2a6769..d610d2fc58f 100644 --- a/mcs/class/System.Core/System.Linq/EnumerableQuery_T.cs +++ b/mcs/class/System.Core/System.Linq/EnumerableQuery_T.cs @@ -3,6 +3,7 @@ // // Authors: // Marek Safar +// Jb Evain // // Copyright (C) 2009 Novell, Inc (http://www.novell.com) // @@ -28,19 +29,71 @@ #if NET_4_0 -using System.Linq.Expressions; +using System.Collections; using System.Collections.Generic; +using System.Linq.Expressions; namespace System.Linq { - public class EnumerableQuery : EnumerableQuery + public class EnumerableQuery : EnumerableQuery, IOrderedQueryable, IQueryable, IQueryProvider { + QueryableEnumerable queryable; + + public Type ElementType { + get { return queryable.ElementType; } + } + + public Expression Expression { + get { return queryable.Expression; } + } + + public IQueryProvider Provider { + get { return queryable; } + } + public EnumerableQuery (Expression expression) { + queryable = new QueryableEnumerable (expression); + } + + public EnumerableQuery (IEnumerable enumerable) + { + queryable = new QueryableEnumerable (enumerable); } - - public EnumerableQuery (IEnumerable expression) + + public IEnumerable GetEnumerable () + { + return queryable.GetEnumerable (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return queryable.GetEnumerator (); + } + + public IEnumerator GetEnumerator () + { + return queryable.GetEnumerator (); + } + + public IQueryable CreateQuery (Expression expression) + { + return queryable.CreateQuery (expression); + } + + public object Execute (Expression expression) + { + return queryable.Execute (expression); + } + + public IQueryable CreateQuery (Expression expression) + { + return new EnumerableQuery (expression); + } + + public TResult Execute (Expression expression) { + return queryable.Execute (expression); } } } diff --git a/mcs/class/System.Core/System.Linq/Internal/AggregationList.cs b/mcs/class/System.Core/System.Linq/Internal/AggregationList.cs new file mode 100644 index 00000000000..50bee2bf317 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/AggregationList.cs @@ -0,0 +1,135 @@ +#if NET_4_0 +// +// AggregationList.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class AggregationList : IList + { + readonly IList> listes; + readonly int count; + + internal AggregationList (IList> listes) + { + this.listes = listes; + foreach (var l in listes) + count += l.Count; + } + + public int IndexOf (T item) + { + throw new NotImplementedException(); + } + + public void Insert (int index, T item) + { + throw new NotImplementedException(); + } + + public void RemoveAt (int index) + { + throw new NotImplementedException(); + } + + public T this[int index] { + get { + int listIndex, newIndex; + GetModifiedIndexes (index, out listIndex, out newIndex); + + return listes[listIndex][newIndex]; + } + set { + throw new NotImplementedException(); + } + } + + void GetModifiedIndexes (int index, out int listIndex, out int newIndex) + { + listIndex = 0; + newIndex = index; + + while (newIndex >= listes[listIndex].Count) { + newIndex -= listes[listIndex].Count; + listIndex++; + + if (listIndex > listes.Count) + throw new ArgumentOutOfRangeException (); + } + } + + public void Add (T item) + { + throw new NotImplementedException(); + } + + public void Clear () + { + throw new NotImplementedException(); + } + + public bool Contains (T item) + { + throw new NotImplementedException(); + } + + public void CopyTo (T[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public bool Remove (T item) + { + throw new NotImplementedException(); + } + + public int Count { + get { + return count; + } + } + + public bool IsReadOnly { + get { + return true; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/ChangeLog b/mcs/class/System.Core/System.Linq/Internal/ChangeLog new file mode 100644 index 00000000000..e7aa1984431 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/ChangeLog @@ -0,0 +1,12 @@ +2010-04-15 Jérémie Laval + + * AggregationList.cs: + * ConcurrentGrouping.cs: + * ConcurrentLookup.cs: + * OrderingEnumerator.cs: + * ParallelQuickSort.cs: + * RangeList.cs: + * RepeatList.cs: + * ReverseList.cs: + * StripPartitioner.cs: Initial check-in of PLinq + diff --git a/mcs/class/System.Core/System.Linq/Internal/ConcurrentGrouping.cs b/mcs/class/System.Core/System.Linq/Internal/ConcurrentGrouping.cs new file mode 100644 index 00000000000..f1cdd3c61b4 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/ConcurrentGrouping.cs @@ -0,0 +1,65 @@ +#if NET_4_0 +// +// ConcurrentGrouping.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class ConcurrentGrouping : IGrouping + { + TKey key; + IEnumerable elements; + + internal ConcurrentGrouping (TKey key, IEnumerable elements) + { + this.key = key; + this.elements = elements; + } + + public TKey Key { + get { + return key; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return ((IEnumerable)elements).GetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return elements.GetEnumerator (); + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/ConcurrentLookup.cs b/mcs/class/System.Core/System.Linq/Internal/ConcurrentLookup.cs new file mode 100644 index 00000000000..a39ccb277d0 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/ConcurrentLookup.cs @@ -0,0 +1,117 @@ +#if NET_4_0 +// +// ConcurrentLookup.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class ConcurrentLookup : ILookup + { + ConcurrentDictionary> dictionary; + + private class AddSlot + { + TElement element; + + internal AddSlot (TElement element) + { + this.element = element; + } + + internal IEnumerable AddMethod (TKey key) + { + List list = new List (); + list.Add (element); + + return list; + } + + internal IEnumerable UpdateMethod (TKey key, IEnumerable old) + { + ICollection coll = (ICollection)old; + coll.Add (element); + + return coll; + } + } + + internal ConcurrentLookup (IEqualityComparer comparer) + { + this.dictionary = new ConcurrentDictionary> (comparer); + } + + internal void Add (TKey key, TElement element) + { + AddSlot slot = new AddSlot (element); + dictionary.AddOrUpdate (key, slot.AddMethod, slot.UpdateMethod); + } + + public bool Contains (TKey key) + { + return dictionary.ContainsKey (key); + } + + public IEnumerable this[TKey key] { + get { + return dictionary[key]; + } + } + + public int Count { + get { + return dictionary.Count; + } + } + + public IList Keys { + get { + return (IList)dictionary.Keys; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return (IEnumerator)GetEnumeratorInternal (); + } + + IEnumerator> IEnumerable>.GetEnumerator () + { + return GetEnumeratorInternal (); + } + + IEnumerator> GetEnumeratorInternal () + { + return dictionary.Select ((pair) => new ConcurrentGrouping (pair.Key, pair.Value)).GetEnumerator (); + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/OrderingEnumerator.cs b/mcs/class/System.Core/System.Linq/Internal/OrderingEnumerator.cs new file mode 100644 index 00000000000..61f0949d039 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/OrderingEnumerator.cs @@ -0,0 +1,144 @@ +#if NET_4_0 +// +// OrderingEnumerator.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + // Remove use of KeyedBuffer + /* Instead, we use a fixed array of nullables. The Add method put the object in its right slot based on the index. + * We use a barrier for synchronisation, each add check that the current range of index accepted in the array is correct + * and if not wait on the Barrier. The Barrier's generation index is used to calculate the next range. + * The IEnumerator interface simply skim the array in order and return the objects. + */ + internal class OrderingEnumerator : IEnumerator + { + readonly int num; + + public BlockingCollection> KeyedBuffer; + KeyValuePair?[] store; + + IEnumerator?> currEnum; + KeyValuePair curr; + + internal OrderingEnumerator (int num) + { + this.num = num; + KeyedBuffer = new BlockingCollection> (); + store = new KeyValuePair?[num]; + } + + public void Dispose () + { + + } + + public void Reset () + { + + } + + public bool MoveNext () + { + if (currEnum == null || !currEnum.MoveNext () || !currEnum.Current.HasValue) { + if (!UpdateCurrent ()) + return false; + } + + if (!currEnum.Current.HasValue) + return false; + + curr = currEnum.Current.Value; + + return true; + } + + public T Current { + get { + return curr.Value; + } + } + + object IEnumerator.Current { + get { + return curr.Value; + } + } + + bool UpdateCurrent () + { + if (KeyedBuffer.IsCompleted) + return false; + + if (KeyedBuffer.Count != num) { + SpinWait sw = new SpinWait (); + while (KeyedBuffer.Count < num && !KeyedBuffer.IsAddingCompleted) { + sw.SpinOnce (); + } + } + + // We gather the lot without removing it + int i = 0; + foreach (KeyValuePair item in KeyedBuffer.GetConsumingEnumerable ()) { + store[i] = item; + + if (++i == num || KeyedBuffer.IsCompleted) + break; + } + + for (int k = i; k < num; k++) { + store[k] = null; + } + + Array.Sort (store, ArraySort); + + currEnum = ((IEnumerable?>)store).GetEnumerator (); + + return currEnum.MoveNext (); + } + + int ArraySort (KeyValuePair? e1, KeyValuePair? e2) + { + if (!e1.HasValue) { + if (!e2.HasValue) + return 0; + + if (e2.HasValue) + return 1; + } + if (!e2.HasValue && e1.HasValue) + return -1; + + return e1.Value.Key.CompareTo (e2.Value.Key); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/ParallelQuickSort.cs b/mcs/class/System.Core/System.Linq/Internal/ParallelQuickSort.cs new file mode 100644 index 00000000000..52d841bfd25 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/ParallelQuickSort.cs @@ -0,0 +1,285 @@ +#if NET_4_0 +// +// ParallelQuickSort.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Collections; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; + +namespace System.Linq +{ + // HACK: ATM: parallelization of the sort is disabled as task + // add more overhead than gain + internal class ParallelQuickSort + { + readonly Comparison comparison; + readonly IList list; + readonly int[] indexes; + + class SortedCollection : IList + { + int[] indexes; + IList source; + + public SortedCollection (IList source, int[] indexes) + { + this.indexes = indexes; + this.source = source; + } + + public int IndexOf (T item) + { + throw new NotImplementedException(); + } + + public void Insert (int index, T item) + { + throw new NotImplementedException(); + } + + public void RemoveAt (int index) + { + throw new NotImplementedException(); + } + + public T this[int index] { + get { + return source[indexes[index]]; + } + set { + throw new NotImplementedException(); + } + } + + public void Add (T item) + { + throw new NotImplementedException(); + } + + public void Clear () + { + throw new NotImplementedException(); + } + + public bool Contains (T item) + { + throw new NotImplementedException(); + } + + public void CopyTo (T[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public bool Remove (T item) + { + throw new NotImplementedException(); + } + + public int Count { + get { + return source.Count; + } + } + + public bool IsReadOnly { + get { + return true; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + } + + private ParallelQuickSort (IList list, Comparison comparison) + { + this.comparison = comparison; + this.list = list; + this.indexes = CreateIndexes (list.Count); + } + + static int[] CreateIndexes (int length) + { + var indexes = new int[length]; + for (int i = 0; i < length; i++) + indexes [i] = i; + + return indexes; + } + + SortedCollection DoSort () + { + if (list.Count > 1) { + if (list.Count < 5) + InsertionSort (0, list.Count - 1); + else + Sort (0, list.Count - 1); + } + + return new SortedCollection (list, indexes); + } + + int Comparison (int index1, int index2) + { + return comparison (list[index1], list[index2]); + } + + void Sort (int left, int right) + { + if (left + 3 <= right) { + int l = left, r = right - 1, pivot = MedianOfThree (left, right); + while (true) { + while (Comparison (indexes [++l], pivot) < 0) { } + while (Comparison (indexes [--r], pivot) > 0) { } + if (l < r) + Swap (l, r); + else + break; + } + + // Restore pivot + Swap (l, right - 1); + // Partition and sort + Sort (left, l - 1); + Sort (l + 1, right); + } else + // If there are three items in the subarray, insertion sort is better + InsertionSort (left, right); + } + + /*void Sort (int left, int right, int depth) + { + int l = left, r = right - 1, pivot = MedianOfThree (left, right); + while (true) { + while (Comparison (indexes[++l], pivot) < 0); + while (Comparison (indexes[--r], pivot) > 0); + if (l < r) + Swap (l, r); + else + break; + } + + // Restore pivot + Swap (l, right - 1); + + // Partition and sort in parallel if appropriate + /*if (depth < maxDepth) { + depth <<= 1; + Task t = Task.Factory.StartNew (() => Sort (left, l - 1, depth)); + Sort (l + 1, right, depth); + + t.Wait (); + } else {*/ + // Sequential + /* Sort (left, l - 1); + Sort (l + 1, right); + //} + }*/ + + /*void ShellSort (int left, int right) + { + int[] gaps = new int[] { 4, 1}; + + for (int ic = 0; ic < gaps.Length; ic++) { + int inc = gaps[ic]; + int l = left + inc; + for (int i = l; i <= right; i++) { + T temp = list[i]; + int j = i; + for (; j >= l && comparison (list[j - inc], temp) > 1; j -= inc) + list[j] = list[j - inc]; + list[j] = temp; + } + } + }*/ + + void InsertionSort (int left, int right) + { + for (int i = left + 1; i <= right; i++) { + int j, tmp = indexes [i]; + + for (j = i; j > left && Comparison (tmp, indexes [j - 1]) < 0; j--) + indexes [j] = indexes [j - 1]; + + indexes [j] = tmp; + } + } + + /* + void InsertionSort (int left, int right) + { + for (int i = left + 1; i <= right; i++) { + int j; + T tmp = list[i]; + + for (j = i; j > left && comparison (tmp, list [j - 1]) < 0; j--) + list [j] = list [j - 1]; + + list [j] = tmp; + } + }*/ + + void Swap (int left, int right) + { + int temp = indexes [right]; + indexes [right] = indexes [left]; + indexes [left] = temp; + } + + int MedianOfThree (int left, int right) + { + int center = (left + right) >> 1; + if (Comparison (indexes[center], indexes[left]) < 0) + Swap (left, center); + if (Comparison (indexes[right], indexes[left]) < 0) + Swap (left, right); + if (Comparison (indexes[right], indexes[center]) < 0) + Swap (center, right); + Swap (center, right - 1); + + return indexes[right - 1]; + } + + public static IList Sort (IList list, Comparison comparison) + { + ParallelQuickSort qs = new ParallelQuickSort (list, comparison); + + return qs.DoSort (); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/ChangeLog b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/ChangeLog new file mode 100644 index 00000000000..e9e87fa266d --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/ChangeLog @@ -0,0 +1,27 @@ +2010-04-15 Jérémie Laval + + * QueryBaseNode.cs: + * QueryCastNode.cs: + * QueryChildNode.cs: + * QueryConcatNode.cs: + * QueryDefaultEmptyNode.cs: + * QueryGroupByNode.cs: + * QueryMuxNode.cs: + * QueryOptionNode.cs: + * QueryOrderByNode.cs: + * QueryOrderGuardNode.cs: + * QueryOrderedStreamNode.cs: + * QueryReverseNode.cs: + * QuerySelectManyNode.cs: + * QuerySelectNode.cs: + * QuerySetNode.cs: + * QueryStartNode.cs: + * QueryStreamNode.cs: + * QueryWhereNode.cs: + * QueryZipNode.cs: + * WrapHelper.cs: Initial check-in of PLinq + +2010-04-15 Jérémie Laval + + * SetInclusion.cs: Initial check-in of PLinq (enum) + diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryBaseNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryBaseNode.cs new file mode 100644 index 00000000000..14c145513ca --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryBaseNode.cs @@ -0,0 +1,49 @@ +#if NET_4_0 +// +// QueryBaseNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; + +namespace System.Linq +{ + internal abstract class QueryBaseNode : IVisitableNode + { + public virtual void Visit (INodeVisitor visitor) + { + visitor.Visit (this); + } + + internal abstract IList> GetEnumerables (QueryOptions options); + + internal abstract IList>> GetOrderedEnumerables (QueryOptions options); + + internal abstract IEnumerable GetSequential (); + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryCastNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryCastNode.cs new file mode 100644 index 00000000000..1bb6f29ad17 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryCastNode.cs @@ -0,0 +1,72 @@ +#if NET_4_0 +// +// QueryCastNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class QueryCastNode : QueryStreamNode + { + public QueryCastNode (QueryBaseNode source) + : base (source, false) + { + + } + + internal override IEnumerable GetSequential () + { + return Parent.GetSequential ().Cast (); + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + IList>> src = Parent.GetOrderedEnumerables (options); + IEnumerable>[] result = new IEnumerable> [src.Count]; + + for (int i = 0; i < src.Count; i++) + result[i] = src[i].Select ((e) => new KeyValuePair (e.Key, (object)e.Value)); + + return result; + } + + internal override IList> GetEnumerables (QueryOptions options) + { + IList> src = Parent.GetEnumerables (options); + IEnumerable[] result = new IEnumerable [src.Count]; + + for (int i = 0; i < src.Count; i++) + result[i] = src[i].Cast (); + + return result; + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryChildNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryChildNode.cs new file mode 100644 index 00000000000..c58834a3f23 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryChildNode.cs @@ -0,0 +1,54 @@ +#if NET_4_0 +// +// QueryChildNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace System.Linq +{ + internal abstract class QueryChildNode : QueryBaseNode + { + QueryBaseNode parent; + + internal QueryChildNode (QueryBaseNode parent) + // : base (isOrdered, true) + { + this.parent = parent; + } + + internal QueryBaseNode Parent { + get { + return parent; + } + } + + public override void Visit (INodeVisitor visitor) + { + visitor.Visit (this); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryConcatNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryConcatNode.cs new file mode 100644 index 00000000000..16a0e77fc3f --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryConcatNode.cs @@ -0,0 +1,86 @@ +#if NET_4_0 +// +// QueryConcatNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class QueryConcatNode : QueryMuxNode + { + public QueryConcatNode (QueryBaseNode first, QueryBaseNode second) + : this (first, second) + { + } + + internal override IList> GetEnumerables (QueryOptions options) + { + IList> first = Parent.GetEnumerables (options); + IList> second = Second.GetEnumerables (options); + + IEnumerable[] result = new IEnumerable[first.Count]; + + for (int i = 0; i < result.Length; i++) + result[i] = CombineEnumerables (first[i], second[i]); + + return result; + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + IList>> first = Parent.GetOrderedEnumerables (options); + IList>> second = Second.GetOrderedEnumerables (options); + + IEnumerable>[] result = new IEnumerable>[first.Count]; + + for (int i = 0; i < result.Length; i++) + result[i] = CombineEnumerables (first[i], second[i]); + + return result; + } + + internal override IEnumerable GetSequential () + { + IEnumerable first = Parent.GetSequential (); + IEnumerable second = Second.GetSequential (); + + return first.Concat (second); + } + + IEnumerable CombineEnumerables (IEnumerable f, IEnumerable s) + { + foreach (var e in f) + yield return e; + foreach (var e in s) + yield return e; + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryDefaultEmptyNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryDefaultEmptyNode.cs new file mode 100644 index 00000000000..e5463d0185a --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryDefaultEmptyNode.cs @@ -0,0 +1,93 @@ +#if NET_4_0 +// +// QueryDefaultEmptyNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class QueryDefaultEmptyNode : QueryStreamNode + { + TSource defaultValue; + + internal QueryDefaultEmptyNode (QueryBaseNode parent, TSource defaultValue) + : base (parent, false) + { + this.defaultValue = defaultValue; + } + + internal override IEnumerable GetSequential () + { + return Parent.GetSequential ().DefaultIfEmpty (defaultValue); + } + + internal override IList> GetEnumerables (QueryOptions options) + { + IList> enumerables = Parent.GetEnumerables (options); + CountdownEvent evt = new CountdownEvent (enumerables.Count); + IEnumerable[] result = new IEnumerable[enumerables.Count]; + + for (int i = 0; i < enumerables.Count; i++) + result[i] = GetEnumerableInternal (enumerables[i], evt, + (s) => s); + + return result; + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + IList>> enumerables = Parent.GetOrderedEnumerables (options); + CountdownEvent evt = new CountdownEvent (enumerables.Count); + IEnumerable>[] result = new IEnumerable>[enumerables.Count]; + + for (int i = 0; i < enumerables.Count; i++) + result[i] = GetEnumerableInternal> (enumerables[i], evt, + (s) => new KeyValuePair (0, s)); + + return result; + } + + IEnumerable GetEnumerableInternal (IEnumerable source, + CountdownEvent evt, + Func converter) + { + bool processed = false; + + foreach (TSecond second in source) { + processed = true; + yield return second; + } + + if (!processed && evt.Signal ()) + yield return converter (defaultValue); + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryGroupByNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryGroupByNode.cs new file mode 100644 index 00000000000..4ccaac9f5ba --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryGroupByNode.cs @@ -0,0 +1,76 @@ +#if NET_4_0 +// +// QueryOrderByNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class QueryGroupByNode : QueryStreamNode, TSource> + { + Func keySelector; + Func elementSelector; + IEqualityComparer comparer; + + public QueryGroupByNode (QueryBaseNode parent, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + : base (parent, false) + { + this.keySelector = keySelector; + this.elementSelector = elementSelector; + this.comparer = comparer; + } + + internal override IEnumerable> GetSequential () + { + IEnumerable src = Parent.GetSequential (); + + return src.GroupBy (keySelector, elementSelector, comparer); + } + + internal override IList>>> GetOrderedEnumerables (QueryOptions options) + { + //ConcurrentLookup lookup = new ConcurrentLookup (); + + //ParallelExecuter.ProcessAndBlock (Parent, (e) => lookup.Add (keySelector (e), elementSelector (e))); + + throw new System.NotImplementedException(); + } + + internal override IList>> GetEnumerables (QueryOptions options) + { + throw new System.NotImplementedException(); + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryMuxNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryMuxNode.cs new file mode 100644 index 00000000000..49fbab6a6da --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryMuxNode.cs @@ -0,0 +1,58 @@ +#if NET_4_0 +// +// QueryMuxNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal abstract class QueryMuxNode : QueryChildNode + { + QueryBaseNode second; + + internal QueryMuxNode (QueryBaseNode parent, QueryBaseNode second) + : base (parent) + { + this.second = second; + } + + internal QueryBaseNode Second { + get { + return second; + } + } + + public override void Visit (INodeVisitor visitor) + { + visitor.Visit (this); + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOptionNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOptionNode.cs new file mode 100644 index 00000000000..ac096c1bee8 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOptionNode.cs @@ -0,0 +1,155 @@ +#if NET_4_0 +// +// QueryOptionNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections.Generic; + +namespace System.Linq +{ + // The first four elements correspond to the public operator With* + // Last CancellationToken parameter is used internally for ImplementerToken + using OptionsList = Tuple; + + internal class QueryOptionNode : QueryChildNode + { + + public QueryOptionNode (QueryBaseNode parent) + : base (parent) + { + + } + + internal virtual OptionsList GetOptions () + { + return new OptionsList (null, null, null, -1, null); + } + + internal override IList> GetEnumerables (QueryOptions options) + { + return Parent.GetEnumerables (options); + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + return Parent.GetOrderedEnumerables (options); + } + + internal override IEnumerable GetSequential () + { + return Parent.GetSequential (); + } + + public override void Visit (INodeVisitor visitor) + { + visitor.Visit (this); + } + } + + internal class ParallelExecutionModeNode : QueryOptionNode + { + ParallelExecutionMode mode; + + internal ParallelExecutionModeNode (ParallelExecutionMode mode, QueryBaseNode parent) + : base (parent) + { + this.mode = mode; + } + + internal override OptionsList GetOptions () + { + return new OptionsList (null, mode, null, -1, null); + } + } + + + internal class ParallelMergeOptionsNode : QueryOptionNode + { + ParallelMergeOptions opts; + + internal ParallelMergeOptionsNode (ParallelMergeOptions opts, QueryBaseNode parent) + : base (parent) + { + this.opts = opts; + } + + internal override OptionsList GetOptions () + { + return new OptionsList (opts, null, null, -1, null); + } + } + + + internal class CancellationTokenNode : QueryOptionNode + { + CancellationToken token; + + internal CancellationTokenNode (CancellationToken token, QueryBaseNode parent) + : base (parent) + { + this.token = token; + } + + internal override OptionsList GetOptions () + { + return new OptionsList (null, null, token, -1, null); + } + } + + internal class DegreeOfParallelismNode : QueryOptionNode + { + int degreeParallelism; + + internal DegreeOfParallelismNode (int degreeParallelism, QueryBaseNode parent) + : base (parent) + { + this.degreeParallelism = degreeParallelism; + } + + internal override OptionsList GetOptions () + { + return new OptionsList (null, null, null, degreeParallelism, null); + } + } + + internal class ImplementerTokenNode : QueryOptionNode + { + CancellationTokenSource source; + + internal ImplementerTokenNode (CancellationTokenSource token, QueryBaseNode parent) + : base (parent) + { + this.source = token; + } + + internal override OptionsList GetOptions () + { + return new OptionsList (null, null, null, -1, source); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderByNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderByNode.cs new file mode 100644 index 00000000000..626100378e2 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderByNode.cs @@ -0,0 +1,122 @@ +#if NET_4_0 +// +// QueryOrderByNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class QueryOrderByNode : QueryOrderGuardNode + { + Comparison comparison; + + public QueryOrderByNode (QueryBaseNode parent, Comparison comparison) + : base (parent, true) + { + this.comparison = comparison; + } + + + public QueryOrderByNode (QueryOrderByNode parent, Comparison comparison) + : base (parent.Parent, true) + { + this.comparison = MergeComparison (parent.ComparisonFunc, comparison); + } + + public Comparison ComparisonFunc { + get { + return comparison; + } + } + + internal override IEnumerable GetSequential () + { + return Parent.GetSequential ().OrderBy ((e) => e, new ComparisonComparer (comparison)); + } + + private class ComparisonComparer : IComparer + { + Comparison comparison; + + internal ComparisonComparer (Comparison comparison) + { + this.comparison = comparison; + } + + int IComparer.Compare (T x, T y) + { + return comparison (x, y); + } + } + + internal override IList> GetEnumerables (QueryOptions options) + { + throw new InvalidOperationException ("Shouldn't be called"); + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + int partitionCount; + IList aggregList = GetAggregatedList (out partitionCount); + IList result = ParallelQuickSort.Sort (aggregList, comparison); + + OrderablePartitioner partitioner = ParallelPartitioner.CreateForStrips (result, 1); + + return WrapHelper.Wrap (partitioner.GetOrderablePartitions (options.PartitionCount)); + } + + IList GetAggregatedList (out int partitionCount) + { + AggregationList result = null; + partitionCount = -1; + + ParallelExecuter.ProcessAndAggregate> (Parent, () => new List (), + LocalCall, + (ls) => { result = new AggregationList (ls); }); + + return result; + } + + IList LocalCall (IList list, T element) + { + list.Add (element); + return list; + } + + static Comparison MergeComparison (Comparison source, Comparison other) + { + return (e1, e2) => { + int result = source (e1, e2); + return result == 0 ? other (e1, e2) : result; + }; + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderGuardNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderGuardNode.cs new file mode 100644 index 00000000000..822446099e0 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderGuardNode.cs @@ -0,0 +1,99 @@ +#if NET_4_0 +// QueryOrderGuardNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; + +namespace System.Linq +{ + internal abstract class QueryOrderGuardNode : QueryStreamNode + { + bool ensureOrder; + + internal QueryOrderGuardNode (QueryBaseNode parent, bool ensureOrder) + : base (parent, ensureOrder) + { + this.ensureOrder = ensureOrder; + } + + public bool EnsureOrder { + get { + return ensureOrder; + } + } + + internal override IEnumerable GetSequential () + { + return Parent.GetSequential (); + } + + public override void Visit (INodeVisitor visitor) + { + visitor.Visit (this); + } + } + + internal class QueryAsUnorderedNode : QueryOrderGuardNode + { + internal QueryAsUnorderedNode (QueryBaseNode parent) + : base (parent, false) + { + + } + + internal override IList> GetEnumerables (QueryOptions options) + { + return Parent.GetEnumerables (options); + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + return Parent.GetOrderedEnumerables (options); + } + + } + + internal class QueryAsOrderedNode : QueryOrderGuardNode + { + internal QueryAsOrderedNode (QueryBaseNode parent) + : base (parent, true) + { + + } + + internal override IList> GetEnumerables (QueryOptions options) + { + return Parent.GetEnumerables (options); + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + return Parent.GetOrderedEnumerables (options); + } + + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderedStreamNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderedStreamNode.cs new file mode 100644 index 00000000000..50203fb9a9d --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryOrderedStreamNode.cs @@ -0,0 +1,40 @@ +#if NET_4_0 +// +// QueryOrderedStreamNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace System.Linq +{ + internal abstract class QueryOrderedStreamNode : QueryStreamNode + { + internal QueryOrderedStreamNode (QueryBaseNode parent, bool isIndexed) + : base (parent, isIndexed) + { + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryReverseNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryReverseNode.cs new file mode 100644 index 00000000000..c8b87cd79bc --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryReverseNode.cs @@ -0,0 +1,67 @@ +#if NET_4_0 +// +// QueryReverseNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Threading; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class QueryReverseNode : QueryStreamNode + { + ParallelQuery source; + + public QueryReverseNode (ParallelQuery source) + : base (source.Node, true) + { + this.source = source; + } + + internal override IEnumerable GetSequential () + { + return Parent.GetSequential ().Reverse (); + } + + // As stated in the doc, in this case we do nothing + internal override IList> GetEnumerables (QueryOptions options) + { + return Parent.GetEnumerables (options); + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + ReverseList reversed = new ReverseList (source.ToArray ()); + OrderablePartitioner partitioner = ParallelPartitioner.CreateForStrips (reversed, 1); + + return WrapHelper.Wrap (partitioner.GetOrderablePartitions (options.PartitionCount)); + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySelectManyNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySelectManyNode.cs new file mode 100644 index 00000000000..6c189adf0c5 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySelectManyNode.cs @@ -0,0 +1,122 @@ +#if NET_4_0 +// +// QueryConcatNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class QuerySelectManyNode : QueryStreamNode + { + Func> collectionSelector; + Func> collectionSelectorIndexed; + Func resultSelector; + + internal QuerySelectManyNode (QueryBaseNode parent, + Func> collectionSelectorIndexed, + Func resultSelector) + : base (parent, true) + { + this.collectionSelectorIndexed = collectionSelectorIndexed; + this.resultSelector = resultSelector; + } + + internal QuerySelectManyNode (QueryBaseNode parent, + Func> collectionSelector, + Func resultSelector) + : base (parent, false) + { + this.collectionSelector = collectionSelector; + this.resultSelector = resultSelector; + } + + internal override IEnumerable GetSequential () + { + IEnumerable source = Parent.GetSequential (); + + if (IsIndexed) + return source.SelectMany (collectionSelectorIndexed, resultSelector); + else + return source.SelectMany (collectionSelector, resultSelector); + } + + internal override IList> GetEnumerables (QueryOptions options) + { + IEnumerable[] result = null; + + if (IsIndexed) { + IList>> enumerables = Parent.GetOrderedEnumerables (options); + result = new IEnumerable[enumerables.Count]; + + for (int i = 0; i < enumerables.Count; i++) + result[i] = GetEnumerableInternal> (enumerables[i], + (kv) => collectionSelectorIndexed (kv.Value, (int)kv.Key), + (e, c) => resultSelector (e.Value, c)); + } else { + IList> enumerables = Parent.GetEnumerables (options); + result = new IEnumerable[enumerables.Count]; + + for (int i = 0; i < enumerables.Count; i++) + result[i] = GetEnumerableInternal (enumerables[i], + collectionSelector, + (e, c) => resultSelector (e, c)); + } + + return result; + } + + // This one is gonna be tricky + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + throw new NotImplementedException (); + } + + IEnumerable GetEnumerableInternal (IEnumerable source, + Func> collectionner, + Func packer) + { + foreach (T element in source) + foreach (TCollection item in collectionner (element)) + yield return packer (element, item); + } + + IEnumerable> GetOrderedEnumerableInternal (IEnumerable> source, + Barrier barrier) + { + foreach (KeyValuePair element in source) { + IEnumerable collection = collectionSelectorIndexed (element.Value, (int)element.Key); + + foreach (TCollection item in collection) + yield return new KeyValuePair (-1, resultSelector (element.Value, item)); + } + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySelectNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySelectNode.cs new file mode 100644 index 00000000000..defbcbeeb62 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySelectNode.cs @@ -0,0 +1,97 @@ +#if NET_4_0 +// +// QuerySelectNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class QuerySelectNode : QueryStreamNode + { + Func indexedSelector; + Func selector; + + internal QuerySelectNode (QueryBaseNode parent, Func selector) + : base (parent, false) + { + this.selector = selector; + } + + internal QuerySelectNode (QueryBaseNode parent, Func selector) + : base (parent, true) + { + this.indexedSelector = selector; + } + + internal override IEnumerable GetSequential () + { + if (IsIndexed) + return Parent.GetSequential ().Select (indexedSelector); + else + return Parent.GetSequential ().Select (selector); + } + + internal override IList> GetEnumerables (QueryOptions options) + { + if (IsIndexed) { + IList>> sources = Parent.GetOrderedEnumerables (options); + IEnumerable[] results = new IEnumerable[sources.Count]; + for (int i = 0; i < results.Length; i++) + results[i] = sources[i].Select ((e) => indexedSelector (e.Value, (int)e.Key)); + return results; + } else { + IList> sources = Parent.GetEnumerables (options); + IEnumerable[] results = new IEnumerable[sources.Count]; + + for (int i = 0; i < results.Length; i++) + results[i] = sources[i].Select (selector); + return results; + } + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + IList>> sources = Parent.GetOrderedEnumerables (options); + IEnumerable>[] results = new IEnumerable>[sources.Count]; + + if (IsIndexed) { + for (int i = 0; i < results.Length; i++) + results[i] = sources[i]. + Select ((e) => new KeyValuePair (e.Key, indexedSelector (e.Value, (int)e.Key))); + } else { + for (int i = 0; i < results.Length; i++) + results[i] = sources[i]. + Select ((e) => new KeyValuePair (e.Key, selector (e.Value))); + } + + return results; + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySetNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySetNode.cs new file mode 100644 index 00000000000..4ea309ae2e0 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QuerySetNode.cs @@ -0,0 +1,145 @@ +#if NET_4_0 +// +// QueryMuxNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class QuerySetNode : QueryMuxNode + { + readonly SetInclusion setInclusion; + readonly IEqualityComparer comparer; + + internal QuerySetNode (SetInclusion setInclusion, IEqualityComparer comparer, + QueryBaseNode first, QueryBaseNode second) + : base (first, second) + { + this.setInclusion = setInclusion; + this.comparer = comparer; + } + + internal override IEnumerable GetSequential () + { + IEnumerable first = Parent.GetSequential (); + IEnumerable second = Second == null ? null : Second.GetSequential (); + + // We try to do some guessing based on the default + switch (setInclusion) { + case SetInclusionDefaults.Union: + return first.Union (second, comparer); + case SetInclusionDefaults.Intersect: + return first.Intersect (second, comparer); + case SetInclusionDefaults.Except: + return first.Except (second, comparer); + case SetInclusionDefaults.Distinct: + return first.Distinct (comparer); + } + + // Default is we return the bare source enumerable + return first; + } + + internal override IList> GetEnumerables (QueryOptions options) + { + IList> first = Parent.GetEnumerables (options); + IList> second = Second.GetEnumerables (options); + + IEnumerable[] result = new IEnumerable[first.Count]; + ConcurrentSkipList checker = new ConcurrentSkipList (comparer); + + InitConcurrentSkipList (checker, second, (e) => e); + + for (int i = 0; i < result.Length; i++) + result[i] = GetEnumerable (first[i], second[i], checker, (e) => e); + + return result; + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + IList>> first = Parent.GetOrderedEnumerables (options); + IList>> second = Second.GetOrderedEnumerables (options); + + IEnumerable>[] result = new IEnumerable>[first.Count]; + ConcurrentSkipList checker = new ConcurrentSkipList (comparer); + + InitConcurrentSkipList (checker, second, (e) => e.Value); + + for (int i = 0; i < result.Length; i++) + result[i] = GetEnumerable> (first[i], second[i], checker, (e) => e.Value); + + return result; + } + + void InitConcurrentSkipList (ConcurrentSkipList checker, + IList> feeds, + Func extractor) + { + if ((setInclusion & SetInclusion.Preload) == 0) + return; + + foreach (IEnumerable feed in feeds) + foreach (TExtract item in feed) + checker.TryAdd (extractor (item)); + } + + IEnumerable GetEnumerable (IEnumerable first, + IEnumerable second, + ConcurrentSkipList checker, + Func extractor) + { + IEnumerator eFirst = first.GetEnumerator (); + IEnumerator eSecond = second == null ? null : second.GetEnumerator (); + + IEnumerator current = eFirst; + bool outInclusion = (setInclusion & SetInclusion.Out) > 0; + bool preload = (setInclusion & SetInclusion.Preload) > 0; + bool relaxed = (setInclusion & SetInclusion.Relaxed) > 0; + + while (current != null) { + while (current.MoveNext ()) { + bool result = relaxed ? + checker.Contains (extractor (current.Current)) : checker.TryAdd (extractor (current.Current)); + + if ((result && outInclusion) + || (!result && !outInclusion)) + yield return current.Current; + } + + if (current == eFirst && !preload) + current = eSecond; + else + break; + } + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryStartNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryStartNode.cs new file mode 100644 index 00000000000..58ac27ee8b1 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryStartNode.cs @@ -0,0 +1,110 @@ +#if NET_4_0 +// +// QueryStartNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Linq +{ + internal class QueryStartNode : QueryBaseNode + { + readonly IEnumerable source; + readonly Partitioner customPartitioner; + + internal QueryStartNode (IEnumerable source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + this.source = source; + } + + internal QueryStartNode (Partitioner custom) + { + if (custom == null) + throw new ArgumentNullException ("custom"); + + this.customPartitioner = custom; + } + + public override void Visit (INodeVisitor visitor) + { + visitor.Visit (this); + } + + internal override IEnumerable GetSequential () + { + if (source != null) + return source; + + return WrapHelper.Wrap (customPartitioner.GetPartitions (1))[0]; + } + + internal override IList> GetEnumerables (QueryOptions options) + { + if (customPartitioner != null) { + return WrapHelper.Wrap (customPartitioner.GetPartitions (options.PartitionCount)); + } + + Partitioner partitioner + = (options.UseStrip) ? ParallelPartitioner.CreateForStrips (source, 1) : ParallelPartitioner.CreateBest (source); + + return WrapHelper.Wrap (partitioner.GetPartitions (options.PartitionCount)); + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + OrderablePartitioner partitioner = null; + if (customPartitioner != null) { + partitioner = customPartitioner as OrderablePartitioner; + if (partitioner == null) + throw new InvalidOperationException ("The partitionner you are using doesn't support ordered partitionning"); + } else { + partitioner = + (options.UseStrip) ? ParallelPartitioner.CreateForStrips (source, 1) : ParallelPartitioner.CreateBest (source); + } + + options.PartitionerSettings = Tuple.Create (partitioner.KeysOrderedAcrossPartitions, + partitioner.KeysOrderedInEachPartition, + partitioner.KeysNormalized); + + // We only support one style of partitioning at the moment. + // Standard partitioners follow this style. + if (options.UseStrip && (!partitioner.KeysOrderedInEachPartition || partitioner.KeysOrderedAcrossPartitions)) + throw new NotImplementedException ("Partitioner must have KeysOrderedInEachPartition " + + "and !KeysOrderedAcrossPartitions" + + "to be used with indexed operators"); + + return WrapHelper.Wrap (partitioner.GetOrderablePartitions (options.PartitionCount)); + } + } +} +#endif \ No newline at end of file diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryStreamNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryStreamNode.cs new file mode 100644 index 00000000000..572b2c59751 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryStreamNode.cs @@ -0,0 +1,57 @@ +#if NET_4_0 +// +// QueryStreamNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; + +namespace System.Linq +{ + internal abstract class QueryStreamNode : QueryChildNode + { + bool isIndexed; + + internal QueryStreamNode (QueryBaseNode parent, bool isIndexed) + : base (parent) + { + this.isIndexed = isIndexed; + } + + public override void Visit (INodeVisitor visitor) + { + visitor.Visit (this); + } + + public bool IsIndexed { + get { + return isIndexed; + } + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryWhereNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryWhereNode.cs new file mode 100644 index 00000000000..74f09d66da9 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryWhereNode.cs @@ -0,0 +1,157 @@ +#if NET_4_0 +// +// QueryWhereNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Threading; +using System.Collections.Generic; + +namespace System.Linq +{ + + internal class QueryWhereNode : QueryStreamNode + { + Func indexedPredicate; + Func predicate; + + internal QueryWhereNode (QueryBaseNode parent, Func predicate) + : base (parent, false) + { + this.predicate = predicate; + } + + internal QueryWhereNode (QueryBaseNode parent, Func predicate) + : base (parent, true) + { + this.indexedPredicate = predicate; + } + + internal override IEnumerable GetSequential () + { + IEnumerable parent = Parent.GetSequential (); + + if (indexedPredicate != null) + return parent.Where (indexedPredicate); + else + return parent.Where (predicate); + } + + internal override IList> GetEnumerables (QueryOptions options) + { + if (IsIndexed) { + IList>> sources = Parent.GetOrderedEnumerables (options); + IEnumerable[] results = new IEnumerable[sources.Count]; + + for (int i = 0; i < results.Length; i++) + results[i] = + sources[i].Where ((e) => indexedPredicate (e.Value, (int)e.Key)).Select ((e) => e.Value); + return results; + } else { + IList> sources = Parent.GetEnumerables (options); + IEnumerable[] results = new IEnumerable[sources.Count]; + + for (int i = 0; i < results.Length; i++) + results[i] = sources[i].Where (predicate); + return results; + } + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + IList>> sources = Parent.GetOrderedEnumerables (options); + IEnumerable>[] results = new IEnumerable>[sources.Count]; + + Tuple[] store = new Tuple[results.Length]; + long lastIndex = 0; + + Barrier barrier = new Barrier (results.Length, delegate (Barrier b) { + // Sort the store + Array.Sort (store, ArraySortMethod); + + // Reassign a good index + int i = 0; + + for (i = 0; i < store.Length && store[i].Item3; i++) { + Tuple old = store[i]; + store[i] = Tuple.Create (old.Item1, lastIndex + i, old.Item3); + } + + // Update lastIndex for next round + lastIndex += i; + }); + + for (int j = 0; j < results.Length; j++) + results[j] = GetEnumerator (sources[j], barrier, store, j); + + return results; + } + + static int ArraySortMethod (Tuple lhs, Tuple rhs) + { + if (lhs.Item3 && !rhs.Item3) + return -1; + if (!lhs.Item3 && rhs.Item3) + return 1; + if (!lhs.Item3 && !rhs.Item3) + return 0; + + return (lhs.Item2 < rhs.Item2) ? -1 : 1; + } + + IEnumerable> GetEnumerator (IEnumerable> source, + Barrier barrier, + Tuple[] store, int index) + { + IEnumerator> current = source.GetEnumerator (); + bool result; + + while (current.MoveNext ()) { + KeyValuePair curr = current.Current; + + if (IsIndexed) + result = indexedPredicate (curr.Value, (int)curr.Key); + else + result = predicate (curr.Value); + + store[index] = Tuple.Create (curr.Value, curr.Key, result); + barrier.SignalAndWait (); + + Tuple value = store [index]; + + if (value.Item3) + yield return new KeyValuePair (value.Item2, value.Item1); + + // Reset + store[index] = Tuple.Create (default (TSource), long.MaxValue, false); + } + + // Remove our participation + barrier.RemoveParticipant (); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryZipNode.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryZipNode.cs new file mode 100644 index 00000000000..8268db5a614 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/QueryZipNode.cs @@ -0,0 +1,135 @@ +#if NET_4_0 +// +// QueryZipNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Linq; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class QueryZipNode : QueryMuxNode + { + Func resultSelector; + + public QueryZipNode (Func resultSelector, QueryBaseNode first, QueryBaseNode second) + : base (first, second) + { + this.resultSelector = resultSelector; + } + + internal override IEnumerable GetSequential () + { + IEnumerable first = Parent.GetSequential (); + IEnumerable second = Second.GetSequential (); + + return first.Zip (second, resultSelector); + } + + internal override IList> GetEnumerables (QueryOptions options) + { + IList> first = Parent.GetEnumerables (options); + IList> second = Second.GetEnumerables (options); + + if (first.Count != second.Count) + throw new InvalidOperationException ("Internal size mismatch"); + + IEnumerable[] result = new IEnumerable[first.Count]; + + for (int i = 0; i < result.Length; i++) + result[i] = GetEnumerable (first[i], second[i]); + + return result; + } + + IEnumerable GetEnumerable (IEnumerable first, IEnumerable second) + { + IEnumerator eFirst = first.GetEnumerator (); + IEnumerator eSecond = second.GetEnumerator (); + + while (eFirst.MoveNext ()) { + if (!eSecond.MoveNext ()) + yield break; + + yield return resultSelector (eFirst.Current, eSecond.Current); + } + } + + internal override IList>> GetOrderedEnumerables (QueryOptions options) + { + IList>> first = Parent.GetOrderedEnumerables (options); + IList>> second = Second.GetOrderedEnumerables (options); + + if (first.Count != second.Count) + throw new InvalidOperationException ("Internal size mismatch"); + + IEnumerable>[] result = new IEnumerable>[first.Count]; + + KeyValuePair[] store1 = new KeyValuePair[result.Length]; + KeyValuePair[] store2 = new KeyValuePair[result.Length]; + + Barrier barrier = new Barrier (result.Length, delegate { + Array.Sort (store1, (e1, e2) => e1.Key.CompareTo (e2.Key)); + Array.Sort (store2, (e1, e2) => e1.Key.CompareTo (e2.Key)); + }); + + for (int i = 0; i < result.Length; i++) + result[i] = GetEnumerable (first[i], second[i], i, store1, store2, barrier); + + return result; + } + + IEnumerable> GetEnumerable (IEnumerable> first, + IEnumerable> second, + int index, + KeyValuePair[] store1, + KeyValuePair[] store2, + Barrier barrier) + { + IEnumerator> eFirst = first.GetEnumerator (); + IEnumerator> eSecond = second.GetEnumerator (); + + while (eFirst.MoveNext ()) { + if (!eSecond.MoveNext ()) + break; + + store1[index] = eFirst.Current; + store2[index] = eSecond.Current; + + barrier.SignalAndWait (); + + yield return new KeyValuePair (store1[index].Key, + resultSelector (store1[index].Value, store2[index].Value)); + } + + barrier.RemoveParticipant (); + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/SetInclusion.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/SetInclusion.cs new file mode 100644 index 00000000000..a1ef21cbe6f --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/SetInclusion.cs @@ -0,0 +1,52 @@ +#if NET_4_0 +// +// SetInclusion.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + [Flags] + internal enum SetInclusion { + In = 0, // Element should already be in checker + Out = 1, // Element shouldn't be already in checker + Preload = 2, // Preload second node content and only do real work on first node content + Relaxed = 4, // first node content isn't added to checker allowing duplicates + } + + internal static class SetInclusionDefaults + { + public const SetInclusion Union = SetInclusion.Out; + public const SetInclusion Intersect = SetInclusion.In; + public const SetInclusion Except = SetInclusion.In | SetInclusion.Preload | SetInclusion.Relaxed; + public const SetInclusion Distinct = SetInclusion.Out | SetInclusion.Preload; + } +} + +#endif \ No newline at end of file diff --git a/mcs/class/System.Core/System.Linq/Internal/QueryNodes/WrapHelper.cs b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/WrapHelper.cs new file mode 100644 index 00000000000..a44d61aa2ec --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/QueryNodes/WrapHelper.cs @@ -0,0 +1,63 @@ +#if NET_4_0 +// +// WrapHelper.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class WrapHelper + { + class EnumeratorWrapper : IEnumerable + { + IEnumerator enumerator; + + public EnumeratorWrapper (IEnumerator enumerator) + { + this.enumerator = enumerator; + } + + public IEnumerator GetEnumerator () + { + return enumerator; + } + + IEnumerator IEnumerable.GetEnumerator () + { + return (IEnumerator)enumerator; + } + } + + internal static IList> Wrap (IList> src) + { + return src.Select ((e) => (IEnumerable)new EnumeratorWrapper (e)).ToArray (); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/RangeList.cs b/mcs/class/System.Core/System.Linq/Internal/RangeList.cs new file mode 100644 index 00000000000..43e7ed22c62 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/RangeList.cs @@ -0,0 +1,125 @@ +#if NET_4_0 +// +// RangeList.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class RangeList : IList + { + readonly int start; + readonly int count; + + public RangeList (int start, int count) + { + this.start = start; + this.count = count; + } + + public int IndexOf (int item) + { + if (!Contains(item)) + return -1; + + return item - start; + } + + public void Insert (int index, int item) + { + throw new NotImplementedException(); + } + + public void RemoveAt (int index) + { + throw new NotImplementedException(); + } + + public int this[int index] { + get { + if (start + index <= count) + return start + index; + else + return -1; + } + set { + throw new NotImplementedException(); + } + } + + public void Add (int item) + { + throw new NotImplementedException(); + } + + public void Clear () + { + throw new NotImplementedException(); + } + + public bool Contains (int item) + { + return start <= item && item <= start + count - 1; + } + + public void CopyTo (int[] array, int arrayIndex) + { + int counter = start; + for (int i = arrayIndex; i < array.Length && i < (i - arrayIndex) + count; i++) + array[i] = counter++; + } + + public bool Remove (int item) + { + throw new NotImplementedException(); + } + + public int Count { + get { + return count; + } + } + + public bool IsReadOnly { + get { + return true; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/RepeatList.cs b/mcs/class/System.Core/System.Linq/Internal/RepeatList.cs new file mode 100644 index 00000000000..35bbd101a67 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/RepeatList.cs @@ -0,0 +1,119 @@ +#if NET_4_0 +// +// RepeatList.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class RepeatList : IList + { + readonly int count; + readonly T element; + + public RepeatList (T element, int count) + { + this.element = element; + this.count = count; + } + + public int IndexOf (T item) + { + // No real index, we may just be interested if the value is different from -1 + return Contains(item) ? 1 : -1; + } + + public void Insert (int index, T item) + { + throw new NotImplementedException(); + } + + public void RemoveAt (int index) + { + throw new NotImplementedException(); + } + + public T this[int index] { + get { + return index < count ? element : default(T); + } + set { + throw new NotImplementedException(); + } + } + + public void Add (T item) + { + throw new NotImplementedException(); + } + + public void Clear () + { + throw new NotImplementedException(); + } + + public bool Contains (T item) + { + return item.Equals(element); + } + + public void CopyTo (T[] array, int arrayIndex) + { + for (int i = arrayIndex; i < array.Length && i < (i - arrayIndex) + count; i++) + array[i] = element; + } + + public bool Remove (T item) + { + throw new NotImplementedException(); + } + + public int Count { + get { + return count; + } + } + + public bool IsReadOnly { + get { + return true; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/ReverseList.cs b/mcs/class/System.Core/System.Linq/Internal/ReverseList.cs new file mode 100644 index 00000000000..b5ca7d02393 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/ReverseList.cs @@ -0,0 +1,119 @@ +#if NET_4_0 +// +// QueryReverseNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Linq; +using System.Threading; +using System.Collections; +using System.Collections.Generic; + +namespace System.Linq +{ + internal class ReverseList : IList + { + readonly IList backend; + readonly int count; + + internal ReverseList (IList backend) + { + this.backend = backend; + this.count = backend.Count; + } + + public int IndexOf (T item) + { + throw new NotImplementedException(); + } + + public void Insert (int index, T item) + { + throw new NotImplementedException(); + } + + public void RemoveAt (int index) + { + throw new NotImplementedException(); + } + + public T this[int index] { + get { + return backend[count - 1 - index]; + } + set { + throw new NotImplementedException(); + } + } + + public void Add (T item) + { + throw new NotImplementedException(); + } + + public void Clear () + { + throw new NotImplementedException(); + } + + public bool Contains (T item) + { + throw new NotImplementedException(); + } + + public void CopyTo (T[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public bool Remove (T item) + { + throw new NotImplementedException(); + } + + public int Count { + get { + return count; + } + } + + public bool IsReadOnly { + get { + return true; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + + IEnumerator IEnumerable.GetEnumerator () + { + return null; + } + } +} + +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/StripPartitioner.cs b/mcs/class/System.Core/System.Linq/Internal/StripPartitioner.cs new file mode 100644 index 00000000000..699cb09604c --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/StripPartitioner.cs @@ -0,0 +1,62 @@ +#if NET_4_0 +// +// StripPartitioner.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + internal class StripPartitioner : OrderablePartitioner + { + IList source; + + public StripPartitioner (IList source) : base (true, false, true) + { + this.source = source; + } + + public override IList>> GetOrderablePartitions (int partitionCount) + { + IEnumerator>[] array = new IEnumerator>[partitionCount]; + for (int i = 0; i < array.Length; i++) + array[i] = GetStripEnumerator (i, partitionCount); + + return array; + } + + IEnumerator> GetStripEnumerator (int start, int partitionCount) + { + for (int i = start; i < source.Count; i += partitionCount) { + //Console.WriteLine ("Num {0} yielding [{1} : {2}]", start, i, source[i]); + yield return new KeyValuePair (i, source [i]); + } + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/Visitors/ChangeLog b/mcs/class/System.Core/System.Linq/Internal/Visitors/ChangeLog new file mode 100644 index 00000000000..55e3ecef9f1 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/Visitors/ChangeLog @@ -0,0 +1,7 @@ +2010-04-15 Jérémie Laval + + * INodeVisitor.cs: + * IVisitableNode.cs: + * QueryCheckerVisitor.cs: + * QueryOptions.cs: First check-in of PLinq + diff --git a/mcs/class/System.Core/System.Linq/Internal/Visitors/INodeVisitor.cs b/mcs/class/System.Core/System.Linq/Internal/Visitors/INodeVisitor.cs new file mode 100644 index 00000000000..1b056fd6864 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/Visitors/INodeVisitor.cs @@ -0,0 +1,43 @@ +#if NET_4_0 +// +// INodeVisitor.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace System.Linq +{ + internal interface INodeVisitor + { + void Visit (QueryBaseNode node); + void Visit (QueryChildNode node); + void Visit (QueryOptionNode node); + void Visit (QueryStartNode node); + void Visit (QueryStreamNode node); + void Visit (QueryOrderGuardNode node); + void Visit (QueryMuxNode node); + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/Visitors/IVisitableNode.cs b/mcs/class/System.Core/System.Linq/Internal/Visitors/IVisitableNode.cs new file mode 100644 index 00000000000..5d7326f77e6 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/Visitors/IVisitableNode.cs @@ -0,0 +1,37 @@ +#if NET_4_0 +// +// IVisitableNode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace System.Linq +{ + internal interface IVisitableNode + { + void Visit (INodeVisitor visitor); + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/Visitors/QueryCheckerVisitor.cs b/mcs/class/System.Core/System.Linq/Internal/Visitors/QueryCheckerVisitor.cs new file mode 100644 index 00000000000..df5660fdc4f --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/Visitors/QueryCheckerVisitor.cs @@ -0,0 +1,162 @@ +#if NET_4_0 +// +// QueryCheckerVisitor.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; + +namespace System.Linq +{ + using OptionsList = Tuple; + + internal class QueryCheckerVisitor : INodeVisitor + { + // Information gathering + ParallelMergeOptions? options = null; + ParallelExecutionMode? mode = null; + CancellationToken? token = null; + int? degreeOfParallelism = null; + bool useStrip; + CancellationToken implementerToken = CancellationToken.None; + + int partitionCount; + bool? behindOrderGuard = null; + + internal QueryCheckerVisitor (int partitionCount) + { + this.partitionCount = partitionCount; + } + + #region INodeVisitor implementation + public void Visit (QueryBaseNode node) + { + // Nothing to do atm. Later we can check if the node is a + // Take or a Skip and set accordingly useStrip + } + + public void Visit (QueryChildNode node) + { + node.Parent.Visit (this); + } + + public void Visit (QueryOptionNode node) + { + MergeOptions (node.GetOptions ()); + + Visit ((QueryChildNode)node); + } + + public void Visit (QueryStartNode node) + { + if (behindOrderGuard == null) + behindOrderGuard = false; + if (degreeOfParallelism != null) + partitionCount = degreeOfParallelism.Value; + } + + public void Visit (QueryStreamNode node) + { + if (node.IsIndexed) + useStrip = true; + + Visit ((QueryChildNode)node); + } + + public void Visit (QueryOrderGuardNode node) + { + if (node.EnsureOrder && behindOrderGuard == null) + behindOrderGuard = true; + } + + public void Visit (QueryMuxNode node) + { + + Visit ((QueryChildNode)node); + } + #endregion + + internal QueryOptions Options { + get { + return new QueryOptions (options, mode, token == null ? CancellationToken.None : token.Value, + useStrip, behindOrderGuard, partitionCount, implementerToken); + } + } + + internal bool UseStrip { + get { + return useStrip; + } + } + + internal bool BehindOrderGuard { + get { + return behindOrderGuard.Value; + } + } + + void MergeOptions (OptionsList list) + { + if (list.Item1 != null) { + if (options == null) + options = list.Item1; + else + Throw ("WithMergeOptions"); + } + + if (list.Item2 != null) { + if (mode == null) + mode = list.Item2; + else + Throw ("WithExecutionMode"); + } + + if (list.Item3 != null) { + if (token == null) + token = list.Item3; + else + Throw ("WithCancellationToken"); + } + + if (list.Item4 != -1) { + if (degreeOfParallelism == null) + degreeOfParallelism = list.Item4; + else + Throw ("WithDegreeOfParallelism"); + } + + // That one is treated specially + if (list.Item5 != null) { + implementerToken = implementerToken.Chain (list.Item5); + } + } + + void Throw (string methName) + { + throw new InvalidOperationException ("You can't have more than one " + methName + " node in a query"); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Internal/Visitors/QueryOptions.cs b/mcs/class/System.Core/System.Linq/Internal/Visitors/QueryOptions.cs new file mode 100644 index 00000000000..f6d0702cc72 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/Internal/Visitors/QueryOptions.cs @@ -0,0 +1,71 @@ +#if NET_4_0 +// +// QueryOptions.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; + +namespace System.Linq +{ + internal class QueryOptions + { + public ParallelMergeOptions? Options; + public ParallelExecutionMode? Mode; + public CancellationToken Token; + /* This token is to be used by some operator (like Take) to tell that + * the execution of the query can be prematurly stopped + * + * It is set when passing QueryOptions to the different node's Get method + * and ParallelExecuter should check after the call to this method is this guy has been + * set. Operator may chain up multiple cancellation token that way. + * When checking for this token, the task body should simply return. + */ + public CancellationToken ImplementerToken; + public bool UseStrip; + public bool? BehindOrderGuard; + public int PartitionCount; + public Tuple PartitionerSettings; + + public QueryOptions (ParallelMergeOptions? options, + ParallelExecutionMode? mode, + CancellationToken token, + bool useStrip, + bool? behindOrderGuard, + int partitionCount, + CancellationToken implementerToken) + { + Options = options; + Mode = mode; + Token = token; + UseStrip = useStrip; + BehindOrderGuard = behindOrderGuard; + PartitionCount = partitionCount; + PartitionerSettings = null; + ImplementerToken = implementerToken; + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/OrderedParallelQuery.cs b/mcs/class/System.Core/System.Linq/OrderedParallelQuery.cs new file mode 100644 index 00000000000..a8b80b78d65 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/OrderedParallelQuery.cs @@ -0,0 +1,54 @@ +#if NET_4_0 +// +// ParallelQuery.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + // Only returned after OrderBy and ThenBy. + public class OrderedParallelQuery : ParallelQuery + { + QueryOrderByNode node; + + internal OrderedParallelQuery (QueryOrderByNode node) + : base (node) + { + this.node = node; + } + + internal new QueryOrderByNode Node { + get { + return node; + } + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/ParallelEnumerable.cs b/mcs/class/System.Core/System.Linq/ParallelEnumerable.cs new file mode 100644 index 00000000000..de5dd6ce54b --- /dev/null +++ b/mcs/class/System.Core/System.Linq/ParallelEnumerable.cs @@ -0,0 +1,2113 @@ +#if NET_4_0 +// +// ParallelEnumerable.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + public static class ParallelEnumerable + { + #region Range & Repeat + public static ParallelQuery Range (int start, int count) + { + if (int.MaxValue - start < count) + throw new ArgumentOutOfRangeException ("count", "start + count - 1 is larger than Int32.MaxValue"); + if (count < 0) + throw new ArgumentOutOfRangeException ("count", "count is less than 0"); + + return (new RangeList (start, count)).AsParallel (); + } + + public static ParallelQuery Repeat (TResult obj, int count) + { + if (count < 0) + throw new ArgumentOutOfRangeException ("count", "count is less than 0"); + + return (new RepeatList (obj, count)).AsParallel (); + } + #endregion + + #region Empty + public static ParallelQuery Empty () + { + return Repeat (default (TResult), 0); + } + #endregion + + #region AsParallel + public static ParallelQuery AsParallel (this IEnumerable source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new QueryStartNode (source)); + } + + public static ParallelQuery AsParallel (this Partitioner source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new QueryStartNode (source)); + } + + public static ParallelQuery AsParallel (this IEnumerable source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new QueryStartNode (source.Cast ())); + } + + public static IEnumerable AsEnumerable (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.AsSequential (); + } + + public static IEnumerable AsSequential ( this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Node.GetSequential (); + } + #endregion + + #region AsOrdered / AsUnordered + public static ParallelQuery AsOrdered (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new QueryAsOrderedNode (source.Node)); + } + + public static ParallelQuery AsUnordered (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new QueryAsUnorderedNode (source.Node)); + } + + public static ParallelQuery AsOrdered (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.TypedQuery.AsOrdered (); + } + #endregion + + #region With* + public static ParallelQuery WithExecutionMode (this ParallelQuery source, + ParallelExecutionMode executionMode) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new ParallelExecutionModeNode (executionMode, source.Node)); + } + + public static ParallelQuery WithCancellation (this ParallelQuery source, + CancellationToken cancellationToken) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new CancellationTokenNode (cancellationToken, source.Node)); + } + + public static ParallelQuery WithMergeOptions (this ParallelQuery source, + ParallelMergeOptions mergeOptions) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new ParallelMergeOptionsNode (mergeOptions, source.Node)); + } + + public static ParallelQuery WithDegreeOfParallelism (this ParallelQuery source, + int degreeParallelism) + { + if (degreeParallelism < 1 || degreeParallelism > 63) + throw new ArgumentException ("degreeOfParallelism is less than 1 or greater than 63", "degreeParallelism"); + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new DegreeOfParallelismNode (degreeParallelism, source.Node)); + } + + internal static ParallelQuery WithImplementerToken (this ParallelQuery source, + CancellationTokenSource token) + { + return new ParallelQuery (new ImplementerTokenNode (token, source.Node)); + } + #endregion + + #region Select + public static ParallelQuery Select (this ParallelQuery source, Func selector) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (selector == null) + throw new ArgumentNullException ("selector"); + + return new ParallelQuery (new QuerySelectNode (source.Node, selector)); + } + + public static ParallelQuery Select (this ParallelQuery source, Func selector) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (selector == null) + throw new ArgumentNullException ("selector"); + + return new ParallelQuery (new QuerySelectNode (source.Node, selector)); + } + #endregion + + #region SelectMany + public static ParallelQuery SelectMany (this ParallelQuery source, + Func> selector) + { + return source.SelectMany (selector, (s, e) => e); + } + + public static ParallelQuery SelectMany (this ParallelQuery source, + Func> selector) + { + return source.SelectMany (selector, (s, e) => e); + } + + public static ParallelQuery SelectMany (this ParallelQuery source, + Func> collectionSelector, + Func resultSelector) + { + return new ParallelQuery (new QuerySelectManyNode (source.Node, + collectionSelector, + resultSelector)); + } + + public static ParallelQuery SelectMany (this ParallelQuery source, + Func> collectionSelector, + Func resultSelector) + { + return new ParallelQuery (new QuerySelectManyNode (source.Node, + collectionSelector, + resultSelector)); + } + #endregion + + #region Where + public static ParallelQuery Where (this ParallelQuery source, Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return new ParallelQuery (new QueryWhereNode (source.Node, predicate)); + } + + public static ParallelQuery Where (this ParallelQuery source, Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return new ParallelQuery (new QueryWhereNode (source.Node, predicate)); + } + #endregion + + #region Aggregate + public static TSource Aggregate (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Aggregate ((Func)null, + func, + func, + (e) => e); + } + + public static TAccumulate Aggregate (this ParallelQuery source, + TAccumulate seed, + Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Aggregate (seed, func, (e) => e); + } + + public static TResult Aggregate (this ParallelQuery source, + TAccumulate seed, + Func func, + Func resultSelector) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + if (resultSelector == null) + throw new ArgumentNullException ("resultSelector"); + + TAccumulate accumulator = seed; + + foreach (TSource value in source) + accumulator = func (accumulator, value); + + return resultSelector (accumulator); + } + + public static TResult Aggregate (this ParallelQuery source, + TAccumulate seed, + Func updateAccumulatorFunc, + Func combineAccumulatorsFunc, + Func resultSelector) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (updateAccumulatorFunc == null) + throw new ArgumentNullException ("updateAccumulatorFunc"); + if (combineAccumulatorsFunc == null) + throw new ArgumentNullException ("combineAccumulatorsFunc"); + if (resultSelector == null) + throw new ArgumentNullException ("resultSelector"); + + return source.Aggregate (() => seed, updateAccumulatorFunc, combineAccumulatorsFunc, resultSelector); + } + + public static TResult Aggregate (this ParallelQuery source, + Func seedFunc, + Func updateAccumulatorFunc, + Func combineAccumulatorsFunc, + Func resultSelector) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (seedFunc == null) + throw new ArgumentNullException ("seedFunc"); + if (updateAccumulatorFunc == null) + throw new ArgumentNullException ("updateAccumulatorFunc"); + if (combineAccumulatorsFunc == null) + throw new ArgumentNullException ("combineAccumulatorsFunc"); + if (resultSelector == null) + throw new ArgumentNullException ("resultSelector"); + + TAccumulate accumulator = default (TAccumulate); + + ParallelExecuter.ProcessAndAggregate (source.Node, seedFunc, updateAccumulatorFunc, (list) => { + accumulator = list [0]; + for (int i = 1; i < list.Count; i++) + accumulator = combineAccumulatorsFunc (accumulator, list[i]); + }); + + return resultSelector (accumulator);; + } + #endregion + + #region ForAll + public static void ForAll (this ParallelQuery source, Action action) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (action == null) + throw new ArgumentNullException ("action"); + + ParallelExecuter.ProcessAndBlock (source.Node, action); + } + #endregion + + #region OrderBy + public static OrderedParallelQuery OrderByDescending (this ParallelQuery source, + Func keySelector, + IComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (keySelector == null) + throw new ArgumentNullException ("keySelector"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + Comparison comparison = (e1, e2) => -comparer.Compare (keySelector (e1), keySelector (e2)); + + return new OrderedParallelQuery (new QueryOrderByNode (source.Node, comparison)); + } + + public static OrderedParallelQuery OrderByDescending (this ParallelQuery source, + Func keySelector) + { + return OrderByDescending (source, keySelector, Comparer.Default); + } + + public static OrderedParallelQuery OrderBy (this ParallelQuery source, + Func keySelector) + { + return OrderBy (source, keySelector, Comparer.Default); + } + + public static OrderedParallelQuery OrderBy (this ParallelQuery source, + Func keySelector, + IComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (keySelector == null) + throw new ArgumentNullException ("keySelector"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + Comparison comparison = (e1, e2) => comparer.Compare (keySelector (e1), keySelector (e2)); + + return new OrderedParallelQuery (new QueryOrderByNode (source.Node, comparison)); + } + #endregion + + #region ThenBy + public static OrderedParallelQuery ThenBy (this OrderedParallelQuery source, + Func keySelector) + { + return ThenBy (source, keySelector, Comparer.Default); + } + + public static OrderedParallelQuery ThenBy (this OrderedParallelQuery source, + Func keySelector, + IComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (keySelector == null) + throw new ArgumentNullException ("keySelector"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + Comparison comparison = (e1, e2) => comparer.Compare (keySelector (e1), keySelector (e2)); + + return new OrderedParallelQuery (new QueryOrderByNode (source.Node, comparison)); + } + + public static OrderedParallelQuery ThenByDescending (this OrderedParallelQuery source, + Func keySelector) + { + return ThenByDescending (source, keySelector, Comparer.Default); + } + + public static OrderedParallelQuery ThenByDescending (this OrderedParallelQuery source, + Func keySelector, + IComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (keySelector == null) + throw new ArgumentNullException ("keySelector"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + Comparison comparison = (e1, e2) => -comparer.Compare (keySelector (e1), keySelector (e2)); + + return new OrderedParallelQuery (new QueryOrderByNode (source.Node, comparison)); + } + #endregion + + #region All + public static bool All (ParallelQuery source, Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + CancellationTokenSource src = new CancellationTokenSource (); + ParallelQuery innerQuery = source.WithImplementerToken (src); + + bool result = true; + innerQuery.ForAll ((e) => { + if (!predicate (e)) { + result = false; + src.Cancel (); + } + }); + + return result; + } + #endregion + + #region Any + public static bool Any (this ParallelQuery source) + { + return Any (source, (_) => true); + } + + public static bool Any (this ParallelQuery source, Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return !source.All ((e) => !predicate (e)); + } + #endregion + + #region Contains + public static bool Contains (this ParallelQuery source, TSource value) + { + return Contains (source, value, EqualityComparer.Default); + } + + public static bool Contains (this ParallelQuery source, TSource value, IEqualityComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + return Any (source, (e) => comparer.Equals (value)); + } + #endregion + + #region SequenceEqual + public static bool SequenceEqual (this ParallelQuery first, + ParallelQuery second) + { + if (first == null) + throw new ArgumentNullException ("first"); + if (second == null) + throw new ArgumentNullException ("second"); + + return first.SequenceEqual (second, EqualityComparer.Default); + } + + public static bool SequenceEqual (this ParallelQuery first, + ParallelQuery second, + IEqualityComparer comparer) + { + if (first == null) + throw new ArgumentNullException ("first"); + if (second == null) + throw new ArgumentNullException ("second"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + CancellationTokenSource source = new CancellationTokenSource (); + ParallelQuery innerQuery + = first.Zip (second, (e1, e2) => comparer.Equals (e1, e2)).Where ((e) => !e).WithImplementerToken (source); + + bool result = true; + + innerQuery.ForAll ((value) => { + result = false; + source.Cancel (); + }); + + return result; + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static bool SequenceEqual (this ParallelQuery first, IEnumerable second) + { + throw new NotSupportedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static bool SequenceEqual (this ParallelQuery first, + IEnumerable second, + IEqualityComparer comparer) + { + throw new NotSupportedException (); + } + + #endregion + + #region GroupBy + public static ParallelQuery> GroupBy ( this ParallelQuery source, + Func keySelector) + { + return source.GroupBy (keySelector, EqualityComparer.Default); + } + + public static ParallelQuery> GroupBy ( this ParallelQuery source, + Func keySelector, + IEqualityComparer comparer) + { + return source.GroupBy (keySelector, (e) => e, comparer); + } + + public static ParallelQuery> GroupBy (this ParallelQuery source, + Func keySelector, + Func elementSelector) + { + return source.GroupBy (keySelector, elementSelector, EqualityComparer.Default); + } + + public static ParallelQuery GroupBy (this ParallelQuery source, + Func keySelector, + Func, TResult> resultSelector) + { + return source.GroupBy (keySelector) + .Select ((g) => resultSelector (g.Key, (IEnumerable)g)); + } + + public static ParallelQuery> GroupBy (this ParallelQuery source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + throw new NotImplementedException (); + } + + public static ParallelQuery GroupBy (this ParallelQuery source, + Func keySelector, + Func elementSelector, + Func, TResult> resultSelector) + { + return source.GroupBy (keySelector, elementSelector) + .Select ((g) => resultSelector (g.Key, (IEnumerable)g)); + } + + public static ParallelQuery GroupBy ( this ParallelQuery source, + Func keySelector, + Func, TResult> resultSelector, + IEqualityComparer comparer) + { + return source.GroupBy (keySelector, comparer) + .Select ((g) => resultSelector (g.Key, (IEnumerable)g)); + } + + public static ParallelQuery GroupBy (this ParallelQuery source, + Func keySelector, + Func elementSelector, + Func, TResult> resultSelector, + IEqualityComparer comparer) + { + return source.GroupBy (keySelector, elementSelector, comparer) + .Select ((g) => resultSelector (g.Key, (IEnumerable)g)); + } + #endregion + + #region GroupJoin + public static ParallelQuery GroupJoin (this ParallelQuery outer, + ParallelQuery inner, + Func outerKeySelector, + Func innerKeySelector, + Func, TResult> resultSelector) + { + return outer.GroupJoin (inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static ParallelQuery GroupJoin (this ParallelQuery outer, + ParallelQuery inner, + Func outerKeySelector, + Func innerKeySelector, + Func, TResult> resultSelector, + IEqualityComparer comparer) + { + throw new NotImplementedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery GroupJoin (this ParallelQuery outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func, TResult> resultSelector) + { + throw new NotSupportedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery GroupJoin (this ParallelQuery outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func, TResult> resultSelector, + IEqualityComparer comparer) + { + throw new NotImplementedException (); + } + #endregion + + #region ElementAt + public static TSource ElementAt ( this ParallelQuery source, int index) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (index < 0) + throw new ArgumentOutOfRangeException ("index"); + if (index == 0) { + try { + return source.First (); + } catch (InvalidOperationException) { + throw new ArgumentOutOfRangeException ("index"); + } + } + + TSource result = default (TSource); + + ParallelQuery innerQuery = source.Where ((e, i) => i == index); + + try { + result = innerQuery.First (); + } catch (InvalidOperationException) { + throw new ArgumentOutOfRangeException ("index"); + } + + return result; + } + + public static TSource ElementAtOrDefault (this ParallelQuery source, int index) + { + if (source == null) + throw new ArgumentNullException ("source"); + + try { + return source.ElementAt (index); + } catch (ArgumentOutOfRangeException) { + return default (TSource); + } + } + #endregion + + #region Intersect + public static ParallelQuery Intersect (this ParallelQuery first, + ParallelQuery second) + { + return Intersect (first, second, EqualityComparer.Default); + } + + public static ParallelQuery Intersect (this ParallelQuery first, + ParallelQuery second, + IEqualityComparer comparer) + { + if (first == null) + throw new ArgumentNullException ("first"); + if (second == null) + throw new ArgumentNullException ("second"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + return new ParallelQuery (new QuerySetNode (SetInclusionDefaults.Intersect, comparer, first.Node, second.Node)); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Intersect (this ParallelQuery first, IEnumerable second) + { + throw new NotSupportedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Intersect (this ParallelQuery first, + IEnumerable second, + IEqualityComparer comparer) + { + throw new NotSupportedException (); + } + #endregion + + #region Join + public static ParallelQuery Join ( this ParallelQuery outer, + ParallelQuery inner, + Func outerKeySelector, + Func innerKeySelector, + Func resultSelector) + { + return outer.Join (inner, outerKeySelector, innerKeySelector, resultSelector, EqualityComparer.Default); + } + + public static ParallelQuery Join ( this ParallelQuery outer, + ParallelQuery inner, + Func outerKeySelector, + Func innerKeySelector, + Func resultSelector, + IEqualityComparer comparer) + { + throw new NotImplementedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Join ( this ParallelQuery outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func resultSelector) + { + throw new NotSupportedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Join (this ParallelQuery outer, + IEnumerable inner, + Func outerKeySelector, + Func innerKeySelector, + Func resultSelector, + IEqualityComparer comparer) + { + throw new NotSupportedException (); + } + #endregion + + #region Except + public static ParallelQuery Except ( this ParallelQuery first, + ParallelQuery second) + { + return Except (first, second, EqualityComparer.Default); + } + + public static ParallelQuery Except ( this ParallelQuery first, + ParallelQuery second, + IEqualityComparer comparer) + { + if (first == null) + throw new ArgumentNullException ("first"); + if (second == null) + throw new ArgumentNullException ("second"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + return new ParallelQuery (new QuerySetNode (SetInclusionDefaults.Except, + comparer, first.Node, second.Node)); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Except (this ParallelQuery first, + IEnumerable second) + { + throw new NotSupportedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Except ( this ParallelQuery first, + IEnumerable second, + IEqualityComparer comparer) + { + throw new NotSupportedException (); + } + #endregion + + #region Distinct + public static ParallelQuery Distinct (this ParallelQuery source) + { + return Distinct (source, EqualityComparer.Default); + } + + public static ParallelQuery Distinct (this ParallelQuery source, IEqualityComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + return new ParallelQuery (new QuerySetNode (SetInclusionDefaults.Distinct, comparer, + source.Node, null)); + } + #endregion + + #region Union + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Union (this ParallelQuery first, + IEnumerable second) + { + throw new NotSupportedException (); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Union(this ParallelQuery first, + IEnumerable second, + IEqualityComparer comparer) + { + throw new NotSupportedException (); + } + + public static ParallelQuery Union (this ParallelQuery first, + ParallelQuery second) + { + return first.Union (second, EqualityComparer.Default); + } + + public static ParallelQuery Union (this ParallelQuery first, + ParallelQuery second, + IEqualityComparer comparer) + { + if (first == null) + throw new ArgumentNullException ("first"); + if (second == null) + throw new ArgumentNullException ("second"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + + return new ParallelQuery (new QuerySetNode (SetInclusionDefaults.Union, comparer, first.Node, second.Node)); + } + #endregion + + #region Take + // TODO : introduce some early break up here, use ImplementerToken + public static ParallelQuery Take (this ParallelQuery source, int count) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Where ((e, i) => i < count); + } + + public static ParallelQuery TakeWhile (this ParallelQuery source, + Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where ((e) => predicate (e)); + } + + public static ParallelQuery TakeWhile (this ParallelQuery source, + Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where ((e, i) => predicate (e, i)); + } + #endregion + + #region Skip + public static ParallelQuery Skip (this ParallelQuery source, int count) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Where ((e, i) => i >= count); + } + + public static ParallelQuery SkipWhile (this ParallelQuery source, + Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where ((e) => !predicate (e)); + } + + public static ParallelQuery SkipWhile (this ParallelQuery source, + Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where ((e, i) => !predicate (e, i)); + } + #endregion + + #region Single + static TSource SingleInternal (this ParallelQuery source, params TSource[] init) + { + TSource result = default(TSource); + bool hasValue = false; + + foreach (TSource element in source) { + if (hasValue) + throw new InvalidOperationException ("The input sequence contains more than one element."); + + result = element; + hasValue = true; + } + + if (!hasValue && init.Length != 0) { + result = init[0]; + hasValue = true; + } + + if (!hasValue) + throw new InvalidOperationException ("The input sequence is empty."); + + return result; + } + + public static TSource Single (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return SingleInternal (source); + } + + public static TSource Single (this ParallelQuery source, + Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where (predicate).Single (); + } + + public static TSource SingleOrDefault (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return SingleInternal (source, default (TSource)); + } + + public static TSource SingleOrDefault (this ParallelQuery source, Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where (predicate).SingleOrDefault (); + } + #endregion + + #region Count + public static int Count (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (() => 0, + (acc, e) => acc + 1, + (acc1, acc2) => acc1 + acc2, + (result) => result); + } + + public static int Count (this ParallelQuery source, Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where (predicate).Count (); + } + + public static long LongCount (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (() => 0, + (acc, e) => acc + 1, + (acc1, acc2) => acc1 + acc2, + (result) => result); + } + + public static long LongCount (this ParallelQuery source, Func predicate) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (predicate == null) + throw new ArgumentNullException ("predicate"); + + return source.Where (predicate).LongCount (); + } + #endregion + + #region Average + public static double Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (() => new int[2], + (acc, e) => { acc[0] += e; acc[1]++; return acc; }, + (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }, + (acc) => acc[0] / ((double)acc[1])); + } + + public static double Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (() => new long[2], + (acc, e) => { acc[0] += e; acc[1]++; return acc; }, + (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }, + (acc) => acc[0] / ((double)acc[1])); + } + + public static decimal Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (() => new decimal[2], + (acc, e) => { acc[0] += e; acc[1]++; return acc; }, + (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }, + (acc) => acc[0] / acc[1]); + } + + public static double Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (() => new double[2], + (acc, e) => { acc[0] += e; acc[1]++; return acc; }, + (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }, + (acc) => acc[0] / ((double)acc[1])); + } + + public static float Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (() => new float[2], + (acc, e) => { acc[0] += e; acc[1]++; return acc; }, + (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }, + (acc) => acc[0] / acc[1]); + } + #endregion + + #region More Average + public static double? Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Average ();; + } + + public static double? Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Average (); + } + + public static decimal? Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Average (); + } + + public static double? Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Average (); + } + + public static float? Average (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Average (); + } + + public static double Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static double Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static float Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static double Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static decimal Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static double? Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static double? Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static float? Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static double? Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + + public static decimal? Average (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Average (); + } + #endregion + + #region Sum + public static int Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (0, (e1, e2) => e1 + e2, (sum1, sum2) => sum1 + sum2, (sum) => sum); + } + + public static long Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate ((long)0, (e1, e2) => e1 + e2, (sum1, sum2) => sum1 + sum2, (sum) => sum); + } + + public static float Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (0.0f, (e1, e2) => e1 + e2, (sum1, sum2) => sum1 + sum2, (sum) => sum); + } + + public static double Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate (0.0, (e1, e2) => e1 + e2, (sum1, sum2) => sum1 + sum2, (sum) => sum); + } + + public static decimal Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Aggregate ((decimal)0, (e1, e2) => e1 + e2, (sum1, sum2) => sum1 + sum2, (sum) => sum); + } + + public static int? Sum (ParallelQuery source) + { + return source.Select ((e) => e.HasValue ? e.Value : 0).Sum (); + } + + public static long? Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Sum (); + } + + public static float? Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Sum (); + } + + public static double? Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Sum (); + } + + public static decimal? Sum (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : 0).Sum (); + } + + public static int Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static long Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static decimal Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static float Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static double Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static int? Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static long? Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static decimal? Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static float? Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + + public static double? Sum (ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Sum (); + } + #endregion + + #region Min-Max + static T BestOrder (ParallelQuery source, Func bestSelector, T seed) + { + if (source == null) + throw new ArgumentNullException ("source"); + + T best = seed; + + best = source.Aggregate (() => seed, + (first, second) => (bestSelector(first, second)) ? first : second, + (first, second) => (bestSelector(first, second)) ? first : second, + (e) => e); + return best; + } + + public static int Min (this ParallelQuery source) + { + return BestOrder (source, (first, second) => first < second, int.MaxValue); + } + + public static long Min (this ParallelQuery source) + { + return BestOrder (source, (first, second) => first < second, long.MaxValue); + } + + public static float Min (this ParallelQuery source) + { + return BestOrder (source, (first, second) => first < second, float.MaxValue); + } + + public static double Min (this ParallelQuery source) + { + return BestOrder (source, (first, second) => first < second, double.MaxValue); + } + + public static decimal Min (this ParallelQuery source) + { + return BestOrder (source, (first, second) => first < second, decimal.MaxValue); + } + + public static TSource Min (this ParallelQuery source) + { + IComparer comparer = Comparer.Default; + + return BestOrder (source, (first, second) => comparer.Compare (first, second) < 0, default (TSource)); + } + + public static TResult Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static int? Min (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : int.MaxValue).Min (); + } + + public static long? Min (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : long.MaxValue).Min (); + } + + public static float? Min (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : float.MaxValue).Min (); + } + + public static double? Min (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : double.MaxValue).Min (); + } + + public static decimal? Min (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : decimal.MaxValue).Min (); + } + + public static int Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static long Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static float Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static double Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static decimal Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static int? Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static long? Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static float? Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static double? Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static decimal? Min (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Min (); + } + + public static int Max (this ParallelQuery source) + { + return BestOrder (source, (first, second) => first > second, int.MinValue); + } + + public static long Max(this ParallelQuery source) + { + return BestOrder(source, (first, second) => first > second, long.MinValue); + } + + public static float Max (this ParallelQuery source) + { + return BestOrder(source, (first, second) => first > second, float.MinValue); + } + + public static double Max (this ParallelQuery source) + { + return BestOrder(source, (first, second) => first > second, double.MinValue); + } + + public static decimal Max (this ParallelQuery source) + { + return BestOrder(source, (first, second) => first > second, decimal.MinValue); + } + + public static TSource Max (this ParallelQuery source) + { + IComparer comparer = Comparer.Default; + + return BestOrder (source, (first, second) => comparer.Compare (first, second) > 0, default (TSource)); + } + + public static TResult Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static int? Max (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : int.MinValue).Max (); + } + + public static long? Max (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : long.MinValue).Max (); + } + + public static float? Max (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : float.MinValue).Max (); + } + + public static double? Max (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : double.MinValue).Max (); + } + + public static decimal? Max (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.Select ((e) => e.HasValue ? e.Value : decimal.MinValue).Max (); + } + + public static int Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static long Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static float Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static double Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static decimal Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static int? Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static long? Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static float? Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static double? Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + + public static decimal? Max (this ParallelQuery source, Func func) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (func == null) + throw new ArgumentNullException ("func"); + + return source.Select (func).Max (); + } + #endregion + + #region Cast / OfType + public static ParallelQuery Cast (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.TypedQuery.Select ((e) => (TResult)e); + } + + public static ParallelQuery OfType (ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return source.TypedQuery.Where ((e) => e is TResult).Cast (); + } + #endregion + + #region Reverse + public static ParallelQuery Reverse (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + return new ParallelQuery (new QueryReverseNode (source)); + } + #endregion + + #region ToArray - ToList - ToDictionary - ToLookup + public static List ToList (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + OrderedParallelQuery ordered = null; + if ((ordered = source as OrderedParallelQuery) != null) + return ToListOrdered (ordered); + + List temp = source.Aggregate (() => new List(50), + (list, e) => { list.Add (e); return list; }, + (list, list2) => { list.AddRange (list2); return list; }, + (list) => list); + return temp; + } + + static List ToListOrdered (this OrderedParallelQuery source) + { + List result = new List (); + + foreach (TSource element in source) + result.Add (element); + + return result; + } + + public static TSource[] ToArray (this ParallelQuery source) + { + if (source == null) + throw new ArgumentNullException ("source"); + + TSource[] result = null; + + Func, TSource, List> intermediate = (list, e) => { + list.Add (e); return list; + }; + + Action>> final = (list) => { + int count = 0; + + for (int i = 0; i < list.Count; i++) + count += list[i].Count; + + result = new TSource[count]; + int insertIndex = -1; + + for (int i = 0; i < list.Count; i++) + for (int j = 0; j < list[i].Count; j++) + result [++insertIndex] = list[i][j]; + }; + + ParallelExecuter.ProcessAndAggregate> (source.Node, + () => new List (), + intermediate, + final); + + return result; + } + + public static Dictionary ToDictionary (this ParallelQuery source, + Func keySelector, + IEqualityComparer comparer) + { + return ToDictionary (source, keySelector, (e) => e, comparer); + } + + public static Dictionary ToDictionary (this ParallelQuery source, + Func keySelector) + { + return ToDictionary (source, keySelector, (e) => e, EqualityComparer.Default); + } + + public static Dictionary ToDictionary (this ParallelQuery source, + Func keySelector, + Func elementSelector) + { + return ToDictionary (source, keySelector, elementSelector, EqualityComparer.Default); + } + + public static Dictionary ToDictionary (this ParallelQuery source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (keySelector == null) + throw new ArgumentNullException ("keySelector"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + if (elementSelector == null) + throw new ArgumentNullException ("elementSelector"); + + return source.Aggregate (() => new Dictionary (comparer), + (d, e) => { d.Add (keySelector (e), elementSelector (e)); return d; }, + (d1, d2) => { foreach (var couple in d2) d1.Add (couple.Key, couple.Value); return d1; }, + (d) => d); + } + + public static ILookup ToLookup ( this ParallelQuery source, + Func keySelector) + { + return ToLookup (source, keySelector, (e) => e, EqualityComparer.Default); + } + + public static ILookup ToLookup ( this ParallelQuery source, + Func keySelector, + IEqualityComparer comparer) + { + return ToLookup (source, keySelector, (e) => e, comparer); + } + + public static ILookup ToLookup (this ParallelQuery source, + Func keySelector, + Func elementSelector) + { + return ToLookup (source, keySelector, elementSelector, EqualityComparer.Default); + } + + public static ILookup ToLookup (this ParallelQuery source, + Func keySelector, + Func elementSelector, + IEqualityComparer comparer) + { + if (source == null) + throw new ArgumentNullException ("source"); + if (keySelector == null) + throw new ArgumentNullException ("keySelector"); + if (comparer == null) + throw new ArgumentNullException ("comparer"); + if (elementSelector == null) + throw new ArgumentNullException ("elementSelector"); + + ConcurrentLookup lookup = new ConcurrentLookup (comparer); + source.ForAll ((e) => lookup.Add (keySelector (e), elementSelector (e))); + + return lookup; + } + #endregion + + #region Concat + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather than " + + "System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() extension method " + + "to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Concat(this ParallelQuery first, + IEnumerable second) + { + throw new NotSupportedException (); + } + + public static ParallelQuery Concat ( this ParallelQuery first, ParallelQuery second) + { + return new ParallelQuery (new QueryConcatNode (first.Node, second.Node)); + } + #endregion + + #region DefaultIfEmpty + public static ParallelQuery DefaultIfEmpty ( this ParallelQuery source) + { + return source.DefaultIfEmpty (default (TSource)); + } + + public static ParallelQuery DefaultIfEmpty ( this ParallelQuery source, TSource defaultValue) + { + return new ParallelQuery (new QueryDefaultEmptyNode (source.Node, defaultValue)); + } + #endregion + + #region First + public static TSource First ( this ParallelQuery source) + { + CancellationTokenSource src = new CancellationTokenSource (); + IEnumerator enumerator = source.WithImplementerToken (src).GetEnumerator (); + + if (enumerator == null || !enumerator.MoveNext ()) + throw new InvalidOperationException ("source contains no element"); + + TSource result = enumerator.Current; + src.Cancel (); + + return result; + } + + public static TSource First ( this ParallelQuery source, Func predicate) + { + return source.Where (predicate).First (); + } + + public static TSource FirstOrDefault (this ParallelQuery source) + { + return source.DefaultIfEmpty ().First (); + } + + public static TSource FirstOrDefault (this ParallelQuery source, Func predicate) + { + return source.Where (predicate).FirstOrDefault (); + } + #endregion + + #region Last + public static TSource Last (this ParallelQuery source) + { + return source.Reverse ().First (); + } + + public static TSource Last ( this ParallelQuery source, Func predicate) + { + return source.Reverse ().First (predicate); + } + + public static TSource LastOrDefault (this ParallelQuery source) + { + return source.Reverse ().FirstOrDefault (); + } + + public static TSource LastOrDefault (this ParallelQuery source, Func predicate) + { + return source.Reverse ().FirstOrDefault (predicate); + } + #endregion + + #region Zip + public static ParallelQuery Zip (this ParallelQuery first, + ParallelQuery second, + Func resultSelector) + { + if (first == null) + throw new ArgumentNullException ("first"); + if (second == null) + throw new ArgumentNullException ("second"); + if (resultSelector == null) + throw new ArgumentNullException ("resultSelector"); + + return new ParallelQuery (new QueryZipNode (resultSelector, first.Node, second.Node)); + } + + [ObsoleteAttribute("The second data source of a binary operator must be of type System.Linq.ParallelQuery rather " + + "than System.Collections.Generic.IEnumerable. To fix this problem, use the AsParallel() " + + "extension method to convert the right data source to System.Linq.ParallelQuery.")] + public static ParallelQuery Zip (this ParallelQuery first, + IEnumerable second, + Func resultSelector) + { + throw new NotSupportedException (); + } + #endregion + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/ParallelExecuter.cs b/mcs/class/System.Core/System.Linq/ParallelExecuter.cs new file mode 100644 index 00000000000..24f9c1a4f6b --- /dev/null +++ b/mcs/class/System.Core/System.Linq/ParallelExecuter.cs @@ -0,0 +1,193 @@ +#if NET_4_0 +// +// ParallelExecuter.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Threading.Tasks; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace System.Linq +{ + // TODO: Refactory each of the Process method into one big entity + // Check CancellationToken.Canceled parameter in the Task's action body too + internal static class ParallelExecuter + { + internal static QueryOptions CheckQuery (QueryBaseNode startingNode) + { + return CheckQuery (startingNode, false); + } + + internal static QueryOptions CheckQuery (QueryBaseNode startingNode, bool blocking) + { + return CheckQuery (startingNode, GetBestWorkerNumber (blocking)); + } + + internal static QueryOptions CheckQuery (QueryBaseNode startingNode, int partitionCount) + { + QueryCheckerVisitor visitor = new QueryCheckerVisitor (partitionCount); + startingNode.Visit (visitor); + + return visitor.Options; + } + + // QueryOptions.ImplementerToken = QueryOptions.ImplementerToken.Chain (myOperatorSource); + internal static CancellationToken Chain (this CancellationToken self, CancellationTokenSource other) + { + CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource (self, other.Token); + return linked.Token; + } + + internal static int GetBestWorkerNumber () + { + return GetBestWorkerNumber (false); + } + + internal static int GetBestWorkerNumber (bool blocking) + { + return blocking ? Environment.ProcessorCount + 1 : Environment.ProcessorCount; + } + + internal static Task[] Process (QueryBaseNode node, Action call, + Func, QueryOptions, IList>> acquisitionFunc, + QueryOptions options) + { + return Process (node, call, acquisitionFunc, null, options); + } + + internal static Task[] Process (QueryBaseNode node, Action call, + Func, QueryOptions, IList>> acquisitionFunc, + Action endAction, + QueryOptions options) + { + IList> enumerables = acquisitionFunc (node, options); + + Task[] tasks = new Task[enumerables.Count]; + + for (int i = 0; i < tasks.Length; i++) { + int index = i; + tasks[i] = Task.Factory.StartNew (() => { + foreach (TElement item in enumerables[index]) { + // This is from specific operators + if (options.ImplementerToken.IsCancellationRequested) + break; + if (options.Token.IsCancellationRequested) + throw new OperationCanceledException (options.Token); + + call (item); + } + if (endAction != null) + endAction (); + }, options.Token); + } + + return tasks; + } + + internal static void ProcessAndBlock (QueryBaseNode node, Action call) + { + QueryOptions options = CheckQuery (node, true); + + Task[] tasks = Process (node, call, (n, o) => n.GetEnumerables (o), options); + Task.WaitAll (tasks, options.Token); + } + + internal static Action ProcessAndCallback (QueryBaseNode node, Action call, + Action callback, QueryOptions options) + { + Task[] tasks = Process (node, call, (n, o) => n.GetEnumerables (o), options); + Task.Factory.ContinueWhenAll (tasks, (_) => callback ()); + + return () => Task.WaitAll (tasks, options.Token); + } + + internal static Action ProcessAndCallback (QueryBaseNode node, Action> call, + Action callback, QueryOptions options) + { + return ProcessAndCallback (node, call, null, callback, options); + } + + internal static Action ProcessAndCallback (QueryBaseNode node, Action> call, + Action endAction, + Action callback, QueryOptions options) + { + Task[] tasks = Process (node, call, (n, o) => n.GetOrderedEnumerables (o), endAction, options); + Task.Factory.ContinueWhenAll (tasks, (_) => callback ()); + + return () => Task.WaitAll (tasks, options.Token); + } + + internal static void ProcessAndAggregate (QueryBaseNode node, + Func seedFunc, + Func localCall, + Action> call) + { + QueryOptions options = CheckQuery (node, true); + + IList> enumerables = node.GetEnumerables (options); + U[] locals = new U[enumerables.Count]; + Task[] tasks = new Task[enumerables.Count]; + + bool init = false; + if (seedFunc != null) { + for (int i = 0; i < locals.Length; i++) + locals[i] = seedFunc (); + init = true; + } + + for (int i = 0; i < tasks.Length; i++) { + int index = i; + tasks[i] = Task.Factory.StartNew (() => { + foreach (T item in enumerables[index]) { + // This is from specific operators + if (options.ImplementerToken.IsCancellationRequested) + break; + if (options.Token.IsCancellationRequested) + throw new OperationCanceledException (options.Token); + + if (!init) { + init = true; + // HACK: TODO: omfwtfitsomuchsucks + locals[index] = (U)(object)item; + continue; + } + + U acc = locals[index]; + locals[index] = localCall (acc, item); + } + }, options.Token); + } + + Task.WaitAll (tasks, options.Token); + + if (call != null) + call (locals); + } + } +} +#endif \ No newline at end of file diff --git a/mcs/class/System.Core/System.Linq/ParallelExecutionMode.cs b/mcs/class/System.Core/System.Linq/ParallelExecutionMode.cs new file mode 100644 index 00000000000..b3c51f70eb6 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/ParallelExecutionMode.cs @@ -0,0 +1,38 @@ +#if NET_4_0 +// +// ParallelExecutionMode.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace System.Linq +{ + public enum ParallelExecutionMode + { + Default = 0, + ForceParallelism = 1 + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/ParallelMergeOptions.cs b/mcs/class/System.Core/System.Linq/ParallelMergeOptions.cs new file mode 100644 index 00000000000..0adea44bc85 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/ParallelMergeOptions.cs @@ -0,0 +1,40 @@ +#if NET_4_0 +// +// ParallelMergeOptions.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; + +namespace System.Linq +{ + public enum ParallelMergeOptions + { + Default = 0, + NotBuffered, + AutoBuffered, + FullyBuffered + } +} +#endif \ No newline at end of file diff --git a/mcs/class/System.Core/System.Linq/ParallelPartitioner.cs b/mcs/class/System.Core/System.Linq/ParallelPartitioner.cs new file mode 100644 index 00000000000..50d623510c8 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/ParallelPartitioner.cs @@ -0,0 +1,76 @@ +// +// ParallelPartitioner.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Collections.Concurrent; + +#if NET_4_0 + +namespace System.Linq +{ + internal static class ParallelPartitioner + { + internal static OrderablePartitioner CreateForChunks (IEnumerable source) + { + return Partitioner.Create (source); + } + + internal static OrderablePartitioner CreateForRange (IList source) + { + return Partitioner.Create (source, true); + } + + internal static OrderablePartitioner CreateBest (IEnumerable source) + { + IList temp = source as IList; + if (temp != null) + return CreateForRange (temp); + + return CreateForChunks (source); + } + + internal static OrderablePartitioner CreateForStrips (IEnumerable source, int stripSize) + { + IList temp = source as IList; + if (temp != null) + return new StripPartitioner (temp); + + return new EnumerablePartitioner (source, stripSize, 1); + } + + internal static OrderablePartitioner CreateForRange (int start, int count) + { + return CreateForRange (new RangeList (start, count)); + } + + internal static OrderablePartitioner CreateForRepeat (T obj, int count) + { + return CreateForRange (new RepeatList (obj, count)); + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/ParallelQuery.cs b/mcs/class/System.Core/System.Linq/ParallelQuery.cs new file mode 100644 index 00000000000..6d99813c026 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/ParallelQuery.cs @@ -0,0 +1,125 @@ +// +// ParallelQuery.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +#if NET_4_0 + +namespace System.Linq +{ + public class ParallelQuery : IEnumerable + { + ParallelExecutionMode execMode = ParallelExecutionMode.Default; + ParallelMergeOptions mergeOptions = ParallelMergeOptions.Default; + + internal ParallelQuery () + { + + } + + internal ParallelMergeOptions MergeOptions { + get { + return mergeOptions; + } + set { + mergeOptions = value; + } + } + + internal ParallelExecutionMode ExecMode { + get { + return execMode; + } + set { + execMode = value; + } + } + + IEnumerator IEnumerable.GetEnumerator () + { + return GetEnumeratorTrick (); + } + + // Trick to get the correct IEnumerator from ParallelQuery + internal virtual IEnumerator GetEnumeratorTrick () + { + return null; + } + + internal virtual ParallelQuery TypedQuery { + get { + return null; + } + } + } + + public class ParallelQuery : ParallelQuery, IEnumerable, IEnumerable + { + QueryBaseNode node; + + internal ParallelQuery (QueryBaseNode node) + { + this.node = node; + } + + internal QueryBaseNode Node { + get { + return node; + } + } + + public virtual IEnumerator GetEnumerator () + { + return GetEnumeratorInternal (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return (IEnumerator)GetEnumeratorInternal (); + } + + IEnumerator GetEnumeratorInternal () + { + return new ParallelQueryEnumerator (node); + } + + internal override IEnumerator GetEnumeratorTrick () + { + return (IEnumerator)GetEnumeratorInternal (); + } + + internal override ParallelQuery TypedQuery { + get { + return new ParallelQuery (new QueryCastNode (node)); + } + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/ParallelQueryEnumerator.cs b/mcs/class/System.Core/System.Linq/ParallelQueryEnumerator.cs new file mode 100644 index 00000000000..d40d20eb689 --- /dev/null +++ b/mcs/class/System.Core/System.Linq/ParallelQueryEnumerator.cs @@ -0,0 +1,128 @@ +// +// ParallelEnumerator.cs +// +// Author: +// Jérémie "Garuma" Laval +// +// Copyright (c) 2010 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Threading; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Concurrent; + +#if NET_4_0 + +namespace System.Linq +{ + internal class ParallelQueryEnumerator : IEnumerator + { + readonly int DefaultBufferSize = ParallelExecuter.GetBestWorkerNumber () * 50; + + BlockingCollection buffer; + IEnumerator loader; + QueryOptions options; + OrderingEnumerator ordEnumerator; + + T current; + + Action waitAction; + + internal ParallelQueryEnumerator (QueryBaseNode node) + { + this.options = ParallelExecuter.CheckQuery (node); + Setup (); + + // Launch adding to the buffer asynchronously via Tasks + if (options.BehindOrderGuard.Value) { + // Keep fairness between tasks (i.e. the same task don't ruin order by adding to much of its own) + Barrier barrier = new Barrier (options.PartitionCount); + waitAction = ParallelExecuter.ProcessAndCallback (node, + (e) => { ordEnumerator.KeyedBuffer.Add (e); barrier.SignalAndWait (); }, + barrier.RemoveParticipant, + ordEnumerator.KeyedBuffer.CompleteAdding, + options); + } else { + waitAction = ParallelExecuter.ProcessAndCallback (node, + buffer.Add, + buffer.CompleteAdding, + options); + } + + if (options.Options.HasValue && options.Options.Value == ParallelMergeOptions.FullyBuffered) + waitAction (); + } + + void Setup () + { + if (!options.BehindOrderGuard.Value) { + if (options.Options.HasValue && (options.Options.Value == ParallelMergeOptions.NotBuffered + || options.Options.Value == ParallelMergeOptions.FullyBuffered)) { + buffer = new BlockingCollection (); + } else { + buffer = new BlockingCollection (DefaultBufferSize); + } + + IEnumerable source = buffer.GetConsumingEnumerable (options.Token); + + loader = source.GetEnumerator (); + } else { + loader = ordEnumerator = new OrderingEnumerator (options.PartitionCount); + } + } + + public void Dispose () + { + + } + + public void Reset () + { + throw new NotSupportedException (); + } + + public bool MoveNext () + { + // If there are no stuff in the buffer + // but CompleteAdding hasn't been called, + // MoveNext blocks until further results are produced + if (!loader.MoveNext ()) + return false; + + current = loader.Current; + return true; + } + + public T Current { + get { + return current; + } + } + + object IEnumerator.Current { + get { + return current; + } + } + } +} +#endif diff --git a/mcs/class/System.Core/System.Linq/Queryable.cs b/mcs/class/System.Core/System.Linq/Queryable.cs index 4aaccdff3bb..a4830add0dd 100644 --- a/mcs/class/System.Core/System.Linq/Queryable.cs +++ b/mcs/class/System.Core/System.Linq/Queryable.cs @@ -1604,5 +1604,23 @@ namespace System.Linq { #endregion +#if NET_4_0 + #region Zip + + public static IQueryable Zip (this IQueryable source1, IEnumerable source2, Expression> resultSelector) + { + Check.Source1AndSource2 (source1, source2); + if (resultSelector == null) + throw new ArgumentNullException ("resultSelector"); + + return source1.Provider.CreateQuery ( + StaticCall ( + MakeGeneric (MethodBase.GetCurrentMethod (), typeof (TFirst), typeof (TSecond), typeof (TResult)), + source1.Expression, + Expression.Quote (resultSelector))); + } + + #endregion +#endif } } diff --git a/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs b/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs index f8ad6d115f4..34046f0a524 100644 --- a/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs +++ b/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs @@ -100,11 +100,7 @@ namespace System.Linq { static Expression TransformQueryable (Expression expression) { -#if NET_4_0 || BOOTSTRAP_NET_4_0 - throw new NotImplementedException (); -#else return new QueryableTransformer ().Transform (expression); -#endif } public IQueryable CreateQuery (Expression expression) diff --git a/mcs/class/System.Core/System.Linq/QueryableTransformer.cs b/mcs/class/System.Core/System.Linq/QueryableTransformer.cs index 4a3685898e9..307045f7c39 100644 --- a/mcs/class/System.Core/System.Linq/QueryableTransformer.cs +++ b/mcs/class/System.Core/System.Linq/QueryableTransformer.cs @@ -89,7 +89,7 @@ namespace System.Linq { parameters [i].ParameterType); } - return new MethodCallExpression (target, method, arguments.ToReadOnlyCollection ()); + return Expression.Call (target, method, arguments); } static Expression UnquoteIfNeeded (Expression expression, Type delegateType) diff --git a/mcs/class/System.Core/System.Linq/SortSequenceContext.cs b/mcs/class/System.Core/System.Linq/SortSequenceContext.cs index 2ec42114a41..a25427e60cb 100644 --- a/mcs/class/System.Core/System.Linq/SortSequenceContext.cs +++ b/mcs/class/System.Core/System.Linq/SortSequenceContext.cs @@ -62,8 +62,10 @@ namespace System.Linq { if (comparison == 0) { if (child_context != null) return child_context.Compare (first_index, second_index); - else - comparison = first_index - second_index; + + comparison = direction == SortDirection.Descending + ? second_index - first_index + : first_index - second_index; } return direction == SortDirection.Descending ? -comparison : comparison; diff --git a/mcs/class/System.Core/System.Runtime.CompilerServices/DynamicAttribute.cs b/mcs/class/System.Core/System.Runtime.CompilerServices/DynamicAttribute.cs index 2d9f7e07847..618551dcc15 100644 --- a/mcs/class/System.Core/System.Runtime.CompilerServices/DynamicAttribute.cs +++ b/mcs/class/System.Core/System.Runtime.CompilerServices/DynamicAttribute.cs @@ -26,7 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if NET_4_0 +#if NET_4_0 || BOOTSTRAP_NET_4_0 using System; using System.Collections.Generic; diff --git a/mcs/class/System.Core/System.Security.Cryptography/Aes.cs b/mcs/class/System.Core/System.Security.Cryptography/Aes.cs index 3c7da47c1d2..eaee476a500 100644 --- a/mcs/class/System.Core/System.Security.Cryptography/Aes.cs +++ b/mcs/class/System.Core/System.Security.Cryptography/Aes.cs @@ -29,7 +29,11 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // + +// Since 4.0 (both FX and SL) this type is defined in mscorlib - before 4.0 it was in System.Core.dll +#if (INSIDE_CORLIB && (NET_4_0 || BOOTSTRAP_NET_4_0 || MOONLIGHT)) || (!INSIDE_CORLIB && !NET_4_0 && !BOOTSTRAP_NET_4_0 && !MOONLIGHT) +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Security.Cryptography { @@ -37,12 +41,22 @@ namespace System.Security.Cryptography { // References: // a. FIPS PUB 197: Advanced Encryption Standard // http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf - + +#if INSIDE_CORLIB + // since 4.0 (both FX and SL) this type now resides inside mscorlib.dll and link back to System.Core.dll + #if MOONLIGHT + // version has not changed between SL3 (System.Core) and SL4 + [TypeForwardedFrom (Consts.AssemblySystem_Core)] + #elif NET_4_0 || BOOTSTRAP_NET_4_0 + // use 3.5 version + [TypeForwardedFrom ("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")] + #endif +#endif public abstract class Aes : SymmetricAlgorithm { - + public static new Aes Create () { - return Create ("System.Security.Cryptography.AesManaged, " + Consts.AssemblySystem_Core); + return Create ("System.Security.Cryptography.AesManaged, " + Consts.AssemblySystem_Core); } public static new Aes Create (string algName) @@ -66,3 +80,5 @@ namespace System.Security.Cryptography { } } } +#endif + diff --git a/mcs/class/System.Core/System.Security.Cryptography/ChangeLog b/mcs/class/System.Core/System.Security.Cryptography/ChangeLog index b25f7385f60..aef59b427ec 100644 --- a/mcs/class/System.Core/System.Security.Cryptography/ChangeLog +++ b/mcs/class/System.Core/System.Security.Cryptography/ChangeLog @@ -1,3 +1,8 @@ +2010-03-18 Sebastien Pouliot + + * Aes.cs: Build here before NET_4_0 (or MOONLIGHT) otherwise + build only if compiled from mscorlib.dll + 2009-11-12 Jb Evain * Aes.cs: avoid using an hardcoded assembly version for System.Core. diff --git a/mcs/class/System.Core/System/Actions.cs b/mcs/class/System.Core/System/Actions.cs index f2a1126214b..5100db90a02 100644 --- a/mcs/class/System.Core/System/Actions.cs +++ b/mcs/class/System.Core/System/Actions.cs @@ -4,7 +4,7 @@ // Authors: // Marek Safar // -// Copyright (C) 2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2007, 2010 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -26,14 +26,16 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#if NET_4_0 || BOOTSTRAP_NET_4_0 using System; using System.Runtime.CompilerServices; +#if NET_4_0 || BOOTSTRAP_NET_4_0 [assembly:TypeForwardedTo (typeof(Action<>))] [assembly:TypeForwardedTo (typeof(Action<,>))] [assembly:TypeForwardedTo (typeof(Action<,,>))] [assembly:TypeForwardedTo (typeof(Action<,,,>))] +#elif MOONLIGHT +[assembly:TypeForwardedTo (typeof (Action))] #endif namespace System @@ -62,6 +64,28 @@ namespace System public delegate void Action ( T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); +#elif MOONLIGHT + // Action, Action are defined in mscorlib.dll for SL4 + public delegate void Action (T1 arg1, T2 arg2); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3); + public delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4); + // Action to are defined in mscorlib.dll for SL4 + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + public delegate void Action ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); #else public delegate void Action (); public delegate void Action (T1 arg1, T2 arg2); diff --git a/mcs/class/System.Core/System/ChangeLog b/mcs/class/System.Core/System/ChangeLog index 5c645381de7..30442613a91 100644 --- a/mcs/class/System.Core/System/ChangeLog +++ b/mcs/class/System.Core/System/ChangeLog @@ -1,3 +1,26 @@ +2010-04-16 Sebastien Pouliot + + * Actions.cs: Forward Action() to mscorlib.dll and add the new + Action<...T16> delegates + * Funcs.cs: Add the new Func<...T16> delegates + * TimeZoneInfo.cs: Forward to mscorlib.dll + +2010-03-30 Sebastien Pouliot + + * InvalidTimeZoneException.cs + * TimeZoneInfo.AdjustmentRule.cs + * TimeZoneInfo.cs + * TimeZoneInfo.TransitionTime.cs + * TimeZoneNotFoundException.cs: + Fix Moonlight since these types now reside in mscorlib + for NET_4_0 and also for SL4 + +2010-03-30 Jb Evain + + * TimeZoneInfo.AdjustmentRule.cs + * TimeZoneInfo.TransitionTime.cs: + Add TypeForwarderFrom attributes. + 2010-01-04 Jb Evain * TimeZoneInfo.AdjustmentRule.cs, TimeZoneInfo.TransitionTime.cs: diff --git a/mcs/class/System.Core/System/Funcs.cs b/mcs/class/System.Core/System/Funcs.cs index c42b582a643..f12496d1619 100644 --- a/mcs/class/System.Core/System/Funcs.cs +++ b/mcs/class/System.Core/System/Funcs.cs @@ -68,5 +68,33 @@ namespace System public delegate TResult Func (T1 arg1, T2 arg2); public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3); public delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4); + + #if MOONLIGHT + // Func to >T1..T8,TResult> are defined in mscorlib.dll for SL4 + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9); + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10); + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11); + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12); + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13); + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14); + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15); + + public delegate TResult Func ( + T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16); + #endif #endif } diff --git a/mcs/class/System.Core/System/InvalidTimeZoneException.cs b/mcs/class/System.Core/System/InvalidTimeZoneException.cs index 465ba4f1b17..50ff757d024 100644 --- a/mcs/class/System.Core/System/InvalidTimeZoneException.cs +++ b/mcs/class/System.Core/System/InvalidTimeZoneException.cs @@ -24,7 +24,7 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if NET_4_0 || BOOTSTRAP_NET_4_0 +#if NET_4_0 || BOOTSTRAP_NET_4_0 || MOONLIGHT using System; using System.Runtime.CompilerServices; diff --git a/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs b/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs index ad45b1827ea..1ec0e11244a 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs @@ -24,14 +24,20 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if (INSIDE_CORLIB && NET_4_0) || (NET_2_1 && !INSIDE_CORLIB) || (NET_3_5 && !NET_4_0 && !BOOTSTRAP_NET_4_0) +#if (INSIDE_CORLIB && (NET_4_0 || MOONLIGHT)) || (MONOTOUCH && !INSIDE_CORLIB) || (NET_3_5 && !NET_4_0 && !BOOTSTRAP_NET_4_0) +using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System { public sealed partial class TimeZoneInfo { [SerializableAttribute] +#if NET_4_0 || BOOTSTRAP_NET_4_0 + [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)] +#elif MOONLIGHT + [TypeForwardedFrom (Consts.AssemblySystem_Core)] +#endif public sealed class AdjustmentRule : IEquatable, ISerializable, IDeserializationCallback { DateTime dateEnd; diff --git a/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs b/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs index 491a07b61db..72eca19ad2c 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs @@ -24,8 +24,9 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if (INSIDE_CORLIB && (NET_4_0 || BOOTSTRAP_NET_4_0)) || (NET_2_1 && !INSIDE_CORLIB) || (NET_3_5 && !NET_4_0 && !BOOTSTRAP_NET_4_0) +#if (INSIDE_CORLIB && (NET_4_0 || BOOTSTRAP_NET_4_0 || MOONLIGHT)) || (MONOTOUCH && !INSIDE_CORLIB) || (NET_3_5 && !NET_4_0 && !BOOTSTRAP_NET_4_0) +using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System @@ -33,6 +34,11 @@ namespace System public sealed partial class TimeZoneInfo { [SerializableAttribute] +#if NET_4_0 || BOOTSTRAP_NET_4_0 + [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)] +#elif MOONLIGHT + [TypeForwardedFrom (Consts.AssemblySystem_Core)] +#endif public struct TransitionTime : IEquatable, ISerializable, IDeserializationCallback { DateTime timeOfDay; diff --git a/mcs/class/System.Core/System/TimeZoneInfo.cs b/mcs/class/System.Core/System/TimeZoneInfo.cs index d6d7fa27797..da0d94fc000 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.cs @@ -27,11 +27,11 @@ using System; using System.Runtime.CompilerServices; -#if !INSIDE_CORLIB && (NET_4_0 || BOOTSTRAP_NET_4_0) +#if !INSIDE_CORLIB && (NET_4_0 || BOOTSTRAP_NET_4_0 || MOONLIGHT) [assembly:TypeForwardedTo (typeof(TimeZoneInfo))] -#elif NET_3_5 || (NET_2_1 && !INSIDE_CORLIB) +#elif NET_3_5 || (MONOTOUCH && !INSIDE_CORLIB) || (MOONLIGHT && INSIDE_CORLIB) using System.Collections.Generic; using System.Collections.ObjectModel; @@ -45,9 +45,11 @@ using Mono; namespace System { -#if NET_4_0 || BOOTSRAP_NET_4_0 +#if NET_4_0 || BOOTSTRAP_NET_4_0 [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)] -#endif +#elif MOONLIGHT + [TypeForwardedFrom (Consts.AssemblySystem_Core)] +#endif [SerializableAttribute] public sealed partial class TimeZoneInfo : IEquatable, ISerializable, IDeserializationCallback { diff --git a/mcs/class/System.Core/System/TimeZoneNotFoundException.cs b/mcs/class/System.Core/System/TimeZoneNotFoundException.cs index accedf33327..8691e73ac00 100644 --- a/mcs/class/System.Core/System/TimeZoneNotFoundException.cs +++ b/mcs/class/System.Core/System/TimeZoneNotFoundException.cs @@ -24,7 +24,7 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if NET_4_0 || BOOTSTRAP_NET_4_0 +#if NET_4_0 || BOOTSTRAP_NET_4_0 || MOONLIGHT using System; using System.Runtime.CompilerServices; diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest.cs index 200f5247d9c..d524e80f5c1 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest.cs @@ -47,18 +47,25 @@ namespace MonoTests.System.Linq.Expressions { Expression.GetFuncType (null); } + static Type [] GetTestTypeArray (int length) + { + return Enumerable.Range (0, length - 1) + .Select (i => typeof (int)) + .ToArray (); + } + [Test] [ExpectedException (typeof (ArgumentException))] public void GetFuncTypeArgEmpty () { - Expression.GetFuncType (new Type [0]); + Expression.GetFuncType (Type.EmptyTypes); } [Test] [ExpectedException (typeof (ArgumentException))] public void GetFuncTypeArgTooBig () { - Expression.GetFuncType (new Type [6]); + Expression.GetFuncType (GetTestTypeArray (64)); } [Test] @@ -91,7 +98,7 @@ namespace MonoTests.System.Linq.Expressions { [ExpectedException (typeof (ArgumentException))] public void GetActionTypeArgTooBig () { - Expression.GetActionType (new Type [5]); + Expression.GetActionType (GetTestTypeArray (45)); } [Test] @@ -126,7 +133,9 @@ namespace MonoTests.System.Linq.Expressions { var p = Expression.Parameter (typeof (string), null); Assert.AreEqual (null, p.Name); Assert.AreEqual (typeof (string), p.Type); +#if !NET_4_0 Assert.AreEqual ("", p.ToString ()); +#endif } [Test] @@ -135,7 +144,9 @@ namespace MonoTests.System.Linq.Expressions { var p = Expression.Parameter (typeof (string), ""); Assert.AreEqual ("", p.Name); Assert.AreEqual (typeof (string), p.Type); +#if !NET_4_0 Assert.AreEqual ("", p.ToString ()); +#endif } [Test] diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AddChecked.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AddChecked.cs index 3f8fe6067a4..d56fe5e933a 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AddChecked.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AddChecked.cs @@ -194,11 +194,12 @@ namespace MonoTests.System.Linq.Expressions // These are invalid: InvalidOperation (Byte.MaxValue, 2); InvalidOperation (SByte.MaxValue, 2); - +#if !NET_4_0 // Stuff that just fits in 32 bits, does not overflow: MustNotOverflow (Int16.MaxValue, 2); + MustNotOverflow (Int16.MaxValue, 2); MustNotOverflow (UInt16.MaxValue, 2); - +#endif // Doubles, floats, do not overflow MustNotOverflow (Single.MaxValue, 1); MustNotOverflow (Double.MaxValue, 1); diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AndAlso.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AndAlso.cs index 2368e07dcbe..27a7e2ec3e7 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AndAlso.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AndAlso.cs @@ -80,7 +80,9 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (ExpressionType.AndAlso, expr.NodeType, "AndAlso#01"); Assert.AreEqual (typeof (bool), expr.Type, "AndAlso#02"); Assert.IsNull (expr.Method, "AndAlso#03"); +#if !NET_4_0 Assert.AreEqual ("(True && False)", expr.ToString(), "AndAlso#04"); +#endif } [Test] @@ -95,8 +97,10 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (typeof (OpClass), expr.Type, "AndAlso#06"); Assert.AreEqual (mi, expr.Method, "AndAlso#07"); Assert.AreEqual ("op_BitwiseAnd", expr.Method.Name, "AndAlso#08"); +#if !NET_4_0 Assert.AreEqual ("(value(MonoTests.System.Linq.Expressions.OpClass) && value(MonoTests.System.Linq.Expressions.OpClass))", expr.ToString(), "AndAlso#09"); +#endif } [Test] diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs index 25125c8850c..8f668d288ab 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs @@ -87,7 +87,11 @@ namespace MonoTests.System.Linq.Expressions { } [Test] +#if NET_4_0 + [ExpectedException (typeof (ArgumentException))] +#else [ExpectedException (typeof (ArgumentNullException))] +#endif public void ArgInstanceNullForNonStaticMethod () { Expression.Call (null, typeof (object).GetMethod ("ToString")); @@ -281,7 +285,7 @@ namespace MonoTests.System.Linq.Expressions { { return (int) (i as ConstantExpression).Value; } - +#if !NET_4_0 // dlr bug 5875 [Test] public void CallMethodWithExpressionParameter () { @@ -292,7 +296,7 @@ namespace MonoTests.System.Linq.Expressions { Assert.AreEqual (42, l ()); } - +#endif static bool fout_called = false; public static int FooOut (out int x) diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Convert.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Convert.cs index 44e61ca8224..9b9d4d9e542 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Convert.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Convert.cs @@ -81,13 +81,16 @@ namespace MonoTests.System.Linq.Expressions { var conv = Expression.Convert (p, typeof (ITzap)); Assert.AreEqual (typeof (ITzap), conv.Type); +#if !NET_4_0 Assert.AreEqual ("Convert()", conv.ToString ()); - +#endif p = Expression.Parameter (typeof (ITzap), null); conv = Expression.Convert (p, typeof (IFoo)); Assert.AreEqual (typeof (IFoo), conv.Type); +#if !NET_4_0 Assert.AreEqual ("Convert()", conv.ToString ()); +#endif } [Test] diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs index ca3ff35f849..06612bdfa18 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs @@ -76,7 +76,9 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (ExpressionType.Equal, expr.NodeType); Assert.AreEqual (typeof (bool), expr.Type); Assert.IsNull (expr.Method); +#if !NET_4_0 Assert.AreEqual ("(1 = 2)", expr.ToString ()); +#endif } [Test] @@ -93,7 +95,9 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (true, expr.IsLifted); Assert.AreEqual (false, expr.IsLiftedToNull); Assert.IsNull (expr.Method); +#if !NET_4_0 Assert.AreEqual ("(1 = 2)", expr.ToString ()); +#endif } [Test] @@ -110,7 +114,9 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (true, expr.IsLifted); Assert.AreEqual (true, expr.IsLiftedToNull); Assert.IsNull (expr.Method); +#if !NET_4_0 Assert.AreEqual ("(1 = 2)", expr.ToString ()); +#endif } [Test] @@ -136,8 +142,9 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (typeof (bool), expr.Type); Assert.AreEqual (mi, expr.Method); Assert.AreEqual ("op_Equality", expr.Method.Name); - +#if !NET_4_0 Assert.AreEqual ("(value(MonoTests.System.Linq.Expressions.OpClass) = value(MonoTests.System.Linq.Expressions.OpClass))", expr.ToString ()); +#endif } [Test] diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Lambda.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Lambda.cs index 08a5c7c2811..8c83e312ec1 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Lambda.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Lambda.cs @@ -239,7 +239,6 @@ namespace MonoTests.System.Linq.Expressions } [Test] - [Category ("NotWorking")] public void NestedParentParameterUse () { var a = Expression.Parameter (typeof (int), null); @@ -268,7 +267,7 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (5, l (1)); } - +#if !NET_4_0 // dlr bug 5875 [Test] public void LambdaReturningExpression () { @@ -281,5 +280,6 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (ExpressionType.Constant, q.NodeType); } +#endif } } diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_OrElse.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_OrElse.cs index 5cdf17de1f7..873dd0d0e27 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_OrElse.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_OrElse.cs @@ -80,7 +80,9 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (ExpressionType.OrElse, expr.NodeType, "OrElse#01"); Assert.AreEqual (typeof (bool), expr.Type, "OrElse#02"); Assert.IsNull (expr.Method, "OrElse#03"); +#if !NET_4_0 Assert.AreEqual ("(True || False)", expr.ToString(), "OrElse#04"); +#endif } [Test] @@ -95,8 +97,10 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (typeof (OpClass), expr.Type, "OrElse#06"); Assert.AreEqual (mi, expr.Method, "OrElse#07"); Assert.AreEqual ("op_BitwiseOr", expr.Method.Name, "OrElse#08"); +#if !NET_4_0 Assert.AreEqual ("(value(MonoTests.System.Linq.Expressions.OpClass) || value(MonoTests.System.Linq.Expressions.OpClass))", expr.ToString(), "OrElse#09"); +#endif } public class BrokenMethod { @@ -276,7 +280,7 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (new Slot (64), orelse (new Slot (64), new Slot (64))); Assert.AreEqual (new Slot (32), orelse (new Slot (32), new Slot (64))); } - +#if !NET_4_0 // dlr bug 5867 [Test] public void UserDefinedOrElseLiftedToNull () { @@ -298,7 +302,7 @@ namespace MonoTests.System.Linq.Expressions Assert.AreEqual (new Slot (32), orelse (new Slot (32), null)); Assert.AreEqual (null, orelse (null, null)); } - +#endif [Test] public void UserDefinedOrElseShortCircuit () { diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Quote.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Quote.cs index b95f542121d..fedaa5f7ab9 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Quote.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Quote.cs @@ -37,14 +37,23 @@ namespace MonoTests.System.Linq.Expressions Expression.Quote (null); } +#if !NET_4_0 [Test] - public void Constant () + public void QuoteConstant () { UnaryExpression expr = Expression.Quote (Expression.Constant (1)); Assert.AreEqual (ExpressionType.Quote, expr.NodeType, "Quote#01"); Assert.AreEqual (typeof (ConstantExpression), expr.Type, "Quote#02"); Assert.AreEqual ("1", expr.ToString(), "Quote#03"); } +#else + [Test] + [ExpectedException (typeof (ArgumentException))] + public void QuoteConstant () + { + Expression.Quote (Expression.Constant (1)); + } +#endif [Test] public void CompiledQuote () diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_SubtractChecked.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_SubtractChecked.cs index 393935ad1f8..cbb41f4edf6 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_SubtractChecked.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_SubtractChecked.cs @@ -184,6 +184,7 @@ namespace MonoTests.System.Linq.Expressions MustOverflow (0, 1); } +#if !NET_4_0 // fixed in net_4_0 [Test] public void TestBugCompatibility () { @@ -191,6 +192,7 @@ namespace MonoTests.System.Linq.Expressions // Sounds very odd, should file a bug with MS. MustNotOverflow (Int16.MinValue, 1); } +#endif // // These should not overflow diff --git a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_TypeIs.cs b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_TypeIs.cs index 914aaa5c341..91fd32e6596 100644 --- a/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_TypeIs.cs +++ b/mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_TypeIs.cs @@ -104,6 +104,7 @@ namespace MonoTests.System.Linq.Expressions Assert.IsTrue (baz_is_bar (new Baz ())); } +#if !NET_4_0 // dlr bug 5868 [Test] [Category ("NotDotNet")] [ExpectedException (typeof (ArgumentException))] @@ -111,6 +112,7 @@ namespace MonoTests.System.Linq.Expressions { Expression.TypeIs ("yoyo".ToConstant (), typeof (void)); } +#endif public static void TacTac () { diff --git a/mcs/class/System.Core/Test/System.Linq/ChangeLog b/mcs/class/System.Core/Test/System.Linq/ChangeLog index 2a8b2b7f858..a53f51058c4 100644 --- a/mcs/class/System.Core/Test/System.Linq/ChangeLog +++ b/mcs/class/System.Core/Test/System.Linq/ChangeLog @@ -1,3 +1,21 @@ +2010-04-23 Jérémie Laval + + * ParallelEnumerableTests.cs: Fix namespace, add NET_4_0 #ifdef + * ParallelTestHelper.cs: Fix namespace + +2010-04-15 Jérémie Laval + + * ParallelEnumerableTests.cs: Tweak Skip unit test to avoid deadlocking for now + +2010-04-15 Jérémie Laval + + * ParallelEnumerableTests.cs: + * ParallelTestHelper.cs: Add PLinq unit tests + +2010-03-24 Jb Evain + + * EnumerableTest.cs: add test for #582502. + 2009-11-12 Eric Maupin * EnumerableMoreTest.cs: Added ToLookup test for null keys, updated old test to check count. diff --git a/mcs/class/System.Core/Test/System.Linq/EnumerableTest.cs b/mcs/class/System.Core/Test/System.Linq/EnumerableTest.cs index addc5438c7f..26655c56dfd 100644 --- a/mcs/class/System.Core/Test/System.Linq/EnumerableTest.cs +++ b/mcs/class/System.Core/Test/System.Linq/EnumerableTest.cs @@ -334,6 +334,21 @@ namespace MonoTests.System.Linq { Assert.AreEqual (23.25, (new long [] { 24, 7, 28, 34 }).Average ()); } + [Test] + public void TestAverageInt32 () + { + // This does not overflow, computation is done with longs + var x = new int [] { Int32.MaxValue, Int32.MaxValue }; + Assert.AreEqual ((double) Int32.MaxValue, x.Average ()); + } + + [Test] + public void TestAverageOverflowOnInt64 () + { + var x = new long [] { Int64.MaxValue, Int64.MaxValue }; + x.Average (); + } + [Test] public void TestAverageOnLongNullable () { @@ -490,6 +505,38 @@ namespace MonoTests.System.Linq { Assert.AreEqual ("Zyx", list [3].Name); } + [Test] + public void TestOrderByDescendingStability () + { + var data = new [] { + new { Key = true, Value = 1 }, + new { Key = false, Value = 2}, + new { Key = true, Value = 3}, + new { Key = false, Value = 4}, + new { Key = true, Value = 5}, + new { Key = false, Value = 6}, + new { Key = true, Value = 7}, + new { Key = false, Value = 8}, + new { Key = true, Value = 9}, + new { Key = false, Value = 10}, + }; + + var expected = new [] { + new { Key = true, Value = 1 }, + new { Key = true, Value = 3}, + new { Key = true, Value = 5}, + new { Key = true, Value = 7}, + new { Key = true, Value = 9}, + new { Key = false, Value = 2}, + new { Key = false, Value = 4}, + new { Key = false, Value = 6}, + new { Key = false, Value = 8}, + new { Key = false, Value = 10}, + }; + + AssertAreSame (expected, data.OrderByDescending (x => x.Key)); + } + static void AssertIsOrdered (IEnumerable e) { int f = int.MinValue; diff --git a/mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs b/mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs new file mode 100644 index 00000000000..ef543347905 --- /dev/null +++ b/mcs/class/System.Core/Test/System.Linq/ParallelEnumerableTests.cs @@ -0,0 +1,747 @@ +// ParallelEnumerableTests.cs +// +// Copyright (c) 2008 Jérémie "Garuma" Laval +// +// Based on Enumerable test suite by Jb Evain (jbevain@novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +#if NET_4_0 + +using System; +using System.Threading; +using System.Linq; + +using System.Collections; +using System.Collections.Generic; + +using NUnit.Framework; + +namespace MonoTests.System.Linq +{ + [TestFixtureAttribute] + public class ParallelEnumerableTests + { + IEnumerable baseEnumerable; + + [SetUpAttribute] + public void Setup () + { + baseEnumerable = Enumerable.Range(1, 10000); + } + + void AreEquivalent (IEnumerable syncEnumerable, IEnumerable asyncEnumerable, int count) + { + int[] sync = Enumerable.ToArray(syncEnumerable); + int[] async = Enumerable.ToArray(asyncEnumerable); + + // This is not AreEquals because ParallelQuery is non-deterministic (IParallelOrderedEnumerable is) + // thus the order of the initial Enumerable might not be preserved + CollectionAssert.AreEquivalent(sync, async, "#" + count); + } + + void AreEquivalent (IEnumerable syncEnumerable, IEnumerable asyncEnumerable, int count) + { + T[] sync = Enumerable.ToArray(syncEnumerable); + T[] async = Enumerable.ToArray(asyncEnumerable); + + // This is not AreEquals because ParallelQuery is non-deterministic (IParallelOrderedEnumerable is) + // thus the order of the initial Enumerable might not be preserved + CollectionAssert.AreEquivalent(sync, async, "#" + count); + } + + static void AssertAreSame (IEnumerable expected, IEnumerable actual) + { + if (expected == null) { + Assert.IsNull (actual); + return; + } + + Assert.IsNotNull (actual); + + IEnumerator ee = expected.GetEnumerator (); + IEnumerator ea = actual.GetEnumerator (); + + while (ee.MoveNext ()) { + Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected."); + Assert.AreEqual (ee.Current, ea.Current); + } + + if (ea.MoveNext ()) + Assert.Fail ("Unexpected element: " + ea.Current); + } + + public static void AssertException (Action action) where T : Exception + { + try { + action (); + } + catch (T) { + return; + } + Assert.Fail ("Expected: " + typeof (T).Name); + } + + static void AssertAreSame (K expectedKey, IEnumerable expectedValues, IGrouping actual) + { + if (expectedValues == null) { + Assert.IsNull (actual); + return; + } + + Assert.IsNotNull (actual); + + Assert.AreEqual (expectedKey, actual.Key); + + var ee = expectedValues.GetEnumerator (); + var ea = actual.GetEnumerator (); + + while (ee.MoveNext ()) { + Assert.IsTrue (ea.MoveNext (), "'" + ee.Current + "' expected."); + Assert.AreEqual (ee.Current, ea.Current); + } + + if (ea.MoveNext ()) + Assert.Fail ("Unexpected element: " + ee.Current); + } + + static void AssertAreSame (IDictionary> expected, IEnumerable> actual) + { + if (expected == null) { + Assert.IsNull (actual); + return; + } + + Assert.IsNotNull (actual); + + var ee = expected.GetEnumerator (); + var ea = actual.GetEnumerator (); + + while (ee.MoveNext ()) { + Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected."); + AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current); + } + + if (ea.MoveNext ()) + Assert.Fail ("Unexpected element: " + ee.Current.Key); + } + + static void AssertAreSame (IDictionary> expected, ILookup actual) + { + if (expected == null) { + Assert.IsNull (actual); + return; + } + + Assert.IsNotNull (actual); + + var ee = expected.GetEnumerator (); + var ea = actual.GetEnumerator (); + + while (ee.MoveNext ()) { + Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + "' expected."); + AssertAreSame (ee.Current.Key, ee.Current.Value, ea.Current); + } + + if (ea.MoveNext ()) + Assert.Fail ("Unexpected element: " + ee.Current.Key); + } + + static void AssertAreSame (IDictionary expected, IDictionary actual) + { + if (expected == null) { + Assert.IsNull (actual); + return; + } + + Assert.IsNotNull (actual); + + var ee = expected.GetEnumerator (); + var ea = actual.GetEnumerator (); + + while (ee.MoveNext ()) { + Assert.IsTrue (ea.MoveNext (), "'" + ee.Current.Key + ", " + ee.Current.Value + "' expected."); + Assert.AreEqual (ee.Current.Key, ea.Current.Key); + Assert.AreEqual (ee.Current.Value, ea.Current.Value); + } + + if (ea.MoveNext ()) + Assert.Fail ("Unexpected element: " + ee.Current.Key + ", " + ee.Current.Value); + } + + [Test] + public void SelectTestCase () + { + ParallelTestHelper.Repeat (() => { + IEnumerable sync = baseEnumerable.Select (i => i * i); + IEnumerable async = baseEnumerable.AsParallel ().Select (i => i * i); + + AreEquivalent(sync, async, 1); + }); + } + + [Test] + public void WhereTestCase () + { + ParallelTestHelper.Repeat (() => { + IEnumerable sync = baseEnumerable.Where(i => i % 2 == 0); + IEnumerable async = baseEnumerable.AsParallel().Where(i => i % 2 == 0); + + AreEquivalent(sync, async, 1); + }); + } + + [Test] + public void CountTestCase () + { + ParallelTestHelper.Repeat (() => { + int sync = baseEnumerable.Count(); + int async = baseEnumerable.AsParallel().Count(); + + Assert.AreEqual(sync, async, "#1"); + }); + } + + [Test] + public void AggregateTestCase () + { + ParallelTestHelper.Repeat (() => { + ParallelQuery range = ParallelEnumerable.Repeat (5, 2643); + double average = range.Aggregate(() => new double[2], + (acc, elem) => { acc[0] += elem; acc[1]++; return acc; }, + (acc1, acc2) => { acc1[0] += acc2[0]; acc1[1] += acc2[1]; return acc1; }, + acc => acc[0] / acc[1]); + + Assert.AreEqual(5.0, average, "#1"); + }); + } + + [Test] + public void TestSimpleExcept () + { + ParallelTestHelper.Repeat (() => { + int [] first = {0, 1, 2, 3, 4, 5}; + int [] second = {2, 4, 6}; + int [] result = {0, 1, 3, 5}; + + AreEquivalent (result, first.AsParallel ().Except (second.AsParallel ()), 1); + }); + } + + [Test] + public void TestSimpleIntersect () + { + ParallelTestHelper.Repeat (() => { + int [] first = {0, 1, 2, 3, 4, 5}; + int [] second = {2, 4, 6}; + int [] result = {2, 4}; + + AreEquivalent (result, first.AsParallel ().Intersect (second.AsParallel ()), 1); + }); + } + + [Test] + public void TestSimpleUnion () + { + ParallelTestHelper.Repeat (() => { + int [] first = {0, 1, 2, 3, 4, 5}; + int [] second = {2, 4, 6}; + int [] result = {0, 1, 2, 3, 4, 5, 6}; + + AreEquivalent (result, first.AsParallel ().Union (second.AsParallel ()), 1); + }); + } + + class Foo {} + class Bar : Foo {} + + [Test] + public void TestCast () + { + Bar a = new Bar (); + Bar b = new Bar (); + Bar c = new Bar (); + + Foo [] foos = new Foo [] {a, b, c}; + Bar [] result = new Bar [] {a, b, c}; + + AreEquivalent (result, foos.AsParallel ().Cast (), 1); + } + + [Test] + public void TestSkip () + { + int [] data = {0, 1, 2, 3, 4, 5}; + int [] result = {3, 4, 5}; + + AssertAreSame (result, data.AsParallel ().AsOrdered ().Skip (3).ToArray ()); + } + + /*[Test] + public void TestSkipWhile () + { + int [] data = {0, 1, 2, 3, 4, 5}; + int [] result = {3, 4, 5}; + + AssertAreSame (result, data.AsParallel ().AsOrdered ().SkipWhile (i => i < 3)); + } + + [Test] + public void TestTake () + { + int [] data = {0, 1, 2, 3, 4, 5}; + int [] result = {0, 1, 2}; + + AssertAreSame (result, data.AsParallel ().AsOrdered ().Take (3)); + } + + [Test] + public void TestTakeWhile () + { + int [] data = {0, 1, 2, 3, 4, 5}; + int [] result = {0, 1, 2}; + + AssertAreSame (result, data.AsParallel ().AsOrdered ().TakeWhile (i => i < 3)); + }*/ + +// [Test] +// public void TestLast () +// { +// int [] data = {1, 2, 3}; +// +// Assert.AreEqual (3, data.AsParallel ().Last ()); +// } +// +// [Test] +// public void TestLastOrDefault () +// { +// int [] data = {}; +// +// Assert.AreEqual (default (int), data.AsParallel ().LastOrDefault ()); +// } +// +// [Test] +// public void TestFirst () +// { +// int [] data = {1, 2, 3}; +// +// Assert.AreEqual (1, data.AsParallel ().First ()); +// } +// +// [Test] +// public void TestFirstOrDefault () +// { +// int [] data = {}; +// +// Assert.AreEqual (default (int), data.AsParallel ().FirstOrDefault ()); +// } + + [Test] + public void TestReverse () + { + int [] data = {0, 1, 2, 3, 4}; + int [] result = {4, 3, 2, 1, 0}; + + AssertAreSame (result, data.AsParallel ().AsOrdered ().Reverse ()); + AssertAreSame (result, ParallelEnumerable.Range (0, 5).AsOrdered ().Reverse ()); + } + + [Test] + public void TestOrderBy () + { + ParallelTestHelper.Repeat (() => { + int [] array = { 14, 53, 3, 9, 11, 14, 5, 32, 2 }; + + var q = array.AsParallel ().OrderBy ((i) => i); + AssertIsOrdered (q, array.Length); + }); + } + + class Baz { + string name; + int age; + + public string Name + { + get { + if (string.IsNullOrEmpty (name)) + return Age.ToString (); + + return name + " (" + Age + ")"; + } + } + + public int Age + { + get { return age + 1; } + } + + public Baz (string name, int age) + { + this.name = name; + this.age = age; + } + + public override int GetHashCode () + { + return this.Age ^ this.Name.GetHashCode (); + } + + public override bool Equals (object obj) + { + Baz b = obj as Baz; + if (b == null) + return false; + + return b.Age == this.Age && b.Name == this.Name; + } + + public override string ToString () + { + return this.Name; + } + } + + static IEnumerable CreateBazCollection () + { + return new [] { + new Baz ("jb", 25), + new Baz ("ana", 20), + new Baz ("reg", 28), + new Baz ("ro", 25), + new Baz ("jb", 7), + }; + } + + [Test] + public void TestOrderByAgeAscendingTheByNameDescending () + { + ParallelTestHelper.Repeat (() => { + var q = from b in CreateBazCollection ().AsParallel() + orderby b.Age ascending, b.Name descending + select b; + //var q = CreateBazCollection ().AsParallel ().OrderBy ((b) => b.Age).ThenByDescending ((b) => b.Name); + + var expected = new [] { + new Baz ("jb", 7), + new Baz ("ana", 20), + new Baz ("ro", 25), + new Baz ("jb", 25), + new Baz ("reg", 28), + }; + + foreach (Baz b in q) { + Console.Write(b.Name + ", " + b.Age + "; "); + } + + AssertAreSame (expected, q); + }); + } + + class Data { + public int ID { get; set; } + public string Name { get; set; } + + public override string ToString () + { + return ID + " " + Name; + } + } + + IEnumerable CreateData () + { + return new [] { + new Data { ID = 10, Name = "bcd" }, + new Data { ID = 20, Name = "Abcd" }, + new Data { ID = 20, Name = "Ab" }, + new Data { ID = 10, Name = "Zyx" }, + }; + } + + [Test] + public void TestOrderByIdDescendingThenByNameAscending () + { + ParallelTestHelper.Repeat (() => { + var q = from d in CreateData ().AsParallel() + orderby d.ID descending, d.Name ascending + select d; + + var list = new List (q); + + Assert.AreEqual ("Ab", list [0].Name); + Assert.AreEqual ("Abcd", list [1].Name); + Assert.AreEqual ("bcd", list [2].Name); + Assert.AreEqual ("Zyx", list [3].Name); + }); + } + + static void AssertIsOrdered (IEnumerable e, int count) + { + int f = int.MinValue; + int c = 0; + + foreach (int i in e) { + Assert.IsTrue (f <= i, string.Format ("{0} <= {1}", f, i)); + f = i; + c++; + } + + Assert.AreEqual (count, c); + } + + /* + [TestAttribute, Ignore] + public void ElementAtTestCase() + { + ParallelTestHelper.Repeat (() => { + Assert.AreEqual(1, baseEnumerable.ElementAt(0), "#1"); + Assert.AreEqual(51, baseEnumerable.ElementAt(50), "#2"); + Assert.AreEqual(489, baseEnumerable.ElementAt(488), "#3"); + }); + } + + [TestAttribute, Ignore] + public void TakeTestCase() + { + ParallelTestHelper.Repeat (() => { + ParallelQuery async = baseEnumerable.AsParallel().Take(2000); + IEnumerable sync = baseEnumerable.Take(2000); + + AreEquivalent(sync, async, 1); + + async = baseEnumerable.AsParallel().Take(100); + sync = baseEnumerable.Take(100); + + AreEquivalent(sync, async, 2); + }); + } + + [TestAttribute, Ignore] + public void SkipTestCase() + { + ParallelTestHelper.Repeat (() => { + ParallelQuery async = baseEnumerable.AsParallel().AsOrdered().Skip(2000); + IEnumerable sync = baseEnumerable.Skip(2000); + + AreEquivalent(sync, async, 1); + + async = baseEnumerable.AsParallel().Skip(100); + sync = baseEnumerable.Skip(100); + + Assert.AreEqual(sync.Count(), async.Count(), "#2"); + }); + } + + [TestAttribute, Ignore] + public void ZipTestCase() + { + ParallelTestHelper.Repeat (() => { + ParallelQuery async1 = ParallelEnumerable.Range(0, 10000); + ParallelQuery async2 = ParallelEnumerable.Repeat(1, 10000).Zip(async1, (e1, e2) => e1 + e2); + + int[] expected = Enumerable.Range (1, 10000).ToArray (); + CollectionAssert.AreEquivalent(expected, Enumerable.ToArray (async2), "#1"); + }); + } + */ + [Test] + public void RangeTestCase () + { + ParallelTestHelper.Repeat (() => { + IEnumerable sync = Enumerable.Range(1, 1000); + IEnumerable async = ParallelEnumerable.Range(1, 1000); + + AreEquivalent (sync, async, 1); + }); + } + + [Test] + public void RepeatTestCase () + { + ParallelTestHelper.Repeat (() => { + IEnumerable sync = Enumerable.Repeat(1, 1000); + IEnumerable async = ParallelEnumerable.Repeat(1, 1000); + + AreEquivalent (sync, async, 1); + }); + } + + [Test] + public void TestSum () + { + int [] data = {1, 2, 3, 4}; + + Assert.AreEqual (10, data.AsParallel().Sum ()); + } + + [Test] + public void SumOnEmpty () + { + int [] data = {}; + + Assert.AreEqual (0, data.AsParallel().Sum ()); + } + + [Test] + public void TestMax () + { + int [] data = {1, 3, 5, 2}; + + Assert.AreEqual (5, data.AsParallel().Max ()); + } + + [Test] + public void TestMin () + { + int [] data = {3, 5, 2, 6, 1, 7}; + + Assert.AreEqual (1, data.AsParallel().Min ()); + } + + [Test] + public void TestToListOrdered () + { + int [] data = { 2, 3, 5 }; + + var list = data.AsParallel().AsOrdered().ToList (); + + AssertAreSame (data, list); + AssertIsOrdered (list, data.Length); + + Assert.AreEqual (typeof (List), list.GetType ()); + } + + [Test] + public void TestToArrayOrdered () + { + ICollection coll = new List (); + coll.Add (0); + coll.Add (1); + coll.Add (2); + + int [] result = {0, 1, 2}; + + var array = coll.AsParallel().AsOrdered().ToArray (); + + AssertAreSame (result, array); + AssertIsOrdered (array, result.Length); + + Assert.AreEqual (typeof (int []), array.GetType ()); + } + + [Test] + public void TestToList () + { + int [] data = {3, 5, 2}; + + var list = data.AsParallel().ToList (); + + CollectionAssert.AreEquivalent (data, list); + + Assert.AreEqual (typeof (List), list.GetType ()); + } + + [Test] + public void TestToArray () + { + ICollection coll = new List (); + coll.Add (0); + coll.Add (1); + coll.Add (2); + + int [] result = {0, 1, 2}; + + var array = coll.AsParallel().ToArray (); + + CollectionAssert.AreEquivalent (result, array); + + Assert.AreEqual (typeof (int []), array.GetType ()); + } + + + [Test] + public void TestAverageOnInt32 () + { + Assert.AreEqual (23.25, (new int [] { 24, 7, 28, 34 }).Average ()); + } + + [Test] + public void TestAverageOnInt64 () + { + Assert.AreEqual (23.25, (new long [] { 24, 7, 28, 34 }).Average ()); + } + + /* + [Test] + public void AnyArgumentNullTest () + { + string [] data = { "2", "1", "5", "3", "4" }; + + + // Any () + AssertException (delegate () { ((IEnumerable) null).AsParallel ().Any (); }); + + // Any (Func) + AssertException (delegate () { ((IEnumerable) null).AsParallel ().Any (x => true); }); + AssertException (delegate () { data.AsParallel ().Any ((Func) null); }); + }*/ + + [Test] + public void AnyTest () + { + int [] data = { 5, 2, 3, 1, 6 }; + int [] empty = { }; + + + // Any () + Assert.IsTrue (data.AsParallel ().Any ()); + Assert.IsFalse (empty.AsParallel ().Any ()); + + // Any (Func) + Assert.IsTrue (data.AsParallel ().Any (x => x == 5)); + Assert.IsFalse (data.AsParallel ().Any (x => x == 9)); + Assert.IsFalse (empty.AsParallel ().Any (x => true)); + } + + /* + [Test] + public void AllArgumentNullTest () + { + string [] data = { "2", "1", "5", "3", "4" }; + + AssertException (delegate () { ((IEnumerable) null).AsParallel ().All (x => true); }); + AssertException (delegate () { data.AsParallel ().All ((Func) null); }); + }*/ + + [Test] + public void AllTest () + { + int [] data = { 5, 2, 3, 1, 6 }; + int [] empty = { }; + + Assert.IsTrue (data.AsParallel ().All (x => true)); + Assert.IsFalse (data.AsParallel ().All (x => x != 1)); + Assert.IsTrue (empty.AsParallel ().All (x => false)); + } + } +} + +#endif diff --git a/mcs/class/System.Core/Test/System.Linq/ParallelTestHelper.cs b/mcs/class/System.Core/Test/System.Linq/ParallelTestHelper.cs new file mode 100644 index 00000000000..eeeef86aedc --- /dev/null +++ b/mcs/class/System.Core/Test/System.Linq/ParallelTestHelper.cs @@ -0,0 +1,90 @@ +#if NET_4_0 +// TestHelper.cs +// +// Copyright (c) 2008 Jérémie "Garuma" Laval +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// + +using System; +using System.Threading; +using System.Collections.Concurrent; + +namespace MonoTests.System.Linq +{ + public static class ParallelTestHelper + { + const int NumRun = 100; + + public static void Repeat (Action action) + { + Repeat (action, NumRun); + } + + public static void Repeat (Action action, int numRun) + { + for (int i = 0; i < numRun; i++) { + //Console.WriteLine ("Run " + i.ToString ()); + action (); + } + } + + public static void ParallelStressTest(TSource obj, Action action) + { + ParallelStressTest(obj, action, Environment.ProcessorCount + 2); + } + + public static void ParallelStressTest(TSource obj, Action action, int numThread) + { + Thread[] threads = new Thread[numThread]; + for (int i = 0; i < numThread; i++) { + threads[i] = new Thread(new ThreadStart(delegate { action(obj); })); + threads[i].Start(); + } + + // Wait for the completion + for (int i = 0; i < numThread; i++) + threads[i].Join(); + } + + public static void ParallelAdder(IProducerConsumerCollection collection, int numThread) + { + int startIndex = -10; + ParallelTestHelper.ParallelStressTest(collection, delegate (IProducerConsumerCollection c) { + int start = Interlocked.Add(ref startIndex, 10); + for (int i = start; i < start + 10; i++) { + c.TryAdd(i); + } + }, numThread); + } + + public static void ParallelRemover(IProducerConsumerCollection collection, int numThread, int times) + { + int t = -1; + ParallelTestHelper.ParallelStressTest(collection, delegate (IProducerConsumerCollection c) { + int num = Interlocked.Increment(ref t); + int value; + if (num < times) + c.TryTake (out value); + }, numThread); + } + } +} +#endif diff --git a/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs b/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs index 9ea3cf1b731..af605f783fa 100644 --- a/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs +++ b/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs @@ -327,7 +327,7 @@ namespace MonoTests.System.Threading } foreach (var t in threads) { - Console.WriteLine (t.ThreadState); + // Console.WriteLine (t.ThreadState); t.Join (); } } @@ -387,7 +387,7 @@ namespace MonoTests.System.Threading v.ExitWriteLock (); foreach (var t in threads) { - Console.WriteLine (t.ThreadState); + // Console.WriteLine (t.ThreadState); t.Join (); } } diff --git a/mcs/class/System.Core/moonlight_bootstrap_System.Core.dll.sources b/mcs/class/System.Core/moonlight_bootstrap_System.Core.dll.sources new file mode 100644 index 00000000000..82f86b00544 --- /dev/null +++ b/mcs/class/System.Core/moonlight_bootstrap_System.Core.dll.sources @@ -0,0 +1 @@ +#include moonlight_raw_System.Core.dll.sources diff --git a/mcs/class/System.Core/moonlight_raw_System.Core.dll.sources b/mcs/class/System.Core/moonlight_raw_System.Core.dll.sources new file mode 100644 index 00000000000..f212d2cb9e0 --- /dev/null +++ b/mcs/class/System.Core/moonlight_raw_System.Core.dll.sources @@ -0,0 +1,73 @@ +../../build/common/Consts.cs +../../build/common/Locale.cs +../../build/common/MonoTODOAttribute.cs +../corlib/Mono.Security.Cryptography/CryptoTools.cs +../corlib/Mono.Security.Cryptography/SymmetricTransform.cs +../corlib/System/Lazy.cs +../corlib/System.Threading/LazyThreadSafetyMode.cs +Assembly/AssemblyInfo.cs +System/Actions.cs +System/Funcs.cs +System/InvalidTimeZoneException.cs +System/TimeZoneInfo.AdjustmentRule.cs +System/TimeZoneInfo.cs +System/TimeZoneInfo.TransitionTime.cs +System/TimeZoneNotFoundException.cs +System.Runtime.CompilerServices/ExecutionScope.cs +System.Runtime.CompilerServices/ExtensionAttribute.cs +System.Runtime.CompilerServices/IStrongBox.cs +System.Runtime.CompilerServices/StrongBox_T.cs +System.Linq/Check.cs +System.Linq/Enumerable.cs +System.Linq/QueryableEnumerable.cs +System.Linq/QueryableTransformer.cs +System.Linq/Grouping.cs +System.Linq/IGrouping.cs +System.Linq/IOrderedQueryable.cs +System.Linq/IOrderedQueryable_T.cs +System.Linq/IOrderedEnumerable_T.cs +System.Linq/IQueryable.cs +System.Linq/IQueryable_T.cs +System.Linq/Lookup.cs +System.Linq/ILookup_T.cs +System.Linq/OrderedEnumerable.cs +System.Linq/OrderedSequence.cs +System.Linq/Queryable.cs +System.Linq/QuickSort.cs +System.Linq/SortContext.cs +System.Linq/SortDirection.cs +System.Linq/SortSequenceContext.cs +System.Linq/IQueryProvider.cs +System.Linq.Expressions/BinaryExpression.cs +System.Linq.Expressions/ConditionalExpression.cs +System.Linq.Expressions/ConstantExpression.cs +System.Linq.Expressions/ElementInit.cs +System.Linq.Expressions/EmitContext.cs +System.Linq.Expressions/Expression.cs +System.Linq.Expressions/Expression_T.cs +System.Linq.Expressions/ExpressionPrinter.cs +System.Linq.Expressions/ExpressionType.cs +System.Linq.Expressions/ExpressionVisitor.cs +System.Linq.Expressions/ExpressionTransformer.cs +System.Linq.Expressions/Extensions.cs +System.Linq.Expressions/InvocationExpression.cs +System.Linq.Expressions/LambdaExpression.cs +System.Linq.Expressions/ListInitExpression.cs +System.Linq.Expressions/MemberAssignment.cs +System.Linq.Expressions/MemberBinding.cs +System.Linq.Expressions/MemberBindingType.cs +System.Linq.Expressions/MemberExpression.cs +System.Linq.Expressions/MemberInitExpression.cs +System.Linq.Expressions/MemberListBinding.cs +System.Linq.Expressions/MemberMemberBinding.cs +System.Linq.Expressions/MethodCallExpression.cs +System.Linq.Expressions/NewArrayExpression.cs +System.Linq.Expressions/NewExpression.cs +System.Linq.Expressions/ParameterExpression.cs +System.Linq.Expressions/TypeBinaryExpression.cs +System.Linq.Expressions/UnaryExpression.cs +System.Collections.Generic/HashSet.cs +../corlib/System.Collections.Generic/CollectionDebuggerView.cs +System.Security.Cryptography/Aes.cs +System.Security.Cryptography/AesManaged.cs +System.Security.Cryptography/AesTransform.cs diff --git a/mcs/class/System.Core/net_2_1_bootstrap_System.Core.dll.sources b/mcs/class/System.Core/net_2_1_bootstrap_System.Core.dll.sources deleted file mode 100644 index 5e32150b429..00000000000 --- a/mcs/class/System.Core/net_2_1_bootstrap_System.Core.dll.sources +++ /dev/null @@ -1 +0,0 @@ -#include net_2_1_raw_System.Core.dll.sources diff --git a/mcs/class/System.Core/net_2_1_raw_System.Core.dll.sources b/mcs/class/System.Core/net_2_1_raw_System.Core.dll.sources deleted file mode 100644 index 844e40b1a78..00000000000 --- a/mcs/class/System.Core/net_2_1_raw_System.Core.dll.sources +++ /dev/null @@ -1,71 +0,0 @@ -../../build/common/Consts.cs -../../build/common/Locale.cs -../../build/common/MonoTODOAttribute.cs -../corlib/Mono.Security.Cryptography/CryptoTools.cs -../corlib/Mono.Security.Cryptography/SymmetricTransform.cs -Assembly/AssemblyInfo.cs -System/Actions.cs -System/Funcs.cs -System/InvalidTimeZoneException.cs -System/TimeZoneInfo.AdjustmentRule.cs -System/TimeZoneInfo.cs -System/TimeZoneInfo.TransitionTime.cs -System/TimeZoneNotFoundException.cs -System.Runtime.CompilerServices/ExecutionScope.cs -System.Runtime.CompilerServices/ExtensionAttribute.cs -System.Runtime.CompilerServices/IStrongBox.cs -System.Runtime.CompilerServices/StrongBox_T.cs -System.Linq/Check.cs -System.Linq/Enumerable.cs -System.Linq/QueryableEnumerable.cs -System.Linq/QueryableTransformer.cs -System.Linq/Grouping.cs -System.Linq/IGrouping.cs -System.Linq/IOrderedQueryable.cs -System.Linq/IOrderedQueryable_T.cs -System.Linq/IOrderedEnumerable_T.cs -System.Linq/IQueryable.cs -System.Linq/IQueryable_T.cs -System.Linq/Lookup.cs -System.Linq/ILookup_T.cs -System.Linq/OrderedEnumerable.cs -System.Linq/OrderedSequence.cs -System.Linq/Queryable.cs -System.Linq/QuickSort.cs -System.Linq/SortContext.cs -System.Linq/SortDirection.cs -System.Linq/SortSequenceContext.cs -System.Linq/IQueryProvider.cs -System.Linq.Expressions/BinaryExpression.cs -System.Linq.Expressions/ConditionalExpression.cs -System.Linq.Expressions/ConstantExpression.cs -System.Linq.Expressions/ElementInit.cs -System.Linq.Expressions/EmitContext.cs -System.Linq.Expressions/Expression.cs -System.Linq.Expressions/Expression_T.cs -System.Linq.Expressions/ExpressionPrinter.cs -System.Linq.Expressions/ExpressionType.cs -System.Linq.Expressions/ExpressionVisitor.cs -System.Linq.Expressions/ExpressionTransformer.cs -System.Linq.Expressions/Extensions.cs -System.Linq.Expressions/InvocationExpression.cs -System.Linq.Expressions/LambdaExpression.cs -System.Linq.Expressions/ListInitExpression.cs -System.Linq.Expressions/MemberAssignment.cs -System.Linq.Expressions/MemberBinding.cs -System.Linq.Expressions/MemberBindingType.cs -System.Linq.Expressions/MemberExpression.cs -System.Linq.Expressions/MemberInitExpression.cs -System.Linq.Expressions/MemberListBinding.cs -System.Linq.Expressions/MemberMemberBinding.cs -System.Linq.Expressions/MethodCallExpression.cs -System.Linq.Expressions/NewArrayExpression.cs -System.Linq.Expressions/NewExpression.cs -System.Linq.Expressions/ParameterExpression.cs -System.Linq.Expressions/TypeBinaryExpression.cs -System.Linq.Expressions/UnaryExpression.cs -System.Collections.Generic/HashSet.cs -../corlib/System.Collections.Generic/CollectionDebuggerView.cs -System.Security.Cryptography/Aes.cs -System.Security.Cryptography/AesManaged.cs -System.Security.Cryptography/AesTransform.cs diff --git a/mcs/class/System.Core/net_4_0_System.Core.dll.sources b/mcs/class/System.Core/net_4_0_System.Core.dll.sources index 138709e664c..220ab49fbca 100644 --- a/mcs/class/System.Core/net_4_0_System.Core.dll.sources +++ b/mcs/class/System.Core/net_4_0_System.Core.dll.sources @@ -42,6 +42,7 @@ System.Linq/ILookup_T.cs System.Linq/OrderedEnumerable.cs System.Linq/OrderedSequence.cs System.Linq/Queryable.cs +System.Linq/QueryableTransformer.cs System.Linq/QuickSort.cs System.Linq/SortContext.cs System.Linq/SortDirection.cs @@ -49,7 +50,6 @@ System.Linq/SortSequenceContext.cs System.Linq/IQueryProvider.cs System.Collections.Generic/HashSet.cs ../corlib/System.Collections.Generic/CollectionDebuggerView.cs -System.Security.Cryptography/Aes.cs System.Security.Cryptography/AesManaged.cs System.Security.Cryptography/AesCryptoServiceProvider.cs System.Security.Cryptography/AesTransform.cs @@ -68,6 +68,7 @@ System.Threading/LockRecursionPolicy.cs System.Threading/ReaderWriterLockSlim.cs System.Linq.Expressions/Extensions.cs +System.Linq.Expressions/ExpressionTransformer.cs Microsoft.Win32.SafeHandles/SafePipeHandle.cs Microsoft.Win32.SafeHandles/SafeMemoryMappedFileHandle.cs @@ -111,6 +112,7 @@ System.IO/HandleInheritability.cs ../dlr/Runtime/Microsoft.Scripting.Core/Actions/IDynamicMetaObjectProvider.cs ../dlr/Runtime/Microsoft.Scripting.Core/Actions/InvokeBinder.cs ../dlr/Runtime/Microsoft.Scripting.Core/Actions/InvokeMemberBinder.cs +../dlr/Runtime/Microsoft.Scripting.Core/Actions/IInvokeOnGetBinder.cs ../dlr/Runtime/Microsoft.Scripting.Core/Actions/RuleCache.cs ../dlr/Runtime/Microsoft.Scripting.Core/Actions/SetIndexBinder.cs ../dlr/Runtime/Microsoft.Scripting.Core/Actions/SetMemberBinder.cs @@ -207,3 +209,48 @@ System.IO/HandleInheritability.cs ../dlr/Runtime/Microsoft.Scripting.Core/Utils/ReferenceEqualityComparer.cs ../dlr/Runtime/Microsoft.Scripting.Core/Utils/TrueReadOnlyCollection.cs ../dlr/Runtime/Microsoft.Scripting.Core/Utils/TypeExtensions.cs +System.Linq/ParallelQueryEnumerator.cs +System.Linq/OrderedParallelQuery.cs +System.Linq/ParallelMergeOptions.cs +System.Linq/ParallelExecutionMode.cs +System.Linq/ParallelEnumerable.cs +System.Linq/ParallelPartitioner.cs +System.Linq/Internal/RangeList.cs +System.Linq/Internal/StripPartitioner.cs +System.Linq/Internal/RepeatList.cs +System.Linq/Internal/ParallelQuickSort.cs +System.Linq/Internal/OrderingEnumerator.cs +System.Linq/Internal/AggregationList.cs +System.Linq/Internal/ConcurrentLookup.cs +System.Linq/Internal/ConcurrentGrouping.cs +System.Linq/Internal/ReverseList.cs +System.Linq/ParallelExecuter.cs +System.Linq/ParallelQuery.cs +System.Linq/Internal/QueryNodes/QueryWhereNode.cs +System.Linq/Internal/QueryNodes/QueryCastNode.cs +System.Linq/Internal/QueryNodes/QueryConcatNode.cs +System.Linq/Internal/QueryNodes/QueryDefaultEmptyNode.cs +System.Linq/Internal/QueryNodes/QueryOptionNode.cs +System.Linq/Internal/QueryNodes/QueryGroupByNode.cs +System.Linq/Internal/QueryNodes/QuerySelectNode.cs +System.Linq/Internal/QueryNodes/QuerySelectManyNode.cs +System.Linq/Internal/QueryNodes/QueryStreamNode.cs +System.Linq/Internal/QueryNodes/QueryOrderedStreamNode.cs +System.Linq/Internal/QueryNodes/QueryStartNode.cs +System.Linq/Internal/QueryNodes/QueryBaseNode.cs +System.Linq/Internal/QueryNodes/QueryChildNode.cs +System.Linq/Internal/QueryNodes/QueryOrderGuardNode.cs +System.Linq/Internal/QueryNodes/QueryOrderByNode.cs +System.Linq/Internal/QueryNodes/QueryMuxNode.cs +System.Linq/Internal/QueryNodes/QueryZipNode.cs +System.Linq/Internal/QueryNodes/QuerySetNode.cs +System.Linq/Internal/QueryNodes/QueryReverseNode.cs +System.Linq/Internal/QueryNodes/SetInclusion.cs +System.Linq/Internal/Visitors/INodeVisitor.cs +System.Linq/Internal/Visitors/IVisitableNode.cs +System.Linq/Internal/Visitors/QueryCheckerVisitor.cs +System.Linq/Internal/Visitors/QueryOptions.cs +System.Linq/Internal/QueryNodes/WrapHelper.cs +../corlib/System.Collections.Concurrent/Partitioners/EnumerablePartitioner.cs +../corlib/System.Collections.Concurrent/ConcurrentSkipList.cs + diff --git a/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog b/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog index fa397259842..b6c487f060b 100644 --- a/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog +++ b/mcs/class/System.Data.DataSetExtensions/System.Data/ChangeLog @@ -1,3 +1,8 @@ +2010-03-26 Miguel de Icaza + + * RowEnumerableDataReader.cs: Applied patch from Tony Fish fixing + bug #591397 + 2008-12-02 Marek Habersack * DataRowExtensions.cs: when Field is specialized on a diff --git a/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs b/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs index 0e583bf611f..4a9e571abb1 100644 --- a/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs +++ b/mcs/class/System.Data.DataSetExtensions/System.Data/RowEnumerableDataReader.cs @@ -44,8 +44,8 @@ namespace System.Data public RowEnumerableDataReader (IEnumerable source, int depth) { this.source = source as EnumerableRowCollection; - if (source == null) - source = new EnumerableRowCollection ((IEnumerable) source); + if (this.source == null) + this.source = new EnumerableRowCollection ((IEnumerable) source); this.depth = depth; } @@ -158,10 +158,16 @@ namespace System.Data public int GetValues (object [] values) { - // FIXME: do we need it? - throw new NotSupportedException (); - } + int fieldCount = FieldCount; + int i; + //target object is byval so we can not just assign new object[] to values , calling side will not change + //hence copy each item into values + for (i = 0; i < values.Length && i < fieldCount; ++i) + values[i] = Current[i]; + return i - 1; + } + public bool IsDBNull (int i) { return Current.IsNull (i); diff --git a/mcs/class/System.Data.Linq/ChangeLog b/mcs/class/System.Data.Linq/ChangeLog index c5d8decf682..3bc8156bb19 100755 --- a/mcs/class/System.Data.Linq/ChangeLog +++ b/mcs/class/System.Data.Linq/ChangeLog @@ -1,3 +1,8 @@ +2010-04-13 Jonathan Pryor + + * src/**/*: Sync with DbLinq r1403. This is DbLinq 0.20 + fixes. + Primarily fixes sqlmetal, codegen, etc. + 2009-12-18 Jonathan Pryor * src/**/*: Sync with DbLinq r1294. This is DbLinq 0.19. Fixes diff --git a/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources b/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources index 6867b7cb288..242c5b64b15 100755 --- a/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources +++ b/mcs/class/System.Data.Linq/System.Data.Linq.dll.sources @@ -222,6 +222,7 @@ src/DbLinq/Schema/Dbml/Adapter/EnumType.cs src/DbLinq/Schema/Dbml/Adapter/INamedType.cs src/DbLinq/Schema/Dbml/Adapter/ISimpleList.cs src/DbLinq/Schema/Dbml/Adapter/SpecifiedPropertyUpdater.cs +src/DbLinq/Schema/Dbml/DatabaseSerializer.cs src/DbLinq/Schema/Dbml/DbmlSchema.Adapter.cs src/DbLinq/Schema/Dbml/DbmlSchema.cs src/DbLinq/Schema/Dbml/DbmlSerializer.cs diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.FbSql.Example/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/examples/DbLinq.FbSql.Example/Properties/AssemblyInfo.cs index 87c9c56522b..7051baf2e92 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.FbSql.Example/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/examples/DbLinq.FbSql.Example/Properties/AssemblyInfo.cs @@ -21,16 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("a87ac4a4-43ee-4a0a-8edf-42843d5e3bc0")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.Mssql.Example/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/examples/DbLinq.Mssql.Example/Properties/AssemblyInfo.cs index ed4b88cdc14..9f9d32200d2 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.Mssql.Example/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/examples/DbLinq.Mssql.Example/Properties/AssemblyInfo.cs @@ -21,16 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("65a7cab4-3c0b-47cd-bc50-dc8201115dbb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.0.1.17")] -[assembly: AssemblyFileVersion("0.19")] diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.MySql.Example/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/examples/DbLinq.MySql.Example/Properties/AssemblyInfo.cs index 4984c17343c..95e94cbbd72 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.MySql.Example/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/examples/DbLinq.MySql.Example/Properties/AssemblyInfo.cs @@ -21,13 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e2381b27-cdb0-401d-9019-f72079b4928d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyVersion("0.0.1.17")] -[assembly: AssemblyFileVersion("0.19")] diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/Properties/AssemblyInfo.cs index 6c8b1dd54f5..d049e83b359 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/Properties/AssemblyInfo.cs @@ -21,13 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e2381b27-cdb0-401d-9019-f72079b4928d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyVersion("0.0.1.17")] -[assembly: AssemblyFileVersion("0.19")] diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/create_Northwind_ora.sql b/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/create_Northwind_ora.sql index da8ecd35dc3..9c8aa14012e 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/create_Northwind_ora.sql +++ b/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/create_Northwind_ora.sql @@ -248,8 +248,8 @@ values ('UKMOD', 'MOD','(secret)','U.K.','E14','London'); insert INTO "Customers" ("CustomerID", "CompanyName","ContactName", "ContactTitle", "Country","PostalCode","City", "Phone") values ('ALFKI', 'Alfreds Futterkiste','Maria Anders','Sales Representative','Germany','12209','Berlin','030-0074321'); -insert INTO "Customers" ("CustomerID", "CompanyName","ContactName", "ContactTitle", "Country","PostalCode","City", "Phone") -values ('BONAP', 'Bon something','Bon Boss','Sales Representative','France','11109','Paris','033-0074321'); +insert INTO "Customers" ("CustomerID", "CompanyName","ContactName", "ContactTitle", "Country", "PostalCode", "Address", "City", "Phone", "Fax") +values ('BONAP', 'Bon app''','Laurence Lebihan','Owner','France','13008','12, rue des Bouchers','Marseille','91.24.45.40', '91.24.45.41'); insert INTO "Customers" ("CustomerID", "CompanyName","ContactName", "ContactTitle", "Country","PostalCode","City", "Phone") values ('WARTH', 'Wartian Herkku','Pirkko Koskitalo','Accounting Manager','Finland','90110','Oulu','981-443655'); diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/drop_Northwind_ora.sql b/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/drop_Northwind_ora.sql index e4beaac4fd4..48cb9d0ea29 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/drop_Northwind_ora.sql +++ b/mcs/class/System.Data.Linq/examples/DbLinq.Ora.Example/sql/drop_Northwind_ora.sql @@ -34,6 +34,7 @@ DROP SEQUENCE Orders_seq; DROP SEQUENCE Employees_seq; DROP SEQUENCE Categories_Seq; DROP SEQUENCE Region_seq; +DROP SEQUENCE Territories_seq; COMMIT; diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/Properties/AssemblyInfo.cs index 4984c17343c..95e94cbbd72 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/Properties/AssemblyInfo.cs @@ -21,13 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e2381b27-cdb0-401d-9019-f72079b4928d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyVersion("0.0.1.17")] -[assembly: AssemblyFileVersion("0.19")] diff --git a/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/nwind/Northwind.cs b/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/nwind/Northwind.cs index f6bf319a19e..9ab167eacae 100644 --- a/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/nwind/Northwind.cs +++ b/mcs/class/System.Data.Linq/examples/DbLinq.SQLite.Example/nwind/Northwind.cs @@ -1,841 +1,899 @@ -#region Auto-generated classes for Northwind database on [TIMESTAMP] - -// -// ____ _ __ __ _ _ +// +// ____ _ __ __ _ _ // | _ \| |__ | \/ | ___| |_ __ _| | // | | | | '_ \| |\/| |/ _ \ __/ _` | | // | |_| | |_) | | | | __/ || (_| | | // |____/|_.__/|_| |_|\___|\__\__,_|_| // -// Auto-generated from Northwind on [TIMESTAMP] -// Please visit http://linq.to/db for more information - -#endregion - -using System; -using System.Data; -using System.Data.Linq.Mapping; -using System.Diagnostics; -using System.Reflection; +// Auto-generated from Northwind on 2010-04-08 15:21:38Z. +// Please visit http://code.google.com/p/dblinq2007/ for more information. +// +namespace nwind +{ + using System; + using System.ComponentModel; + using System.Data; #if MONO_STRICT -using System.Data.Linq; + using System.Data.Linq; #else // MONO_STRICT -using DbLinq.Data.Linq; -using DbLinq.Vendor; + using DbLinq.Data.Linq; + using DbLinq.Vendor; #endif // MONO_STRICT -using System.ComponentModel; - -namespace nwind -{ + using System.Data.Linq.Mapping; + using System.Diagnostics; + + public partial class Northwind : DataContext { - #region Extensibility Method Definitions - + + #region Extensibility Method Declarations partial void OnCreated(); - #endregion - - public Northwind(string connectionString) - : base(connectionString) + + + public Northwind(string connectionString) : + base(connectionString) { - OnCreated(); + this.OnCreated(); } - - public Northwind(IDbConnection connection) - #if MONO_STRICT - : base(connection) - #else // MONO_STRICT - : base(connection, new DbLinq.Sqlite.SqliteVendor()) - #endif // MONO_STRICT + + public Northwind(string connection, MappingSource mappingSource) : + base(connection, mappingSource) { - OnCreated(); + this.OnCreated(); } - - public Northwind(string connection, MappingSource mappingSource) - : base(connection, mappingSource) + + public Northwind(IDbConnection connection, MappingSource mappingSource) : + base(connection, mappingSource) { - OnCreated(); + this.OnCreated(); } - - public Northwind(IDbConnection connection, MappingSource mappingSource) - : base(connection, mappingSource) + + public Table Categories { - OnCreated(); + get + { + return this.GetTable(); + } } - - #if !MONO_STRICT - public Northwind(IDbConnection connection, IVendor vendor) - : base(connection, vendor) + + public Table Customers { - OnCreated(); + get + { + return this.GetTable(); + } } - #endif // !MONO_STRICT - - #if !MONO_STRICT - public Northwind(IDbConnection connection, MappingSource mappingSource, IVendor vendor) - : base(connection, mappingSource, vendor) + + public Table CustomerCustomerDemo { - OnCreated(); + get + { + return this.GetTable(); + } } - #endif // !MONO_STRICT - - public Table Categories { get { return GetTable(); } } - public Table Customers { get { return GetTable(); } } - public Table CustomerCustomerDemo { get { return GetTable(); } } - public Table CustomerDemographics { get { return GetTable(); } } - public Table Employees { get { return GetTable(); } } - public Table EmployeeTerritories { get { return GetTable(); } } - public Table Orders { get { return GetTable(); } } - public Table OrderDetails { get { return GetTable(); } } - public Table Products { get { return GetTable(); } } - public Table Regions { get { return GetTable(); } } - public Table Shippers { get { return GetTable(); } } - public Table Suppliers { get { return GetTable(); } } - public Table Territories { get { return GetTable(); } } - - } - - [Table(Name = "main.Categories")] - public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public Table CustomerDemographics { - if (PropertyChanging != null) + get { - PropertyChanging(this, emptyChangingEventArgs); + return this.GetTable(); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public Table Employees { - if (PropertyChanged != null) + get { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return this.GetTable(); } } + + public Table EmployeeTerritories + { + get + { + return this.GetTable(); + } + } + + public Table Orders + { + get + { + return this.GetTable(); + } + } + + public Table OrderDetails + { + get + { + return this.GetTable(); + } + } + + public Table Products + { + get + { + return this.GetTable(); + } + } + + public Table Regions + { + get + { + return this.GetTable(); + } + } + + public Table Shippers + { + get + { + return this.GetTable(); + } + } + + public Table Suppliers + { + get + { + return this.GetTable(); + } + } + + public Table Territories + { + get + { + return this.GetTable(); + } + } + } + + #region Start MONO_STRICT +#if MONO_STRICT - #endregion - - #region Extensibility Method Definitions - + public partial class Northwind + { + + public Northwind(IDbConnection connection) : + base(connection) + { + this.OnCreated(); + } + } + #region End MONO_STRICT + #endregion +#else // MONO_STRICT + + public partial class Northwind + { + + public Northwind(IDbConnection connection) : + base(connection, new DbLinq.Sqlite.SqliteVendor()) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, IVendor sqlDialect) : + base(connection, sqlDialect) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, MappingSource mappingSource, IVendor sqlDialect) : + base(connection, mappingSource, sqlDialect) + { + this.OnCreated(); + } + } + #region End Not MONO_STRICT + #endregion +#endif // MONO_STRICT + #endregion + + [Table(Name="main.Categories")] + public partial class Category : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _categoryID; + + private string _categoryName; + + private string _description; + + private byte[] _picture; + + private EntitySet _products; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCategoryIDChanged(); + partial void OnCategoryIDChanging(int value); + partial void OnCategoryNameChanged(); + partial void OnCategoryNameChanging(string value); + partial void OnDescriptionChanged(); + partial void OnDescriptionChanging(string value); + partial void OnPictureChanged(); - partial void OnPictureChanging(Byte[] value); - + + partial void OnPictureChanging(byte[] value); #endregion - - #region int CategoryID - - private int _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Category() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int CategoryID { get { - return _categoryID; + return this._categoryID; } set { - if (value != _categoryID) + if ((_categoryID != value)) { - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); } } } - - #endregion - - #region string CategoryName - - private string _categoryName; - [DebuggerNonUserCode] - [Column(Storage = "_categoryName", Name = "CategoryName", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_categoryName", Name="CategoryName", DbType="nvarchar (15)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CategoryName { get { - return _categoryName; + return this._categoryName; } set { - if (value != _categoryName) + if (((_categoryName == value) + == false)) { - OnCategoryNameChanging(value); - SendPropertyChanging(); - _categoryName = value; - SendPropertyChanged("CategoryName"); - OnCategoryNameChanged(); + this.OnCategoryNameChanging(value); + this.SendPropertyChanging(); + this._categoryName = value; + this.SendPropertyChanged("CategoryName"); + this.OnCategoryNameChanged(); } } } - - #endregion - - #region string Description - - private string _description; - [DebuggerNonUserCode] - [Column(Storage = "_description", Name = "Description", DbType = "ntext", AutoSync = AutoSync.Never)] + + [Column(Storage="_description", Name="Description", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Description { get { - return _description; + return this._description; } set { - if (value != _description) + if (((_description == value) + == false)) { - OnDescriptionChanging(value); - SendPropertyChanging(); - _description = value; - SendPropertyChanged("Description"); - OnDescriptionChanged(); + this.OnDescriptionChanging(value); + this.SendPropertyChanging(); + this._description = value; + this.SendPropertyChanged("Description"); + this.OnDescriptionChanged(); } } } - - #endregion - - #region Byte[] Picture - - private Byte[] _picture; - [DebuggerNonUserCode] - [Column(Storage = "_picture", Name = "Picture", DbType = "image", AutoSync = AutoSync.Never)] - public Byte[] Picture + + [Column(Storage="_picture", Name="Picture", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Picture { get { - return _picture; + return this._picture; } set { - if (value != _picture) + if (((_picture == value) + == false)) { - OnPictureChanging(value); - SendPropertyChanging(); - _picture = value; - SendPropertyChanged("Picture"); - OnPictureChanged(); + this.OnPictureChanging(value); + this.SendPropertyChanging(); + this._picture = value; + this.SendPropertyChanged("Picture"); + this.OnPictureChanged(); } } } - - #endregion - + #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "fk_Products_1")] - [DebuggerNonUserCode] + [Association(Storage="_products", OtherKey="CategoryID", ThisKey="CategoryID", Name="fk_Products_1")] + [DebuggerNonUserCode()] public EntitySet Products { get { - return _products; + return this._products; } set { - _products = value; + this._products = value; } } - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) - { - entity.Category = this; - } - - private void Products_Detach(Product entity) - { - entity.Category = null; - } - - - #endregion - - #region ctor - - public Category() - { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Customers")] - public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = null; + } #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Customers")] + public partial class Customer : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _customerID; + + private string _fax; + + private string _phone; + + private string _postalCode; + + private string _region; + + private EntitySet _customerCustomerDemo; + + private EntitySet _orders; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnContactNameChanged(); + partial void OnContactNameChanging(string value); + partial void OnContactTitleChanged(); + partial void OnContactTitleChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnFaxChanged(); + partial void OnFaxChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] + + + public Customer() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactName { get { - return _contactName; + return this._contactName; } set { - if (value != _contactName) + if (((_contactName == value) + == false)) { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); } } } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactTitle { get { - return _contactTitle; + return this._contactTitle; } set { - if (value != _contactTitle) + if (((_contactTitle == value) + == false)) { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Fax { get { - return _fax; + return this._fax; } set { - if (value != _fax) + if (((_fax == value) + == false)) { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - + #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_CustomerCustomerDemo_0")] - [DebuggerNonUserCode] + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_CustomerCustomerDemo_0")] + [DebuggerNonUserCode()] public EntitySet CustomerCustomerDemo { get { - return _customerCustomerDemo; + return this._customerCustomerDemo; } set { - _customerCustomerDemo = value; + this._customerCustomerDemo = value; } } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_Orders_2")] - [DebuggerNonUserCode] + + [Association(Storage="_orders", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_Orders_2")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + #region Attachment handlers private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) { + this.SendPropertyChanging(); entity.Customer = this; } - + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) { + this.SendPropertyChanging(); entity.Customer = null; } - + private void Orders_Attach(Order entity) { + this.SendPropertyChanging(); entity.Customer = this; } - + private void Orders_Detach(Order entity) { + this.SendPropertyChanging(); entity.Customer = null; } - - - #endregion - - #region ctor - - public Customer() - { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); - } - #endregion - } - - [Table(Name = "main.CustomerCustomerDemo")] - public partial class CustomerCustomerDemo : INotifyPropertyChanging, INotifyPropertyChanged + + [Table(Name="main.CustomerCustomerDemo")] + public partial class CustomerCustomerDemo : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private string _customerTypeID; + + private EntityRef _customer = new EntityRef(); + + private EntityRef _customerDemographic = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnCustomerTypeIDChanged(); + partial void OnCustomerTypeIDChanging(string value); - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + + public CustomerCustomerDemo() + { + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { if (_customer.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerTypeID { get { - return _customerTypeID; + return this._customerTypeID; } set { - if (value != _customerTypeID) + if (((_customerTypeID == value) + == false)) { if (_customerDemographic.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_CustomerCustomerDemo_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_CustomerCustomerDemo_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Customer Customer { get { - return _customer.Entity; + return this._customer.Entity; } set { - if (value != _customer.Entity) + if (((this._customer.Entity == value) + == false)) { - if (_customer.Entity != null) + if ((this._customer.Entity != null)) { - var previousCustomer = _customer.Entity; - _customer.Entity = null; + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; previousCustomer.CustomerCustomerDemo.Remove(this); } - _customer.Entity = value; - if (value != null) + this._customer.Entity = value; + if ((value != null)) { value.CustomerCustomerDemo.Add(this); _customerID = value.CustomerID; @@ -847,28 +905,28 @@ namespace nwind } } } - - private EntityRef _customerDemographic; - [Association(Storage = "_customerDemographic", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "fk_CustomerCustomerDemo_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_customerDemographic", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="fk_CustomerCustomerDemo_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public CustomerDemographic CustomerDemographic { get { - return _customerDemographic.Entity; + return this._customerDemographic.Entity; } set { - if (value != _customerDemographic.Entity) + if (((this._customerDemographic.Entity == value) + == false)) { - if (_customerDemographic.Entity != null) + if ((this._customerDemographic.Entity != null)) { - var previousCustomerDemographic = _customerDemographic.Entity; - _customerDemographic.Entity = null; + CustomerDemographic previousCustomerDemographic = this._customerDemographic.Entity; + this._customerDemographic.Entity = null; previousCustomerDemographic.CustomerCustomerDemo.Remove(this); } - _customerDemographic.Entity = value; - if (value != null) + this._customerDemographic.Entity = value; + if ((value != null)) { value.CustomerCustomerDemo.Add(this); _customerTypeID = value.CustomerTypeID; @@ -880,783 +938,756 @@ namespace nwind } } } - - #endregion - - #region ctor - - public CustomerCustomerDemo() - { - _customer = new EntityRef(); - _customerDemographic = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.CustomerDemographics")] - public partial class CustomerDemographic : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.CustomerDemographics")] + public partial class CustomerDemographic : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerDesc; + + private string _customerTypeID; + + private EntitySet _customerCustomerDemo; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerDescChanged(); + partial void OnCustomerDescChanging(string value); + partial void OnCustomerTypeIDChanged(); + partial void OnCustomerTypeIDChanging(string value); - #endregion - - #region string CustomerDesc - - private string _customerDesc; - [DebuggerNonUserCode] - [Column(Storage = "_customerDesc", Name = "CustomerDesc", DbType = "ntext", AutoSync = AutoSync.Never)] + + + public CustomerDemographic() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerDesc", Name="CustomerDesc", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string CustomerDesc { get { - return _customerDesc; + return this._customerDesc; } set { - if (value != _customerDesc) + if (((_customerDesc == value) + == false)) { - OnCustomerDescChanging(value); - SendPropertyChanging(); - _customerDesc = value; - SendPropertyChanged("CustomerDesc"); - OnCustomerDescChanged(); + this.OnCustomerDescChanging(value); + this.SendPropertyChanging(); + this._customerDesc = value; + this.SendPropertyChanged("CustomerDesc"); + this.OnCustomerDescChanged(); } } } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerTypeID { get { - return _customerTypeID; + return this._customerTypeID; } set { - if (value != _customerTypeID) + if (((_customerTypeID == value) + == false)) { - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "fk_CustomerCustomerDemo_1")] - [DebuggerNonUserCode] + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="fk_CustomerCustomerDemo_1")] + [DebuggerNonUserCode()] public EntitySet CustomerCustomerDemo { get { - return _customerCustomerDemo; + return this._customerCustomerDemo; } set { - _customerCustomerDemo = value; + this._customerCustomerDemo = value; } } - - #endregion - - #region Attachement handlers - - private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) - { - entity.CustomerDemographic = this; - } - - private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) - { - entity.CustomerDemographic = null; - } - - - #endregion - - #region ctor - - public CustomerDemographic() - { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Employees")] - public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - + + #region Attachment handlers + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = this; + } + + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = null; + } #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Employees")] + public partial class Employee : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private System.Nullable _birthDate; + + private string _city; + + private string _country; + + private int _employeeID; + + private string _extension; + + private string _firstName; + + private System.Nullable _hireDate; + + private string _homePhone; + + private string _lastName; + + private string _notes; + + private byte[] _photo; + + private string _photoPath; + + private string _postalCode; + + private string _region; + + private System.Nullable _reportsTo; + + private string _title; + + private string _titleOfCourtesy; + + private EntitySet _employeeTerritories; + + private EntitySet _employees; + + private EntitySet _orders; + + private EntityRef _reportsToEmployee = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnBirthDateChanged(); - partial void OnBirthDateChanging(DateTime? value); + + partial void OnBirthDateChanging(System.Nullable value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnEmployeeIDChanged(); + partial void OnEmployeeIDChanging(int value); + partial void OnExtensionChanged(); + partial void OnExtensionChanging(string value); + partial void OnFirstNameChanged(); + partial void OnFirstNameChanging(string value); + partial void OnHireDateChanged(); - partial void OnHireDateChanging(DateTime? value); + + partial void OnHireDateChanging(System.Nullable value); + partial void OnHomePhoneChanged(); + partial void OnHomePhoneChanging(string value); + partial void OnLastNameChanged(); + partial void OnLastNameChanging(string value); + partial void OnNotesChanged(); + partial void OnNotesChanging(string value); + partial void OnPhotoChanged(); - partial void OnPhotoChanging(Byte[] value); + + partial void OnPhotoChanging(byte[] value); + partial void OnPhotoPathChanged(); + partial void OnPhotoPathChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); + partial void OnReportsToChanged(); - partial void OnReportsToChanging(int? value); + + partial void OnReportsToChanging(System.Nullable value); + partial void OnTitleChanged(); + partial void OnTitleChanging(string value); + partial void OnTitleOfCourtesyChanged(); + partial void OnTitleOfCourtesyChanging(string value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] + + + public Employee() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + _employees = new EntitySet(new Action(this.Employees_Attach), new Action(this.Employees_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region DateTime? BirthDate - - private DateTime? _birthDate; - [DebuggerNonUserCode] - [Column(Storage = "_birthDate", Name = "BirthDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? BirthDate + + [Column(Storage="_birthDate", Name="BirthDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable BirthDate { get { - return _birthDate; + return this._birthDate; } set { - if (value != _birthDate) + if ((_birthDate != value)) { - OnBirthDateChanging(value); - SendPropertyChanging(); - _birthDate = value; - SendPropertyChanged("BirthDate"); - OnBirthDateChanged(); + this.OnBirthDateChanging(value); + this.SendPropertyChanging(); + this._birthDate = value; + this.SendPropertyChanged("BirthDate"); + this.OnBirthDateChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region int EmployeeID - - private int _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region string Extension - - private string _extension; - [DebuggerNonUserCode] - [Column(Storage = "_extension", Name = "Extension", DbType = "nvarchar (4)", AutoSync = AutoSync.Never)] + + [Column(Storage="_extension", Name="Extension", DbType="nvarchar (4)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Extension { get { - return _extension; + return this._extension; } set { - if (value != _extension) + if (((_extension == value) + == false)) { - OnExtensionChanging(value); - SendPropertyChanging(); - _extension = value; - SendPropertyChanged("Extension"); - OnExtensionChanged(); + this.OnExtensionChanging(value); + this.SendPropertyChanging(); + this._extension = value; + this.SendPropertyChanged("Extension"); + this.OnExtensionChanged(); } } } - - #endregion - - #region string FirstName - - private string _firstName; - [DebuggerNonUserCode] - [Column(Storage = "_firstName", Name = "FirstName", DbType = "nvarchar (10)", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_firstName", Name="FirstName", DbType="nvarchar (10)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string FirstName { get { - return _firstName; + return this._firstName; } set { - if (value != _firstName) + if (((_firstName == value) + == false)) { - OnFirstNameChanging(value); - SendPropertyChanging(); - _firstName = value; - SendPropertyChanged("FirstName"); - OnFirstNameChanged(); + this.OnFirstNameChanging(value); + this.SendPropertyChanging(); + this._firstName = value; + this.SendPropertyChanged("FirstName"); + this.OnFirstNameChanged(); } } } - - #endregion - - #region DateTime? HireDate - - private DateTime? _hireDate; - [DebuggerNonUserCode] - [Column(Storage = "_hireDate", Name = "HireDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? HireDate + + [Column(Storage="_hireDate", Name="HireDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable HireDate { get { - return _hireDate; + return this._hireDate; } set { - if (value != _hireDate) + if ((_hireDate != value)) { - OnHireDateChanging(value); - SendPropertyChanging(); - _hireDate = value; - SendPropertyChanged("HireDate"); - OnHireDateChanged(); + this.OnHireDateChanging(value); + this.SendPropertyChanging(); + this._hireDate = value; + this.SendPropertyChanged("HireDate"); + this.OnHireDateChanged(); } } } - - #endregion - - #region string HomePhone - - private string _homePhone; - [DebuggerNonUserCode] - [Column(Storage = "_homePhone", Name = "HomePhone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] + + [Column(Storage="_homePhone", Name="HomePhone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string HomePhone { get { - return _homePhone; + return this._homePhone; } set { - if (value != _homePhone) + if (((_homePhone == value) + == false)) { - OnHomePhoneChanging(value); - SendPropertyChanging(); - _homePhone = value; - SendPropertyChanged("HomePhone"); - OnHomePhoneChanged(); + this.OnHomePhoneChanging(value); + this.SendPropertyChanging(); + this._homePhone = value; + this.SendPropertyChanged("HomePhone"); + this.OnHomePhoneChanged(); } } } - - #endregion - - #region string LastName - - private string _lastName; - [DebuggerNonUserCode] - [Column(Storage = "_lastName", Name = "LastName", DbType = "nvarchar (20)", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_lastName", Name="LastName", DbType="nvarchar (20)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string LastName { get { - return _lastName; + return this._lastName; } set { - if (value != _lastName) + if (((_lastName == value) + == false)) { - OnLastNameChanging(value); - SendPropertyChanging(); - _lastName = value; - SendPropertyChanged("LastName"); - OnLastNameChanged(); + this.OnLastNameChanging(value); + this.SendPropertyChanging(); + this._lastName = value; + this.SendPropertyChanged("LastName"); + this.OnLastNameChanged(); } } } - - #endregion - - #region string Notes - - private string _notes; - [DebuggerNonUserCode] - [Column(Storage = "_notes", Name = "Notes", DbType = "ntext", AutoSync = AutoSync.Never)] + + [Column(Storage="_notes", Name="Notes", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Notes { get { - return _notes; + return this._notes; } set { - if (value != _notes) + if (((_notes == value) + == false)) { - OnNotesChanging(value); - SendPropertyChanging(); - _notes = value; - SendPropertyChanged("Notes"); - OnNotesChanged(); + this.OnNotesChanging(value); + this.SendPropertyChanging(); + this._notes = value; + this.SendPropertyChanged("Notes"); + this.OnNotesChanged(); } - } - } - - #endregion - - #region Byte[] Photo - - private Byte[] _photo; - [DebuggerNonUserCode] - [Column(Storage = "_photo", Name = "Photo", DbType = "image", AutoSync = AutoSync.Never)] - public Byte[] Photo + } + } + + [Column(Storage="_photo", Name="Photo", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Photo { get { - return _photo; + return this._photo; } set { - if (value != _photo) + if (((_photo == value) + == false)) { - OnPhotoChanging(value); - SendPropertyChanging(); - _photo = value; - SendPropertyChanged("Photo"); - OnPhotoChanged(); + this.OnPhotoChanging(value); + this.SendPropertyChanging(); + this._photo = value; + this.SendPropertyChanged("Photo"); + this.OnPhotoChanged(); } } } - - #endregion - - #region string PhotoPath - - private string _photoPath; - [DebuggerNonUserCode] - [Column(Storage = "_photoPath", Name = "PhotoPath", DbType = "nvarchar (255)", AutoSync = AutoSync.Never)] + + [Column(Storage="_photoPath", Name="PhotoPath", DbType="nvarchar (255)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PhotoPath { get { - return _photoPath; + return this._photoPath; } set { - if (value != _photoPath) + if (((_photoPath == value) + == false)) { - OnPhotoPathChanging(value); - SendPropertyChanging(); - _photoPath = value; - SendPropertyChanged("PhotoPath"); - OnPhotoPathChanged(); + this.OnPhotoPathChanging(value); + this.SendPropertyChanging(); + this._photoPath = value; + this.SendPropertyChanged("PhotoPath"); + this.OnPhotoPathChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - - #region int? ReportsTo - - private int? _reportsTo; - [DebuggerNonUserCode] - [Column(Storage = "_reportsTo", Name = "ReportsTo", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? ReportsTo + + [Column(Storage="_reportsTo", Name="ReportsTo", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReportsTo { get { - return _reportsTo; + return this._reportsTo; } set { - if (value != _reportsTo) + if ((_reportsTo != value)) { if (_reportsToEmployee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnReportsToChanging(value); - SendPropertyChanging(); - _reportsTo = value; - SendPropertyChanged("ReportsTo"); - OnReportsToChanged(); + this.OnReportsToChanging(value); + this.SendPropertyChanging(); + this._reportsTo = value; + this.SendPropertyChanged("ReportsTo"); + this.OnReportsToChanged(); } } } - - #endregion - - #region string Title - - private string _title; - [DebuggerNonUserCode] - [Column(Storage = "_title", Name = "Title", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] + + [Column(Storage="_title", Name="Title", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Title { get { - return _title; + return this._title; } set { - if (value != _title) + if (((_title == value) + == false)) { - OnTitleChanging(value); - SendPropertyChanging(); - _title = value; - SendPropertyChanged("Title"); - OnTitleChanged(); + this.OnTitleChanging(value); + this.SendPropertyChanging(); + this._title = value; + this.SendPropertyChanged("Title"); + this.OnTitleChanged(); } } } - - #endregion - - #region string TitleOfCourtesy - - private string _titleOfCourtesy; - [DebuggerNonUserCode] - [Column(Storage = "_titleOfCourtesy", Name = "TitleOfCourtesy", DbType = "nvarchar (25)", AutoSync = AutoSync.Never)] + + [Column(Storage="_titleOfCourtesy", Name="TitleOfCourtesy", DbType="nvarchar (25)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string TitleOfCourtesy { get { - return _titleOfCourtesy; + return this._titleOfCourtesy; } set { - if (value != _titleOfCourtesy) + if (((_titleOfCourtesy == value) + == false)) { - OnTitleOfCourtesyChanging(value); - SendPropertyChanging(); - _titleOfCourtesy = value; - SendPropertyChanged("TitleOfCourtesy"); - OnTitleOfCourtesyChanged(); + this.OnTitleOfCourtesyChanging(value); + this.SendPropertyChanging(); + this._titleOfCourtesy = value; + this.SendPropertyChanged("TitleOfCourtesy"); + this.OnTitleOfCourtesyChanged(); } } } - - #endregion - + #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_EmployeeTerritories_1")] - [DebuggerNonUserCode] + [Association(Storage="_employeeTerritories", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_EmployeeTerritories_1")] + [DebuggerNonUserCode()] public EntitySet EmployeeTerritories { get { - return _employeeTerritories; + return this._employeeTerritories; } set { - _employeeTerritories = value; + this._employeeTerritories = value; } } - - private EntitySet _employees; - [Association(Storage = "_employees", OtherKey = "ReportsTo", ThisKey = "EmployeeID", Name = "fk_Employees_0")] - [DebuggerNonUserCode] + + [Association(Storage="_employees", OtherKey="ReportsTo", ThisKey="EmployeeID", Name="fk_Employees_0")] + [DebuggerNonUserCode()] public EntitySet Employees { get { - return _employees; + return this._employees; } set { - _employees = value; + this._employees = value; } } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_Orders_1")] - [DebuggerNonUserCode] + + [Association(Storage="_orders", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_Orders_1")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - #endregion - + #region Parents - - private EntityRef _reportsToEmployee; - [Association(Storage = "_reportsToEmployee", OtherKey = "EmployeeID", ThisKey = "ReportsTo", Name = "fk_Employees_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_reportsToEmployee", OtherKey="EmployeeID", ThisKey="ReportsTo", Name="fk_Employees_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee ReportsToEmployee { get { - return _reportsToEmployee.Entity; + return this._reportsToEmployee.Entity; } set { - if (value != _reportsToEmployee.Entity) + if (((this._reportsToEmployee.Entity == value) + == false)) { - if (_reportsToEmployee.Entity != null) + if ((this._reportsToEmployee.Entity != null)) { - var previousEmployee = _reportsToEmployee.Entity; - _reportsToEmployee.Entity = null; + Employee previousEmployee = this._reportsToEmployee.Entity; + this._reportsToEmployee.Entity = null; previousEmployee.Employees.Remove(this); } - _reportsToEmployee.Entity = value; - if (value != null) + this._reportsToEmployee.Entity = value; + if ((value != null)) { value.Employees.Add(this); _reportsTo = value.EmployeeID; @@ -1668,185 +1699,174 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + #region Attachment handlers private void EmployeeTerritories_Attach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Employee = this; } - + private void EmployeeTerritories_Detach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Employee = null; } - + private void Employees_Attach(Employee entity) { + this.SendPropertyChanging(); entity.ReportsToEmployee = this; } - + private void Employees_Detach(Employee entity) { + this.SendPropertyChanging(); entity.ReportsToEmployee = null; } - + private void Orders_Attach(Order entity) { + this.SendPropertyChanging(); entity.Employee = this; } - + private void Orders_Detach(Order entity) { + this.SendPropertyChanging(); entity.Employee = null; } - - - #endregion - - #region ctor - - public Employee() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _employees = new EntitySet(Employees_Attach, Employees_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - _reportsToEmployee = new EntityRef(); - OnCreated(); - } - #endregion - } - - [Table(Name = "main.EmployeeTerritories")] - public partial class EmployeeTerritory : INotifyPropertyChanging, INotifyPropertyChanged + + [Table(Name="main.EmployeeTerritories")] + public partial class EmployeeTerritory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _employeeID; + + private string _territoryID; + + private EntityRef _territory = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnEmployeeIDChanged(); + partial void OnEmployeeIDChanging(int value); + partial void OnTerritoryIDChanged(); + partial void OnTerritoryIDChanging(string value); - #endregion - - #region int EmployeeID - - private int _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + + public EmployeeTerritory() + { + this.OnCreated(); + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { if (_employee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryID { get { - return _territoryID; + return this._territoryID; } set { - if (value != _territoryID) + if (((_territoryID == value) + == false)) { if (_territory.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _territory; - [Association(Storage = "_territory", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "fk_EmployeeTerritories_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_territory", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="fk_EmployeeTerritories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Territory Territory { get { - return _territory.Entity; + return this._territory.Entity; } set { - if (value != _territory.Entity) + if (((this._territory.Entity == value) + == false)) { - if (_territory.Entity != null) + if ((this._territory.Entity != null)) { - var previousTerritory = _territory.Entity; - _territory.Entity = null; + Territory previousTerritory = this._territory.Entity; + this._territory.Entity = null; previousTerritory.EmployeeTerritories.Remove(this); } - _territory.Entity = value; - if (value != null) + this._territory.Entity = value; + if ((value != null)) { value.EmployeeTerritories.Add(this); _territoryID = value.TerritoryID; @@ -1858,28 +1878,28 @@ namespace nwind } } } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_EmployeeTerritories_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_EmployeeTerritories_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee Employee { get { - return _employee.Entity; + return this._employee.Entity; } set { - if (value != _employee.Entity) + if (((this._employee.Entity == value) + == false)) { - if (_employee.Entity != null) + if ((this._employee.Entity != null)) { - var previousEmployee = _employee.Entity; - _employee.Entity = null; + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; previousEmployee.EmployeeTerritories.Remove(this); } - _employee.Entity = value; - if (value != null) + this._employee.Entity = value; + if ((value != null)) { value.EmployeeTerritories.Add(this); _employeeID = value.EmployeeID; @@ -1891,508 +1911,491 @@ namespace nwind } } } - - - #endregion - - #region ctor - - public EmployeeTerritory() - { - _territory = new EntityRef(); - _employee = new EntityRef(); - OnCreated(); - } - #endregion - - } - - [Table(Name = "main.Orders")] - public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Orders")] + public partial class Order : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private System.Nullable _employeeID; + + private System.Nullable _freight; + + private System.Nullable _orderDate; + + private int _orderID; + + private System.Nullable _requiredDate; + + private string _shipAddress; + + private string _shipCity; + + private string _shipCountry; + + private string _shipName; + + private System.Nullable _shippedDate; + + private string _shipPostalCode; + + private string _shipRegion; + + private System.Nullable _shipVia; + + private EntitySet _orderDetails; + + private EntityRef _shipper = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + private EntityRef _customer = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(int? value); + + partial void OnEmployeeIDChanging(System.Nullable value); + partial void OnFreightChanged(); - partial void OnFreightChanging(decimal? value); + + partial void OnFreightChanging(System.Nullable value); + partial void OnOrderDateChanged(); - partial void OnOrderDateChanging(DateTime? value); + + partial void OnOrderDateChanging(System.Nullable value); + partial void OnOrderIDChanged(); + partial void OnOrderIDChanging(int value); + partial void OnRequiredDateChanged(); - partial void OnRequiredDateChanging(DateTime? value); + + partial void OnRequiredDateChanging(System.Nullable value); + partial void OnShipAddressChanged(); + partial void OnShipAddressChanging(string value); + partial void OnShipCityChanged(); + partial void OnShipCityChanging(string value); + partial void OnShipCountryChanged(); + partial void OnShipCountryChanging(string value); + partial void OnShipNameChanged(); + partial void OnShipNameChanging(string value); + partial void OnShippedDateChanged(); - partial void OnShippedDateChanging(DateTime? value); + + partial void OnShippedDateChanging(System.Nullable value); + partial void OnShipPostalCodeChanged(); + partial void OnShipPostalCodeChanging(string value); + partial void OnShipRegionChanged(); + partial void OnShipRegionChanging(string value); + partial void OnShipViaChanged(); - partial void OnShipViaChanging(int? value); - + + partial void OnShipViaChanging(System.Nullable value); #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", AutoSync = AutoSync.Never)] + + + public Order() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { if (_customer.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region int? EmployeeID - - private int? _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? EmployeeID + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { if (_employee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region decimal? Freight - - private decimal? _freight; - [DebuggerNonUserCode] - [Column(Storage = "_freight", Name = "Freight", DbType = "money", AutoSync = AutoSync.Never)] - public decimal? Freight + + [Column(Storage="_freight", Name="Freight", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable Freight { get { - return _freight; + return this._freight; } set { - if (value != _freight) + if ((_freight != value)) { - OnFreightChanging(value); - SendPropertyChanging(); - _freight = value; - SendPropertyChanged("Freight"); - OnFreightChanged(); + this.OnFreightChanging(value); + this.SendPropertyChanging(); + this._freight = value; + this.SendPropertyChanged("Freight"); + this.OnFreightChanged(); } } } - - #endregion - - #region DateTime? OrderDate - - private DateTime? _orderDate; - [DebuggerNonUserCode] - [Column(Storage = "_orderDate", Name = "OrderDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? OrderDate + + [Column(Storage="_orderDate", Name="OrderDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable OrderDate { get { - return _orderDate; + return this._orderDate; } set { - if (value != _orderDate) + if ((_orderDate != value)) { - OnOrderDateChanging(value); - SendPropertyChanging(); - _orderDate = value; - SendPropertyChanged("OrderDate"); - OnOrderDateChanged(); + this.OnOrderDateChanging(value); + this.SendPropertyChanging(); + this._orderDate = value; + this.SendPropertyChanged("OrderDate"); + this.OnOrderDateChanged(); } } } - - #endregion - - #region int OrderID - - private int _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_orderID", Name="OrderID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int OrderID { get { - return _orderID; + return this._orderID; } set { - if (value != _orderID) + if ((_orderID != value)) { - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); } } } - - #endregion - - #region DateTime? RequiredDate - - private DateTime? _requiredDate; - [DebuggerNonUserCode] - [Column(Storage = "_requiredDate", Name = "RequiredDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? RequiredDate + + [Column(Storage="_requiredDate", Name="RequiredDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable RequiredDate { get { - return _requiredDate; + return this._requiredDate; } set { - if (value != _requiredDate) + if ((_requiredDate != value)) { - OnRequiredDateChanging(value); - SendPropertyChanging(); - _requiredDate = value; - SendPropertyChanged("RequiredDate"); - OnRequiredDateChanged(); + this.OnRequiredDateChanging(value); + this.SendPropertyChanging(); + this._requiredDate = value; + this.SendPropertyChanged("RequiredDate"); + this.OnRequiredDateChanged(); } } } - - #endregion - - #region string ShipAddress - - private string _shipAddress; - [DebuggerNonUserCode] - [Column(Storage = "_shipAddress", Name = "ShipAddress", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipAddress", Name="ShipAddress", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipAddress { get { - return _shipAddress; + return this._shipAddress; } set { - if (value != _shipAddress) + if (((_shipAddress == value) + == false)) { - OnShipAddressChanging(value); - SendPropertyChanging(); - _shipAddress = value; - SendPropertyChanged("ShipAddress"); - OnShipAddressChanged(); + this.OnShipAddressChanging(value); + this.SendPropertyChanging(); + this._shipAddress = value; + this.SendPropertyChanged("ShipAddress"); + this.OnShipAddressChanged(); } } } - - #endregion - - #region string ShipCity - - private string _shipCity; - [DebuggerNonUserCode] - [Column(Storage = "_shipCity", Name = "ShipCity", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipCity", Name="ShipCity", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipCity { get { - return _shipCity; + return this._shipCity; } set { - if (value != _shipCity) + if (((_shipCity == value) + == false)) { - OnShipCityChanging(value); - SendPropertyChanging(); - _shipCity = value; - SendPropertyChanged("ShipCity"); - OnShipCityChanged(); + this.OnShipCityChanging(value); + this.SendPropertyChanging(); + this._shipCity = value; + this.SendPropertyChanged("ShipCity"); + this.OnShipCityChanged(); } } } - - #endregion - - #region string ShipCountry - - private string _shipCountry; - [DebuggerNonUserCode] - [Column(Storage = "_shipCountry", Name = "ShipCountry", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipCountry", Name="ShipCountry", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipCountry { get { - return _shipCountry; + return this._shipCountry; } set { - if (value != _shipCountry) + if (((_shipCountry == value) + == false)) { - OnShipCountryChanging(value); - SendPropertyChanging(); - _shipCountry = value; - SendPropertyChanged("ShipCountry"); - OnShipCountryChanged(); + this.OnShipCountryChanging(value); + this.SendPropertyChanging(); + this._shipCountry = value; + this.SendPropertyChanged("ShipCountry"); + this.OnShipCountryChanged(); } } } - - #endregion - - #region string ShipName - - private string _shipName; - [DebuggerNonUserCode] - [Column(Storage = "_shipName", Name = "ShipName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipName", Name="ShipName", DbType="nvarchar (40)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipName { get { - return _shipName; + return this._shipName; } set { - if (value != _shipName) + if (((_shipName == value) + == false)) { - OnShipNameChanging(value); - SendPropertyChanging(); - _shipName = value; - SendPropertyChanged("ShipName"); - OnShipNameChanged(); + this.OnShipNameChanging(value); + this.SendPropertyChanging(); + this._shipName = value; + this.SendPropertyChanged("ShipName"); + this.OnShipNameChanged(); } } } - - #endregion - - #region DateTime? ShippedDate - - private DateTime? _shippedDate; - [DebuggerNonUserCode] - [Column(Storage = "_shippedDate", Name = "ShippedDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? ShippedDate + + [Column(Storage="_shippedDate", Name="ShippedDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShippedDate { get { - return _shippedDate; + return this._shippedDate; } set { - if (value != _shippedDate) + if ((_shippedDate != value)) { - OnShippedDateChanging(value); - SendPropertyChanging(); - _shippedDate = value; - SendPropertyChanged("ShippedDate"); - OnShippedDateChanged(); + this.OnShippedDateChanging(value); + this.SendPropertyChanging(); + this._shippedDate = value; + this.SendPropertyChanged("ShippedDate"); + this.OnShippedDateChanged(); } } } - - #endregion - - #region string ShipPostalCode - - private string _shipPostalCode; - [DebuggerNonUserCode] - [Column(Storage = "_shipPostalCode", Name = "ShipPostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipPostalCode", Name="ShipPostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipPostalCode { get { - return _shipPostalCode; + return this._shipPostalCode; } set { - if (value != _shipPostalCode) + if (((_shipPostalCode == value) + == false)) { - OnShipPostalCodeChanging(value); - SendPropertyChanging(); - _shipPostalCode = value; - SendPropertyChanged("ShipPostalCode"); - OnShipPostalCodeChanged(); + this.OnShipPostalCodeChanging(value); + this.SendPropertyChanging(); + this._shipPostalCode = value; + this.SendPropertyChanged("ShipPostalCode"); + this.OnShipPostalCodeChanged(); } } } - - #endregion - - #region string ShipRegion - - private string _shipRegion; - [DebuggerNonUserCode] - [Column(Storage = "_shipRegion", Name = "ShipRegion", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipRegion", Name="ShipRegion", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipRegion { get { - return _shipRegion; + return this._shipRegion; } set { - if (value != _shipRegion) + if (((_shipRegion == value) + == false)) { - OnShipRegionChanging(value); - SendPropertyChanging(); - _shipRegion = value; - SendPropertyChanged("ShipRegion"); - OnShipRegionChanged(); + this.OnShipRegionChanging(value); + this.SendPropertyChanging(); + this._shipRegion = value; + this.SendPropertyChanged("ShipRegion"); + this.OnShipRegionChanged(); } } } - - #endregion - - #region int? ShipVia - - private int? _shipVia; - [DebuggerNonUserCode] - [Column(Storage = "_shipVia", Name = "ShipVia", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? ShipVia + + [Column(Storage="_shipVia", Name="ShipVia", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShipVia { get { - return _shipVia; + return this._shipVia; } set { - if (value != _shipVia) + if ((_shipVia != value)) { if (_shipper.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnShipViaChanging(value); - SendPropertyChanging(); - _shipVia = value; - SendPropertyChanged("ShipVia"); - OnShipViaChanged(); + this.OnShipViaChanging(value); + this.SendPropertyChanging(); + this._shipVia = value; + this.SendPropertyChanged("ShipVia"); + this.OnShipViaChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"fk_Order Details_1\"")] - [DebuggerNonUserCode] + [Association(Storage="_orderDetails", OtherKey="OrderID", ThisKey="OrderID", Name="fk_Order Details_1")] + [DebuggerNonUserCode()] public EntitySet OrderDetails { get { - return _orderDetails; + return this._orderDetails; } set { - _orderDetails = value; + this._orderDetails = value; } } - - #endregion - + #region Parents - - private EntityRef _shipper; - [Association(Storage = "_shipper", OtherKey = "ShipperID", ThisKey = "ShipVia", Name = "fk_Orders_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_shipper", OtherKey="ShipperID", ThisKey="ShipVia", Name="fk_Orders_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Shipper Shipper { get { - return _shipper.Entity; + return this._shipper.Entity; } set { - if (value != _shipper.Entity) + if (((this._shipper.Entity == value) + == false)) { - if (_shipper.Entity != null) + if ((this._shipper.Entity != null)) { - var previousShipper = _shipper.Entity; - _shipper.Entity = null; + Shipper previousShipper = this._shipper.Entity; + this._shipper.Entity = null; previousShipper.Orders.Remove(this); } - _shipper.Entity = value; - if (value != null) + this._shipper.Entity = value; + if ((value != null)) { value.Orders.Add(this); _shipVia = value.ShipperID; @@ -2404,28 +2407,28 @@ namespace nwind } } } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_Orders_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_Orders_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee Employee { get { - return _employee.Entity; + return this._employee.Entity; } set { - if (value != _employee.Entity) + if (((this._employee.Entity == value) + == false)) { - if (_employee.Entity != null) + if ((this._employee.Entity != null)) { - var previousEmployee = _employee.Entity; - _employee.Entity = null; + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; previousEmployee.Orders.Remove(this); } - _employee.Entity = value; - if (value != null) + this._employee.Entity = value; + if ((value != null)) { value.Orders.Add(this); _employeeID = value.EmployeeID; @@ -2437,28 +2440,28 @@ namespace nwind } } } - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_Orders_2", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_Orders_2", IsForeignKey=true)] + [DebuggerNonUserCode()] public Customer Customer { get { - return _customer.Entity; + return this._customer.Entity; } set { - if (value != _customer.Entity) + if (((this._customer.Entity == value) + == false)) { - if (_customer.Entity != null) + if ((this._customer.Entity != null)) { - var previousCustomer = _customer.Entity; - _customer.Entity = null; + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; previousCustomer.Orders.Remove(this); } - _customer.Entity = value; - if (value != null) + this._customer.Entity = value; + if ((value != null)) { value.Orders.Add(this); _customerID = value.CustomerID; @@ -2470,249 +2473,230 @@ namespace nwind } } } - - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) - { - entity.Order = this; - } - - private void OrderDetails_Detach(OrderDetail entity) - { - entity.Order = null; - } - - - #endregion - - #region ctor - - public Order() - { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _shipper = new EntityRef(); - _employee = new EntityRef(); - _customer = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.\"Order Details\"")] - public partial class OrderDetail : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = null; + } #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Order Details")] + public partial class OrderDetail : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private float _discount; + + private int _orderID; + + private int _productID; + + private short _quantity; + + private decimal _unitPrice; + + private EntityRef _product = new EntityRef(); + + private EntityRef _order = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnDiscountChanged(); + partial void OnDiscountChanging(float value); + partial void OnOrderIDChanged(); + partial void OnOrderIDChanging(int value); + partial void OnProductIDChanged(); + partial void OnProductIDChanging(int value); + partial void OnQuantityChanged(); + partial void OnQuantityChanging(short value); + partial void OnUnitPriceChanged(); + partial void OnUnitPriceChanging(decimal value); - #endregion - - #region float Discount - - private float _discount; - [DebuggerNonUserCode] - [Column(Storage = "_discount", Name = "Discount", DbType = "real", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public OrderDetail() + { + this.OnCreated(); + } + + [Column(Storage="_discount", Name="Discount", DbType="real", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public float Discount { get { - return _discount; + return this._discount; } set { - if (value != _discount) + if ((_discount != value)) { - OnDiscountChanging(value); - SendPropertyChanging(); - _discount = value; - SendPropertyChanged("Discount"); - OnDiscountChanged(); + this.OnDiscountChanging(value); + this.SendPropertyChanging(); + this._discount = value; + this.SendPropertyChanged("Discount"); + this.OnDiscountChanged(); } } } - - #endregion - - #region int OrderID - - private int _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_orderID", Name="OrderID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int OrderID { get { - return _orderID; + return this._orderID; } set { - if (value != _orderID) + if ((_orderID != value)) { if (_order.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); } } } - - #endregion - - #region int ProductID - - private int _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_productID", Name="ProductID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int ProductID { get { - return _productID; + return this._productID; } set { - if (value != _productID) + if ((_productID != value)) { if (_product.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); } } } - - #endregion - - #region short Quantity - - private short _quantity; - [DebuggerNonUserCode] - [Column(Storage = "_quantity", Name = "Quantity", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_quantity", Name="Quantity", DbType="smallint", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public short Quantity { get { - return _quantity; + return this._quantity; } set { - if (value != _quantity) + if ((_quantity != value)) { - OnQuantityChanging(value); - SendPropertyChanging(); - _quantity = value; - SendPropertyChanged("Quantity"); - OnQuantityChanged(); + this.OnQuantityChanging(value); + this.SendPropertyChanging(); + this._quantity = value; + this.SendPropertyChanged("Quantity"); + this.OnQuantityChanged(); } } } - - #endregion - - #region decimal UnitPrice - - private decimal _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public decimal UnitPrice { get { - return _unitPrice; + return this._unitPrice; } set { - if (value != _unitPrice) + if ((_unitPrice != value)) { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _product; - [Association(Storage = "_product", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"fk_Order Details_0\"", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_product", OtherKey="ProductID", ThisKey="ProductID", Name="fk_Order Details_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Product Product { get { - return _product.Entity; + return this._product.Entity; } set { - if (value != _product.Entity) + if (((this._product.Entity == value) + == false)) { - if (_product.Entity != null) + if ((this._product.Entity != null)) { - var previousProduct = _product.Entity; - _product.Entity = null; + Product previousProduct = this._product.Entity; + this._product.Entity = null; previousProduct.OrderDetails.Remove(this); } - _product.Entity = value; - if (value != null) + this._product.Entity = value; + if ((value != null)) { value.OrderDetails.Add(this); _productID = value.ProductID; @@ -2724,28 +2708,28 @@ namespace nwind } } } - - private EntityRef _order; - [Association(Storage = "_order", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"fk_Order Details_1\"", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_order", OtherKey="OrderID", ThisKey="OrderID", Name="fk_Order Details_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Order Order { get { - return _order.Entity; + return this._order.Entity; } set { - if (value != _order.Entity) + if (((this._order.Entity == value) + == false)) { - if (_order.Entity != null) + if ((this._order.Entity != null)) { - var previousOrder = _order.Entity; - _order.Entity = null; + Order previousOrder = this._order.Entity; + this._order.Entity = null; previousOrder.OrderDetails.Remove(this); } - _order.Entity = value; - if (value != null) + this._order.Entity = value; + if ((value != null)) { value.OrderDetails.Add(this); _orderID = value.OrderID; @@ -2757,392 +2741,372 @@ namespace nwind } } } - - - #endregion - - #region ctor - - public OrderDetail() - { - _product = new EntityRef(); - _order = new EntityRef(); - OnCreated(); - } - #endregion - - } - - [Table(Name = "main.Products")] - public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Products")] + public partial class Product : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private System.Nullable _categoryID; + + private bool _discontinued; + + private int _productID; + + private string _productName; + + private string _quantityPerUnit; + + private System.Nullable _reorderLevel; + + private System.Nullable _supplierID; + + private System.Nullable _unitPrice; + + private System.Nullable _unitsInStock; + + private System.Nullable _unitsOnOrder; + + private EntitySet _orderDetails; + + private EntityRef _supplier = new EntityRef(); + + private EntityRef _category = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCategoryIDChanged(); - partial void OnCategoryIDChanging(int? value); + + partial void OnCategoryIDChanging(System.Nullable value); + partial void OnDiscontinuedChanged(); + partial void OnDiscontinuedChanging(bool value); + partial void OnProductIDChanged(); + partial void OnProductIDChanging(int value); + partial void OnProductNameChanged(); + partial void OnProductNameChanging(string value); + partial void OnQuantityPerUnitChanged(); + partial void OnQuantityPerUnitChanging(string value); + partial void OnReorderLevelChanged(); - partial void OnReorderLevelChanging(short? value); + + partial void OnReorderLevelChanging(System.Nullable value); + partial void OnSupplierIDChanged(); - partial void OnSupplierIDChanging(int? value); + + partial void OnSupplierIDChanging(System.Nullable value); + partial void OnUnitPriceChanged(); - partial void OnUnitPriceChanging(decimal? value); + + partial void OnUnitPriceChanging(System.Nullable value); + partial void OnUnitsInStockChanged(); - partial void OnUnitsInStockChanging(short? value); + + partial void OnUnitsInStockChanging(System.Nullable value); + partial void OnUnitsOnOrderChanged(); - partial void OnUnitsOnOrderChanging(short? value); - + + partial void OnUnitsOnOrderChanging(System.Nullable value); #endregion - - #region int? CategoryID - - private int? _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? CategoryID + + + public Product() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable CategoryID { get { - return _categoryID; + return this._categoryID; } set { - if (value != _categoryID) + if ((_categoryID != value)) { if (_category.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); } } } - - #endregion - - #region bool Discontinued - - private bool _discontinued; - [DebuggerNonUserCode] - [Column(Storage = "_discontinued", Name = "Discontinued", DbType = "bit", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_discontinued", Name="Discontinued", DbType="bit", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public bool Discontinued { get { - return _discontinued; + return this._discontinued; } set { - if (value != _discontinued) + if ((_discontinued != value)) { - OnDiscontinuedChanging(value); - SendPropertyChanging(); - _discontinued = value; - SendPropertyChanged("Discontinued"); - OnDiscontinuedChanged(); + this.OnDiscontinuedChanging(value); + this.SendPropertyChanging(); + this._discontinued = value; + this.SendPropertyChanged("Discontinued"); + this.OnDiscontinuedChanged(); } } } - - #endregion - - #region int ProductID - - private int _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_productID", Name="ProductID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int ProductID { get { - return _productID; + return this._productID; } set { - if (value != _productID) + if ((_productID != value)) { - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); } } } - - #endregion - - #region string ProductName - - private string _productName; - [DebuggerNonUserCode] - [Column(Storage = "_productName", Name = "ProductName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_productName", Name="ProductName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string ProductName { get { - return _productName; + return this._productName; } set { - if (value != _productName) + if (((_productName == value) + == false)) { - OnProductNameChanging(value); - SendPropertyChanging(); - _productName = value; - SendPropertyChanged("ProductName"); - OnProductNameChanged(); + this.OnProductNameChanging(value); + this.SendPropertyChanging(); + this._productName = value; + this.SendPropertyChanged("ProductName"); + this.OnProductNameChanged(); } } } - - #endregion - - #region string QuantityPerUnit - - private string _quantityPerUnit; - [DebuggerNonUserCode] - [Column(Storage = "_quantityPerUnit", Name = "QuantityPerUnit", DbType = "nvarchar (20)", AutoSync = AutoSync.Never)] + + [Column(Storage="_quantityPerUnit", Name="QuantityPerUnit", DbType="nvarchar (20)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string QuantityPerUnit { get { - return _quantityPerUnit; + return this._quantityPerUnit; } set { - if (value != _quantityPerUnit) + if (((_quantityPerUnit == value) + == false)) { - OnQuantityPerUnitChanging(value); - SendPropertyChanging(); - _quantityPerUnit = value; - SendPropertyChanged("QuantityPerUnit"); - OnQuantityPerUnitChanged(); + this.OnQuantityPerUnitChanging(value); + this.SendPropertyChanging(); + this._quantityPerUnit = value; + this.SendPropertyChanged("QuantityPerUnit"); + this.OnQuantityPerUnitChanged(); } } } - - #endregion - - #region short? ReorderLevel - - private short? _reorderLevel; - [DebuggerNonUserCode] - [Column(Storage = "_reorderLevel", Name = "ReorderLevel", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? ReorderLevel + + [Column(Storage="_reorderLevel", Name="ReorderLevel", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReorderLevel { get { - return _reorderLevel; + return this._reorderLevel; } set { - if (value != _reorderLevel) + if ((_reorderLevel != value)) { - OnReorderLevelChanging(value); - SendPropertyChanging(); - _reorderLevel = value; - SendPropertyChanged("ReorderLevel"); - OnReorderLevelChanged(); + this.OnReorderLevelChanging(value); + this.SendPropertyChanging(); + this._reorderLevel = value; + this.SendPropertyChanged("ReorderLevel"); + this.OnReorderLevelChanged(); } } } - - #endregion - - #region int? SupplierID - - private int? _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? SupplierID + + [Column(Storage="_supplierID", Name="SupplierID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable SupplierID { get { - return _supplierID; + return this._supplierID; } set { - if (value != _supplierID) + if ((_supplierID != value)) { if (_supplier.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); } } } - - #endregion - - #region decimal? UnitPrice - - private decimal? _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never)] - public decimal? UnitPrice + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitPrice { get { - return _unitPrice; + return this._unitPrice; } set { - if (value != _unitPrice) + if ((_unitPrice != value)) { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); } } } - - #endregion - - #region short? UnitsInStock - - private short? _unitsInStock; - [DebuggerNonUserCode] - [Column(Storage = "_unitsInStock", Name = "UnitsInStock", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? UnitsInStock + + [Column(Storage="_unitsInStock", Name="UnitsInStock", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsInStock { get { - return _unitsInStock; + return this._unitsInStock; } set { - if (value != _unitsInStock) + if ((_unitsInStock != value)) { - OnUnitsInStockChanging(value); - SendPropertyChanging(); - _unitsInStock = value; - SendPropertyChanged("UnitsInStock"); - OnUnitsInStockChanged(); + this.OnUnitsInStockChanging(value); + this.SendPropertyChanging(); + this._unitsInStock = value; + this.SendPropertyChanged("UnitsInStock"); + this.OnUnitsInStockChanged(); } } } - - #endregion - - #region short? UnitsOnOrder - - private short? _unitsOnOrder; - [DebuggerNonUserCode] - [Column(Storage = "_unitsOnOrder", Name = "UnitsOnOrder", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? UnitsOnOrder + + [Column(Storage="_unitsOnOrder", Name="UnitsOnOrder", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsOnOrder { get { - return _unitsOnOrder; + return this._unitsOnOrder; } set { - if (value != _unitsOnOrder) + if ((_unitsOnOrder != value)) { - OnUnitsOnOrderChanging(value); - SendPropertyChanging(); - _unitsOnOrder = value; - SendPropertyChanged("UnitsOnOrder"); - OnUnitsOnOrderChanged(); + this.OnUnitsOnOrderChanging(value); + this.SendPropertyChanging(); + this._unitsOnOrder = value; + this.SendPropertyChanged("UnitsOnOrder"); + this.OnUnitsOnOrderChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"fk_Order Details_0\"")] - [DebuggerNonUserCode] + [Association(Storage="_orderDetails", OtherKey="ProductID", ThisKey="ProductID", Name="fk_Order Details_0")] + [DebuggerNonUserCode()] public EntitySet OrderDetails { get { - return _orderDetails; + return this._orderDetails; } set { - _orderDetails = value; + this._orderDetails = value; } } - - #endregion - + #region Parents - - private EntityRef _supplier; - [Association(Storage = "_supplier", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "fk_Products_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_supplier", OtherKey="SupplierID", ThisKey="SupplierID", Name="fk_Products_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Supplier Supplier { get { - return _supplier.Entity; + return this._supplier.Entity; } set { - if (value != _supplier.Entity) + if (((this._supplier.Entity == value) + == false)) { - if (_supplier.Entity != null) + if ((this._supplier.Entity != null)) { - var previousSupplier = _supplier.Entity; - _supplier.Entity = null; + Supplier previousSupplier = this._supplier.Entity; + this._supplier.Entity = null; previousSupplier.Products.Remove(this); } - _supplier.Entity = value; - if (value != null) + this._supplier.Entity = value; + if ((value != null)) { value.Products.Add(this); _supplierID = value.SupplierID; @@ -3154,28 +3118,28 @@ namespace nwind } } } - - private EntityRef _category; - [Association(Storage = "_category", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "fk_Products_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_category", OtherKey="CategoryID", ThisKey="CategoryID", Name="fk_Products_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Category Category { get { - return _category.Entity; + return this._category.Entity; } set { - if (value != _category.Entity) + if (((this._category.Entity == value) + == false)) { - if (_category.Entity != null) + if ((this._category.Entity != null)) { - var previousCategory = _category.Entity; - _category.Entity = null; + Category previousCategory = this._category.Entity; + this._category.Entity = null; previousCategory.Products.Remove(this); } - _category.Entity = value; - if (value != null) + this._category.Entity = value; + if ((value != null)) { value.Products.Add(this); _categoryID = value.CategoryID; @@ -3187,939 +3151,880 @@ namespace nwind } } } - - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) - { - entity.Product = this; - } - - private void OrderDetails_Detach(OrderDetail entity) - { - entity.Product = null; - } - - - #endregion - - #region ctor - - public Product() - { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _supplier = new EntityRef(); - _category = new EntityRef(); - OnCreated(); - } - #endregion - - } - - [Table(Name = "main.Region")] - public partial class Region : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = null; + } #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Region")] + public partial class Region : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _regionDescription; + + private int _regionID; + + private EntitySet _territories; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnRegionDescriptionChanged(); + partial void OnRegionDescriptionChanging(string value); + partial void OnRegionIDChanged(); + partial void OnRegionIDChanging(int value); - #endregion - - #region string RegionDescription - - private string _regionDescription; - [DebuggerNonUserCode] - [Column(Storage = "_regionDescription", Name = "RegionDescription", DbType = "nchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Region() + { + _territories = new EntitySet(new Action(this.Territories_Attach), new Action(this.Territories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionDescription", Name="RegionDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string RegionDescription { get { - return _regionDescription; + return this._regionDescription; } set { - if (value != _regionDescription) + if (((_regionDescription == value) + == false)) { - OnRegionDescriptionChanging(value); - SendPropertyChanging(); - _regionDescription = value; - SendPropertyChanged("RegionDescription"); - OnRegionDescriptionChanged(); + this.OnRegionDescriptionChanging(value); + this.SendPropertyChanging(); + this._regionDescription = value; + this.SendPropertyChanged("RegionDescription"); + this.OnRegionDescriptionChanged(); } } } - - #endregion - - #region int RegionID - - private int _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_regionID", Name="RegionID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int RegionID { get { - return _regionID; + return this._regionID; } set { - if (value != _regionID) + if ((_regionID != value)) { - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _territories; - [Association(Storage = "_territories", OtherKey = "RegionID", ThisKey = "RegionID", Name = "fk_Territories_0")] - [DebuggerNonUserCode] + [Association(Storage="_territories", OtherKey="RegionID", ThisKey="RegionID", Name="fk_Territories_0")] + [DebuggerNonUserCode()] public EntitySet Territories { get { - return _territories; + return this._territories; } set { - _territories = value; + this._territories = value; } } - - - #endregion - - #region Attachement handlers - - private void Territories_Attach(Territory entity) - { - entity.Region = this; - } - - private void Territories_Detach(Territory entity) - { - entity.Region = null; - } - - - #endregion - - #region ctor - - public Region() - { - _territories = new EntitySet(Territories_Attach, Territories_Detach); - OnCreated(); - } - #endregion - - } - - [Table(Name = "main.Shippers")] - public partial class Shipper : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - + + #region Attachment handlers + private void Territories_Attach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = this; + } + + private void Territories_Detach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = null; + } #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Shippers")] + public partial class Shipper : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _companyName; + + private string _phone; + + private int _shipperID; + + private EntitySet _orders; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnShipperIDChanged(); + partial void OnShipperIDChanging(int value); - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Shipper() + { + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region int ShipperID - - private int _shipperID; - [DebuggerNonUserCode] - [Column(Storage = "_shipperID", Name = "ShipperID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_shipperID", Name="ShipperID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int ShipperID { get { - return _shipperID; + return this._shipperID; } set { - if (value != _shipperID) + if ((_shipperID != value)) { - OnShipperIDChanging(value); - SendPropertyChanging(); - _shipperID = value; - SendPropertyChanged("ShipperID"); - OnShipperIDChanged(); + this.OnShipperIDChanging(value); + this.SendPropertyChanging(); + this._shipperID = value; + this.SendPropertyChanged("ShipperID"); + this.OnShipperIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "ShipVia", ThisKey = "ShipperID", Name = "fk_Orders_0")] - [DebuggerNonUserCode] + [Association(Storage="_orders", OtherKey="ShipVia", ThisKey="ShipperID", Name="fk_Orders_0")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - - #endregion - - #region Attachement handlers - - private void Orders_Attach(Order entity) - { - entity.Shipper = this; - } - - private void Orders_Detach(Order entity) - { - entity.Shipper = null; - } - - - #endregion - - #region ctor - - public Shipper() - { - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); - } - #endregion - - } - - [Table(Name = "main.Suppliers")] - public partial class Supplier : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - + + #region Attachment handlers + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = null; + } #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Suppliers")] + public partial class Supplier : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _fax; + + private string _homePage; + + private string _phone; + + private string _postalCode; + + private string _region; + + private int _supplierID; + + private EntitySet _products; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnContactNameChanged(); + partial void OnContactNameChanging(string value); + partial void OnContactTitleChanged(); + partial void OnContactTitleChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnFaxChanged(); + partial void OnFaxChanging(string value); + partial void OnHomePageChanged(); + partial void OnHomePageChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); + partial void OnSupplierIDChanged(); + partial void OnSupplierIDChanging(int value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] + + + public Supplier() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactName { get { - return _contactName; + return this._contactName; } set { - if (value != _contactName) + if (((_contactName == value) + == false)) { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); } } } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactTitle { get { - return _contactTitle; + return this._contactTitle; } set { - if (value != _contactTitle) + if (((_contactTitle == value) + == false)) { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Fax { get { - return _fax; + return this._fax; } set { - if (value != _fax) + if (((_fax == value) + == false)) { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); } } } - - #endregion - - #region string HomePage - - private string _homePage; - [DebuggerNonUserCode] - [Column(Storage = "_homePage", Name = "HomePage", DbType = "ntext", AutoSync = AutoSync.Never)] + + [Column(Storage="_homePage", Name="HomePage", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string HomePage { get { - return _homePage; + return this._homePage; } set { - if (value != _homePage) + if (((_homePage == value) + == false)) { - OnHomePageChanging(value); - SendPropertyChanging(); - _homePage = value; - SendPropertyChanged("HomePage"); - OnHomePageChanged(); + this.OnHomePageChanging(value); + this.SendPropertyChanging(); + this._homePage = value; + this.SendPropertyChanged("HomePage"); + this.OnHomePageChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - - #region int SupplierID - - private int _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_supplierID", Name="SupplierID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int SupplierID { get { - return _supplierID; + return this._supplierID; } set { - if (value != _supplierID) + if ((_supplierID != value)) { - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "fk_Products_0")] - [DebuggerNonUserCode] + [Association(Storage="_products", OtherKey="SupplierID", ThisKey="SupplierID", Name="fk_Products_0")] + [DebuggerNonUserCode()] public EntitySet Products { get { - return _products; + return this._products; } set { - _products = value; + this._products = value; } } - - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) - { - entity.Supplier = this; - } - - private void Products_Detach(Product entity) - { - entity.Supplier = null; - } - - - #endregion - - #region ctor - - public Supplier() - { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); - } - #endregion - - } - - [Table(Name = "main.Territories")] - public partial class Territory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = null; + } #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="main.Territories")] + public partial class Territory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _regionID; + + private string _territoryDescription; + + private string _territoryID; + + private EntitySet _employeeTerritories; + + private EntityRef _region = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnRegionIDChanged(); + partial void OnRegionIDChanging(int value); + partial void OnTerritoryDescriptionChanged(); + partial void OnTerritoryDescriptionChanging(string value); + partial void OnTerritoryIDChanged(); + partial void OnTerritoryIDChanging(string value); - #endregion - - #region int RegionID - - private int _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "INTEGER", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Territory() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionID", Name="RegionID", DbType="INTEGER", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public int RegionID { get { - return _regionID; + return this._regionID; } set { - if (value != _regionID) + if ((_regionID != value)) { if (_region.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); } } } - - #endregion - - #region string TerritoryDescription - - private string _territoryDescription; - [DebuggerNonUserCode] - [Column(Storage = "_territoryDescription", Name = "TerritoryDescription", DbType = "nchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_territoryDescription", Name="TerritoryDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryDescription { get { - return _territoryDescription; + return this._territoryDescription; } set { - if (value != _territoryDescription) + if (((_territoryDescription == value) + == false)) { - OnTerritoryDescriptionChanging(value); - SendPropertyChanging(); - _territoryDescription = value; - SendPropertyChanged("TerritoryDescription"); - OnTerritoryDescriptionChanged(); + this.OnTerritoryDescriptionChanging(value); + this.SendPropertyChanging(); + this._territoryDescription = value; + this.SendPropertyChanged("TerritoryDescription"); + this.OnTerritoryDescriptionChanged(); } } } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryID { get { - return _territoryID; + return this._territoryID; } set { - if (value != _territoryID) + if (((_territoryID == value) + == false)) { - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "fk_EmployeeTerritories_0")] - [DebuggerNonUserCode] + [Association(Storage="_employeeTerritories", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="fk_EmployeeTerritories_0")] + [DebuggerNonUserCode()] public EntitySet EmployeeTerritories { get { - return _employeeTerritories; + return this._employeeTerritories; } set { - _employeeTerritories = value; + this._employeeTerritories = value; } } - - #endregion - + #region Parents - - private EntityRef _region; - [Association(Storage = "_region", OtherKey = "RegionID", ThisKey = "RegionID", Name = "fk_Territories_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_region", OtherKey="RegionID", ThisKey="RegionID", Name="fk_Territories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Region Region { get { - return _region.Entity; + return this._region.Entity; } set { - if (value != _region.Entity) + if (((this._region.Entity == value) + == false)) { - if (_region.Entity != null) + if ((this._region.Entity != null)) { - var previousRegion = _region.Entity; - _region.Entity = null; + Region previousRegion = this._region.Entity; + this._region.Entity = null; previousRegion.Territories.Remove(this); } - _region.Entity = value; - if (value != null) + this._region.Entity = value; + if ((value != null)) { value.Territories.Add(this); _regionID = value.RegionID; @@ -4131,35 +4036,42 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + #region Attachment handlers private void EmployeeTerritories_Attach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Territory = this; } - + private void EmployeeTerritories_Detach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Territory = null; } - - - #endregion - - #region ctor - - public Territory() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _region = new EntityRef(); - OnCreated(); - } - #endregion - } } diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs index b2fc7bd758a..5a83c57afda 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/FirebirdSqlProvider.cs @@ -75,16 +75,6 @@ namespace DbLinq.Firebird protected override char SafeNameStartQuote { get { return ' '; } } protected override char SafeNameEndQuote { get { return ' '; } } - /// - /// MySQL is case insensitive, and names always specify a case (there is no default casing) - /// However, tables appear to be full lowercase - /// - /// - /// - protected override bool IsNameCaseSafe(string dbName) - { - return dbName == dbName.ToUpperInvariant(); - } /// /// Returns a table alias diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs index 2de7be5f7cc..a80098686f0 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Firebird/Properties/AssemblyInfo.cs @@ -42,16 +42,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("7ad419fa-9b5c-46d6-8567-ac33f6b69833")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs index 1055044df7a..12a04ebaa2c 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/IngresSqlProvider.cs @@ -100,11 +100,6 @@ namespace DbLinq.Ingres return (":" + nameBase).ToLower(); } - protected override bool IsNameCaseSafe(string dbName) - { - return dbName == dbName.ToLower(); - } - protected override SqlStatement GetLiteralStringConcat(SqlStatement a, SqlStatement b) { // This needs to be bracketed in case subsequent functions are called upon it diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs index 75ce1c2b8d9..770b7b0a56b 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Ingres/Properties/AssemblyInfo.cs @@ -41,13 +41,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("d393f4ff-9bb6-42ad-bb84-d207115f48b1")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs index 24a347e9a5b..aa3e5a5aa6c 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.MySql/MySqlSqlProvider.cs @@ -72,16 +72,5 @@ namespace DbLinq.MySql protected override char SafeNameStartQuote { get { return '`'; } } protected override char SafeNameEndQuote { get { return '`'; } } - - /// - /// MySQL is case insensitive, and names always specify a case (there is no default casing) - /// However, tables appear to be full lowercase - /// - /// - /// - protected override bool IsNameCaseSafe(string dbName) - { - return true; - } } } diff --git a/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs index 75f5d331923..2d1afcc56ee 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.MySql/Properties/AssemblyInfo.cs @@ -41,13 +41,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("c8c37bc2-84ee-41b0-893e-02b4375eabbe")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs index d941456f87e..5f5618baa30 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.Constraints.cs @@ -26,6 +26,7 @@ using System; using System.Collections.Generic; using System.Data; +using System.Linq; using System.Text; using System.Text.RegularExpressions; using DbLinq.Util; @@ -39,30 +40,18 @@ namespace DbLinq.Oracle public string TableSchema; public string ConstraintName; public string TableName; - public string ColumnName; + public List ColumnNames = new List(); + public string ColumnNameList { get { return string.Join(",", ColumnNames.ToArray()); } } public string ConstraintType; public string ReverseConstraintName; public string Expression; public override string ToString() { - return "User_Constraint " + TableName + "." + ColumnName; + return "User_Constraint " + TableName + "." + ColumnNameList; } } - protected virtual DataConstraint ReadConstraint(IDataReader rdr) - { - var constraint = new DataConstraint(); - int field = 0; - constraint.TableSchema = rdr.GetAsString(field++); - constraint.ConstraintName = rdr.GetAsString(field++); - constraint.TableName = rdr.GetAsString(field++); - constraint.ColumnName = rdr.GetAsString(field++); - constraint.ConstraintType = rdr.GetAsString(field++); - constraint.ReverseConstraintName = rdr.GetAsString(field++); - return constraint; - } - private static Regex TriggerMatch1 = new Regex(@".*SELECT\s+(?\S+.*)\s+INTO\s+\:new.(?\S+)\s+FROM\s+DUAL.*", RegexOptions.Compiled | RegexOptions.IgnoreCase); @@ -97,7 +86,7 @@ namespace DbLinq.Oracle string expression, column; if (MatchTrigger(TriggerMatch1, body, out expression, out column)) { - constraint.ColumnName = column.Trim('"'); + constraint.ColumnNames.Add(column.Trim('"')); constraint.Expression = expression; } return constraint; @@ -108,15 +97,41 @@ namespace DbLinq.Oracle var constraints = new List(); string sql = @" -SELECT UCC.owner, UCC.constraint_name, UCC.table_name, UCC.column_name, UC.constraint_type, UC.R_constraint_name +SELECT UCC.owner, UCC.constraint_name, UCC.table_name, UC.constraint_type, UC.R_constraint_name, UCC.column_name, UCC.position FROM all_cons_columns UCC, all_constraints UC WHERE UCC.constraint_name=UC.constraint_name AND UCC.table_name=UC.table_name +AND UCC.owner=UC.owner AND UCC.TABLE_NAME NOT LIKE '%$%' AND UCC.TABLE_NAME NOT LIKE 'LOGMNR%' AND UCC.TABLE_NAME NOT IN ('HELP','SQLPLUS_PRODUCT_PROFILE') AND UC.CONSTRAINT_TYPE!='C' and lower(UCC.owner) = :owner"; - constraints.AddRange(DataCommand.Find(conn, sql, ":owner", db.ToLower(), ReadConstraint)); + constraints.AddRange(DataCommand.Find(conn, sql, ":owner", db.ToLower(), + r => new + { + Key = new + { + Owner = r.GetString(0), + ConName = r.GetString(1), + TableName = r.GetString(2), + ConType = r.GetString(3), + RevCconName = r.GetAsString(4) + }, + Value = new + { + ColName = r.GetString(5), + ColPos = r.GetInt32(6) + } + }) + .GroupBy(r => r.Key, r => r.Value, (r, rs) => new DataConstraint + { + TableSchema = r.Owner, + ConstraintName = r.ConName, + TableName = r.TableName, + ConstraintType = r.ConType, + ReverseConstraintName = r.RevCconName, + ColumnNames = rs.OrderBy(t => t.ColPos).Select(t => t.ColName).ToList() + })); string sql2 = @" diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs index 41e36908ca5..d6e56a9ac5b 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/OracleSchemaLoader.cs @@ -51,7 +51,7 @@ namespace DbLinq.Oracle DbLinq.Schema.Dbml.Table table = schema.Tables.FirstOrDefault(t => constraintFullDbName == t.Name); if (table == null) { - WriteErrorLine("ERROR L100: Table '" + constraint.TableName + "' not found for column " + constraint.ColumnName); + WriteErrorLine("ERROR L100: Table '" + constraint.TableName + "' not found for column " + constraint.ColumnNameList); continue; } @@ -61,7 +61,7 @@ namespace DbLinq.Oracle if (constraint.ConstraintType == "P") { //A) add primary key - DbLinq.Schema.Dbml.Column pkColumn = table.Type.Columns.Where(c => c.Name == constraint.ColumnName).First(); + DbLinq.Schema.Dbml.Column pkColumn = table.Type.Columns.Where(c => constraint.ColumnNames.Contains(c.Name)).First(); pkColumn.IsPrimaryKey = true; } else if (constraint.ConstraintType == "R") @@ -75,16 +75,16 @@ namespace DbLinq.Oracle continue; } - LoadForeignKey(schema, table, constraint.ColumnName, constraint.TableName, constraint.TableSchema, - referencedConstraint.ColumnName, referencedConstraint.TableName, + LoadForeignKey(schema, table, constraint.ColumnNameList, constraint.TableName, constraint.TableSchema, + referencedConstraint.ColumnNameList, referencedConstraint.TableName, referencedConstraint.TableSchema, constraint.ConstraintName, nameFormat, names); } // custom type, this is a trigger - else if (constraint.ConstraintType == "T" && constraint.ColumnName != null) + else if (constraint.ConstraintType == "T" && constraint.ColumnNames.Count == 1) { - var column = table.Type.Columns.Where(c => c.Name == constraint.ColumnName).First(); + var column = table.Type.Columns.Where(c => c.Name == constraint.ColumnNames[0]).First(); column.Expression = constraint.Expression; column.IsDbGenerated = true; } diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs index 9a78b7b4ad8..505b7c151fc 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Oracle/Properties/AssemblyInfo.cs @@ -41,13 +41,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e1f0992f-a414-4479-905e-96c5d51b8cb6")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs index 0778a6b40b7..12270e73fb0 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSchemaLoader.cs @@ -106,7 +106,7 @@ namespace DbLinq.PostgreSql //In Sasha's DB, they don't end with "_pkey", you need to rely on ReadForeignConstraints(). //In Northwind, they do end with "_pkey". bool isPrimaryKey = keyColRow.ConstraintName.EndsWith("_pkey") - || primaryKeys.Count(k => k.ConstraintName == keyColRow.ConstraintName) == 1; + || primaryKeys.Count(k => k.ConstraintName == keyColRow.ConstraintName) > 0; if (isPrimaryKey) { diff --git a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs index a546ec56ac0..e86a06adf75 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/PgsqlSqlProvider.cs @@ -145,15 +145,5 @@ namespace DbLinq.PostgreSql return string.Format("({0})::{1}", a, sqlTypeName); } - - /// - /// In PostgreSQL an insensitive name is lowercase - /// - /// - /// - protected override bool IsNameCaseSafe(string dbName) - { - return dbName == dbName.ToLower(); - } } } diff --git a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs index 75ce1c2b8d9..770b7b0a56b 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.PostgreSql/Properties/AssemblyInfo.cs @@ -41,13 +41,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("d393f4ff-9bb6-42ad-bb84-d207115f48b1")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs index a8e46b765c4..dce8d434470 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.ProductInfo.cs @@ -45,4 +45,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("0.19")] +[assembly: AssemblyFileVersion("0.20")] +[assembly: AssemblyVersion("0.20")] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs index cd372eab8df..8a1049d42eb 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/Properties/AssemblyInfo.cs @@ -41,13 +41,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("55bd884f-8aa6-4dbb-8d29-2d8e879e5f0b")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs index 7b884ee5227..de092b37fad 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.SqlServer/SqlServerVendor.cs @@ -62,6 +62,13 @@ namespace DbLinq.SqlServer protected readonly SqlServerSqlProvider sqlProvider = new SqlServerSqlProvider(); public override ISqlProvider SqlProvider { get { return sqlProvider; } } + protected override void AppendServer(StringBuilder connectionString, string host) + { + // As per http://www.connectionstrings.com/sql-server, + // port numbers are separated from host names via comma + AppendConnectionString(connectionString, ConnectionStringServer, host.Replace(':', ',')); + } + //NOTE: for Oracle, we want to consider 'Array Binding' //http://download-west.oracle.com/docs/html/A96160_01/features.htm#1049674 @@ -91,6 +98,11 @@ namespace DbLinq.SqlServer var dc = new DataColumn(); dc.ColumnName = column.MappedName; dc.DataType = column.Member.GetMemberType(); + if (dc.DataType.IsNullable()) + { + dc.AllowDBNull = true; + dc.DataType = dc.DataType.GetNullableType(); + } dt.Columns.Add(dc); } @@ -105,7 +117,7 @@ namespace DbLinq.SqlServer //if (pair.Value.IsDbGenerated) // continue; //don't assign IDENTITY col object value = pair.Member.GetMemberValue(row); - dr[pair.MappedName] = value; + dr[pair.MappedName] = value ?? DBNull.Value; } //dr[1 dt.Rows.Add(dr); diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs index 715ab5b0935..2b949b11c4d 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/Properties/AssemblyInfo.cs @@ -41,13 +41,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("9a57ce12-ad10-479f-b181-eb267c8e6c19")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs index be8e02a37be..2df555dbf01 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Columns.cs @@ -49,7 +49,7 @@ namespace DbLinq.Sqlite protected override IList ReadColumns(IDbConnection connectionString, string databaseName) { - const string sql = @" SELECT tbl_name FROM sqlite_master WHERE type='table' order by tbl_name"; + var sql = string.Format(SelectTablesFormat, ""); const string pragma = @"PRAGMA table_info('{0}');"; return Schema.DataCommand.Find(connectionString, sql, pragma, ReadColumn); diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs index 6f50e1a87e7..88b9c8f5d20 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.Tables.cs @@ -33,9 +33,7 @@ namespace DbLinq.Sqlite { public override IList ReadTables(IDbConnection connectionString, string databaseName) { - // note: the ReadDataNameAndSchema relies on information order - const string sql = @" SELECT tbl_name, 'main' FROM sqlite_master WHERE type='table' order by tbl_name"; - + string sql = string.Format(SelectTablesFormat, ", 'main'"); return Util.DataCommand.Find(connectionString, sql, ReadDataNameAndSchema); } } diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs index 2278bec5e78..ceb44afed3f 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSchemaLoader.cs @@ -58,6 +58,16 @@ namespace DbLinq.Sqlite return name; } + // note: the ReadDataNameAndSchema relies on information order; + // tbl_name MUST be first + const string SelectTablesFormat = +@" SELECT tbl_name{0} + FROM sqlite_master + WHERE type='table' AND + tbl_name NOT LIKE 'sqlite_%' + ORDER BY tbl_name"; + + /// /// Gets a usable name for the database. /// diff --git a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs index d9329948675..55f690bf8dd 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq.Sqlite/SqliteSqlProvider.cs @@ -60,11 +60,6 @@ namespace DbLinq.Sqlite return "COUNT(*)"; } - protected override bool IsNameCaseSafe(string namePart) - { - return true; - } - public override SqlStatement GetLiteral(bool literal) { if (literal) diff --git a/mcs/class/System.Data.Linq/src/DbLinq.sln b/mcs/class/System.Data.Linq/src/DbLinq.sln index 6e3fa4de84a..06181faed20 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq.sln +++ b/mcs/class/System.Data.Linq/src/DbLinq.sln @@ -103,6 +103,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DbMetal_test_sqlite", "DbMe EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlMetal_test_sqlite", "DbMetal\Test\SqlMetal_test_sqlite.csproj", "{874A37C6-E59B-4C0D-AAD2-0286E0DA8FD9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestReporter", "Tools\TestReporter\TestReporter.csproj", "{EEE5CAA1-0312-45F2-94ED-BC311A19CAEF}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug - Mono Strict|Any CPU = Debug - Mono Strict|Any CPU @@ -326,6 +328,12 @@ Global {874A37C6-E59B-4C0D-AAD2-0286E0DA8FD9}.Debug|Any CPU.Build.0 = Debug|Any CPU {874A37C6-E59B-4C0D-AAD2-0286E0DA8FD9}.Release|Any CPU.ActiveCfg = Release|Any CPU {874A37C6-E59B-4C0D-AAD2-0286E0DA8FD9}.Release|Any CPU.Build.0 = Release|Any CPU + {EEE5CAA1-0312-45F2-94ED-BC311A19CAEF}.Debug - Mono Strict|Any CPU.ActiveCfg = Debug|Any CPU + {EEE5CAA1-0312-45F2-94ED-BC311A19CAEF}.Debug - Mono Strict|Any CPU.Build.0 = Debug|Any CPU + {EEE5CAA1-0312-45F2-94ED-BC311A19CAEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEE5CAA1-0312-45F2-94ED-BC311A19CAEF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEE5CAA1-0312-45F2-94ED-BC311A19CAEF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEE5CAA1-0312-45F2-94ED-BC311A19CAEF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs index 838d2b02167..9710a8aad0b 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs @@ -236,18 +236,18 @@ namespace DbLinq.Data.Linq System.Text.RegularExpressions.Regex reProvider = new System.Text.RegularExpressions.Regex(@"DbLinqProvider=([\w\.]+);?"); - string assemblyFile = null; + string assemblyName = null; string vendor; if (!reProvider.IsMatch(connectionString)) { vendor = "SqlServer"; - assemblyFile = "DbLinq.SqlServer.dll"; + assemblyName = "DbLinq.SqlServer"; } else { var match = reProvider.Match(connectionString); vendor = match.Groups[1].Value; - assemblyFile = "DbLinq." + vendor + ".dll"; + assemblyName = "DbLinq." + vendor; //plain DbLinq - non MONO: //IVendor classes are in DLLs such as "DbLinq.MySql.dll" @@ -268,16 +268,15 @@ namespace DbLinq.Data.Linq #if MONO_STRICT assembly = typeof (DataContext).Assembly; // System.Data.Linq.dll #else - //TODO: check if DLL is already loaded? - assembly = Assembly.LoadFrom(assemblyFile); + assembly = Assembly.Load(assemblyName); #endif } catch (Exception e) { throw new ArgumentException( string.Format( - "Unable to load the `{0}' DbLinq vendor within assembly `{1}'.", - assemblyFile, vendor), + "Unable to load the `{0}' DbLinq vendor within assembly '{1}.dll'.", + assemblyName, vendor), "connectionString", e); } } @@ -399,11 +398,11 @@ namespace DbLinq.Data.Linq SubmitChangesImpl(failureMode); else { - using (IDatabaseTransaction transaction = DatabaseContext.Transaction()) + using (IDbTransaction transaction = DatabaseContext.CreateTransaction()) { try { - Transaction = (DbTransaction) transaction.Transaction; + Transaction = (DbTransaction) transaction; SubmitChangesImpl(failureMode); // TODO: handle conflicts (which can only occur when concurrency mode is implemented) transaction.Commit(); @@ -1025,7 +1024,10 @@ namespace DbLinq.Data.Linq set { throw new NotImplementedException(); } } - public DbTransaction Transaction { get; set; } + public DbTransaction Transaction { + get { return (DbTransaction) DatabaseContext.CurrentTransaction; } + set { DatabaseContext.CurrentTransaction = value; } + } /// /// Runs the given reader and returns columns. diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs index 97fc4ec1768..9d8fae805f7 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/IDatabaseContext.cs @@ -63,7 +63,10 @@ namespace DbLinq.Data.Linq.Database /// Creates a transaction. /// /// - IDatabaseTransaction Transaction(); + IDbTransaction CreateTransaction(); + + IDbTransaction CurrentTransaction { get; set; } + /// /// Opens a connection. /// diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs index 1a1e7900f02..3bf55cd7480 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/DatabaseContext.cs @@ -44,6 +44,8 @@ namespace DbLinq.Data.Linq.Database.Implementation set { ChangeConnection(value, false); } } + public IDbTransaction CurrentTransaction { get; set; } + private readonly DbProviderFactory _providerFactory; /// /// Gets the provider factory. @@ -101,9 +103,11 @@ namespace DbLinq.Data.Linq.Database.Implementation /// Creates a transaction. /// /// - public IDatabaseTransaction Transaction() + public IDbTransaction CreateTransaction() { - return new DatabaseTransaction(Connection); + if (CurrentTransaction != null) + throw new InvalidOperationException("Attempting to create a transaction while within a transaction."); + return CurrentTransaction = Connection.BeginTransaction(); } /// @@ -114,7 +118,7 @@ namespace DbLinq.Data.Linq.Database.Implementation { IDbCommand command = Connection.CreateCommand(); if (command.Transaction == null) - command.Transaction = DatabaseTransaction.currentTransaction; + command.Transaction = CurrentTransaction; return command; } diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs index f4a147511a4..fab34f7a7bd 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Database/Implementation/TransactionalCommand.cs @@ -47,7 +47,7 @@ namespace DbLinq.Data.Linq.Database.Implementation /// /// Ambient transaction /// - private readonly IDatabaseTransaction _transaction; + private readonly IDbTransaction _transaction; private readonly IDbCommand _command; @@ -100,8 +100,8 @@ namespace DbLinq.Data.Linq.Database.Implementation // the transaction is optional if (createTransaction && !haveHigherTransaction) { - _transaction = dataContext.DatabaseContext.Transaction(); - _command.Transaction = _transaction.Transaction; + _transaction = dataContext.DatabaseContext.CreateTransaction(); + _command.Transaction = _transaction; } else _command.Transaction = dataContext.Transaction; diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs index 28f4f97d821..329a974c3fc 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs @@ -184,7 +184,7 @@ namespace DbLinq.Data.Linq.Mapping } public bool GetBooleanAttribute(XmlReader r, string attributeName) { - return r.GetAttribute(attributeName) == "true"; + return string.Compare(r.GetAttribute(attributeName), "true", StringComparison.OrdinalIgnoreCase) == 0; } public UpdateCheck GetUpdateCheckAttribute(XmlReader r, string attributeName) { diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs index 187a5e8dacd..36f2bd07a8d 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/ExpressionDispatcher.Registrar.cs @@ -271,13 +271,13 @@ namespace DbLinq.Data.Linq.Sugar.Implementation // our table is created, with the expressions // now check if we didn't register exactly the same - if ((from t in builderContext.EnumerateScopeTables() where t.IsEqualTo(otherTableExpression) select t).SingleOrDefault() == null) - { - builderContext.CurrentSelect.Tables.Add(otherTableExpression); - foreach (var createdColumn in createdColumns) - builderContext.CurrentSelect.Columns.Add(createdColumn); - } - + var existingTable = (from t in builderContext.EnumerateScopeTables() where t.IsEqualTo(otherTableExpression) select t).SingleOrDefault(); + if (existingTable != null) + return existingTable; + + builderContext.CurrentSelect.Tables.Add(otherTableExpression); + foreach (var createdColumn in createdColumns) + builderContext.CurrentSelect.Columns.Add(createdColumn); return otherTableExpression; } diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs index 8fa90b9d8e4..62505027c72 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryBuilder.cs @@ -402,9 +402,27 @@ namespace DbLinq.Data.Linq.Sugar.Implementation SetInSelectCache(expressions, query); } } + else if (query.InputParameters.Count > 0) + { + Profiler.At("START: GetSelectQuery(), building Expression parameters of cached query"); + var parameters = BuildExpressionParameters(expressions, queryContext); + query = new SelectQuery(queryContext.DataContext, query.Sql, parameters, query.RowObjectCreator, query.ExecuteMethodName); + Profiler.At("END: GetSelectQuery(), building Expression parameters of cached query"); + } return query; } + IList BuildExpressionParameters(ExpressionChain expressions, QueryContext queryContext) + { + var builderContext = new BuilderContext(queryContext); + var previousExpression = ExpressionDispatcher.CreateTableExpression(expressions.Expressions[0], builderContext); + previousExpression = BuildExpressionQuery(expressions, previousExpression, builderContext); + BuildOffsetsAndLimits(builderContext); + // then prepare Parts for SQL translation + PrepareSqlOperands(builderContext); + return builderContext.ExpressionQuery.Parameters; + } + /// /// Returns a Delegate to create a row for a given IDataRecord /// The Delegate is Func<IDataRecord,MappingContext,"tableType"> diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs index 0e7b6048877..6790688147b 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Table.Extended.cs @@ -76,9 +76,9 @@ namespace DbLinq.Data.Linq public void BulkInsert(IEnumerable entities, int pageSize) { using (Context.DatabaseContext.OpenConnection()) - using (var transaction = Context.DatabaseContext.Transaction()) + using (var transaction = Context.DatabaseContext.CreateTransaction()) { - Context.Vendor.BulkInsert(this, entities.ToList(), pageSize, transaction.Transaction); + Context.Vendor.BulkInsert(this, entities.ToList(), pageSize, Context.Transaction); transaction.Commit(); } } diff --git a/mcs/class/System.Data.Linq/src/DbLinq/DbLinq.csproj b/mcs/class/System.Data.Linq/src/DbLinq/DbLinq.csproj index 41f2ab884ab..1f265f21d01 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/DbLinq.csproj +++ b/mcs/class/System.Data.Linq/src/DbLinq/DbLinq.csproj @@ -59,11 +59,9 @@ - - @@ -217,6 +215,7 @@ + diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs index fe34254a95a..af422061187 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Properties/AssemblyInfo.cs @@ -42,15 +42,6 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e2381b27-cdb0-401d-9019-f72079b4928d")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] // Regarding tests, it is mandatory, since we test internals @@ -112,6 +103,13 @@ using DbLinq.Factory; + "962a12b830c2a70eb70ec77823eb5750e5bdef9e01d097c30b5c5463c3d07d3472b58e4c02f279" + "2309259f")] +[assembly: InternalsVisibleTo("DbLinq.SqlServer, PublicKey=" ++ "0024000004800000940000000602000000240000525341310004000001000100c5753d8c47f400" ++ "83f549016a5711238ac8ec297605abccd3dc4b6d0f280b4764eb2cc58ec4e37831edad7e7a07b8" ++ "fe4a9cbb059374c0cc047aa28839fed7176761813caf6a2ffa0bff9afb50ead56dd3f56186a663" ++ "962a12b830c2a70eb70ec77823eb5750e5bdef9e01d097c30b5c5463c3d07d3472b58e4c02f279" ++ "2309259f")] + [assembly: InternalsVisibleTo("DbLinq.Ingres, PublicKey=" + "0024000004800000940000000602000000240000525341310004000001000100c5753d8c47f400" + "83f549016a5711238ac8ec297605abccd3dc4b6d0f280b4764eb2cc58ec4e37831edad7e7a07b8" diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DatabaseSerializer.cs b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DatabaseSerializer.cs new file mode 100644 index 00000000000..073eef9f156 --- /dev/null +++ b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DatabaseSerializer.cs @@ -0,0 +1,2223 @@ +// It is automatically generated +using System; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; +using System.Text; +using System.Collections; +using System.Globalization; + +namespace DbLinq.Schema.Dbml +{ + #if !MONO_STRICT + public + #endif + class GeneratedReader : XmlSerializationReader + { + static readonly System.Reflection.MethodInfo fromBinHexStringMethod = typeof (XmlConvert).GetMethod ("FromBinHexString", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new System.Type [] {typeof (string)}, null); + static byte [] FromBinHexString (string input) + { + return input == null ? null : (byte []) fromBinHexStringMethod.Invoke (null, new object [] {input}); + } + public object ReadRoot_Database () + { + Reader.MoveToContent(); + if (Reader.LocalName != "Database" || Reader.NamespaceURI != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownNodeException(); + return ReadObject_Database (false, true); + } + + public DbLinq.Schema.Dbml.Database ReadObject_Database (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Database ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Database" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Database) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Database), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") { + ob.@Name = Reader.Value; + } + else if (Reader.LocalName == "EntityNamespace" && Reader.NamespaceURI == "") { + ob.@EntityNamespace = Reader.Value; + } + else if (Reader.LocalName == "ContextNamespace" && Reader.NamespaceURI == "") { + ob.@ContextNamespace = Reader.Value; + } + else if (Reader.LocalName == "Class" && Reader.NamespaceURI == "") { + ob.@Class = Reader.Value; + } + else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") { + ob.@AccessModifier = GetEnumValue_AccessModifier (Reader.Value); + ob.AccessModifierSpecified = true; + } + else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") { + ob.@Modifier = GetEnumValue_ClassModifier (Reader.Value); + ob.ModifierSpecified = true; + } + else if (Reader.LocalName == "BaseType" && Reader.NamespaceURI == "") { + ob.@BaseType = Reader.Value; + } + else if (Reader.LocalName == "Provider" && Reader.NamespaceURI == "") { + ob.@Provider = Reader.Value; + } + else if (Reader.LocalName == "ExternalMapping" && Reader.NamespaceURI == "") { + ob.@ExternalMapping = XmlConvert.ToBoolean (Reader.Value); + ob.ExternalMappingSpecified = true; + } + else if (Reader.LocalName == "Serialization" && Reader.NamespaceURI == "") { + ob.@Serialization = GetEnumValue_SerializationMode (Reader.Value); + ob.SerializationSpecified = true; + } + else if (Reader.LocalName == "EntityBase" && Reader.NamespaceURI == "") { + ob.@EntityBase = Reader.Value; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b0=false, b1=false, b2=false; + + DbLinq.Schema.Dbml.Table[] o4; + o4 = null; + DbLinq.Schema.Dbml.Function[] o6; + o6 = null; + int n3=0, n5=0; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "Table" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b1) { + o4 = (DbLinq.Schema.Dbml.Table[]) EnsureArrayIndex (o4, n3, typeof(DbLinq.Schema.Dbml.Table)); + o4[n3] = ReadObject_Table (false, true); + n3++; + } + else if (Reader.LocalName == "Function" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b2) { + o6 = (DbLinq.Schema.Dbml.Function[]) EnsureArrayIndex (o6, n5, typeof(DbLinq.Schema.Dbml.Function)); + o6[n5] = ReadObject_Function (false, true); + n5++; + } + else if (Reader.LocalName == "Connection" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b0) { + b0 = true; + ob.@Connection = ReadObject_Connection (false, true); + } + else { + UnknownNode (ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + o4 = (DbLinq.Schema.Dbml.Table[]) ShrinkArray (o4, n3, typeof(DbLinq.Schema.Dbml.Table), true); + ob.@Table = o4; + o6 = (DbLinq.Schema.Dbml.Function[]) ShrinkArray (o6, n5, typeof(DbLinq.Schema.Dbml.Function), true); + ob.@Function = o6; + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.AccessModifier ReadObject_AccessModifier (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.AccessModifier res = GetEnumValue_AccessModifier (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.AccessModifier GetEnumValue_AccessModifier (string xmlName) + { + switch (xmlName) + { + case "Public": return DbLinq.Schema.Dbml.AccessModifier.Public; + case "Internal": return DbLinq.Schema.Dbml.AccessModifier.Internal; + case "Protected": return DbLinq.Schema.Dbml.AccessModifier.Protected; + case "ProtectedInternal": return DbLinq.Schema.Dbml.AccessModifier.ProtectedInternal; + case "Private": return DbLinq.Schema.Dbml.AccessModifier.Private; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.AccessModifier)); + } + } + + public DbLinq.Schema.Dbml.ClassModifier ReadObject_ClassModifier (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.ClassModifier res = GetEnumValue_ClassModifier (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.ClassModifier GetEnumValue_ClassModifier (string xmlName) + { + switch (xmlName) + { + case "Sealed": return DbLinq.Schema.Dbml.ClassModifier.Sealed; + case "Abstract": return DbLinq.Schema.Dbml.ClassModifier.Abstract; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.ClassModifier)); + } + } + + public DbLinq.Schema.Dbml.SerializationMode ReadObject_SerializationMode (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.SerializationMode res = GetEnumValue_SerializationMode (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.SerializationMode GetEnumValue_SerializationMode (string xmlName) + { + switch (xmlName) + { + case "None": return DbLinq.Schema.Dbml.SerializationMode.None; + case "Unidirectional": return DbLinq.Schema.Dbml.SerializationMode.Unidirectional; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.SerializationMode)); + } + } + + public DbLinq.Schema.Dbml.Table ReadObject_Table (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Table ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Table" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Table) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Table), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") { + ob.@Name = Reader.Value; + } + else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") { + ob.@Member = Reader.Value; + } + else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") { + ob.@AccessModifier = GetEnumValue_AccessModifier (Reader.Value); + ob.AccessModifierSpecified = true; + } + else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") { + ob.@Modifier = GetEnumValue_MemberModifier (Reader.Value); + ob.ModifierSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b7=false, b8=false, b9=false, b10=false; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "UpdateFunction" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b9) { + b9 = true; + ob.@UpdateFunction = ReadObject_TableFunction (false, true); + } + else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b7) { + b7 = true; + ob.@Type = ReadObject_Type (false, true); + } + else if (Reader.LocalName == "InsertFunction" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b8) { + b8 = true; + ob.@InsertFunction = ReadObject_TableFunction (false, true); + } + else if (Reader.LocalName == "DeleteFunction" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b10) { + b10 = true; + ob.@DeleteFunction = ReadObject_TableFunction (false, true); + } + else { + UnknownNode (ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.Function ReadObject_Function (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Function ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Function" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Function) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Function), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") { + ob.@Name = Reader.Value; + } + else if (Reader.LocalName == "Id" && Reader.NamespaceURI == "") { + ob.@Id = Reader.Value; + } + else if (Reader.LocalName == "Method" && Reader.NamespaceURI == "") { + ob.@Method = Reader.Value; + } + else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") { + ob.@AccessModifier = GetEnumValue_AccessModifier (Reader.Value); + ob.AccessModifierSpecified = true; + } + else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") { + ob.@Modifier = GetEnumValue_MemberModifier (Reader.Value); + ob.ModifierSpecified = true; + } + else if (Reader.LocalName == "HasMultipleResults" && Reader.NamespaceURI == "") { + ob.@HasMultipleResults = XmlConvert.ToBoolean (Reader.Value); + ob.HasMultipleResultsSpecified = true; + } + else if (Reader.LocalName == "IsComposable" && Reader.NamespaceURI == "") { + ob.@IsComposable = XmlConvert.ToBoolean (Reader.Value); + ob.IsComposableSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b11=false, b12=false; + + DbLinq.Schema.Dbml.Parameter[] o14; + o14 = null; + System.Object[] o16; + o16 = null; + int n13=0, n15=0; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "Return" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b12) { + o16 = (System.Object[]) EnsureArrayIndex (o16, n15, typeof(System.Object)); + o16[n15] = ReadObject_Return (false, true); + n15++; + } + else if (Reader.LocalName == "ElementType" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b12) { + o16 = (System.Object[]) EnsureArrayIndex (o16, n15, typeof(System.Object)); + o16[n15] = ReadObject_Type (false, true); + n15++; + } + else if (Reader.LocalName == "Parameter" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b11) { + o14 = (DbLinq.Schema.Dbml.Parameter[]) EnsureArrayIndex (o14, n13, typeof(DbLinq.Schema.Dbml.Parameter)); + o14[n13] = ReadObject_Parameter (false, true); + n13++; + } + else { + UnknownNode (ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + o14 = (DbLinq.Schema.Dbml.Parameter[]) ShrinkArray (o14, n13, typeof(DbLinq.Schema.Dbml.Parameter), true); + ob.@Parameter = o14; + o16 = (System.Object[]) ShrinkArray (o16, n15, typeof(System.Object), true); + ob.@Items = o16; + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.Connection ReadObject_Connection (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Connection ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Connection" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Connection) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Connection), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Provider" && Reader.NamespaceURI == "") { + ob.@Provider = Reader.Value; + } + else if (Reader.LocalName == "Mode" && Reader.NamespaceURI == "") { + ob.@Mode = GetEnumValue_ConnectionMode (Reader.Value); + ob.ModeSpecified = true; + } + else if (Reader.LocalName == "ConnectionString" && Reader.NamespaceURI == "") { + ob.@ConnectionString = Reader.Value; + } + else if (Reader.LocalName == "SettingsObjectName" && Reader.NamespaceURI == "") { + ob.@SettingsObjectName = Reader.Value; + } + else if (Reader.LocalName == "SettingsPropertyName" && Reader.NamespaceURI == "") { + ob.@SettingsPropertyName = Reader.Value; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + UnknownNode (ob); + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.MemberModifier ReadObject_MemberModifier (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.MemberModifier res = GetEnumValue_MemberModifier (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.MemberModifier GetEnumValue_MemberModifier (string xmlName) + { + switch (xmlName) + { + case "Virtual": return DbLinq.Schema.Dbml.MemberModifier.Virtual; + case "Override": return DbLinq.Schema.Dbml.MemberModifier.Override; + case "New": return DbLinq.Schema.Dbml.MemberModifier.New; + case "NewVirtual": return DbLinq.Schema.Dbml.MemberModifier.NewVirtual; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.MemberModifier)); + } + } + + public DbLinq.Schema.Dbml.TableFunction ReadObject_TableFunction (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.TableFunction ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "TableFunction" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.TableFunction) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.TableFunction), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "FunctionId" && Reader.NamespaceURI == "") { + ob.@FunctionId = Reader.Value; + } + else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") { + ob.@AccessModifier = GetEnumValue_AccessModifier (Reader.Value); + ob.AccessModifierSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b17=false, b18=false; + + DbLinq.Schema.Dbml.TableFunctionParameter[] o20; + o20 = null; + int n19=0; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "Return" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b18) { + b18 = true; + ob.@Return = ReadObject_TableFunctionReturn (false, true); + } + else if (Reader.LocalName == "Argument" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b17) { + o20 = (DbLinq.Schema.Dbml.TableFunctionParameter[]) EnsureArrayIndex (o20, n19, typeof(DbLinq.Schema.Dbml.TableFunctionParameter)); + o20[n19] = ReadObject_TableFunctionParameter (false, true); + n19++; + } + else { + UnknownNode (ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + o20 = (DbLinq.Schema.Dbml.TableFunctionParameter[]) ShrinkArray (o20, n19, typeof(DbLinq.Schema.Dbml.TableFunctionParameter), true); + ob.@Argument = o20; + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.Type ReadObject_Type (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Type ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Type" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Type) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Type), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "IdRef" && Reader.NamespaceURI == "") { + ob.@IdRef = Reader.Value; + } + else if (Reader.LocalName == "Id" && Reader.NamespaceURI == "") { + ob.@Id = Reader.Value; + } + else if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") { + ob.@Name = Reader.Value; + } + else if (Reader.LocalName == "InheritanceCode" && Reader.NamespaceURI == "") { + ob.@InheritanceCode = Reader.Value; + } + else if (Reader.LocalName == "IsInheritanceDefault" && Reader.NamespaceURI == "") { + ob.@IsInheritanceDefault = XmlConvert.ToBoolean (Reader.Value); + ob.IsInheritanceDefaultSpecified = true; + } + else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") { + ob.@AccessModifier = GetEnumValue_AccessModifier (Reader.Value); + ob.AccessModifierSpecified = true; + } + else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") { + ob.@Modifier = GetEnumValue_ClassModifier (Reader.Value); + ob.ModifierSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + bool b21=false, b22=false; + + System.Object[] o24; + o24 = null; + DbLinq.Schema.Dbml.Type[] o26; + o26 = null; + int n23=0, n25=0; + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + if (Reader.LocalName == "Column" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b21) { + o24 = (System.Object[]) EnsureArrayIndex (o24, n23, typeof(System.Object)); + o24[n23] = ReadObject_Column (false, true); + n23++; + } + else if (Reader.LocalName == "Association" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b21) { + o24 = (System.Object[]) EnsureArrayIndex (o24, n23, typeof(System.Object)); + o24[n23] = ReadObject_Association (false, true); + n23++; + } + else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "http://schemas.microsoft.com/linqtosql/dbml/2007" && !b22) { + o26 = (DbLinq.Schema.Dbml.Type[]) EnsureArrayIndex (o26, n25, typeof(DbLinq.Schema.Dbml.Type)); + o26[n25] = ReadObject_Type (false, true); + n25++; + } + else { + UnknownNode (ob); + } + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + o24 = (System.Object[]) ShrinkArray (o24, n23, typeof(System.Object), true); + ob.@Items = o24; + o26 = (DbLinq.Schema.Dbml.Type[]) ShrinkArray (o26, n25, typeof(DbLinq.Schema.Dbml.Type), true); + ob.@Type1 = o26; + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.Return ReadObject_Return (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Return ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Return" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Return) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Return), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") { + ob.@Type = Reader.Value; + } + else if (Reader.LocalName == "DbType" && Reader.NamespaceURI == "") { + ob.@DbType = Reader.Value; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + UnknownNode (ob); + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.Parameter ReadObject_Parameter (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Parameter ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Parameter" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Parameter) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Parameter), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") { + ob.@Name = Reader.Value; + } + else if (Reader.LocalName == "Parameter" && Reader.NamespaceURI == "") { + ob.@Parameter1 = Reader.Value; + } + else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") { + ob.@Type = Reader.Value; + } + else if (Reader.LocalName == "DbType" && Reader.NamespaceURI == "") { + ob.@DbType = Reader.Value; + } + else if (Reader.LocalName == "Direction" && Reader.NamespaceURI == "") { + ob.@Direction = GetEnumValue_ParameterDirection (Reader.Value); + ob.DirectionSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + UnknownNode (ob); + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.ConnectionMode ReadObject_ConnectionMode (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.ConnectionMode res = GetEnumValue_ConnectionMode (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.ConnectionMode GetEnumValue_ConnectionMode (string xmlName) + { + switch (xmlName) + { + case "ConnectionString": return DbLinq.Schema.Dbml.ConnectionMode.ConnectionString; + case "AppSettings": return DbLinq.Schema.Dbml.ConnectionMode.AppSettings; + case "WebSettings": return DbLinq.Schema.Dbml.ConnectionMode.WebSettings; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.ConnectionMode)); + } + } + + public DbLinq.Schema.Dbml.TableFunctionReturn ReadObject_TableFunctionReturn (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.TableFunctionReturn ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "TableFunctionReturn" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.TableFunctionReturn) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.TableFunctionReturn), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") { + ob.@Member = Reader.Value; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + UnknownNode (ob); + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.TableFunctionParameter ReadObject_TableFunctionParameter (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.TableFunctionParameter ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "TableFunctionParameter" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.TableFunctionParameter) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.TableFunctionParameter), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Parameter" && Reader.NamespaceURI == "") { + ob.@Parameter = Reader.Value; + } + else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") { + ob.@Member = Reader.Value; + } + else if (Reader.LocalName == "Version" && Reader.NamespaceURI == "") { + ob.@Version = GetEnumValue_Version (Reader.Value); + ob.VersionSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + UnknownNode (ob); + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.Column ReadObject_Column (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Column ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Column" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Column) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Column), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") { + ob.@Name = Reader.Value; + } + else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") { + ob.@Member = Reader.Value; + } + else if (Reader.LocalName == "Storage" && Reader.NamespaceURI == "") { + ob.@Storage = Reader.Value; + } + else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") { + ob.@AccessModifier = GetEnumValue_AccessModifier (Reader.Value); + ob.AccessModifierSpecified = true; + } + else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") { + ob.@Modifier = GetEnumValue_MemberModifier (Reader.Value); + ob.ModifierSpecified = true; + } + else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") { + ob.@Type = Reader.Value; + } + else if (Reader.LocalName == "DbType" && Reader.NamespaceURI == "") { + ob.@DbType = Reader.Value; + } + else if (Reader.LocalName == "IsReadOnly" && Reader.NamespaceURI == "") { + ob.@IsReadOnly = XmlConvert.ToBoolean (Reader.Value); + ob.IsReadOnlySpecified = true; + } + else if (Reader.LocalName == "IsPrimaryKey" && Reader.NamespaceURI == "") { + ob.@IsPrimaryKey = XmlConvert.ToBoolean (Reader.Value); + ob.IsPrimaryKeySpecified = true; + } + else if (Reader.LocalName == "IsDbGenerated" && Reader.NamespaceURI == "") { + ob.@IsDbGenerated = XmlConvert.ToBoolean (Reader.Value); + ob.IsDbGeneratedSpecified = true; + } + else if (Reader.LocalName == "CanBeNull" && Reader.NamespaceURI == "") { + ob.@CanBeNull = XmlConvert.ToBoolean (Reader.Value); + ob.CanBeNullSpecified = true; + } + else if (Reader.LocalName == "UpdateCheck" && Reader.NamespaceURI == "") { + ob.@UpdateCheck = GetEnumValue_UpdateCheck (Reader.Value); + ob.UpdateCheckSpecified = true; + } + else if (Reader.LocalName == "IsDiscriminator" && Reader.NamespaceURI == "") { + ob.@IsDiscriminator = XmlConvert.ToBoolean (Reader.Value); + ob.IsDiscriminatorSpecified = true; + } + else if (Reader.LocalName == "Expression" && Reader.NamespaceURI == "") { + ob.@Expression = Reader.Value; + } + else if (Reader.LocalName == "IsVersion" && Reader.NamespaceURI == "") { + ob.@IsVersion = XmlConvert.ToBoolean (Reader.Value); + ob.IsVersionSpecified = true; + } + else if (Reader.LocalName == "IsDelayLoaded" && Reader.NamespaceURI == "") { + ob.@IsDelayLoaded = XmlConvert.ToBoolean (Reader.Value); + ob.IsDelayLoadedSpecified = true; + } + else if (Reader.LocalName == "AutoSync" && Reader.NamespaceURI == "") { + ob.@AutoSync = GetEnumValue_AutoSync (Reader.Value); + ob.AutoSyncSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + UnknownNode (ob); + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.Association ReadObject_Association (bool isNullable, bool checkType) + { + DbLinq.Schema.Dbml.Association ob = null; + if (isNullable && ReadNull()) return null; + + if (checkType) + { + System.Xml.XmlQualifiedName t = GetXsiType(); + if (t == null) + { } + else if (t.Name != "Association" || t.Namespace != "http://schemas.microsoft.com/linqtosql/dbml/2007") + throw CreateUnknownTypeException(t); + } + + ob = (DbLinq.Schema.Dbml.Association) Activator.CreateInstance(typeof(DbLinq.Schema.Dbml.Association), true); + + Reader.MoveToElement(); + + while (Reader.MoveToNextAttribute()) + { + if (Reader.LocalName == "Name" && Reader.NamespaceURI == "") { + ob.@Name = Reader.Value; + } + else if (Reader.LocalName == "Member" && Reader.NamespaceURI == "") { + ob.@Member = Reader.Value; + } + else if (Reader.LocalName == "Storage" && Reader.NamespaceURI == "") { + ob.@Storage = Reader.Value; + } + else if (Reader.LocalName == "AccessModifier" && Reader.NamespaceURI == "") { + ob.@AccessModifier = GetEnumValue_AccessModifier (Reader.Value); + ob.AccessModifierSpecified = true; + } + else if (Reader.LocalName == "Modifier" && Reader.NamespaceURI == "") { + ob.@Modifier = GetEnumValue_MemberModifier (Reader.Value); + ob.ModifierSpecified = true; + } + else if (Reader.LocalName == "Type" && Reader.NamespaceURI == "") { + ob.@Type = Reader.Value; + } + else if (Reader.LocalName == "ThisKey" && Reader.NamespaceURI == "") { + ob.@ThisKey = Reader.Value; + } + else if (Reader.LocalName == "OtherKey" && Reader.NamespaceURI == "") { + ob.@OtherKey = Reader.Value; + } + else if (Reader.LocalName == "IsForeignKey" && Reader.NamespaceURI == "") { + ob.@IsForeignKey = XmlConvert.ToBoolean (Reader.Value); + ob.IsForeignKeySpecified = true; + } + else if (Reader.LocalName == "Cardinality" && Reader.NamespaceURI == "") { + ob.@Cardinality = GetEnumValue_Cardinality (Reader.Value); + ob.CardinalitySpecified = true; + } + else if (Reader.LocalName == "DeleteRule" && Reader.NamespaceURI == "") { + ob.@DeleteRule = Reader.Value; + } + else if (Reader.LocalName == "DeleteOnNull" && Reader.NamespaceURI == "") { + ob.@DeleteOnNull = XmlConvert.ToBoolean (Reader.Value); + ob.DeleteOnNullSpecified = true; + } + else if (IsXmlnsAttribute (Reader.Name)) { + } + else { + UnknownNode (ob); + } + } + + Reader.MoveToElement (); + Reader.MoveToElement(); + if (Reader.IsEmptyElement) { + Reader.Skip (); + return ob; + } + + Reader.ReadStartElement(); + Reader.MoveToContent(); + + while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) + { + if (Reader.NodeType == System.Xml.XmlNodeType.Element) + { + UnknownNode (ob); + } + else + UnknownNode(ob); + + Reader.MoveToContent(); + } + + ReadEndElement(); + + return ob; + } + + public DbLinq.Schema.Dbml.ParameterDirection ReadObject_ParameterDirection (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.ParameterDirection res = GetEnumValue_ParameterDirection (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.ParameterDirection GetEnumValue_ParameterDirection (string xmlName) + { + switch (xmlName) + { + case "In": return DbLinq.Schema.Dbml.ParameterDirection.In; + case "Out": return DbLinq.Schema.Dbml.ParameterDirection.Out; + case "InOut": return DbLinq.Schema.Dbml.ParameterDirection.InOut; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.ParameterDirection)); + } + } + + public DbLinq.Schema.Dbml.Version ReadObject_Version (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.Version res = GetEnumValue_Version (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.Version GetEnumValue_Version (string xmlName) + { + switch (xmlName) + { + case "Current": return DbLinq.Schema.Dbml.Version.Current; + case "Original": return DbLinq.Schema.Dbml.Version.Original; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.Version)); + } + } + + public DbLinq.Schema.Dbml.UpdateCheck ReadObject_UpdateCheck (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.UpdateCheck res = GetEnumValue_UpdateCheck (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.UpdateCheck GetEnumValue_UpdateCheck (string xmlName) + { + switch (xmlName) + { + case "Always": return DbLinq.Schema.Dbml.UpdateCheck.Always; + case "Never": return DbLinq.Schema.Dbml.UpdateCheck.Never; + case "WhenChanged": return DbLinq.Schema.Dbml.UpdateCheck.WhenChanged; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.UpdateCheck)); + } + } + + public DbLinq.Schema.Dbml.AutoSync ReadObject_AutoSync (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.AutoSync res = GetEnumValue_AutoSync (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.AutoSync GetEnumValue_AutoSync (string xmlName) + { + switch (xmlName) + { + case "Never": return DbLinq.Schema.Dbml.AutoSync.Never; + case "OnInsert": return DbLinq.Schema.Dbml.AutoSync.OnInsert; + case "OnUpdate": return DbLinq.Schema.Dbml.AutoSync.OnUpdate; + case "Always": return DbLinq.Schema.Dbml.AutoSync.Always; + case "Default": return DbLinq.Schema.Dbml.AutoSync.Default; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.AutoSync)); + } + } + + public DbLinq.Schema.Dbml.Cardinality ReadObject_Cardinality (bool isNullable, bool checkType) + { + Reader.ReadStartElement (); + DbLinq.Schema.Dbml.Cardinality res = GetEnumValue_Cardinality (Reader.ReadString()); + if (Reader.NodeType != XmlNodeType.None) + Reader.ReadEndElement (); + return res; + } + + DbLinq.Schema.Dbml.Cardinality GetEnumValue_Cardinality (string xmlName) + { + switch (xmlName) + { + case "One": return DbLinq.Schema.Dbml.Cardinality.One; + case "Many": return DbLinq.Schema.Dbml.Cardinality.Many; + default: + throw CreateUnknownConstantException (xmlName, typeof(DbLinq.Schema.Dbml.Cardinality)); + } + } + + protected override void InitCallbacks () + { + } + + protected override void InitIDs () + { + } + + } + + #if !MONO_STRICT + public + #endif + class GeneratedWriter : XmlSerializationWriter + { + const string xmlNamespace = "http://www.w3.org/2000/xmlns/"; + static readonly System.Reflection.MethodInfo toBinHexStringMethod = typeof (XmlConvert).GetMethod ("ToBinHexString", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, new System.Type [] {typeof (byte [])}, null); + static string ToBinHexString (byte [] input) + { + return input == null ? null : (string) toBinHexStringMethod.Invoke (null, new object [] {input}); + } + public void WriteRoot_Database (object o) + { + WriteStartDocument (); + DbLinq.Schema.Dbml.Database ob = (DbLinq.Schema.Dbml.Database) o; + TopLevelElement (); + WriteObject_Database (ob, "Database", "http://schemas.microsoft.com/linqtosql/dbml/2007", true, false, true); + } + + void WriteObject_Database (DbLinq.Schema.Dbml.Database ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Database)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Database", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Name", "", ob.@Name); + WriteAttribute ("EntityNamespace", "", ob.@EntityNamespace); + WriteAttribute ("ContextNamespace", "", ob.@ContextNamespace); + WriteAttribute ("Class", "", ob.@Class); + if (ob.@AccessModifierSpecified) { + WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob.@AccessModifier)); + } + if (ob.@ModifierSpecified) { + WriteAttribute ("Modifier", "", GetEnumValue_ClassModifier (ob.@Modifier)); + } + WriteAttribute ("BaseType", "", ob.@BaseType); + WriteAttribute ("Provider", "", ob.@Provider); + if (ob.@ExternalMappingSpecified) { + WriteAttribute ("ExternalMapping", "", (ob.@ExternalMapping?"true":"false")); + } + if (ob.@SerializationSpecified) { + WriteAttribute ("Serialization", "", GetEnumValue_SerializationMode (ob.@Serialization)); + } + WriteAttribute ("EntityBase", "", ob.@EntityBase); + + WriteObject_Connection (ob.@Connection, "Connection", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + if (ob.@Table != null) { + for (int n27 = 0; n27 < ob.@Table.Length; n27++) { + WriteObject_Table (ob.@Table[n27], "Table", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + } + if (ob.@Function != null) { + for (int n28 = 0; n28 < ob.@Function.Length; n28++) { + WriteObject_Function (ob.@Function[n28], "Function", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + } + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_AccessModifier (DbLinq.Schema.Dbml.AccessModifier ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.AccessModifier)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("AccessModifier", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_AccessModifier (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_AccessModifier (DbLinq.Schema.Dbml.AccessModifier val) + { + switch (val) { + case DbLinq.Schema.Dbml.AccessModifier.Public: return "Public"; + case DbLinq.Schema.Dbml.AccessModifier.Internal: return "Internal"; + case DbLinq.Schema.Dbml.AccessModifier.Protected: return "Protected"; + case DbLinq.Schema.Dbml.AccessModifier.ProtectedInternal: return "ProtectedInternal"; + case DbLinq.Schema.Dbml.AccessModifier.Private: return "Private"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.AccessModifier).FullName); + } + } + + void WriteObject_ClassModifier (DbLinq.Schema.Dbml.ClassModifier ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.ClassModifier)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("ClassModifier", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_ClassModifier (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_ClassModifier (DbLinq.Schema.Dbml.ClassModifier val) + { + switch (val) { + case DbLinq.Schema.Dbml.ClassModifier.Sealed: return "Sealed"; + case DbLinq.Schema.Dbml.ClassModifier.Abstract: return "Abstract"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.ClassModifier).FullName); + } + } + + void WriteObject_SerializationMode (DbLinq.Schema.Dbml.SerializationMode ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.SerializationMode)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("SerializationMode", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_SerializationMode (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_SerializationMode (DbLinq.Schema.Dbml.SerializationMode val) + { + switch (val) { + case DbLinq.Schema.Dbml.SerializationMode.None: return "None"; + case DbLinq.Schema.Dbml.SerializationMode.Unidirectional: return "Unidirectional"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.SerializationMode).FullName); + } + } + + void WriteObject_Connection (DbLinq.Schema.Dbml.Connection ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Connection)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Connection", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Provider", "", ob.@Provider); + if (ob.@ModeSpecified) { + WriteAttribute ("Mode", "", GetEnumValue_ConnectionMode (ob.@Mode)); + } + WriteAttribute ("ConnectionString", "", ob.@ConnectionString); + WriteAttribute ("SettingsObjectName", "", ob.@SettingsObjectName); + WriteAttribute ("SettingsPropertyName", "", ob.@SettingsPropertyName); + + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_Table (DbLinq.Schema.Dbml.Table ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Table)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Table", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Name", "", ob.@Name); + WriteAttribute ("Member", "", ob.@Member); + if (ob.@AccessModifierSpecified) { + WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob.@AccessModifier)); + } + if (ob.@ModifierSpecified) { + WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob.@Modifier)); + } + + WriteObject_Type (ob.@Type, "Type", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + WriteObject_TableFunction (ob.@InsertFunction, "InsertFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + WriteObject_TableFunction (ob.@UpdateFunction, "UpdateFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + WriteObject_TableFunction (ob.@DeleteFunction, "DeleteFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_Function (DbLinq.Schema.Dbml.Function ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Function)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Function", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Name", "", ob.@Name); + WriteAttribute ("Id", "", ob.@Id); + WriteAttribute ("Method", "", ob.@Method); + if (ob.@AccessModifierSpecified) { + WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob.@AccessModifier)); + } + if (ob.@ModifierSpecified) { + WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob.@Modifier)); + } + if (ob.@HasMultipleResultsSpecified) { + WriteAttribute ("HasMultipleResults", "", (ob.@HasMultipleResults?"true":"false")); + } + if (ob.@IsComposableSpecified) { + WriteAttribute ("IsComposable", "", (ob.@IsComposable?"true":"false")); + } + + if (ob.@Parameter != null) { + for (int n29 = 0; n29 < ob.@Parameter.Length; n29++) { + WriteObject_Parameter (ob.@Parameter[n29], "Parameter", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + } + if (ob.@Items != null) { + for (int n30 = 0; n30 < ob.@Items.Length; n30++) { + if (((object)ob.@Items[n30]) == null) { } + else if (ob.@Items[n30].GetType() == typeof(DbLinq.Schema.Dbml.Return)) { + WriteObject_Return (((DbLinq.Schema.Dbml.Return) ob.@Items[n30]), "Return", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + else if (ob.@Items[n30].GetType() == typeof(DbLinq.Schema.Dbml.Type)) { + WriteObject_Type (((DbLinq.Schema.Dbml.Type) ob.@Items[n30]), "ElementType", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + else throw CreateUnknownTypeException (ob.@Items[n30]); + } + } + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_ConnectionMode (DbLinq.Schema.Dbml.ConnectionMode ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.ConnectionMode)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("ConnectionMode", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_ConnectionMode (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_ConnectionMode (DbLinq.Schema.Dbml.ConnectionMode val) + { + switch (val) { + case DbLinq.Schema.Dbml.ConnectionMode.ConnectionString: return "ConnectionString"; + case DbLinq.Schema.Dbml.ConnectionMode.AppSettings: return "AppSettings"; + case DbLinq.Schema.Dbml.ConnectionMode.WebSettings: return "WebSettings"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.ConnectionMode).FullName); + } + } + + void WriteObject_MemberModifier (DbLinq.Schema.Dbml.MemberModifier ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.MemberModifier)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("MemberModifier", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_MemberModifier (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_MemberModifier (DbLinq.Schema.Dbml.MemberModifier val) + { + switch (val) { + case DbLinq.Schema.Dbml.MemberModifier.Virtual: return "Virtual"; + case DbLinq.Schema.Dbml.MemberModifier.Override: return "Override"; + case DbLinq.Schema.Dbml.MemberModifier.New: return "New"; + case DbLinq.Schema.Dbml.MemberModifier.NewVirtual: return "NewVirtual"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.MemberModifier).FullName); + } + } + + void WriteObject_Type (DbLinq.Schema.Dbml.Type ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Type)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Type", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("IdRef", "", ob.@IdRef); + WriteAttribute ("Id", "", ob.@Id); + WriteAttribute ("Name", "", ob.@Name); + WriteAttribute ("InheritanceCode", "", ob.@InheritanceCode); + if (ob.@IsInheritanceDefaultSpecified) { + WriteAttribute ("IsInheritanceDefault", "", (ob.@IsInheritanceDefault?"true":"false")); + } + if (ob.@AccessModifierSpecified) { + WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob.@AccessModifier)); + } + if (ob.@ModifierSpecified) { + WriteAttribute ("Modifier", "", GetEnumValue_ClassModifier (ob.@Modifier)); + } + + if (ob.@Items != null) { + for (int n31 = 0; n31 < ob.@Items.Length; n31++) { + if (((object)ob.@Items[n31]) == null) { } + else if (ob.@Items[n31].GetType() == typeof(DbLinq.Schema.Dbml.Column)) { + WriteObject_Column (((DbLinq.Schema.Dbml.Column) ob.@Items[n31]), "Column", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + else if (ob.@Items[n31].GetType() == typeof(DbLinq.Schema.Dbml.Association)) { + WriteObject_Association (((DbLinq.Schema.Dbml.Association) ob.@Items[n31]), "Association", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + else throw CreateUnknownTypeException (ob.@Items[n31]); + } + } + if (ob.@Type1 != null) { + for (int n32 = 0; n32 < ob.@Type1.Length; n32++) { + WriteObject_Type (ob.@Type1[n32], "Type", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + } + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_TableFunction (DbLinq.Schema.Dbml.TableFunction ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.TableFunction)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("TableFunction", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("FunctionId", "", ob.@FunctionId); + if (ob.@AccessModifierSpecified) { + WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob.@AccessModifier)); + } + + if (ob.@Argument != null) { + for (int n33 = 0; n33 < ob.@Argument.Length; n33++) { + WriteObject_TableFunctionParameter (ob.@Argument[n33], "Argument", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + } + } + WriteObject_TableFunctionReturn (ob.@Return, "Return", "http://schemas.microsoft.com/linqtosql/dbml/2007", false, false, true); + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_Parameter (DbLinq.Schema.Dbml.Parameter ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Parameter)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Parameter", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Name", "", ob.@Name); + WriteAttribute ("Parameter", "", ob.@Parameter1); + WriteAttribute ("Type", "", ob.@Type); + WriteAttribute ("DbType", "", ob.@DbType); + if (ob.@DirectionSpecified) { + WriteAttribute ("Direction", "", GetEnumValue_ParameterDirection (ob.@Direction)); + } + + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_Return (DbLinq.Schema.Dbml.Return ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Return)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Return", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Type", "", ob.@Type); + WriteAttribute ("DbType", "", ob.@DbType); + + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_Column (DbLinq.Schema.Dbml.Column ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Column)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Column", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Name", "", ob.@Name); + WriteAttribute ("Member", "", ob.@Member); + WriteAttribute ("Storage", "", ob.@Storage); + if (ob.@AccessModifierSpecified) { + WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob.@AccessModifier)); + } + if (ob.@ModifierSpecified) { + WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob.@Modifier)); + } + WriteAttribute ("Type", "", ob.@Type); + WriteAttribute ("DbType", "", ob.@DbType); + if (ob.@IsReadOnlySpecified) { + WriteAttribute ("IsReadOnly", "", (ob.@IsReadOnly?"true":"false")); + } + if (ob.@IsPrimaryKeySpecified) { + WriteAttribute ("IsPrimaryKey", "", (ob.@IsPrimaryKey?"true":"false")); + } + if (ob.@IsDbGeneratedSpecified) { + WriteAttribute ("IsDbGenerated", "", (ob.@IsDbGenerated?"true":"false")); + } + if (ob.@CanBeNullSpecified) { + WriteAttribute ("CanBeNull", "", (ob.@CanBeNull?"true":"false")); + } + if (ob.@UpdateCheckSpecified) { + WriteAttribute ("UpdateCheck", "", GetEnumValue_UpdateCheck (ob.@UpdateCheck)); + } + if (ob.@IsDiscriminatorSpecified) { + WriteAttribute ("IsDiscriminator", "", (ob.@IsDiscriminator?"true":"false")); + } + WriteAttribute ("Expression", "", ob.@Expression); + if (ob.@IsVersionSpecified) { + WriteAttribute ("IsVersion", "", (ob.@IsVersion?"true":"false")); + } + if (ob.@IsDelayLoadedSpecified) { + WriteAttribute ("IsDelayLoaded", "", (ob.@IsDelayLoaded?"true":"false")); + } + if (ob.@AutoSyncSpecified) { + WriteAttribute ("AutoSync", "", GetEnumValue_AutoSync (ob.@AutoSync)); + } + + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_Association (DbLinq.Schema.Dbml.Association ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Association)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Association", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Name", "", ob.@Name); + WriteAttribute ("Member", "", ob.@Member); + WriteAttribute ("Storage", "", ob.@Storage); + if (ob.@AccessModifierSpecified) { + WriteAttribute ("AccessModifier", "", GetEnumValue_AccessModifier (ob.@AccessModifier)); + } + if (ob.@ModifierSpecified) { + WriteAttribute ("Modifier", "", GetEnumValue_MemberModifier (ob.@Modifier)); + } + WriteAttribute ("Type", "", ob.@Type); + WriteAttribute ("ThisKey", "", ob.@ThisKey); + WriteAttribute ("OtherKey", "", ob.@OtherKey); + if (ob.@IsForeignKeySpecified) { + WriteAttribute ("IsForeignKey", "", (ob.@IsForeignKey?"true":"false")); + } + if (ob.@CardinalitySpecified) { + WriteAttribute ("Cardinality", "", GetEnumValue_Cardinality (ob.@Cardinality)); + } + WriteAttribute ("DeleteRule", "", ob.@DeleteRule); + if (ob.@DeleteOnNullSpecified) { + WriteAttribute ("DeleteOnNull", "", (ob.@DeleteOnNull?"true":"false")); + } + + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_TableFunctionParameter (DbLinq.Schema.Dbml.TableFunctionParameter ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.TableFunctionParameter)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("TableFunctionParameter", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Parameter", "", ob.@Parameter); + WriteAttribute ("Member", "", ob.@Member); + if (ob.@VersionSpecified) { + WriteAttribute ("Version", "", GetEnumValue_Version (ob.@Version)); + } + + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_TableFunctionReturn (DbLinq.Schema.Dbml.TableFunctionReturn ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + if (((object)ob) == null) + { + if (isNullable) + WriteNullTagLiteral(element, namesp); + return; + } + + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.TableFunctionReturn)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("TableFunctionReturn", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + WriteAttribute ("Member", "", ob.@Member); + + if (writeWrappingElem) WriteEndElement (ob); + } + + void WriteObject_ParameterDirection (DbLinq.Schema.Dbml.ParameterDirection ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.ParameterDirection)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("ParameterDirection", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_ParameterDirection (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_ParameterDirection (DbLinq.Schema.Dbml.ParameterDirection val) + { + switch (val) { + case DbLinq.Schema.Dbml.ParameterDirection.In: return "In"; + case DbLinq.Schema.Dbml.ParameterDirection.Out: return "Out"; + case DbLinq.Schema.Dbml.ParameterDirection.InOut: return "InOut"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.ParameterDirection).FullName); + } + } + + void WriteObject_UpdateCheck (DbLinq.Schema.Dbml.UpdateCheck ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.UpdateCheck)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("UpdateCheck", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_UpdateCheck (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_UpdateCheck (DbLinq.Schema.Dbml.UpdateCheck val) + { + switch (val) { + case DbLinq.Schema.Dbml.UpdateCheck.Always: return "Always"; + case DbLinq.Schema.Dbml.UpdateCheck.Never: return "Never"; + case DbLinq.Schema.Dbml.UpdateCheck.WhenChanged: return "WhenChanged"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.UpdateCheck).FullName); + } + } + + void WriteObject_AutoSync (DbLinq.Schema.Dbml.AutoSync ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.AutoSync)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("AutoSync", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_AutoSync (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_AutoSync (DbLinq.Schema.Dbml.AutoSync val) + { + switch (val) { + case DbLinq.Schema.Dbml.AutoSync.Never: return "Never"; + case DbLinq.Schema.Dbml.AutoSync.OnInsert: return "OnInsert"; + case DbLinq.Schema.Dbml.AutoSync.OnUpdate: return "OnUpdate"; + case DbLinq.Schema.Dbml.AutoSync.Always: return "Always"; + case DbLinq.Schema.Dbml.AutoSync.Default: return "Default"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.AutoSync).FullName); + } + } + + void WriteObject_Cardinality (DbLinq.Schema.Dbml.Cardinality ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Cardinality)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Cardinality", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_Cardinality (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_Cardinality (DbLinq.Schema.Dbml.Cardinality val) + { + switch (val) { + case DbLinq.Schema.Dbml.Cardinality.One: return "One"; + case DbLinq.Schema.Dbml.Cardinality.Many: return "Many"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.Cardinality).FullName); + } + } + + void WriteObject_Version (DbLinq.Schema.Dbml.Version ob, string element, string namesp, bool isNullable, bool needType, bool writeWrappingElem) + { + System.Type type = ob.GetType (); + if (type == typeof(DbLinq.Schema.Dbml.Version)) + { } + else { + throw CreateUnknownTypeException (ob); + } + + if (writeWrappingElem) { + WriteStartElement (element, namesp, ob); + } + + if (needType) WriteXsiType("Version", "http://schemas.microsoft.com/linqtosql/dbml/2007"); + + Writer.WriteString (GetEnumValue_Version (ob)); + if (writeWrappingElem) WriteEndElement (ob); + } + + string GetEnumValue_Version (DbLinq.Schema.Dbml.Version val) + { + switch (val) { + case DbLinq.Schema.Dbml.Version.Current: return "Current"; + case DbLinq.Schema.Dbml.Version.Original: return "Original"; + default: throw CreateInvalidEnumValueException ((long) val, typeof (DbLinq.Schema.Dbml.Version).FullName); + } + } + + protected override void InitCallbacks () + { + } + + } + + + #if !MONO_STRICT + public + #endif + class BaseXmlSerializer : System.Xml.Serialization.XmlSerializer + { + protected override System.Xml.Serialization.XmlSerializationReader CreateReader () { + return new GeneratedReader (); + } + + protected override System.Xml.Serialization.XmlSerializationWriter CreateWriter () { + return new GeneratedWriter (); + } + + public override bool CanDeserialize (System.Xml.XmlReader xmlReader) { + return true; + } + } + + #if !MONO_STRICT + public + #endif + sealed class DatabaseSerializer : BaseXmlSerializer + { + protected override void Serialize (object obj, System.Xml.Serialization.XmlSerializationWriter writer) { + ((GeneratedWriter)writer).WriteRoot_Database(obj); + } + + protected override object Deserialize (System.Xml.Serialization.XmlSerializationReader reader) { + return ((GeneratedReader)reader).ReadRoot_Database(); + } + } + + #if !TARGET_JVM + #if !MONO_STRICT + public + #endif + class XmlSerializerContract : System.Xml.Serialization.XmlSerializerImplementation + { + System.Collections.Hashtable readMethods = null; + System.Collections.Hashtable writeMethods = null; + System.Collections.Hashtable typedSerializers = null; + + public override System.Xml.Serialization.XmlSerializationReader Reader { + get { + return new GeneratedReader(); + } + } + + public override System.Xml.Serialization.XmlSerializationWriter Writer { + get { + return new GeneratedWriter(); + } + } + + public override System.Collections.Hashtable ReadMethods { + get { + lock (this) { + if (readMethods == null) { + readMethods = new System.Collections.Hashtable (); + readMethods.Add (@"DbLinq.Schema.Dbml.Database", @"ReadRoot_Database"); + } + return readMethods; + } + } + } + + public override System.Collections.Hashtable WriteMethods { + get { + lock (this) { + if (writeMethods == null) { + writeMethods = new System.Collections.Hashtable (); + writeMethods.Add (@"DbLinq.Schema.Dbml.Database", @"WriteRoot_Database"); + } + return writeMethods; + } + } + } + + public override System.Collections.Hashtable TypedSerializers { + get { + lock (this) { + if (typedSerializers == null) { + typedSerializers = new System.Collections.Hashtable (); + typedSerializers.Add (@"DbLinq.Schema.Dbml.Database", new DatabaseSerializer()); + } + return typedSerializers; + } + } + } + + public XmlSerializer GetSerializer (System.Type type) + { + switch (type.FullName) { + case "DbLinq.Schema.Dbml.Database": + return (XmlSerializer) TypedSerializers ["DbLinq.Schema.Dbml.Database"]; + + } + return base.GetSerializer (type); + } + + public override bool CanSerialize (System.Type type) { + if (type == typeof(DbLinq.Schema.Dbml.Database)) return true; + return false; + } + } + + #endif +} + diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs index 790f254a47d..1a7bb7259ad 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Schema/Dbml/DbmlSerializer.cs @@ -99,7 +99,7 @@ namespace DbLinq.Schema.Dbml using (Stream xsdStream = OpenXsd()) using (XmlReader xmlReader = OpenXml(xmlStream, xsdStream, validationErrors)) { - var xmlSerializer = new XmlSerializer(typeof(Database)); + var xmlSerializer = new DatabaseSerializer(); var dbml = (Database)xmlSerializer.Deserialize(xmlReader); return dbml; } @@ -125,8 +125,8 @@ namespace DbLinq.Schema.Dbml /// The DBML. public static void Write(Stream xmlStream, Database dbml) { - var xmlSerializer = new XmlSerializer(dbml.GetType()); + var xmlSerializer = new DatabaseSerializer(); xmlSerializer.Serialize(xmlStream, dbml); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq.csproj b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq.csproj index df24530535a..d4d63b2c128 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq.csproj +++ b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq.csproj @@ -117,10 +117,8 @@ - - @@ -269,6 +267,7 @@ + diff --git a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/Assembly/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/Assembly/AssemblyInfo.cs index 7fb0dbc2269..04a391d4dfc 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/Assembly/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/Assembly/AssemblyInfo.cs @@ -80,3 +80,10 @@ using DbLinq.Factory; "962a12b830c2a70eb70ec77823eb5750e5bdef9e01d097c30b5c5463c3d07d3472b58e4c02f279" + "2309259f")] +[assembly: InternalsVisibleTo("sqlmetal_test_net_4_0, PublicKey=" + +"0024000004800000940000000602000000240000525341310004000001000100c5753d8c47f400" + +"83f549016a5711238ac8ec297605abccd3dc4b6d0f280b4764eb2cc58ec4e37831edad7e7a07b8" + +"fe4a9cbb059374c0cc047aa28839fed7176761813caf6a2ffa0bff9afb50ead56dd3f56186a663" + +"962a12b830c2a70eb70ec77823eb5750e5bdef9e01d097c30b5c5463c3d07d3472b58e4c02f279" + +"2309259f")] + diff --git a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs index 0516d0a4a9b..cc4a0066f79 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ColumnAttribute.cs @@ -34,6 +34,11 @@ namespace System.Data.Linq.Mapping [AttributeUsage (AttributeTargets.Property|AttributeTargets.Field, AllowMultiple = false)] public sealed class ColumnAttribute : DataAttribute { + public ColumnAttribute() + { + CanBeNull = true; + } + public AutoSync AutoSync { get; set; } public bool CanBeNull { get; set; } public string DbType { get; set; } diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs index 0dcd4ed70b5..449c50904f5 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/AssemblyInfo.cs @@ -21,15 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("52112670-1196-4229-ae51-535cf23869cb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/DbLinq_test_ndb_strict.csproj b/mcs/class/System.Data.Linq/src/DbLinq/Test/DbLinq_test_ndb_strict.csproj index 92a13c68a13..a54fd61fc0d 100755 --- a/mcs/class/System.Data.Linq/src/DbLinq/Test/DbLinq_test_ndb_strict.csproj +++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/DbLinq_test_ndb_strict.csproj @@ -3,7 +3,7 @@ Debug AnyCPU - 9.0.30729 + 9.0.21022 2.0 {AB60629C-6B19-4465-89AA-DBD7A0428F4B} Library @@ -77,6 +77,7 @@ + diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs index 0dcd4ed70b5..449c50904f5 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/Properties/AssemblyInfo.cs @@ -21,15 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("52112670-1196-4229-ae51-535cf23869cb")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs index da8098f7797..c552d999b11 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Properties/AssemblyInfo.cs @@ -21,15 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("0cae4ddc-abd5-4c2a-96c0-918ed1d736e4")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("0.0.1.17")] -[assembly: AssemblyFileVersion("0.19")] diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs index e452032ce0d..1f443c32ac6 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs @@ -193,11 +193,12 @@ namespace nwind Assert.IsTrue(p1.ProductID == 1); } + [Test] public void A8_SelectSingleOrDefault_QueryCacheDisabled() { Northwind db = CreateDB(); #if !MONO_STRICT - db.QueryCacheEnabled = false; + db.QueryCacheEnabled = true; #endif // Query for a specific customer diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Test/System.Data.Linq.Mapping/ColumnAttributeTest.cs b/mcs/class/System.Data.Linq/src/DbLinq/Test/System.Data.Linq.Mapping/ColumnAttributeTest.cs new file mode 100755 index 00000000000..5ff896778a2 --- /dev/null +++ b/mcs/class/System.Data.Linq/src/DbLinq/Test/System.Data.Linq.Mapping/ColumnAttributeTest.cs @@ -0,0 +1,64 @@ +#region MIT license +// +// MIT license +// +// Copyright (c) 2010 Novell, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +#endregion + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.SqlClient; +using System.IO; +using System.Linq; +using System.Reflection; + +using System.Data.Linq.Mapping; + +using DbLinq.Null; +using NUnit.Framework; + +namespace System.Data.Linq.Mapping.Test +{ + [TestFixture] + public class ColumnAttributeTest + { + [Test] + public void Ctor() + { + var c = new ColumnAttribute(); + Assert.AreEqual(AutoSync.Default, c.AutoSync); + Assert.AreEqual(true, c.CanBeNull); + Assert.AreEqual(null, c.DbType); + Assert.AreEqual(null, c.Expression); + Assert.AreEqual(false, c.IsDbGenerated); + Assert.AreEqual(false, c.IsDiscriminator); + Assert.AreEqual(false, c.IsVersion); + Assert.AreEqual(UpdateCheck.Always, c.UpdateCheck); + Assert.AreEqual(false, c.IsPrimaryKey); + Assert.AreEqual(null, c.Name); + Assert.AreEqual(null, c.Storage); + Assert.AreEqual(c.GetType(), c.TypeId); + } + } +} diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs index df6f25a5239..c6b93b01436 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/ISchemaLoader.cs @@ -62,12 +62,5 @@ namespace DbLinq.Vendor /// Database Load(string databaseName, INameAliases nameAliases, NameFormat nameFormat, bool loadStoredProcedures, string contextNamespace, string entityNamespace); - - /// - /// Checks all names in DBML schema, - /// and enquotes the ones where a casing problem could occur - /// - /// - void CheckNamesSafety(Database schema); } } diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs index 696ee8779e7..56ab5bb1d5b 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.ForeignKey.cs @@ -92,7 +92,8 @@ namespace DbLinq.Vendor.Implementation assoc.ThisKey = foreignKey; assoc.OtherKey = reverseForeignKey; assoc.Member = associationName.ManyToOneMemberName; - assoc.Cardinality = Cardinality.Many; // TODO: check this is the right direction (even if it appears to be useless) + assoc.CardinalitySpecified = false; + // TODO: generate assoc.Cardinality? table.Type.Associations.Add(assoc); //and insert the reverse association: @@ -100,7 +101,8 @@ namespace DbLinq.Vendor.Implementation reverseAssociation.Name = constraintName; reverseAssociation.Type = table.Type.Name; reverseAssociation.Member = associationName.OneToManyMemberName; - reverseAssociation.Cardinality = Cardinality.One; + reverseAssociation.CardinalitySpecified = false; + // TODO: generate reverseAssociation.Cardinality? reverseAssociation.ThisKey = reverseForeignKey; reverseAssociation.OtherKey = foreignKey; reverseAssociation.DeleteRule = "NO ACTION"; diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs index fdcfa54b55a..6fed0b84e3b 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.Name.cs @@ -34,32 +34,6 @@ namespace DbLinq.Vendor.Implementation { partial class SchemaLoader { - /// - /// Checks all names in DBML schema, - /// and enquotes the ones where a casing problem could occur - /// - /// - public virtual void CheckNamesSafety(Database schema) - { - schema.Name = Vendor.SqlProvider.GetSafeName(schema.Name); - foreach (var table in schema.Table) - { - table.Name = Vendor.SqlProvider.GetSafeName(table.Name); - foreach (var column in table.Type.Columns) - { - column.Name = Vendor.SqlProvider.GetSafeName(column.Name); - } - foreach (var association in table.Type.Associations) - { - association.Name = Vendor.SqlProvider.GetSafeName(association.Name); - } - } - foreach (var storedProcedure in schema.Functions) - { - storedProcedure.Name = Vendor.SqlProvider.GetSafeName(storedProcedure.Name); - } - } - /// /// Gets the primary keys. /// @@ -149,22 +123,36 @@ namespace DbLinq.Vendor.Implementation column.Storage = storageGenerator(column.Member); } - Dictionary storageFields = new Dictionary(); - Dictionary memberFields = new Dictionary(); + HashSet storageFields = new HashSet(); + HashSet memberFields = new HashSet(); + foreach (var column in table.Type.Columns) + { + storageFields.Add(column.Storage); + memberFields.Add(column.Member); + } + foreach (var association in table.Type.Associations) { association.Storage = storageGenerator(association.Member); //Associations may contain the same foreign key more than once - add a number suffix to duplicates - int storageSuffix = 0; - if ( storageFields.TryGetValue(association.Storage, out storageSuffix) ) - association.Storage += storageSuffix; - storageFields[association.Storage] = storageSuffix + 1; + for (var suffix = 0; ; suffix++) + { + var name = suffix == 0 ? association.Storage : association.Storage + suffix; + if (storageFields.Contains(name)) continue; + association.Storage = name; + storageFields.Add(name); + break; + } - int memberSuffix = 0; - if ( memberFields.TryGetValue(association.Member, out memberSuffix) ) - association.Member += memberSuffix; - memberFields[association.Member] = memberSuffix + 1; + for (var suffix = 0; ; suffix++) + { + var name = suffix == 0 ? association.Member : association.Member + suffix; + if (memberFields.Contains(name)) continue; + association.Member = name; + memberFields.Add(name); + break; + } } } } diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs index 2f179d3124a..ba670473e12 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.TypeMapping.cs @@ -147,12 +147,16 @@ namespace DbLinq.Vendor.Implementation case "float4": case "real": case "binary_float": // oracle type + case "unsigned float": // mysql type + case "float unsigned": // mysql type return typeof(Single); // double case "double": case "double precision": case "binary_double": // oracle type + case "unsigned double":// mysql type + case "double unsigned":// mysql type return typeof(Double); // decimal @@ -180,6 +184,7 @@ namespace DbLinq.Vendor.Implementation //enum case "enum": + case "set": return MapEnumDbType(dataType); // date @@ -188,6 +193,7 @@ namespace DbLinq.Vendor.Implementation case "ingresdate": case "timestamp": case "timestamp without time zone": + case "timestamp with time zone": case "time": case "time without time zone": //reported by twain_bu...@msn.com, case "time with time zone": @@ -430,7 +436,7 @@ namespace DbLinq.Vendor.Implementation #endregion } - protected static Regex DefaultEnumDefinitionEx = new Regex(@"\s*enum\s*\((?.*)\s*\)\s*", RegexOptions.Compiled); + protected static Regex DefaultEnumDefinitionEx = new Regex(@"\s*(enum|set)\s*\((?.*)\s*\)\s*", RegexOptions.Compiled); protected static Regex EnumValuesEx = new Regex(@"\'(?\w*)\'\s*,?\s*", RegexOptions.Compiled); /// diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs index 528fc0a1796..ef05fc55baa 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SchemaLoader.cs @@ -38,6 +38,7 @@ using DbLinq.Data.Linq; using DbLinq.Factory; using DbLinq.Schema; using DbLinq.Schema.Dbml; +using System.Text.RegularExpressions; namespace DbLinq.Vendor.Implementation { @@ -237,6 +238,8 @@ namespace DbLinq.Vendor.Implementation return CreateTableName(dbTableName, dbSchema, nameAliases, nameFormat, GetExtraction(dbTableName)); } + Regex startsWithNumber = new Regex(@"^\d", RegexOptions.Compiled); + /// /// Creates the name of the column. /// @@ -265,6 +268,10 @@ namespace DbLinq.Vendor.Implementation var tableName = CreateTableName(dbTableName, dbSchema, nameAliases, nameFormat); if (columnName.PropertyName == tableName.ClassName) columnName.PropertyName = columnName.PropertyName + "1"; + + if (startsWithNumber.IsMatch(columnName.PropertyName)) + columnName.PropertyName = "_" + columnName.PropertyName; + columnName.DbName = dbColumnName; return columnName; } diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs index a2d0d0c97fc..2ede68f2369 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/SqlProvider.cs @@ -1587,11 +1587,7 @@ namespace DbLinq.Vendor.Implementation /// protected virtual string GetSafeNamePart(string namePart) { - if (IsMadeSafe(namePart)) - return namePart; - if (IsNameSafe(namePart) && IsNameCaseSafe(namePart)) - return namePart; - return MakeNameSafe(namePart); + return IsMadeSafe(namePart) ? namePart : MakeNameSafe(namePart); } /// @@ -1609,23 +1605,6 @@ namespace DbLinq.Vendor.Implementation return namePart[0] == SafeNameStartQuote && namePart[l - 1] == SafeNameEndQuote; } - /// - /// Determines whether [is name case safe] [the specified name part]. - /// - /// The name part. - /// - /// true if [is name case safe] [the specified name part]; otherwise, false. - /// - protected virtual bool IsNameCaseSafe(string namePart) - { - foreach (char c in namePart) - { - if (char.IsLower(c)) - return false; - } - return true; - } - /// /// Gets the safe name start quote. /// @@ -1647,53 +1626,6 @@ namespace DbLinq.Vendor.Implementation return namePart.Enquote(SafeNameStartQuote, SafeNameEndQuote); } - /// - /// Determines if a given field is dangerous (related to a SQL keyword or containing problematic characters) - /// - protected virtual bool IsNameSafe(string name) - { - var nameL = name.ToLower(); - switch (nameL) - { - case "user": - case "default": - case "bit": - case "int": - case "smallint": - case "tinyint": - case "mediumint": - - case "float": - case "double": - case "real": - case "decimal": - case "numeric": - - case "blob": - case "text": - case "char": - case "varchar": - - case "date": - case "time": - case "datetime": - case "timestamp": - case "year": - - case "select": - case "from": - case "where": - case "order": - case "by": - case "key": - case "index": - - return false; - default: - return !name.Contains(' '); - } - } - private static readonly Regex _fieldIdentifierEx = new Regex(@"\[(?[\w.]+)\]", RegexOptions.Singleline | RegexOptions.ExplicitCapture | diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs index 6a28f53b072..c9b68f575dd 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs @@ -39,6 +39,7 @@ using DbLinq.Data.Linq; using Data = DbLinq.Data; using IExecuteResult = System.Data.Linq.IExecuteResult; +using System.Text; namespace DbLinq.Vendor.Implementation { @@ -134,10 +135,43 @@ namespace DbLinq.Vendor.Implementation /// The parts. /// The name. /// The value. - protected virtual void AddConnectionStringPart(IList parts, string name, string value) + protected void AppendConnectionString(StringBuilder connectionString, string name, string value) { if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(name)) - parts.Add(string.Format("{0}={1}", name, value)); + connectionString.AppendFormat("{0}={1};", name, value); + } + + protected virtual void AppendDatabase(StringBuilder connectionString, string databaseName) + { + AppendConnectionString(connectionString, ConnectionStringDatabase, databaseName); + } + + protected virtual void AppendPassword(StringBuilder connectionString, string password) + { + AppendConnectionString(connectionString, ConnectionStringPassword, password); + } + + protected virtual void AppendServer(StringBuilder connectionString, string host) + { + // A majority of databases want a server/host port number as a separate key: + // http://www.connectionstrings.com/postgre-sql + // http://www.connectionstrings.com/firebird + // http://www.connectionstrings.com/mysql + // So make this the default. + if (host == null) + return; + var colonIdx = host.IndexOf(':'); + string port = colonIdx < 0 || host.Length == (colonIdx + 1) ? null : host.Substring(colonIdx + 1); + if (colonIdx >= 0) + host = host.Substring(0, colonIdx); + AppendConnectionString(connectionString, ConnectionStringServer, host); + if (port != null) + AppendConnectionString(connectionString, "Port", port); + } + + protected virtual void AppendUser(StringBuilder connectionString, string userName) + { + AppendConnectionString(connectionString, ConnectionStringUser, userName); } /// @@ -150,12 +184,12 @@ namespace DbLinq.Vendor.Implementation /// public virtual string BuildConnectionString(string host, string databaseName, string userName, string password) { - var connectionStringParts = new List(); - AddConnectionStringPart(connectionStringParts, ConnectionStringServer, host); - AddConnectionStringPart(connectionStringParts, ConnectionStringDatabase, databaseName); - AddConnectionStringPart(connectionStringParts, ConnectionStringUser, userName); - AddConnectionStringPart(connectionStringParts, ConnectionStringPassword, password); - return string.Join(";", connectionStringParts.ToArray()); + var connectionString = new StringBuilder(); + AppendServer(connectionString, host); + AppendDatabase(connectionString, databaseName); + AppendUser(connectionString, userName); + AppendPassword(connectionString, password); + return connectionString.ToString(); } /// diff --git a/mcs/class/System.Data.Linq/src/DbMetal/App.config b/mcs/class/System.Data.Linq/src/DbMetal/App.config index 4d607bb799f..e92412528c5 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/App.config +++ b/mcs/class/System.Data.Linq/src/DbMetal/App.config @@ -18,7 +18,7 @@ - + diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs b/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs index 94dafb94a3c..73d26d6459c 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Configuration/ProvidersSection.cs @@ -24,9 +24,11 @@ // #endregion using System; +using System.IO; using System.Linq; using System.Collections.Generic; using System.Configuration; +using System.Text; namespace DbMetal.Configuration { @@ -91,15 +93,31 @@ namespace DbMetal.Configuration string[] allKeyStrings = allKeys.OfType().ToArray(); element = null; - error = allKeys.Length == 0 - ? "There are no entries in your app.config" - : "Key " + name + " not found among " + allKeys.Length + " config entries {" + string.Join(",",allKeyStrings) + "}"; + string configFile = Path.GetFileName(typeof(Program).Assembly.Location)+ ".config"; + error = allKeys.Length == 0 + ? string.Format("There are no entries in your {0} file.", configFile) + : GetProvidersDescription(name, allKeyStrings.Length, configFile); return false; } element = (ProviderElement)BaseGet(name.ToLower()); error = null; return true; } + + private string GetProvidersDescription(string name, int numKeys, string configFile) + { + var message = new StringBuilder(); + message.AppendFormat("Provider '{0}' not found among the {1} config entries in your {2} file. ", + name, numKeys, configFile); + message.AppendLine("Valid providers include:"); + foreach (ProviderElement p in this.Cast().OrderBy(e => e.Name)) + { + message.AppendFormat("\t{0} [{1}]", + p.Name, p.DatabaseConnection); + message.AppendLine(); + } + return message.ToString(); + } } [ConfigurationProperty("providers", IsDefaultCollection = true)] diff --git a/mcs/class/System.Data.Linq/src/DbMetal/DbMetal.csproj b/mcs/class/System.Data.Linq/src/DbMetal/DbMetal.csproj index 812787d14af..06018206389 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/DbMetal.csproj +++ b/mcs/class/System.Data.Linq/src/DbMetal/DbMetal.csproj @@ -71,13 +71,11 @@ Properties\DbLinq.ProductInfo.cs - + - - @@ -192,15 +190,18 @@ - - rem this is what I call loose coupling -copy "$(SolutionDir)..\lib\Npgsql.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\Mono.Security.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\Ingres.Stereo.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\Oracle.DataAccess.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\MySql.Data.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\System.Data.SQLite.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\FirebirdSql.Data.FirebirdClient.dll" "$(TargetDir)" - - - \ No newline at end of file + + + + + + + + + + + + + diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeDomGenerator.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeDomGenerator.cs new file mode 100755 index 00000000000..c52bbeb3a02 --- /dev/null +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeDomGenerator.cs @@ -0,0 +1,1474 @@ +#region MIT license +// +// MIT license +// +// Copyright (c) 2007-2008 Jiri Moudry, Pascal Craponne +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +#endregion +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Data.Linq.Mapping; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +using Microsoft.CSharp; +using Microsoft.VisualBasic; + +using DbLinq.Schema.Dbml; +using DbLinq.Schema.Dbml.Adapter; +using DbLinq.Util; + +namespace DbMetal.Generator +{ +#if !MONO_STRICT + public +#endif + class CodeDomGenerator : ICodeGenerator + { + CodeDomProvider Provider { get; set; } + + // Provided only for Processor.EnumerateCodeGenerators(). DO NOT USE. + public CodeDomGenerator() + { + } + + public CodeDomGenerator(CodeDomProvider provider) + { + this.Provider = provider; + } + + public string LanguageCode { + get { return "*"; } + } + + public string Extension { + get { return "*"; } + } + + public static CodeDomGenerator CreateFromFileExtension(string extension) + { + return CreateFromLanguage(CodeDomProvider.GetLanguageFromExtension(extension)); + } + + public static CodeDomGenerator CreateFromLanguage(string language) + { + return new CodeDomGenerator(CodeDomProvider.CreateProvider(language)); + } + + public void Write(TextWriter textWriter, Database dbSchema, GenerationContext context) + { + Context = context; + Provider.CreateGenerator(textWriter).GenerateCodeFromNamespace( + GenerateCodeDomModel(dbSchema), textWriter, + new CodeGeneratorOptions() { + BracingStyle = "C", + IndentString = "\t", + }); + } + + static void Warning(string format, params object[] args) + { + Console.Error.Write(Path.GetFileName(Environment.GetCommandLineArgs()[0])); + Console.Error.Write(": warning: "); + Console.Error.WriteLine(format, args); + } + + private CodeTypeMember CreatePartialMethod(string methodName, params CodeParameterDeclarationExpression[] parameters) + { + string prototype = null; + if (Provider is CSharpCodeProvider) + { + prototype = + "\t\tpartial void {0}({1});" + Environment.NewLine + + "\t\t"; + } + else if (Provider is VBCodeProvider) + { + prototype = + "\t\tPartial Private Sub {0}({1})" + Environment.NewLine + + "\t\tEnd Sub" + Environment.NewLine + + "\t\t"; + } + + if (prototype == null) + { + var method = new CodeMemberMethod() { + Name = methodName, + }; + method.Parameters.AddRange(parameters); + return method; + } + + var methodDecl = new StringWriter(); + var gen = Provider.CreateGenerator(methodDecl); + + bool comma = false; + foreach (var p in parameters) + { + if (comma) + methodDecl.Write(", "); + comma = true; + gen.GenerateCodeFromExpression(p, methodDecl, null); + } + return new CodeSnippetTypeMember(string.Format(prototype, methodName, methodDecl.ToString())); + } + + CodeThisReferenceExpression thisReference = new CodeThisReferenceExpression(); + + protected GenerationContext Context { get; set; } + + protected virtual CodeNamespace GenerateCodeDomModel(Database database) + { + CodeNamespace _namespace = new CodeNamespace(Context.Parameters.Namespace ?? database.ContextNamespace); + + _namespace.Imports.Add(new CodeNamespaceImport("System")); + _namespace.Imports.Add(new CodeNamespaceImport("System.ComponentModel")); +#if MONO_STRICT + _namespace.Imports.Add(new CodeNamespaceImport("System.Data")); + _namespace.Imports.Add(new CodeNamespaceImport("System.Data.Linq")); + _namespace.Imports.Add(new CodeNamespaceImport("System.Data.Linq.Mapping")); +#else + AddConditionalImports(_namespace.Imports, + "System.Data", + "MONO_STRICT", + new[] { "System.Data.Linq" }, + new[] { "DbLinq.Data.Linq", "DbLinq.Vendor" }, + "System.Data.Linq.Mapping"); +#endif + _namespace.Imports.Add(new CodeNamespaceImport("System.Diagnostics")); + + var time = Context.Parameters.GenerateTimestamps ? DateTime.Now.ToString("u") : "[TIMESTAMP]"; + var header = new CodeCommentStatement(GenerateCommentBanner(database, time)); + _namespace.Comments.Add(header); + + _namespace.Types.Add(GenerateContextClass(database)); +#if !MONO_STRICT + _namespace.Types.Add(GenerateMonoStrictContextConstructors(database)); + _namespace.Types.Add(GenerateNotMonoStrictContextConstructors(database)); +#endif + + foreach (Table table in database.Tables) + _namespace.Types.Add(GenerateTableClass(table, database)); + return _namespace; + } + + void AddConditionalImports(CodeNamespaceImportCollection imports, + string firstImport, + string conditional, + string[] importsIfTrue, + string[] importsIfFalse, + string lastImport) + { + if (Provider is CSharpCodeProvider) + { + // HACK HACK HACK + // Would be better if CodeDom actually supported conditional compilation constructs... + // This is predecated upon CSharpCodeGenerator.GenerateNamespaceImport() being implemented as: + // output.Write ("using "); + // output.Write (GetSafeName (import.Namespace)); + // output.WriteLine (';'); + // Thus, with "crafty" execution of the namespace, we can stuff arbitrary text in there... + + var block = new StringBuilder(); + // No 'using', as GenerateNamespaceImport() writes it. + block.Append(firstImport).Append(";").Append(Environment.NewLine); + block.Append("#if ").Append(conditional).Append(Environment.NewLine); + foreach (var ns in importsIfTrue) + block.Append("\tusing ").Append(ns).Append(";").Append(Environment.NewLine); + block.Append("#else // ").Append(conditional).Append(Environment.NewLine); + foreach (var ns in importsIfFalse) + block.Append("\tusing ").Append(ns).Append(";").Append(Environment.NewLine); + block.Append("#endif // ").Append(conditional).Append(Environment.NewLine); + block.Append("\tusing ").Append(lastImport); + // No ';', as GenerateNamespaceImport() writes it. + + imports.Add(new CodeNamespaceImport(block.ToString())); + } + else if (Provider is VBCodeProvider) + { + // HACK HACK HACK + // Would be better if CodeDom actually supported conditional compilation constructs... + // This is predecated upon VBCodeGenerator.GenerateNamespaceImport() being implemented as: + // output.Write ("Imports "); + // output.Write (import.Namespace); + // output.WriteLine (); + // Thus, with "crafty" execution of the namespace, we can stuff arbitrary text in there... + + var block = new StringBuilder(); + // No 'Imports', as GenerateNamespaceImport() writes it. + block.Append(firstImport).Append(Environment.NewLine); + block.Append("#If ").Append(conditional).Append(" Then").Append(Environment.NewLine); + foreach (var ns in importsIfTrue) + block.Append("Imports ").Append(ns).Append(Environment.NewLine); + block.Append("#Else ' ").Append(conditional).Append(Environment.NewLine); + foreach (var ns in importsIfFalse) + block.Append("Imports ").Append(ns).Append(Environment.NewLine); + block.Append("#End If ' ").Append(conditional).Append(Environment.NewLine); + block.Append("Imports ").Append(lastImport); + // No newline, as GenerateNamespaceImport() writes it. + + imports.Add(new CodeNamespaceImport(block.ToString())); + } + else + { + // Default to using the DbLinq imports + imports.Add(new CodeNamespaceImport(firstImport)); + foreach (var ns in importsIfTrue) + imports.Add(new CodeNamespaceImport(ns)); + imports.Add(new CodeNamespaceImport(lastImport)); + } + } + + private string GenerateCommentBanner(Database database, string time) + { + var result = new StringBuilder(); + + // http://www.network-science.de/ascii/ + // http://www.network-science.de/ascii/ascii.php?TEXT=MetalSequel&x=14&y=14&FONT=_all+fonts+with+your+text_&RICH=no&FORM=left&STRE=no&WIDT=80 + result.Append( + @" + ____ _ __ __ _ _ + | _ \| |__ | \/ | ___| |_ __ _| | + | | | | '_ \| |\/| |/ _ \ __/ _` | | + | |_| | |_) | | | | __/ || (_| | | + |____/|_.__/|_| |_|\___|\__\__,_|_| + +"); + result.AppendLine(String.Format(" Auto-generated from {0} on {1}.", database.Name, time)); + result.AppendLine(" Please visit http://code.google.com/p/dblinq2007/ for more information."); + + return result.ToString(); + } + + protected virtual CodeTypeDeclaration GenerateContextClass(Database database) + { + var _class = new CodeTypeDeclaration() { + IsClass = true, + IsPartial = true, + Name = database.Class, + TypeAttributes = TypeAttributes.Public + }; + + _class.BaseTypes.Add(GetContextBaseType(database.BaseType)); + + var onCreated = CreatePartialMethod("OnCreated"); + onCreated.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Extensibility Method Declarations")); + onCreated.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null)); + _class.Members.Add(onCreated); + + // Implement Constructor + GenerateContextConstructors(_class, database); + + foreach (Table table in database.Tables) + { + var tableType = new CodeTypeReference(table.Type.Name); + var property = new CodeMemberProperty() { + Attributes = MemberAttributes.Public | MemberAttributes.Final, + Name = table.Member, + Type = new CodeTypeReference("Table", tableType), + }; + property.GetStatements.Add( + new CodeMethodReturnStatement( + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression(thisReference, "GetTable", tableType)))); + _class.Members.Add(property); + } + + foreach (var function in database.Functions) + { + GenerateContextFunction(_class, function); + } + + return _class; + } + + static string GetContextBaseType(string type) + { + string baseType = "DataContext"; + + if (!string.IsNullOrEmpty(type)) + { + var t = TypeLoader.Load(type); + if (t != null) + baseType = t.Name; + } + + return baseType; + } + + void GenerateContextConstructors(CodeTypeDeclaration contextType, Database database) + { + // .ctor(string connectionString); + var constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { new CodeParameterDeclarationExpression(typeof(string), "connectionString") }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connectionString")); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); + +#if MONO_STRICT + // .ctor(IDbConnection connection); + constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { new CodeParameterDeclarationExpression("IDbConnection", "connection") }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection")); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); +#endif + + // .ctor(string connection, MappingSource mappingSource); + constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { + new CodeParameterDeclarationExpression(typeof(string), "connection"), + new CodeParameterDeclarationExpression("MappingSource", "mappingSource"), + }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection")); + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("mappingSource")); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); + + // .ctor(IDbConnection connection, MappingSource mappingSource); + constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { + new CodeParameterDeclarationExpression("IDbConnection", "connection"), + new CodeParameterDeclarationExpression("MappingSource", "mappingSource"), + }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection")); + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("mappingSource")); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); + } + + CodeTypeDeclaration GenerateMonoStrictContextConstructors(Database database) + { + var contextType = new CodeTypeDeclaration() + { + IsClass = true, + IsPartial = true, + Name = database.Class, + TypeAttributes = TypeAttributes.Public + }; + AddConditionalIfElseBlocks(contextType, "MONO_STRICT"); + + // .ctor(IDbConnection connection); + var constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { new CodeParameterDeclarationExpression("IDbConnection", "connection") }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection")); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); + + return contextType; + } + + void AddConditionalIfElseBlocks(CodeTypeMember member, string condition) + { + string startIf = null, elseIf = null; + if (Provider is CSharpCodeProvider) + { + startIf = string.Format("Start {0}{1}#if {0}{1}", condition, Environment.NewLine); + elseIf = string.Format("End {0}{1}\t#endregion{1}#else // {0}", condition, Environment.NewLine); + } + if (Provider is VBCodeProvider) + { + startIf = string.Format("Start {0}\"{1}#If {0} Then{1} '", condition, Environment.NewLine); + elseIf = string.Format("End {0}\"{1}\t#End Region{1}#Else ' {0}", condition, Environment.NewLine); + } + if (startIf != null && elseIf != null) + { + member.StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, startIf)); + member.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, elseIf)); + } + } + + void AddConditionalEndifBlocks(CodeTypeMember member, string condition) + { + string endIf = null; + if (Provider is CSharpCodeProvider) + { + endIf = string.Format("End Not {0}{1}\t#endregion{1}#endif // {0}", condition, Environment.NewLine); + } + if (Provider is VBCodeProvider) + { + endIf = string.Format("End Not {0}\"{1}\t#End Region{1}#End If ' {0}", condition, Environment.NewLine); + } + if (endIf != null) + { + member.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, endIf)); + member.EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null)); + } + } + + CodeTypeDeclaration GenerateNotMonoStrictContextConstructors(Database database) + { + var contextType = new CodeTypeDeclaration() { + IsClass = true, + IsPartial = true, + Name = database.Class, + TypeAttributes = TypeAttributes.Public + }; + AddConditionalEndifBlocks(contextType, "MONO_STRICT"); + + // .ctor(IDbConnection connection); + var constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { new CodeParameterDeclarationExpression("IDbConnection", "connection") }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection")); + constructor.BaseConstructorArgs.Add(new CodeObjectCreateExpression(Context.SchemaLoader.Vendor.GetType())); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); + + // .ctor(IDbConnection connection, IVendor mappingSource); + constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { + new CodeParameterDeclarationExpression("IDbConnection", "connection"), + new CodeParameterDeclarationExpression("IVendor", "sqlDialect"), + }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection")); + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("sqlDialect")); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); + + // .ctor(IDbConnection connection, MappingSource mappingSource, IVendor mappingSource); + constructor = new CodeConstructor() { + Attributes = MemberAttributes.Public, + Parameters = { + new CodeParameterDeclarationExpression("IDbConnection", "connection"), + new CodeParameterDeclarationExpression("MappingSource", "mappingSource"), + new CodeParameterDeclarationExpression("IVendor", "sqlDialect"), + }, + }; + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("connection")); + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("mappingSource")); + constructor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("sqlDialect")); + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + contextType.Members.Add(constructor); + + return contextType; + } + + void GenerateContextFunction(CodeTypeDeclaration contextType, Function function) + { + if (function == null || string.IsNullOrEmpty(function.Name)) + { + Warning("L33 Invalid storedProcdure object: missing name."); + return; + } + + var methodRetType = GetFunctionReturnType(function); + var method = new CodeMemberMethod() { + Attributes = ToMemberAttributes(function), + Name = function.Method ?? function.Name, + ReturnType = methodRetType, + CustomAttributes = { + new CodeAttributeDeclaration("Function", + new CodeAttributeArgument("Name", new CodePrimitiveExpression(function.Name)), + new CodeAttributeArgument("IsComposable", new CodePrimitiveExpression(function.IsComposable))), + }, + }; + if (method.Parameters != null) + method.Parameters.AddRange(function.Parameters.Select(x => GetFunctionParameterType(x)).ToArray()); + if (function.Return != null && !string.IsNullOrEmpty(function.Return.DbType)) + method.ReturnTypeCustomAttributes.Add( + new CodeAttributeDeclaration("Parameter", + new CodeAttributeArgument("DbType", new CodePrimitiveExpression(function.Return.DbType)))); + + contextType.Members.Add(method); + + for (int i = 0; i < function.Parameters.Count; ++i) + { + var p = function.Parameters[i]; + if (!p.DirectionOut) + continue; + method.Statements.Add( + new CodeAssignStatement( + new CodeVariableReferenceExpression(p.Name), + new CodeDefaultValueExpression(new CodeTypeReference(p.Type)))); + } + + var executeMethodCallArgs = new List() { + thisReference, + new CodeCastExpression( + new CodeTypeReference("System.Reflection.MethodInfo"), + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression( + new CodeTypeReferenceExpression("System.Reflection.MethodBase"), "GetCurrentMethod"))), + }; + if (method.Parameters != null) + executeMethodCallArgs.AddRange( + function.Parameters.Select(p => (CodeExpression) new CodeVariableReferenceExpression(p.Name))); + method.Statements.Add( + new CodeVariableDeclarationStatement( + new CodeTypeReference("IExecuteResult"), + "result", + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression(thisReference, "ExecuteMethodCall"), + executeMethodCallArgs.ToArray()))); + for (int i = 0; i < function.Parameters.Count; ++i) + { + var p = function.Parameters[i]; + if (!p.DirectionOut) + continue; + method.Statements.Add( + new CodeAssignStatement( + new CodeVariableReferenceExpression(p.Name), + new CodeCastExpression( + new CodeTypeReference(p.Type), + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression( + new CodeVariableReferenceExpression("result"), + "GetParameterValue"), + new CodePrimitiveExpression(i))))); + } + + if (methodRetType != null) + { + method.Statements.Add( + new CodeMethodReturnStatement( + new CodeCastExpression( + method.ReturnType, + new CodePropertyReferenceExpression( + new CodeVariableReferenceExpression("result"), + "ReturnValue")))); + } + } + + CodeTypeReference GetFunctionReturnType(Function function) + { + CodeTypeReference type = null; + if (function.Return != null) + { + type = GetFunctionType(function.Return.Type); + } + + bool isDataShapeUnknown = function.ElementType == null + && function.BodyContainsSelectStatement + && !function.IsComposable; + if (isDataShapeUnknown) + { + //if we don't know the shape of results, and the proc body contains some selects, + //we have no choice but to return an untyped DataSet. + // + //TODO: either parse proc body like microsoft, + //or create a little GUI tool which would call the proc with test values, to determine result shape. + type = new CodeTypeReference(typeof(DataSet)); + } + return type; + } + + static CodeTypeReference GetFunctionType(string type) + { + var t = System.Type.GetType(type); + if (t == null) + return new CodeTypeReference(type); + if (t.IsValueType) + return new CodeTypeReference(typeof(Nullable<>)) { + TypeArguments = { + new CodeTypeReference(t), + }, + }; + return new CodeTypeReference(t); + } + + CodeParameterDeclarationExpression GetFunctionParameterType(Parameter parameter) + { + var p = new CodeParameterDeclarationExpression(GetFunctionType(parameter.Type), parameter.Name) { + CustomAttributes = { + new CodeAttributeDeclaration("Parameter", + new CodeAttributeArgument("Name", new CodePrimitiveExpression(parameter.Name)), + new CodeAttributeArgument("DbType", new CodePrimitiveExpression(parameter.DbType))), + }, + }; + switch (parameter.Direction) + { + case DbLinq.Schema.Dbml.ParameterDirection.In: + p.Direction = FieldDirection.In; + break; + case DbLinq.Schema.Dbml.ParameterDirection.Out: + p.Direction = FieldDirection.Out; + break; + case DbLinq.Schema.Dbml.ParameterDirection.InOut: + p.Direction = FieldDirection.In | FieldDirection.Out; + break; + default: + throw new ArgumentOutOfRangeException(); + } + return p; + } + + protected CodeTypeDeclaration GenerateTableClass(Table table, Database database) + { + var _class = new CodeTypeDeclaration() { + IsClass = true, + IsPartial = true, + Name = table.Type.Name, + TypeAttributes = TypeAttributes.Public, + CustomAttributes = { + new CodeAttributeDeclaration("Table", + new CodeAttributeArgument("Name", new CodePrimitiveExpression(table.Name))), + }, + }; + + WriteCustomTypes(_class, table); + + var havePrimaryKeys = table.Type.Columns.Any(c => c.IsPrimaryKey); + if (havePrimaryKeys) + { + GenerateINotifyPropertyChanging(_class); + GenerateINotifyPropertyChanged(_class); + } + + // Implement Constructor + var constructor = new CodeConstructor() { Attributes = MemberAttributes.Public }; + // children are EntitySet + foreach (var child in GetClassChildren(table)) + { + // if the association has a storage, we use it. Otherwise, we use the property name + var entitySetMember = GetStorageFieldName(child); + constructor.Statements.Add( + new CodeAssignStatement( + new CodeVariableReferenceExpression(entitySetMember), + new CodeObjectCreateExpression( + new CodeTypeReference("EntitySet", new CodeTypeReference(child.Type)), + new CodeDelegateCreateExpression( + new CodeTypeReference("Action", new CodeTypeReference(child.Type)), + thisReference, child.Member + "_Attach"), + new CodeDelegateCreateExpression( + new CodeTypeReference("Action", new CodeTypeReference(child.Type)), + thisReference, child.Member + "_Detach")))); + } + constructor.Statements.Add(new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "OnCreated"))); + _class.Members.Add(constructor); + + if (Context.Parameters.GenerateEqualsHash) + { + GenerateEntityGetHashCodeAndEquals(_class, table); + } + + GenerateExtensibilityDeclarations(_class, table); + + // todo: add these when the actually get called + //partial void OnLoaded(); + //partial void OnValidate(System.Data.Linq.ChangeAction action); + + // columns + foreach (Column column in table.Type.Columns) + { + var relatedAssociations = from a in table.Type.Associations + where a.IsForeignKey && a.TheseKeys.Contains(column.Name) + select a; + + var type = ToCodeTypeReference(column); + var columnMember = column.Member ?? column.Name; + + var field = new CodeMemberField(type, GetStorageFieldName(column)); + _class.Members.Add(field); + var fieldReference = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name); + + var onChanging = GetChangingMethodName(columnMember); + var onChanged = GetChangedMethodName(columnMember); + + var property = new CodeMemberProperty(); + property.Type = type; + property.Name = columnMember; + property.Attributes = MemberAttributes.Public | MemberAttributes.Final; + + var defAttrValues = new ColumnAttribute(); + var args = new List() { + new CodeAttributeArgument("Storage", new CodePrimitiveExpression(GetStorageFieldName(column))), + new CodeAttributeArgument("Name", new CodePrimitiveExpression(column.Name)), + new CodeAttributeArgument("DbType", new CodePrimitiveExpression(column.DbType)), + }; + if (defAttrValues.IsPrimaryKey != column.IsPrimaryKey) + args.Add(new CodeAttributeArgument("IsPrimaryKey", new CodePrimitiveExpression(column.IsPrimaryKey))); + if (defAttrValues.IsDbGenerated != column.IsDbGenerated) + args.Add(new CodeAttributeArgument("IsDbGenerated", new CodePrimitiveExpression(column.IsDbGenerated))); + if (column.AutoSync != DbLinq.Schema.Dbml.AutoSync.Default) + args.Add(new CodeAttributeArgument("AutoSync", + new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("AutoSync"), column.AutoSync.ToString()))); + if (defAttrValues.CanBeNull != column.CanBeNull) + args.Add(new CodeAttributeArgument("CanBeNull", new CodePrimitiveExpression(column.CanBeNull))); + if (column.Expression != null) + args.Add(new CodeAttributeArgument("Expression", new CodePrimitiveExpression(column.Expression))); + property.CustomAttributes.Add( + new CodeAttributeDeclaration("Column", args.ToArray())); + property.CustomAttributes.Add(new CodeAttributeDeclaration("DebuggerNonUserCode")); + + property.GetStatements.Add(new CodeMethodReturnStatement(fieldReference)); + + var whenUpdating = new List( + from assoc in relatedAssociations + select (CodeStatement) new CodeConditionStatement( + new CodePropertyReferenceExpression( + new CodeVariableReferenceExpression(GetStorageFieldName(assoc)), + "HasLoadedOrAssignedValue"), + new CodeThrowExceptionStatement( + new CodeObjectCreateExpression(typeof(System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException))))); + whenUpdating.Add( + new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChanging, new CodePropertySetValueReferenceExpression()))); + if (havePrimaryKeys) + whenUpdating.Add( + new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "SendPropertyChanging"))); + whenUpdating.Add( + new CodeAssignStatement(fieldReference, new CodePropertySetValueReferenceExpression())); + if (havePrimaryKeys) + whenUpdating.Add( + new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, "SendPropertyChanged", new CodePrimitiveExpression(property.Name)))); + whenUpdating.Add( + new CodeExpressionStatement(new CodeMethodInvokeExpression(thisReference, onChanged))); + + var fieldType = TypeLoader.Load(column.Type); + // This is needed for VB.NET generation; + // int/string/etc. can use '<>' for comparison, but NOT arrays and other reference types. + // arrays/etc. require the 'Is' operator, which is CodeBinaryOperatorType.IdentityEquality. + // The VB IsNot operator is not exposed from CodeDom. + // Thus, we need to special-case: if fieldType is a ref or nullable type, + // generate '(field Is value) = false'; otherwise, + // generate '(field <> value)' + CodeBinaryOperatorExpression condition = fieldType.IsClass || fieldType.IsNullable() + ? ValuesAreNotEqual_Ref(new CodeVariableReferenceExpression(field.Name), new CodePropertySetValueReferenceExpression()) + : ValuesAreNotEqual(new CodeVariableReferenceExpression(field.Name), new CodePropertySetValueReferenceExpression()); + property.SetStatements.Add(new CodeConditionStatement(condition, whenUpdating.ToArray())); + _class.Members.Add(property); + } + + GenerateEntityChildren(_class, table, database); + GenerateEntityChildrenAttachment(_class, table, database); + GenerateEntityParents(_class, table, database); + + return _class; + } + + void WriteCustomTypes(CodeTypeDeclaration entity, Table table) + { + // detect required custom types + foreach (var column in table.Type.Columns) + { + var extendedType = column.ExtendedType; + var enumType = extendedType as EnumType; + if (enumType != null) + { + Context.ExtendedTypes[column] = new GenerationContext.ExtendedTypeAndName { + Type = column.ExtendedType, + Table = table + }; + } + } + + var customTypesNames = new List(); + + // create names and avoid conflits + foreach (var extendedTypePair in Context.ExtendedTypes) + { + if (extendedTypePair.Value.Table != table) + continue; + + if (string.IsNullOrEmpty(extendedTypePair.Value.Type.Name)) + { + string name = extendedTypePair.Key.Member + "Type"; + for (; ; ) + { + if ((from t in Context.ExtendedTypes.Values where t.Type.Name == name select t).FirstOrDefault() == null) + { + extendedTypePair.Value.Type.Name = name; + break; + } + // at 3rd loop, it will look ugly, however we will never go there + name = extendedTypePair.Value.Table.Type.Name + name; + } + } + customTypesNames.Add(extendedTypePair.Value.Type.Name); + } + + // write custom types + if (customTypesNames.Count > 0) + { + var customTypes = new List(customTypesNames.Count); + + foreach (var extendedTypePair in Context.ExtendedTypes) + { + if (extendedTypePair.Value.Table != table) + continue; + + var extendedType = extendedTypePair.Value.Type; + var enumValue = extendedType as EnumType; + + if (enumValue != null) + { + var enumType = new CodeTypeDeclaration(enumValue.Name) { + TypeAttributes = TypeAttributes.Public, + IsEnum = true, + }; + customTypes.Add(enumType); + var orderedValues = from nv in enumValue orderby nv.Value select nv; + int currentValue = 1; + foreach (var nameValue in orderedValues) + { + var field = new CodeMemberField() { + Name = nameValue.Key, + }; + enumType.Members.Add(field); + if (nameValue.Value != currentValue) + { + currentValue = nameValue.Value; + field.InitExpression = new CodePrimitiveExpression(nameValue.Value); + } + currentValue++; + } + } + } + + if (customTypes.Count == 0) + return; + customTypes.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, + string.Format("Custom type definitions for {0}", string.Join(", ", customTypesNames.ToArray())))); + customTypes.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null)); + entity.Members.AddRange(customTypes.ToArray()); + } + } + + void GenerateExtensibilityDeclarations(CodeTypeDeclaration entity, Table table) + { + var partialMethods = new[] { CreatePartialMethod("OnCreated") } + .Concat(table.Type.Columns.Select(c => new[] { CreateChangedMethodDecl(c), CreateChangingMethodDecl(c) }) + .SelectMany(md => md)).ToArray(); + partialMethods.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Extensibility Method Declarations")); + partialMethods.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null)); + entity.Members.AddRange(partialMethods); + } + + static string GetChangedMethodName(string columnName) + { + return string.Format("On{0}Changed", columnName); + } + + CodeTypeMember CreateChangedMethodDecl(Column column) + { + return CreatePartialMethod(GetChangedMethodName(column.Member)); + } + + static string GetChangingMethodName(string columnName) + { + return string.Format("On{0}Changing", columnName); + } + + CodeTypeMember CreateChangingMethodDecl(Column column) + { + return CreatePartialMethod(GetChangingMethodName(column.Member), + new CodeParameterDeclarationExpression(ToCodeTypeReference(column), "value")); + } + + static CodeTypeReference ToCodeTypeReference(Column column) + { + var t = System.Type.GetType(column.Type); + if (t == null) + return new CodeTypeReference(column.Type); + return t.IsValueType && column.CanBeNull + ? new CodeTypeReference("System.Nullable", new CodeTypeReference(column.Type)) + : new CodeTypeReference(column.Type); + } + + CodeBinaryOperatorExpression ValuesAreNotEqual(CodeExpression a, CodeExpression b) + { + return new CodeBinaryOperatorExpression(a, CodeBinaryOperatorType.IdentityInequality, b); + } + + CodeBinaryOperatorExpression ValuesAreNotEqual_Ref(CodeExpression a, CodeExpression b) + { + return new CodeBinaryOperatorExpression( + new CodeBinaryOperatorExpression( + a, + CodeBinaryOperatorType.IdentityEquality, + b), + CodeBinaryOperatorType.ValueEquality, + new CodePrimitiveExpression(false)); + } + + CodeBinaryOperatorExpression ValueIsNull(CodeExpression value) + { + return new CodeBinaryOperatorExpression( + value, + CodeBinaryOperatorType.IdentityEquality, + new CodePrimitiveExpression(null)); + } + + CodeBinaryOperatorExpression ValueIsNotNull(CodeExpression value) + { + return new CodeBinaryOperatorExpression( + value, + CodeBinaryOperatorType.IdentityInequality, + new CodePrimitiveExpression(null)); + } + + static string GetStorageFieldName(Column column) + { + return GetStorageFieldName(column.Storage ?? column.Member); + } + + static string GetStorageFieldName(string storage) + { + if (storage.StartsWith("_")) + return storage; + return "_" + storage; + } + + private void GenerateINotifyPropertyChanging(CodeTypeDeclaration entity) + { + entity.BaseTypes.Add(typeof(INotifyPropertyChanging)); + var propertyChangingEvent = new CodeMemberEvent() { + Attributes = MemberAttributes.Public, + Name = "PropertyChanging", + Type = new CodeTypeReference(typeof(PropertyChangingEventHandler)), + ImplementationTypes = { + new CodeTypeReference(typeof(INotifyPropertyChanging)) + }, + }; + var eventArgs = new CodeMemberField(new CodeTypeReference(typeof(PropertyChangingEventArgs)), "emptyChangingEventArgs") { + Attributes = MemberAttributes.Static | MemberAttributes.Private, + InitExpression = new CodeObjectCreateExpression(new CodeTypeReference(typeof(PropertyChangingEventArgs)), + new CodePrimitiveExpression("")), + }; + var method = new CodeMemberMethod() { + Attributes = MemberAttributes.Family, + Name = "SendPropertyChanging", + }; + method.Statements.Add(new CodeVariableDeclarationStatement(typeof(PropertyChangingEventHandler), "h") { + InitExpression = new CodeEventReferenceExpression(thisReference, "PropertyChanging"), + }); + method.Statements.Add(new CodeConditionStatement( + ValueIsNotNull(new CodeVariableReferenceExpression("h")), + new CodeExpressionStatement( + new CodeDelegateInvokeExpression(new CodeVariableReferenceExpression("h"), thisReference, new CodeFieldReferenceExpression(null, "emptyChangingEventArgs"))))); + + entity.Members.Add(propertyChangingEvent); + entity.Members.Add(eventArgs); + entity.Members.Add(method); + } + + private void GenerateINotifyPropertyChanged(CodeTypeDeclaration entity) + { + entity.BaseTypes.Add(typeof(INotifyPropertyChanged)); + + var propertyChangedEvent = new CodeMemberEvent() { + Attributes = MemberAttributes.Public, + Name = "PropertyChanged", + Type = new CodeTypeReference(typeof(PropertyChangedEventHandler)), + ImplementationTypes = { + new CodeTypeReference(typeof(INotifyPropertyChanged)) + }, + }; + + var method = new CodeMemberMethod() { + Attributes = MemberAttributes.Family, + Name = "SendPropertyChanged", + Parameters = { new CodeParameterDeclarationExpression(typeof(System.String), "propertyName") } + }; + method.Statements.Add(new CodeVariableDeclarationStatement(typeof(PropertyChangedEventHandler), "h") { + InitExpression = new CodeEventReferenceExpression(thisReference, "PropertyChanged"), + }); + method.Statements.Add(new CodeConditionStatement( + ValueIsNotNull(new CodeVariableReferenceExpression("h")), + new CodeExpressionStatement( + new CodeDelegateInvokeExpression(new CodeVariableReferenceExpression("h"), thisReference, new CodeObjectCreateExpression(typeof(PropertyChangedEventArgs), new CodeVariableReferenceExpression("propertyName")))))); + + entity.Members.Add(propertyChangedEvent); + entity.Members.Add(method); + } + + void GenerateEntityGetHashCodeAndEquals(CodeTypeDeclaration entity, Table table) + { + var primaryKeys = table.Type.Columns.Where(c => c.IsPrimaryKey); + var pkCount = primaryKeys.Count(); + if (pkCount == 0) + { + Warning("Table {0} has no primary key(s). Skipping /generate-equals-hash for this table.", + table.Name); + return; + } + entity.BaseTypes.Add(new CodeTypeReference(typeof(IEquatable<>)) { + TypeArguments = { new CodeTypeReference(entity.Name) }, + }); + + var method = new CodeMemberMethod() { + Attributes = MemberAttributes.Public | MemberAttributes.Override, + Name = "GetHashCode", + ReturnType = new CodeTypeReference(typeof(int)), + }; + entity.Members.Add(method); + method.Statements.Add(new CodeVariableDeclarationStatement(typeof(int), "hc", new CodePrimitiveExpression(0))); + var numShifts = 32 / pkCount; + int pki = 0; + foreach (var pk in primaryKeys) + { + var shift = 1 << (pki++ * numShifts); + // lack of exclusive-or means we instead split the 32-bit hash code value + // into pkCount "chunks", each chunk being numShifts in size. + // Thus, if there are two primary keys, the first primary key gets the + // lower 16 bits, while the second primray key gets the upper 16 bits. + CodeStatement update = new CodeAssignStatement( + new CodeVariableReferenceExpression("hc"), + new CodeBinaryOperatorExpression( + new CodeVariableReferenceExpression("hc"), + CodeBinaryOperatorType.BitwiseOr, + new CodeBinaryOperatorExpression( + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression( + new CodeVariableReferenceExpression(GetStorageFieldName(pk)), + "GetHashCode")), + CodeBinaryOperatorType.Multiply, + new CodePrimitiveExpression(shift)))); + var pkType = System.Type.GetType(pk.Type); + if (pk.CanBeNull || (pkType != null && (pkType.IsClass || pkType.IsNullable()))) + { + update = new CodeConditionStatement( + ValueIsNotNull(new CodeVariableReferenceExpression(GetStorageFieldName(pk))), + update); + } + method.Statements.Add(update); + } + method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("hc"))); + + method = new CodeMemberMethod() { + Attributes = MemberAttributes.Public | MemberAttributes.Override, + Name = "Equals", + ReturnType = new CodeTypeReference(typeof(bool)), + Parameters = { + new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(object)), "value"), + }, + }; + entity.Members.Add(method); + method.Statements.Add( + new CodeConditionStatement( + ValueIsNull(new CodeVariableReferenceExpression("value")), + new CodeMethodReturnStatement(new CodePrimitiveExpression(false)))); + method.Statements.Add( + new CodeConditionStatement( + ValuesAreNotEqual_Ref( + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression( + new CodeVariableReferenceExpression("value"), + "GetType")), + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression(thisReference, "GetType"))), + new CodeMethodReturnStatement(new CodePrimitiveExpression(false)))); + method.Statements.Add( + new CodeVariableDeclarationStatement( + new CodeTypeReference(entity.Name), + "other", + new CodeCastExpression(new CodeTypeReference(entity.Name), new CodeVariableReferenceExpression("value")))); + method.Statements.Add( + new CodeMethodReturnStatement( + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression(thisReference, "Equals"), + new CodeVariableReferenceExpression("other")))); + + method = new CodeMemberMethod() { + Attributes = MemberAttributes.Public, + Name = "Equals", + ReturnType = new CodeTypeReference(typeof(bool)), + Parameters = { + new CodeParameterDeclarationExpression(new CodeTypeReference(entity.Name), "value"), + }, + ImplementationTypes = { + new CodeTypeReference("IEquatable", new CodeTypeReference(entity.Name)), + }, + }; + entity.Members.Add(method); + method.Statements.Add( + new CodeConditionStatement( + ValueIsNull(new CodeVariableReferenceExpression("value")), + new CodeMethodReturnStatement(new CodePrimitiveExpression(false)))); + + CodeExpression equals = null; + foreach (var pk in primaryKeys) + { + var compare = new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression( + new CodePropertyReferenceExpression( + new CodeTypeReferenceExpression( + new CodeTypeReference("System.Collections.Generic.EqualityComparer", + new CodeTypeReference(pk.Type))), + "Default"), + "Equals"), + new CodeFieldReferenceExpression(thisReference, GetStorageFieldName(pk)), + new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("value"), GetStorageFieldName(pk))); + equals = equals == null + ? (CodeExpression) compare + : (CodeExpression) new CodeBinaryOperatorExpression( + equals, + CodeBinaryOperatorType.BooleanAnd, + compare); + } + method.Statements.Add( + new CodeMethodReturnStatement(equals)); + } + + void GenerateEntityChildren(CodeTypeDeclaration entity, Table table, Database schema) + { + var children = GetClassChildren(table); + if (children.Any()) + { + var childMembers = new List(); + + foreach (var child in children) + { + bool hasDuplicates = (from c in children where c.Member == child.Member select c).Count() > 1; + + // the following is apparently useless + var targetTable = schema.Tables.FirstOrDefault(t => t.Type.Name == child.Type); + if (targetTable == null) + { + //Logger.Write(Level.Error, "ERROR L143 target table class not found:" + child.Type); + continue; + } + + var childType = new CodeTypeReference("EntitySet", new CodeTypeReference(child.Type)); + var storage = GetStorageFieldName(child); + entity.Members.Add(new CodeMemberField(childType, storage)); + + var childName = hasDuplicates + ? child.Member + "_" + string.Join("", child.OtherKeys.ToArray()) + : child.Member; + var property = new CodeMemberProperty() { + Name = childName, + Type = childType, + Attributes = ToMemberAttributes(child), + CustomAttributes = { + new CodeAttributeDeclaration("Association", + new CodeAttributeArgument("Storage", new CodePrimitiveExpression(GetStorageFieldName(child))), + new CodeAttributeArgument("OtherKey", new CodePrimitiveExpression(child.OtherKey)), + new CodeAttributeArgument("ThisKey", new CodePrimitiveExpression(child.ThisKey)), + new CodeAttributeArgument("Name", new CodePrimitiveExpression(child.Name))), + new CodeAttributeDeclaration("DebuggerNonUserCode"), + }, + }; + childMembers.Add(property); + property.GetStatements.Add(new CodeMethodReturnStatement( + new CodeFieldReferenceExpression(thisReference, storage))); + property.SetStatements.Add(new CodeAssignStatement( + new CodeFieldReferenceExpression(thisReference, storage), + new CodePropertySetValueReferenceExpression())); + } + + if (childMembers.Count == 0) + return; + childMembers.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Children")); + childMembers.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null)); + entity.Members.AddRange(childMembers.ToArray()); + } + } + + IEnumerable GetClassChildren(Table table) + { + return table.Type.Associations.Where(a => !a.IsForeignKey); + } + + static MemberAttributes ToMemberAttributes(Association association) + { + MemberAttributes attrs = 0; + if (!association.AccessModifierSpecified) + attrs |= MemberAttributes.Public; + else + switch (association.AccessModifier) + { + case AccessModifier.Internal: attrs = MemberAttributes.Assembly; break; + case AccessModifier.Private: attrs = MemberAttributes.Private; break; + case AccessModifier.Protected: attrs = MemberAttributes.Family; break; + case AccessModifier.ProtectedInternal: attrs = MemberAttributes.FamilyOrAssembly; break; + case AccessModifier.Public: attrs = MemberAttributes.Public; break; + default: + throw new ArgumentOutOfRangeException("association", "Modifier value '" + association.AccessModifierSpecified + "' is an unsupported value."); + } + if (!association.ModifierSpecified) + attrs |= MemberAttributes.Final; + else + switch (association.Modifier) + { + case MemberModifier.New: attrs |= MemberAttributes.New | MemberAttributes.Final; break; + case MemberModifier.NewVirtual: attrs |= MemberAttributes.New; break; + case MemberModifier.Override: attrs |= MemberAttributes.Override; break; + case MemberModifier.Virtual: break; + } + return attrs; + } + + static MemberAttributes ToMemberAttributes(Function function) + { + MemberAttributes attrs = 0; + if (!function.AccessModifierSpecified) + attrs |= MemberAttributes.Public; + else + switch (function.AccessModifier) + { + case AccessModifier.Internal: attrs = MemberAttributes.Assembly; break; + case AccessModifier.Private: attrs = MemberAttributes.Private; break; + case AccessModifier.Protected: attrs = MemberAttributes.Family; break; + case AccessModifier.ProtectedInternal: attrs = MemberAttributes.FamilyOrAssembly; break; + case AccessModifier.Public: attrs = MemberAttributes.Public; break; + default: + throw new ArgumentOutOfRangeException("function", "Modifier value '" + function.AccessModifierSpecified + "' is an unsupported value."); + } + if (!function.ModifierSpecified) + attrs |= MemberAttributes.Final; + else + switch (function.Modifier) + { + case MemberModifier.New: attrs |= MemberAttributes.New | MemberAttributes.Final; break; + case MemberModifier.NewVirtual: attrs |= MemberAttributes.New; break; + case MemberModifier.Override: attrs |= MemberAttributes.Override; break; + case MemberModifier.Virtual: break; + } + return attrs; + } + + static string GetStorageFieldName(Association association) + { + return association.Storage != null + ? GetStorageFieldName(association.Storage) + : "_" + CreateIdentifier(association.Member ?? association.Name); + } + + static string CreateIdentifier(string value) + { + return Regex.Replace(value, @"\W", "_"); + } + + void GenerateEntityChildrenAttachment(CodeTypeDeclaration entity, Table table, Database schema) + { + var children = GetClassChildren(table).ToList(); + if (!children.Any()) + return; + + var havePrimaryKeys = table.Type.Columns.Any(c => c.IsPrimaryKey); + + var handlers = new List(); + + foreach (var child in children) + { + // the reverse child is the association seen from the child + // we're going to use it... + var reverseChild = schema.GetReverseAssociation(child); + // ... to get the parent name + var memberName = reverseChild.Member; + + var sendPropertyChanging = new CodeExpressionStatement( + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression(thisReference, "SendPropertyChanging"))); + + var attach = new CodeMemberMethod() { + Name = child.Member + "_Attach", + Parameters = { + new CodeParameterDeclarationExpression(child.Type, "entity"), + }, + }; + handlers.Add(attach); + if (havePrimaryKeys) + attach.Statements.Add(sendPropertyChanging); + attach.Statements.Add( + new CodeAssignStatement( + new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("entity"), memberName), + thisReference)); + + var detach = new CodeMemberMethod() { + Name = child.Member + "_Detach", + Parameters = { + new CodeParameterDeclarationExpression(child.Type, "entity"), + }, + }; + handlers.Add(detach); + if (havePrimaryKeys) + detach.Statements.Add(sendPropertyChanging); + detach.Statements.Add( + new CodeAssignStatement( + new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("entity"), memberName), + new CodePrimitiveExpression(null))); + } + + if (handlers.Count == 0) + return; + + handlers.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Attachment handlers")); + handlers.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null)); + entity.Members.AddRange(handlers.ToArray()); + } + + void GenerateEntityParents(CodeTypeDeclaration entity, Table table, Database schema) + { + var parents = table.Type.Associations.Where(a => a.IsForeignKey); + if (!parents.Any()) + return; + + var parentMembers = new List(); + + foreach (var parent in parents) + { + bool hasDuplicates = (from p in parents where p.Member == parent.Member select p).Count() > 1; + // WriteClassParent(writer, parent, hasDuplicates, schema, context); + // the following is apparently useless + DbLinq.Schema.Dbml.Table targetTable = schema.Tables.FirstOrDefault(t => t.Type.Name == parent.Type); + if (targetTable == null) + { + //Logger.Write(Level.Error, "ERROR L191 target table type not found: " + parent.Type + " (processing " + parent.Name + ")"); + continue; + } + + string member = parent.Member; + string storageField = GetStorageFieldName(parent); + // TODO: remove this + if (member == parent.ThisKey) + { + member = parent.ThisKey + targetTable.Type.Name; //repeat name to prevent collision (same as Linq) + storageField = "_x_" + parent.Member; + } + + var parentType = new CodeTypeReference(targetTable.Type.Name); + entity.Members.Add(new CodeMemberField(new CodeTypeReference("EntityRef", parentType), storageField) { + InitExpression = new CodeObjectCreateExpression(new CodeTypeReference("EntityRef", parentType)), + }); + + var parentName = hasDuplicates + ? member + "_" + string.Join("", parent.TheseKeys.ToArray()) + : member; + var property = new CodeMemberProperty() { + Name = parentName, + Type = parentType, + Attributes = ToMemberAttributes(parent), + CustomAttributes = { + new CodeAttributeDeclaration("Association", + new CodeAttributeArgument("Storage", new CodePrimitiveExpression(storageField)), + new CodeAttributeArgument("OtherKey", new CodePrimitiveExpression(parent.OtherKey)), + new CodeAttributeArgument("ThisKey", new CodePrimitiveExpression(parent.ThisKey)), + new CodeAttributeArgument("Name", new CodePrimitiveExpression(parent.Name)), + new CodeAttributeArgument("IsForeignKey", new CodePrimitiveExpression(parent.IsForeignKey))), + new CodeAttributeDeclaration("DebuggerNonUserCode"), + }, + }; + parentMembers.Add(property); + property.GetStatements.Add(new CodeMethodReturnStatement( + new CodePropertyReferenceExpression( + new CodeFieldReferenceExpression(thisReference, storageField), + "Entity"))); + + // algorithm is: + // 1.1. must be different than previous value + // 1.2. or HasLoadedOrAssignedValue is false (but why?) + // 2. implementations before change + // 3. if previous value not null + // 3.1. place parent in temp variable + // 3.2. set [Storage].Entity to null + // 3.3. remove it from parent list + // 4. assign value to [Storage].Entity + // 5. if value is not null + // 5.1. add it to parent list + // 5.2. set FK members with entity keys + // 6. else + // 6.1. set FK members to defaults (null or 0) + // 7. implementationas after change + var otherAssociation = schema.GetReverseAssociation(parent); + var parentEntity = new CodePropertyReferenceExpression( + new CodeFieldReferenceExpression(thisReference, storageField), + "Entity"); + var parentTable = schema.Tables.Single(t => t.Type.Associations.Contains(parent)); + var childKeys = parent.TheseKeys.ToArray(); + var childColumns = (from ck in childKeys select table.Type.Columns.Single(c => c.Member == ck)) + .ToArray(); + var parentKeys = parent.OtherKeys.ToArray(); + property.SetStatements.Add(new CodeConditionStatement( + // 1.1 + ValuesAreNotEqual_Ref(parentEntity, new CodePropertySetValueReferenceExpression()), + // 2. TODO: code before the change + // 3. + new CodeConditionStatement( + ValueIsNotNull(parentEntity), + // 3.1 + new CodeVariableDeclarationStatement(parentType, "previous" + parent.Type, parentEntity), + // 3.2 + new CodeAssignStatement(parentEntity, new CodePrimitiveExpression(null)), + // 3.3 + new CodeExpressionStatement( + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression( + new CodePropertyReferenceExpression( + new CodeVariableReferenceExpression("previous" + parent.Type), + otherAssociation.Member), + "Remove"), + thisReference))), + // 4. + new CodeAssignStatement(parentEntity, new CodePropertySetValueReferenceExpression()), + // 5. if value is null or not... + new CodeConditionStatement( + ValueIsNotNull(new CodePropertySetValueReferenceExpression()), + // 5.1 + new CodeStatement[]{ + new CodeExpressionStatement( + new CodeMethodInvokeExpression( + new CodeMethodReferenceExpression( + new CodePropertyReferenceExpression( + new CodePropertySetValueReferenceExpression(), + otherAssociation.Member), + "Add"), + thisReference)) + // 5.2 + }.Concat(Enumerable.Range(0, parentKeys.Length).Select(i => + (CodeStatement) new CodeAssignStatement( + new CodeVariableReferenceExpression(GetStorageFieldName(childColumns[i])), + new CodePropertyReferenceExpression( + new CodePropertySetValueReferenceExpression(), + parentKeys[i])) + )).ToArray(), + // 6. + Enumerable.Range(0, parentKeys.Length).Select(i => { + var column = parentTable.Type.Columns.Single(c => c.Member == childKeys[i]); + return (CodeStatement) new CodeAssignStatement( + new CodeVariableReferenceExpression(GetStorageFieldName(childColumns[i])), + column.CanBeNull + ? (CodeExpression) new CodePrimitiveExpression(null) + : (CodeExpression) new CodeDefaultValueExpression(new CodeTypeReference(column.Type))); + }).ToArray()) + // 7: TODO + )); + } + + if (parentMembers.Count == 0) + return; + parentMembers.First().StartDirectives.Add(new CodeRegionDirective(CodeRegionMode.Start, "Parents")); + parentMembers.Last().EndDirectives.Add(new CodeRegionDirective(CodeRegionMode.End, null)); + entity.Members.AddRange(parentMembers.ToArray()); + } + } +} diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs index 36dc76c68d8..8a9eb415f44 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/CodeWriter.cs @@ -139,15 +139,18 @@ namespace DbMetal.Generator using (WriteEnum(specificationDefinition, name)) { var orderedValues = from nv in values orderby nv.Value select nv; - int currentValue = 1; + int currentValue = 1, counter = 0; foreach (var nameValue in orderedValues) { + + var suffix = ++counter < orderedValues.Count() ? "," : ""; + if (nameValue.Value == currentValue) - WriteLine(string.Format("{0},", nameValue.Key)); + WriteLine(string.Format("{0}{1}", nameValue.Key, suffix)); else { currentValue = nameValue.Value; - WriteLine(string.Format("{0} = {1},", nameValue.Key, nameValue.Value)); + WriteLine(string.Format("{0} = {1}{2}", nameValue.Key, nameValue.Value, suffix)); } currentValue++; } diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs index 3a8c5806c5e..ecae22bee6a 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/ISchemaLoaderFactory.cs @@ -39,13 +39,6 @@ namespace DbMetal.Generator /// ISchemaLoader Load(Parameters parameters); - /// - /// loads a ISchemaLoader from a provider id string (used by schema loader) - /// - /// - /// - ISchemaLoader Load(string provider); - /// /// given a schemaLoaderType and dbConnType /// (e.g. DbLinq.Oracle.OracleSchemaLoader and System.Data.OracleClient.OracleConnection), diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs index 7f5369a0e9b..00c0350fd94 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CSCodeGenerator.cs @@ -34,8 +34,8 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator #endif class CSCodeGenerator : CodeGenerator { - public override string LanguageCode { get { return "C#"; } } - public override string Extension { get { return ".cs"; } } + public override string LanguageCode { get { return "obsolete-c#"; } } + public override string Extension { get { return ".obsolete-cs"; } } protected override CodeWriter CreateCodeWriter(TextWriter textWriter) { diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs index 345129abf0d..cd41a57c30f 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.Class.cs @@ -76,8 +76,6 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator var tableAttribute = NewAttributeDefinition(); tableAttribute["Name"] = table.Name; - //using (WriteAttributes(writer, context.Parameters.EntityExposedAttributes)) - using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.EntityExposedAttributes))) using (writer.WriteAttribute(tableAttribute)) using (writer.WriteClass(specifications, table.Type.Name, entityBase, context.Parameters.EntityInterfaces)) @@ -86,7 +84,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator WriteCustomTypes(writer, table, schema, context); WriteClassExtensibilityDeclarations(writer, table, context); WriteClassProperties(writer, table, context); - if (context.Parameters.GenerateEqualsAndHash) + if (context.Parameters.GenerateEqualsHash) WriteClassEqualsAndHash(writer, table, context); WriteClassChildren(writer, table, schema, context); WriteClassParents(writer, table, schema, context); @@ -119,13 +117,12 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator var member = writer.GetVariableExpression(primaryKey.Storage); string primaryKeyHashCode = writer.GetMethodCallExpression(writer.GetMemberExpression(member, "GetHashCode")); if (primaryKey.CanBeNull - || primaryKey.ExtendedType == null || GetType(primaryKey.Type, false).IsClass) // this patch to ensure that even if DB does not allow nulls, // our in-memory object won't generate a fault { var isNullExpression = writer.GetEqualExpression(member, writer.GetNullExpression()); var nullExpression = writer.GetLiteralValue(0); - primaryKeyHashCode = writer.GetTernaryExpression(isNullExpression, nullExpression, primaryKeyHashCode); + primaryKeyHashCode = "(" + writer.GetTernaryExpression(isNullExpression, nullExpression, primaryKeyHashCode) + ")"; } if (string.IsNullOrEmpty(hashCode)) hashCode = primaryKeyHashCode; @@ -154,9 +151,14 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator foreach (var primaryKey in primaryKeys) { var member = writer.GetVariableExpression(primaryKey.Storage); - string primaryKeyTest = writer.GetMethodCallExpression(writer.GetMemberExpression(writer.GetLiteralType(typeof(object)), "Equals"), - member, - writer.GetMemberExpression(other, member)); + string primaryKeyTest = writer.GetMethodCallExpression( + writer.GetMemberExpression( + writer.GetMemberExpression( + writer.GetGenericName("System.Collections.Generic.EqualityComparer", primaryKey.Type), + "Default"), + "Equals"), + member, + writer.GetMemberExpression(other, member)); if (string.IsNullOrEmpty(andExpression)) andExpression = primaryKeyTest; else @@ -269,7 +271,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator /// /// /// - protected virtual string[] GetAttributeNames(GenerationContext context, string[] attributes) + protected virtual string[] GetAttributeNames(GenerationContext context, IEnumerable attributes) { return (from a in attributes select GetName(a)).ToArray(); } @@ -325,7 +327,7 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator specifications |= GetSpecificationDefinition(property.Modifier); //using (WriteAttributes(writer, context.Parameters.MemberExposedAttributes)) - using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberExposedAttributes))) + using (WriteAttributes(writer, GetAttributeNames(context, context.Parameters.MemberAttributes))) using (writer.WriteAttribute(NewAttributeDefinition())) using (writer.WriteAttribute(column)) using (writer.WriteProperty(specifications, property.Member, GetTypeOrExtendedType(writer, property))) diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs index bc3a7e28b70..690f04702f9 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/CodeTextGenerator/CodeGenerator.cs @@ -177,12 +177,8 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator implementation.WriteHeader(writer, context); // write namespaces for members attributes - foreach (var memberExposedAttribute in context.Parameters.MemberExposedAttributes) - WriteUsingNamespace(writer, GetNamespace(memberExposedAttribute)); - - // write namespaces for clases attributes - foreach (var entityExposedAttribute in context.Parameters.EntityExposedAttributes) - WriteUsingNamespace(writer, GetNamespace(entityExposedAttribute)); + foreach (var memberAttribute in context.Parameters.MemberAttributes) + WriteUsingNamespace(writer, GetNamespace(memberAttribute)); writer.WriteLine(); } @@ -224,12 +220,10 @@ namespace DbMetal.Generator.Implementation.CodeTextGenerator string contextBase = schema.BaseType; - var contextBaseType = TypeLoader.Load(contextBase); - // if we don't specify a base type, use the default - if (string.IsNullOrEmpty(contextBase)) - { - contextBaseType = typeof(DataContext); - } + var contextBaseType = string.IsNullOrEmpty(contextBase) + ? typeof(DataContext) + : TypeLoader.Load(contextBase); + // in all cases, get the literal type name from loaded type contextBase = writer.GetLiteralType(contextBaseType); diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs index 5a93e5031d5..f3dee040a33 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/Processor.cs @@ -72,37 +72,31 @@ namespace DbMetal.Generator.Implementation { var parameters = new Parameters { Log = Log }; - if (args.Length == 0) - PrintUsage(parameters); + parameters.WriteHeader(); - else + try { - parameters.WriteHeader(); - - try - { - parameters.Parse(args); - } - catch (Exception e) - { - Output.WriteErrorLine(Log, e.Message); - PrintUsage(parameters); - return; - } + parameters.Parse(args); + } + catch (Exception e) + { + Output.WriteErrorLine(Log, e.Message); + PrintUsage(parameters); + return; + } - if (parameters.Help) - { - PrintUsage(parameters); - return; - } + if (args.Length == 0 || parameters.Help) + { + PrintUsage(parameters); + return; + } - ProcessSchema(parameters); + ProcessSchema(parameters); - if (parameters.ReadLineAtExit) - { - // '-readLineAtExit' flag: useful when running from Visual Studio - Console.ReadKey(); - } + if (parameters.Readline) + { + // '-readLineAtExit' flag: useful when running from Visual Studio + Console.ReadKey(); } } @@ -114,14 +108,47 @@ namespace DbMetal.Generator.Implementation ISchemaLoader schemaLoader; // then we load the schema var dbSchema = ReadSchema(parameters, out schemaLoader); + + if (!SchemaIsValid(dbSchema)) + return; + // the we write it (to DBML or code) WriteSchema(dbSchema, schemaLoader, parameters); } catch (Exception ex) { string assemblyName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; - Output.WriteErrorLine(Log, assemblyName + " failed:" + ex); + Log.WriteErrorLine(assemblyName + ": {0}", parameters.Debug ? ex.ToString() : ex.Message); + } + } + + bool SchemaIsValid(Database database) + { + bool error = false; + foreach (var table in database.Tables) + { + error = ValidateAssociations(database, table) || error; } + return !error; + } + + bool ValidateAssociations(Database database, Table table) + { + bool error = false; + foreach (var association in table.Type.Associations) + { + var otherType = database.Tables.Single(t => t.Type.Name == association.Type).Type; + var otherAssociation = otherType.Associations.Single(a => a.Type == table.Type.Name && a.ThisKey == association.OtherKey); + var otherColumn = otherType.Columns.Single(c => c.Member == association.OtherKey); + + if (association.CardinalitySpecified && association.Cardinality == Cardinality.Many && association.IsForeignKey) + { + error = true; + Log.WriteErrorLine("Error DBML1059: The IsForeignKey attribute of the Association element '{0}' of the Type element '{1}' cannnot be '{2}' when the Cardinality attribute is '{3}'.", + association.Name, table.Type.Name, association.IsForeignKey, association.Cardinality); + } + } + return error; } protected void WriteSchema(Database dbSchema, ISchemaLoader schemaLoader, Parameters parameters) @@ -147,9 +174,6 @@ namespace DbMetal.Generator.Implementation if (string.IsNullOrEmpty(filename)) filename = dbSchema.Name; - // TODO: move such check to runtime. - schemaLoader.CheckNamesSafety(dbSchema); - parameters.Write("<<< writing C# classes in file '{0}'", filename); GenerateCode(parameters, dbSchema, schemaLoader, filename); @@ -182,7 +206,7 @@ namespace DbMetal.Generator.Implementation protected virtual ICodeGenerator FindCodeGeneratorByExtension(string extension) { - return EnumerateCodeGenerators().SingleOrDefault(gen => gen.Extension == extension); + return EnumerateCodeGenerators().SingleOrDefault(gen => gen.Extension == extension.ToLowerInvariant()); } public virtual ICodeGenerator FindCodeGenerator(Parameters parameters, string filename) @@ -194,9 +218,10 @@ namespace DbMetal.Generator.Implementation public void GenerateCode(Parameters parameters, Database dbSchema, ISchemaLoader schemaLoader, string filename) { - ICodeGenerator codeGenerator = FindCodeGenerator(parameters, filename); - if (codeGenerator == null) - throw new ArgumentException("Please specify either a /language or a /code file"); + ICodeGenerator codeGenerator = FindCodeGenerator(parameters, filename) ?? + (string.IsNullOrEmpty(parameters.Language) + ? CodeDomGenerator.CreateFromFileExtension(Path.GetExtension(filename)) + : CodeDomGenerator.CreateFromLanguage(parameters.Language)); if (string.IsNullOrEmpty(filename)) filename = dbSchema.Class; @@ -232,7 +257,8 @@ namespace DbMetal.Generator.Implementation else // load DBML { dbSchema = ReadSchema(parameters, parameters.SchemaXmlFile); - schemaLoader = SchemaLoaderFactory.Load(dbSchema.Provider); + parameters.Provider = parameters.Provider ?? dbSchema.Provider; + schemaLoader = SchemaLoaderFactory.Load(parameters); } if (schemaLoader == null) diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs index cd06ffd4157..fe8662c0599 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Generator/Implementation/SchemaLoaderFactory.cs @@ -60,27 +60,9 @@ namespace DbMetal.Generator.Implementation string databaseConnectionType; string sqlDialectType; GetLoaderAndConnection(parameters, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType); - if (dbLinqSchemaLoaderType == null) - throw new ApplicationException("Please provide -Provider=MySql (or Oracle, OracleODP, PostgreSql, Sqlite - see app.config for provider listing)"); return Load(parameters, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType); } - /// - /// loads a ISchemaLoader from a provider id string (used by schema loader) - /// - /// - /// - public ISchemaLoader Load(string provider) - { - string dbLinqSchemaLoaderType; - string databaseConnectionType; - string sqlDialectType; - GetLoaderAndConnection(provider, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType); - if (dbLinqSchemaLoaderType == null) - return null; - return Load(null, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType); - } - /// /// given a schemaLoaderType and dbConnType /// (e.g. DbLinq.Oracle.OracleSchemaLoader and System.Data.OracleClient.OracleConnection), @@ -140,106 +122,20 @@ namespace DbMetal.Generator.Implementation public ISchemaLoader Load(Parameters parameters, string dbLinqSchemaLoaderTypeName, string databaseConnectionTypeName, string sqlDialectTypeName) { - AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; Type dbLinqSchemaLoaderType = Type.GetType(dbLinqSchemaLoaderTypeName); Type databaseConnectionType = Type.GetType(databaseConnectionTypeName); Type sqlDialectType = string.IsNullOrEmpty(sqlDialectTypeName) ? null : Type.GetType(sqlDialectTypeName); if (dbLinqSchemaLoaderType == null) - throw new ArgumentException("Unable to resolve dbLinqSchemaLoaderType: " + dbLinqSchemaLoaderTypeName); + throw new ArgumentException("Could not load dbLinqSchemaLoaderType type '" + dbLinqSchemaLoaderTypeName + "'. Try using the --with-schema-loader=TYPE option."); if (databaseConnectionType == null) - throw new ArgumentException("Unable to resolve databaseConnectionType: " + databaseConnectionTypeName); + throw new ArgumentException("Could not load databaseConnectionType type '" + databaseConnectionTypeName + "'. Try using the --with-dbconnection=TYPE option."); ISchemaLoader loader = Load(parameters, dbLinqSchemaLoaderType, databaseConnectionType, sqlDialectType); - AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve; return loader; } - private Assembly LoadAssembly(string path) - { - if (File.Exists(path)) - return Assembly.LoadFile(path); - return null; - } - - private Assembly LoadAssembly(string baseName, string path) - { - string basePath = Path.Combine(path, baseName); - Assembly assembly = LoadAssembly(basePath + ".dll"); - if (assembly == null) - assembly = LoadAssembly(basePath + ".exe"); - return assembly; - } - - private Assembly LocalLoadAssembly(string baseName) - { - Assembly assembly = LoadAssembly(baseName, Directory.GetCurrentDirectory()); - if (assembly == null) { - var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase); - assembly = LoadAssembly(baseName, path); - } - return assembly; - } - - private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) - { - // try to load from within the current AppDomain - IList assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (Assembly loadedAssembly in assemblies) - { - if (loadedAssembly.GetName().Name == args.Name) - return loadedAssembly; - } - var assembly = LocalLoadAssembly(args.Name); - if (assembly == null) - assembly = GacLoadAssembly(args.Name); - return assembly; - } - - /// - /// This is dirty, and must not be used in production environment - /// - /// - /// - private Assembly GacLoadAssembly(string shortName) - { - var systemRoot = Environment.GetEnvironmentVariable("SystemRoot"); - string assemblyDirectory = Path.Combine(systemRoot, "Assembly"); - var assembly = GacLoadAssembly(shortName, Path.Combine(assemblyDirectory, "GAC_MSIL")); - if (assembly == null) - assembly = GacLoadAssembly(shortName, Path.Combine(assemblyDirectory, "GAC_32")); - if (assembly == null) - assembly = GacLoadAssembly(shortName, Path.Combine(assemblyDirectory, "GAC")); - return assembly; - } - - private Assembly GacLoadAssembly(string shortName, string directory) - { - string assemblyDirectory = Path.Combine(directory, shortName); - if (Directory.Exists(assemblyDirectory)) - { - Version latestVersion = null; - string latestVersionDirectory = null; - foreach (string versionDirectory in Directory.GetDirectories(assemblyDirectory)) - { - var testVersion = new Version(Path.GetFileName(versionDirectory).Split('_')[0]); - if (latestVersion == null || testVersion.CompareTo(latestVersion) > 0) - { - latestVersion = testVersion; - latestVersionDirectory = versionDirectory; - } - } - if (latestVersionDirectory != null) - { - string assemblyPath = Path.Combine(latestVersionDirectory, shortName + ".dll"); - if (File.Exists(assemblyPath)) - return Assembly.LoadFile(assemblyPath); - } - } - return null; - } - - protected void GetLoaderAndConnection(string provider, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType) + private void GetLoaderAndConnection(string provider, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType) { var configuration = (ProvidersSection)ConfigurationManager.GetSection("providers"); @@ -247,8 +143,7 @@ namespace DbMetal.Generator.Implementation string errorMsg = null; if (configuration == null || !configuration.Providers.TryGetProvider(provider, out element, out errorMsg)) { - Output.WriteErrorLine(Log, "Failed to load provider {0} : {1}", provider, errorMsg); - throw new ApplicationException("Failed to load provider " + provider); + throw new ApplicationException(string.Format("Failed to load provider {0}: {1}", provider, errorMsg)); } //var element = configuration.Providers.GetProvider(provider); @@ -260,22 +155,33 @@ namespace DbMetal.Generator.Implementation protected void GetLoaderAndConnection(Parameters parameters, out string dbLinqSchemaLoaderType, out string databaseConnectionType, out string sqlDialectType) { + dbLinqSchemaLoaderType = databaseConnectionType = sqlDialectType = null; + if (!string.IsNullOrEmpty(parameters.Provider)) { GetLoaderAndConnection(parameters.Provider, out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType); } - else + else if (!string.IsNullOrEmpty(parameters.DbLinqSchemaLoaderProvider) && + !string.IsNullOrEmpty(parameters.DatabaseConnectionProvider) && + !string.IsNullOrEmpty(parameters.SqlDialectType)) { - dbLinqSchemaLoaderType = parameters.DbLinqSchemaLoaderProvider; - databaseConnectionType = parameters.DatabaseConnectionProvider; - sqlDialectType = parameters.SqlDialectType; + // User manually specified everything we need; don't bother with the + // default .exe.config provider lookup } - if (string.IsNullOrEmpty(dbLinqSchemaLoaderType)) + else { // No provider specified, not explicitly provided either // Default to using SQL Server for sqlmetal.exe compatibility GetLoaderAndConnection("SqlServer", out dbLinqSchemaLoaderType, out databaseConnectionType, out sqlDialectType); } + + // Allow command-line options to override the .exe.config file. + if (!string.IsNullOrEmpty(parameters.DbLinqSchemaLoaderProvider)) + dbLinqSchemaLoaderType = parameters.DbLinqSchemaLoaderProvider; + if (!string.IsNullOrEmpty(parameters.DatabaseConnectionProvider)) + databaseConnectionType = parameters.DatabaseConnectionProvider; + if (!string.IsNullOrEmpty(parameters.SqlDialectType)) + sqlDialectType = parameters.SqlDialectType; } } diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs b/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs index 9d6eb21255c..c9bd728c20d 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Parameters.cs @@ -41,70 +41,62 @@ namespace DbMetal { /// /// user name for database access - /// SQLMetal compatible /// public string User { get; set; } /// /// user password for database access - /// SQLMetal compatible /// public string Password { get; set; } /// /// server host name - /// SQLMetal compatible /// public string Server { get; set; } /// /// database name - /// SQLMetal compatible /// public string Database { get; set; } /// /// This connection string if present overrides User, Password, Server. /// Database is always used to generate the specific DataContext name - /// SQLMetal compatible /// public string Conn { get; set; } /// /// the namespace to put our classes into - /// SQLMetal compatible /// public string Namespace { get; set; } /// /// the language to generate classes for - /// SQLMetal compatible /// public string Language { get; set; } /// /// If present, write out C# code - /// SQLMetal compatible /// public string Code { get; set; } /// - /// If present, write out DBML XML representing the DB - /// SQLMetal compatible + /// if present, write out DBML XML representing the DB /// public string Dbml { get; set; } /// /// when true, we will call Singularize()/Pluralize() functions. - /// SQLMetal compatible /// public bool Pluralize { get; set; } + /// + /// the culture used for word recognition and pluralization + /// public string Culture { get; set; } /// - /// Load object renamings from an xml file - /// DbLinq specific + /// load object renamings from an xml file /// public string Aliases { get; set; } @@ -123,93 +115,84 @@ namespace DbMetal /// /// base class from which all generated entities will inherit - /// SQLMetal compatible /// public string EntityBase { get; set; } /// - /// Interfaces to be implemented + /// interfaces to be implemented /// public string[] EntityInterfaces { get; set; } /// - /// Extra attributes to be implemented by class - /// - public string EntityAttributes { get; set; } - public string[] EntityExposedAttributes { get { return GetArray(EntityAttributes); } } - - /// - /// Extra attributes to be implemented by class + /// extra attributes to be implemented by class members /// - public string MemberAttributes { get; set; } - public string[] MemberExposedAttributes { get { return GetArray(MemberAttributes); } } + public IList MemberAttributes { get; set; } /// - /// base class from which all generated entities will inherit - /// SQLMetal compatible + /// generate Equals() and GetHashCode() /// - public bool GenerateEqualsAndHash { get; set; } + public bool GenerateEqualsHash { get; set; } /// /// export stored procedures - /// SQLMetal compatible /// public bool Sprocs { get; set; } /// /// preserve case of database names - /// DbLinq specific /// public string Case { get; set; } - bool useDomainTypes = true; - - /// - /// if true, and PostgreSql database contains DOMAINS (typedefs), - /// we will generate code DbType='DerivedType'. - /// if false, generate code DbType='BaseType'. - /// DbLinq specific - /// - public bool UseDomainTypes - { - get { return useDomainTypes; } - set { useDomainTypes = value; } - } - /// /// force a Console.ReadKey at end of program. /// Useful when running from Studio, so the output window does not disappear /// picrap comment: you may use the tool to write output to Visual Studio output window instead of a console window - /// DbLinq specific /// - public bool ReadLineAtExit { get; set; } + public bool Readline { get; set; } /// /// specifies a provider (which here is a pair or ISchemaLoader and IDbConnection implementors) - /// SQLMetal compatible /// public string Provider { get; set; } /// - /// For fine tuning, we allow to specifiy an ISchemaLoader - /// DbLinq specific + /// for fine tuning, we allow to specifiy an ISchemaLoader /// public string DbLinqSchemaLoaderProvider { get; set; } /// - /// For fine tuning, we allow to specifiy an IDbConnection - /// DbLinq specific + /// for fine tuning, we allow to specifiy an IDbConnection /// public string DatabaseConnectionProvider { get; set; } + /// + /// the SQL dialect used by the database + /// public string SqlDialectType { get; set; } + /// + /// the types to be generated + /// public IList GenerateTypes { get; set; } + /// + /// if true, put a timestamp comment before the generated code + /// public bool GenerateTimestamps { get; set; } + /// + /// show help + /// public bool Help { get; set; } + /// + /// Show stack traces in error messages, etc., instead of just the message. + /// + public bool Debug { get; set; } + + /// + /// non-option parameters + /// public IList Extra = new List(); TextWriter log; @@ -227,111 +210,113 @@ namespace DbMetal Schema = true; Culture = "en"; GenerateTypes = new List(); + MemberAttributes = new List(); GenerateTimestamps = true; EntityInterfaces = new []{ "INotifyPropertyChanging", "INotifyPropertyChanged" }; } - /// - /// Converts a list separated by a comma to a string array - /// - /// - /// - public string[] GetArray(string list) - { - if (string.IsNullOrEmpty(list)) - return new string[0]; - return (from entityInterface in list.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) - select entityInterface.Trim()).ToArray(); - } - public void Parse(IList args) { Options = new OptionSet() { + // SQLMetal compatible { "c|conn=", "Database {CONNECTION STRING}. Cannot be used with /server, " +"/user or /password options.", conn => Conn = conn }, + // SQLMetal compatible { "u|user=", "Login user {NAME}.", name => User = name }, + // SQLMetal compatible { "p|password=", "Login {PASSWORD}.", password => Password = password }, + // SQLMetal compatible { "s|server=", "Database server {NAME}.", name => Server = name }, + // SQLMetal compatible { "d|database=", "Database catalog {NAME} on server.", name => Database = name }, { "provider=", "Specify {PROVIDER}. May be Ingres, MySql, Oracle, OracleODP, PostgreSql or Sqlite.", provider => Provider = provider }, - { "dbLinqSchemaLoaderProvider=", - "Specify a custom ISchemaLoader implementation {TYPE}.", + { "with-schema-loader=", + "ISchemaLoader implementation {TYPE}.", type => DbLinqSchemaLoaderProvider = type }, - { "databaseConnectionProvider=", - "Specify a custom IDbConnection implementation {TYPE}.", + { "with-dbconnection=", + "IDbConnection implementation {TYPE}.", type => DatabaseConnectionProvider = type }, - { "sqlDialectType=", - "The IVendor implementation {TYPE}.", + { "with-sql-dialect=", + "IVendor implementation {TYPE}.", type => SqlDialectType = type }, + // SQLMetal compatible { "code=", "Output as source code to {FILE}. Cannot be used with /dbml option.", file => Code = file }, + // SQLMetal compatible { "dbml=", "Output as dbml to {FILE}. Cannot be used with /map option.", file => Dbml = file }, + // SQLMetal compatible { "language=", "Language {NAME} for source code: C#, C#2 or VB " +"(default: derived from extension on code file name).", name => Language = name }, - { "aliases|renamesFile=", + { "aliases=", "Use mapping {FILE}.", file => Aliases = file }, { "schema", - "Generate schema in code files (default='true').", - v => Schema = v != null}, + "Generate schema in code files (default: enabled).", + v => Schema = v != null }, + // SQLMetal compatible { "namespace=", "Namespace {NAME} of generated code (default: no namespace).", name => Namespace = name }, - { "entityBase=", + // SQLMetal compatible + { "entitybase=", "Base {TYPE} of entity classes in the generated code " +"(default: entities have no base class).", type => EntityBase = type }, - { "entityAttributes=", - "Comma separated {ATTRIBUTE(S)} of entity classes in the generated code.", - attributes => EntityAttributes = attributes }, - { "memberAttributes=", - "Comma separated {ATTRIBUTE(S)} of entity members in the generated code.", - attributes => MemberAttributes = attributes }, + { "member-attribute=", + "{ATTRIBUTE} for entity members in the generated code, " + +"can be specified multiple times.", + attribute => MemberAttributes.Add(attribute) }, { "generate-type=", "Generate only the {TYPE} selected, can be specified multiple times " +"and does not prevent references from being generated (default: " +"generate a DataContex subclass and all the entities in the schema).", type => GenerateTypes.Add(type) }, - { "generateEqualsAndHash", + { "generate-equals-hash", "Generates overrides for Equals() and GetHashCode() methods.", - v => GenerateEqualsAndHash = v != null}, + v => GenerateEqualsHash = v != null }, + // SQLMetal compatible { "sprocs", "Extract stored procedures.", v => Sprocs = v != null}, + // SQLMetal compatible { "pluralize", "Automatically pluralize or singularize class and member names " +"using specified culture rules.", v => Pluralize = v != null}, { "culture=", - "Specify {CULTURE} for word recognition and pluralization (default=\"en\").", + "Specify {CULTURE} for word recognition and pluralization (default: \"en\").", culture => Culture = culture }, { "case=", "Transform names with the indicated {STYLE} " +"(default: net; may be: leave, pascal, camel, net).", style => Case = style }, { "generate-timestamps", - "Generate timestampes in the generated code. True by default.", + "Generate timestampes in the generated code (default: enabled).", v => GenerateTimestamps = v != null }, - { "readlineAtExit", + { "readline", "Wait for a key to be pressed after processing.", - v => ReadLineAtExit = v != null }, + v => Readline = v != null }, + { "debug", + "Enables additional information to help with debugging, " + + "such as full stack traces in error messages.", + v => Debug = v != null }, { "h|?|help", "Show this help", v => Help = v != null } diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs index 8bf4086f27e..6ca42bc77db 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Properties/AssemblyInfo.cs @@ -41,13 +41,4 @@ using DbLinq.Factory; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("7ae782c4-e495-44ff-821d-8580dbe184d4")] -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyFileVersion("0.19")] - [assembly: DbLinq] diff --git a/mcs/class/System.Data.Linq/src/DbMetal/SqlMetal.csproj b/mcs/class/System.Data.Linq/src/DbMetal/SqlMetal.csproj index ef0399ae348..65c1a81eab1 100755 --- a/mcs/class/System.Data.Linq/src/DbMetal/SqlMetal.csproj +++ b/mcs/class/System.Data.Linq/src/DbMetal/SqlMetal.csproj @@ -63,13 +63,11 @@ Properties\DbLinq.ProductInfo.cs - + - - @@ -162,15 +160,18 @@ - - rem this is what I call loose coupling -copy "$(SolutionDir)..\lib\Npgsql.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\Mono.Security.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\Ingres.Stereo.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\Oracle.DataAccess.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\MySql.Data.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\System.Data.SQLite.dll" "$(TargetDir)" -copy "$(SolutionDir)..\lib\FirebirdSql.Data.FirebirdClient.dll" "$(TargetDir)" - - - \ No newline at end of file + + + + + + + + + + + + + diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/AppRunner.cs b/mcs/class/System.Data.Linq/src/DbMetal/Test/AppRunner.cs new file mode 100755 index 00000000000..6d402273566 --- /dev/null +++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/AppRunner.cs @@ -0,0 +1,108 @@ +#region MIT license +// +// MIT license +// +// Copyright (c) 2010 Novell, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +#endregion + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using DbMetal; +using NUnit.Framework; + +namespace DbMetal_Test_Sqlite +{ + class DbMetalAppDomainSetup : MarshalByRefObject + { + public void SetStandardError(TextWriter stderr) + { + Console.SetError(stderr); + } + + public void Run(string[] args) + { + Program.Main(args); + } + } + + static class AppRunner + { +#if MONO_STRICT + const string Program = "sqlmetal"; + const string DbConnectionProvider = "Mono.Data.Sqlite.SqliteConnection, Mono.Data.Sqlite"; + const string DbLinqSchemaLoader = "DbLinq.Vendor.DbSchemaLoader, System.Data.Linq"; + const string SqlDialect = "DbLinq.Sqlite.SqliteVendor, System.Data.Linq"; +#else + const string Program = "DbMetal"; + const string DbConnectionProvider = "System.Data.SQLite.SQLiteConnection, System.Data.SQLite"; + const string DbLinqSchemaLoader = "DbLinq.Vendor.DbSchemaLoader, DbLinq"; + const string SqlDialect = "DbLinq.Sqlite.SqliteVendor, DbLinq.Sqlite"; +#endif + + public static void WithinAppDomain(string expectedFile, string createdFile, IEnumerable args) + { + var bd = AppDomain.CurrentDomain.BaseDirectory; + var info = new AppDomainSetup() + { + ApplicationBase = bd, + ApplicationName = Program + ".exe", + ConfigurationFile = Program + ".exe.config", + }; + AppDomain ad = AppDomain.CreateDomain("DbMetal Sqlite Test", null, info); + var t = typeof(DbMetalAppDomainSetup); + var s = (DbMetalAppDomainSetup)ad.CreateInstanceAndUnwrap(t.Assembly.GetName().Name, t.FullName); + var stderr = new StringWriter(); + s.SetStandardError(stderr); + var testdir = Path.Combine(bd, Path.Combine("..", "tests")); + var expectedDir = Path.Combine(testdir, "expected"); + s.Run(new []{ + "/provider:Sqlite", + "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"), + }.Concat(args).ToArray()); + AppDomain.Unload(ad); + if (stderr.GetStringBuilder().Length != 0) + Console.Error.Write(stderr.GetStringBuilder().ToString()); + Assert.AreEqual(0, stderr.GetStringBuilder().Length); + FileAssert.AreEqual(Path.Combine(expectedDir, string.Format (expectedFile, Program)), createdFile); + File.Delete(createdFile); + } + + public static void WithDbSchemaLoader(string expectedFile, string createdFile, IEnumerable args) + { + var bd = AppDomain.CurrentDomain.BaseDirectory; + var testdir = Path.Combine(bd, Path.Combine("..", "tests")); + var expectedDir = Path.Combine(testdir, "expected"); + + DbMetal.Program.Main(new []{ + "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"), + "--with-dbconnection=" + DbConnectionProvider, + "--with-schema-loader=" + DbLinqSchemaLoader, + "--with-sql-dialect=" + SqlDialect, + }.Concat(args).ToArray()); + + FileAssert.AreEqual(Path.Combine(expectedDir, string.Format(expectedFile, Program)), createdFile); + File.Delete(createdFile); + } + } +} \ No newline at end of file diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateDbmlFromSqliteDbTest.cs b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateDbmlFromSqliteDbTest.cs new file mode 100755 index 00000000000..f3ac66bdc0c --- /dev/null +++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateDbmlFromSqliteDbTest.cs @@ -0,0 +1,55 @@ +#region MIT license +// +// MIT license +// +// Copyright (c) 2010 Novell, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +#endregion + +using System; +using System.IO; +using DbMetal; +using NUnit.Framework; + +namespace DbMetal_Test_Sqlite +{ + [TestFixture] + public class CreateDbmlFromSqliteDbTest + { + [Test] + public void CreateViaProvider() + { + var created = "Northwind.dbml"; + AppRunner.WithinAppDomain("Northwind.Sqlite-{0}.dbml", created, new[]{ + "/dbml:" + created, + }); + } + + [Test] + public void CreateViaDbSchemaLoader() + { + var created = "Northwind.dbml"; + AppRunner.WithDbSchemaLoader("Northwind.Sqlite+DbSchemaLoader-{0}.dbml", created, new[]{ + "/dbml:" + created, + }); + } + } +} diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs index ed3abfaa2ad..cfd87026294 100755 --- a/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs +++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/CreateEntitiesFromSqliteDbTest.cs @@ -31,93 +31,35 @@ using NUnit.Framework; namespace DbMetal_Test_Sqlite { - class DbMetalAppDomainSetup : MarshalByRefObject - { - public void SetStandardError(TextWriter stderr) - { - Console.SetError(stderr); - } - - public void Run(string[] args) - { - Program.Main(args); - } - } - [TestFixture] public class CreateEntitiesFromSqliteDbTest { [Test] public void CreateViaProvider() { -#if MONO_STRICT - var app = "sqlmetal"; -#else - var app = "DbMetal"; -#endif - var bd = AppDomain.CurrentDomain.BaseDirectory; - var info = new AppDomainSetup() - { - ApplicationBase = bd, - ApplicationName = app + ".exe", - ConfigurationFile = app + ".exe.config", - }; - AppDomain ad = AppDomain.CreateDomain("DbMetal Sqlite Test", null, info); - var t = typeof(DbMetalAppDomainSetup); - var s = (DbMetalAppDomainSetup)ad.CreateInstanceAndUnwrap(t.Assembly.GetName().Name, t.FullName); - var stderr = new StringWriter(); - s.SetStandardError(stderr); - var testdir = Path.Combine(bd, Path.Combine("..", "tests")); - var db = Path.Combine(bd, Path.Combine("..", Path.Combine("tests", "Northwind.db3"))); - s.Run(new string[]{ - "/code:Northwind.Sqlite.cs", - "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"), + var created = "Northwind.Sqlite.cs"; + AppRunner.WithinAppDomain("Northwind.Sqlite-{0}.cs", created, new[]{ + "/code:" + created, "/database:Northwind", + "--generate-equals-hash", "--generate-timestamps-", "/namespace:nwind", "/pluralize", - "/provider:Sqlite", }); - AppDomain.Unload(ad); - if (stderr.GetStringBuilder().Length != 0) - Console.Error.Write(stderr.GetStringBuilder().ToString()); - Assert.AreEqual(0, stderr.GetStringBuilder().Length); - FileAssert.AreEqual(Path.Combine(testdir, "Northwind.Expected.Sqlite-" + app + ".cs"), "Northwind.Sqlite.cs"); - File.Delete("Northwind.Sqlite.cs"); } [Test] public void CreateViaDbSchemaLoader() { -#if MONO_STRICT - var app = "sqlmetal"; - var dbConnectionProvider = "Mono.Data.Sqlite.SqliteConnection, Mono.Data.Sqlite"; - var dbLinqSchemaLoader = "DbLinq.Vendor.DbSchemaLoader, System.Data.Linq"; - var sqlDialect = "DbLinq.Sqlite.SqliteVendor, System.Data.Linq"; -#else - var app = "DbMetal"; - var dbConnectionProvider = "System.Data.SQLite.SQLiteConnection, System.Data.SQLite"; - var dbLinqSchemaLoader = "DbLinq.Vendor.DbSchemaLoader, DbLinq"; - var sqlDialect = "DbLinq.Sqlite.SqliteVendor, DbLinq.Sqlite"; -#endif - var bd = AppDomain.CurrentDomain.BaseDirectory; - var testdir = Path.Combine(bd, Path.Combine("..", "tests")); - var expectedDir = Path.Combine(testdir, "expected"); - - Program.Main(new string[]{ - "/code:Northwind.Sqlite.cs", - "/conn:Data Source=" + Path.Combine(testdir, "Northwind.db3"), + var created = "Northwind.Sqlite.cs"; + AppRunner.WithDbSchemaLoader("Northwind.Sqlite+DbSchemaLoader-{0}.cs", created, new[]{ + "/code:" + created, "/database:Northwind", - "/databaseConnectionProvider=" + dbConnectionProvider, - "/dbLinqSchemaLoaderProvider=" + dbLinqSchemaLoader, + "--generate-equals-hash", "--generate-timestamps-", "/namespace:nwind", "/pluralize", - "/sqlDialectType=" + sqlDialect, }); - - FileAssert.AreEqual(Path.Combine(expectedDir, "Northwind.Sqlite+DbSchemaLoader-" + app + ".cs"), "Northwind.Sqlite.cs"); - File.Delete("Northwind.Sqlite.cs"); } } } \ No newline at end of file diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/DbMetal_test_sqlite.csproj b/mcs/class/System.Data.Linq/src/DbMetal/Test/DbMetal_test_sqlite.csproj index 665c8adde76..fb4fd3594c8 100755 --- a/mcs/class/System.Data.Linq/src/DbMetal/Test/DbMetal_test_sqlite.csproj +++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/DbMetal_test_sqlite.csproj @@ -42,6 +42,8 @@ + + diff --git a/mcs/class/System.Data.Linq/src/DbMetal/Test/SqlMetal_test_sqlite.csproj b/mcs/class/System.Data.Linq/src/DbMetal/Test/SqlMetal_test_sqlite.csproj index 99b67ea1b8c..ab31e2c5805 100755 --- a/mcs/class/System.Data.Linq/src/DbMetal/Test/SqlMetal_test_sqlite.csproj +++ b/mcs/class/System.Data.Linq/src/DbMetal/Test/SqlMetal_test_sqlite.csproj @@ -42,6 +42,8 @@ + + diff --git a/mcs/class/System.Data.Linq/src/DbMetal/sqlmetal.exe.config b/mcs/class/System.Data.Linq/src/DbMetal/sqlmetal.exe.config index 66337327ae5..4ba59b2321f 100644 --- a/mcs/class/System.Data.Linq/src/DbMetal/sqlmetal.exe.config +++ b/mcs/class/System.Data.Linq/src/DbMetal/sqlmetal.exe.config @@ -13,7 +13,7 @@ - + diff --git a/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs index 8b6d0f969f6..d869a5bf033 100644 --- a/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/Tools/NUnitRunner/Properties/AssemblyInfo.cs @@ -21,16 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("2e39c94e-8988-41cf-a6a4-81a82fa02066")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs b/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs index 6cbd4fbe3b2..57032638bcf 100644 --- a/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs +++ b/mcs/class/System.Data.Linq/src/Tools/TestNamespaceWriter/Properties/AssemblyInfo.cs @@ -21,16 +21,3 @@ using System.Runtime.InteropServices; // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("a4b927a0-9719-47b5-ad36-21ecf88d7978")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/mcs/class/System.Data.Linq/tests/Northwind.Expected.Sqlite-DbMetal.cs b/mcs/class/System.Data.Linq/tests/Northwind.Expected.Sqlite-DbMetal.cs deleted file mode 100755 index f6bf319a19e..00000000000 --- a/mcs/class/System.Data.Linq/tests/Northwind.Expected.Sqlite-DbMetal.cs +++ /dev/null @@ -1,4165 +0,0 @@ -#region Auto-generated classes for Northwind database on [TIMESTAMP] - -// -// ____ _ __ __ _ _ -// | _ \| |__ | \/ | ___| |_ __ _| | -// | | | | '_ \| |\/| |/ _ \ __/ _` | | -// | |_| | |_) | | | | __/ || (_| | | -// |____/|_.__/|_| |_|\___|\__\__,_|_| -// -// Auto-generated from Northwind on [TIMESTAMP] -// Please visit http://linq.to/db for more information - -#endregion - -using System; -using System.Data; -using System.Data.Linq.Mapping; -using System.Diagnostics; -using System.Reflection; -#if MONO_STRICT -using System.Data.Linq; -#else // MONO_STRICT -using DbLinq.Data.Linq; -using DbLinq.Vendor; -#endif // MONO_STRICT -using System.ComponentModel; - -namespace nwind -{ - public partial class Northwind : DataContext - { - #region Extensibility Method Definitions - - partial void OnCreated(); - - #endregion - - public Northwind(string connectionString) - : base(connectionString) - { - OnCreated(); - } - - public Northwind(IDbConnection connection) - #if MONO_STRICT - : base(connection) - #else // MONO_STRICT - : base(connection, new DbLinq.Sqlite.SqliteVendor()) - #endif // MONO_STRICT - { - OnCreated(); - } - - public Northwind(string connection, MappingSource mappingSource) - : base(connection, mappingSource) - { - OnCreated(); - } - - public Northwind(IDbConnection connection, MappingSource mappingSource) - : base(connection, mappingSource) - { - OnCreated(); - } - - #if !MONO_STRICT - public Northwind(IDbConnection connection, IVendor vendor) - : base(connection, vendor) - { - OnCreated(); - } - #endif // !MONO_STRICT - - #if !MONO_STRICT - public Northwind(IDbConnection connection, MappingSource mappingSource, IVendor vendor) - : base(connection, mappingSource, vendor) - { - OnCreated(); - } - #endif // !MONO_STRICT - - public Table Categories { get { return GetTable(); } } - public Table Customers { get { return GetTable(); } } - public Table CustomerCustomerDemo { get { return GetTable(); } } - public Table CustomerDemographics { get { return GetTable(); } } - public Table Employees { get { return GetTable(); } } - public Table EmployeeTerritories { get { return GetTable(); } } - public Table Orders { get { return GetTable(); } } - public Table OrderDetails { get { return GetTable(); } } - public Table Products { get { return GetTable(); } } - public Table Regions { get { return GetTable(); } } - public Table Shippers { get { return GetTable(); } } - public Table Suppliers { get { return GetTable(); } } - public Table Territories { get { return GetTable(); } } - - } - - [Table(Name = "main.Categories")] - public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCategoryIDChanged(); - partial void OnCategoryIDChanging(int value); - partial void OnCategoryNameChanged(); - partial void OnCategoryNameChanging(string value); - partial void OnDescriptionChanged(); - partial void OnDescriptionChanging(string value); - partial void OnPictureChanged(); - partial void OnPictureChanging(Byte[] value); - - #endregion - - #region int CategoryID - - private int _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int CategoryID - { - get - { - return _categoryID; - } - set - { - if (value != _categoryID) - { - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); - } - } - } - - #endregion - - #region string CategoryName - - private string _categoryName; - [DebuggerNonUserCode] - [Column(Storage = "_categoryName", Name = "CategoryName", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = false)] - public string CategoryName - { - get - { - return _categoryName; - } - set - { - if (value != _categoryName) - { - OnCategoryNameChanging(value); - SendPropertyChanging(); - _categoryName = value; - SendPropertyChanged("CategoryName"); - OnCategoryNameChanged(); - } - } - } - - #endregion - - #region string Description - - private string _description; - [DebuggerNonUserCode] - [Column(Storage = "_description", Name = "Description", DbType = "ntext", AutoSync = AutoSync.Never)] - public string Description - { - get - { - return _description; - } - set - { - if (value != _description) - { - OnDescriptionChanging(value); - SendPropertyChanging(); - _description = value; - SendPropertyChanged("Description"); - OnDescriptionChanged(); - } - } - } - - #endregion - - #region Byte[] Picture - - private Byte[] _picture; - [DebuggerNonUserCode] - [Column(Storage = "_picture", Name = "Picture", DbType = "image", AutoSync = AutoSync.Never)] - public Byte[] Picture - { - get - { - return _picture; - } - set - { - if (value != _picture) - { - OnPictureChanging(value); - SendPropertyChanging(); - _picture = value; - SendPropertyChanged("Picture"); - OnPictureChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "fk_Products_1")] - [DebuggerNonUserCode] - public EntitySet Products - { - get - { - return _products; - } - set - { - _products = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) - { - entity.Category = this; - } - - private void Products_Detach(Product entity) - { - entity.Category = null; - } - - - #endregion - - #region ctor - - public Category() - { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Customers")] - public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnAddressChanged(); - partial void OnAddressChanging(string value); - partial void OnCityChanged(); - partial void OnCityChanging(string value); - partial void OnCompanyNameChanged(); - partial void OnCompanyNameChanging(string value); - partial void OnContactNameChanged(); - partial void OnContactNameChanging(string value); - partial void OnContactTitleChanged(); - partial void OnContactTitleChanging(string value); - partial void OnCountryChanged(); - partial void OnCountryChanging(string value); - partial void OnCustomerIDChanged(); - partial void OnCustomerIDChanging(string value); - partial void OnFaxChanged(); - partial void OnFaxChanging(string value); - partial void OnPhoneChanged(); - partial void OnPhoneChanging(string value); - partial void OnPostalCodeChanged(); - partial void OnPostalCodeChanging(string value); - partial void OnRegionChanged(); - partial void OnRegionChanging(string value); - - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] - public string Address - { - get - { - return _address; - } - set - { - if (value != _address) - { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); - } - } - } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string City - { - get - { - return _city; - } - set - { - if (value != _city) - { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); - } - } - } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] - public string CompanyName - { - get - { - return _companyName; - } - set - { - if (value != _companyName) - { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); - } - } - } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] - public string ContactName - { - get - { - return _contactName; - } - set - { - if (value != _contactName) - { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); - } - } - } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] - public string ContactTitle - { - get - { - return _contactTitle; - } - set - { - if (value != _contactTitle) - { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); - } - } - } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string Country - { - get - { - return _country; - } - set - { - if (value != _country) - { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); - } - } - } - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public string CustomerID - { - get - { - return _customerID; - } - set - { - if (value != _customerID) - { - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); - } - } - } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] - public string Fax - { - get - { - return _fax; - } - set - { - if (value != _fax) - { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); - } - } - } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] - public string Phone - { - get - { - return _phone; - } - set - { - if (value != _phone) - { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); - } - } - } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] - public string PostalCode - { - get - { - return _postalCode; - } - set - { - if (value != _postalCode) - { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); - } - } - } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string Region - { - get - { - return _region; - } - set - { - if (value != _region) - { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_CustomerCustomerDemo_0")] - [DebuggerNonUserCode] - public EntitySet CustomerCustomerDemo - { - get - { - return _customerCustomerDemo; - } - set - { - _customerCustomerDemo = value; - } - } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_Orders_2")] - [DebuggerNonUserCode] - public EntitySet Orders - { - get - { - return _orders; - } - set - { - _orders = value; - } - } - - - #endregion - - #region Attachement handlers - - private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) - { - entity.Customer = this; - } - - private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) - { - entity.Customer = null; - } - - private void Orders_Attach(Order entity) - { - entity.Customer = this; - } - - private void Orders_Detach(Order entity) - { - entity.Customer = null; - } - - - #endregion - - #region ctor - - public Customer() - { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.CustomerCustomerDemo")] - public partial class CustomerCustomerDemo : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCustomerIDChanged(); - partial void OnCustomerIDChanging(string value); - partial void OnCustomerTypeIDChanged(); - partial void OnCustomerTypeIDChanging(string value); - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public string CustomerID - { - get - { - return _customerID; - } - set - { - if (value != _customerID) - { - if (_customer.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); - } - } - } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public string CustomerTypeID - { - get - { - return _customerTypeID; - } - set - { - if (value != _customerTypeID) - { - if (_customerDemographic.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); - } - } - } - - #endregion - - #region Parents - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_CustomerCustomerDemo_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Customer Customer - { - get - { - return _customer.Entity; - } - set - { - if (value != _customer.Entity) - { - if (_customer.Entity != null) - { - var previousCustomer = _customer.Entity; - _customer.Entity = null; - previousCustomer.CustomerCustomerDemo.Remove(this); - } - _customer.Entity = value; - if (value != null) - { - value.CustomerCustomerDemo.Add(this); - _customerID = value.CustomerID; - } - else - { - _customerID = default(string); - } - } - } - } - - private EntityRef _customerDemographic; - [Association(Storage = "_customerDemographic", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "fk_CustomerCustomerDemo_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public CustomerDemographic CustomerDemographic - { - get - { - return _customerDemographic.Entity; - } - set - { - if (value != _customerDemographic.Entity) - { - if (_customerDemographic.Entity != null) - { - var previousCustomerDemographic = _customerDemographic.Entity; - _customerDemographic.Entity = null; - previousCustomerDemographic.CustomerCustomerDemo.Remove(this); - } - _customerDemographic.Entity = value; - if (value != null) - { - value.CustomerCustomerDemo.Add(this); - _customerTypeID = value.CustomerTypeID; - } - else - { - _customerTypeID = default(string); - } - } - } - } - - - #endregion - - #region ctor - - public CustomerCustomerDemo() - { - _customer = new EntityRef(); - _customerDemographic = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.CustomerDemographics")] - public partial class CustomerDemographic : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCustomerDescChanged(); - partial void OnCustomerDescChanging(string value); - partial void OnCustomerTypeIDChanged(); - partial void OnCustomerTypeIDChanging(string value); - - #endregion - - #region string CustomerDesc - - private string _customerDesc; - [DebuggerNonUserCode] - [Column(Storage = "_customerDesc", Name = "CustomerDesc", DbType = "ntext", AutoSync = AutoSync.Never)] - public string CustomerDesc - { - get - { - return _customerDesc; - } - set - { - if (value != _customerDesc) - { - OnCustomerDescChanging(value); - SendPropertyChanging(); - _customerDesc = value; - SendPropertyChanged("CustomerDesc"); - OnCustomerDescChanged(); - } - } - } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public string CustomerTypeID - { - get - { - return _customerTypeID; - } - set - { - if (value != _customerTypeID) - { - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "fk_CustomerCustomerDemo_1")] - [DebuggerNonUserCode] - public EntitySet CustomerCustomerDemo - { - get - { - return _customerCustomerDemo; - } - set - { - _customerCustomerDemo = value; - } - } - - - #endregion - - #region Attachement handlers - - private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) - { - entity.CustomerDemographic = this; - } - - private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) - { - entity.CustomerDemographic = null; - } - - - #endregion - - #region ctor - - public CustomerDemographic() - { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Employees")] - public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnAddressChanged(); - partial void OnAddressChanging(string value); - partial void OnBirthDateChanged(); - partial void OnBirthDateChanging(DateTime? value); - partial void OnCityChanged(); - partial void OnCityChanging(string value); - partial void OnCountryChanged(); - partial void OnCountryChanging(string value); - partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(int value); - partial void OnExtensionChanged(); - partial void OnExtensionChanging(string value); - partial void OnFirstNameChanged(); - partial void OnFirstNameChanging(string value); - partial void OnHireDateChanged(); - partial void OnHireDateChanging(DateTime? value); - partial void OnHomePhoneChanged(); - partial void OnHomePhoneChanging(string value); - partial void OnLastNameChanged(); - partial void OnLastNameChanging(string value); - partial void OnNotesChanged(); - partial void OnNotesChanging(string value); - partial void OnPhotoChanged(); - partial void OnPhotoChanging(Byte[] value); - partial void OnPhotoPathChanged(); - partial void OnPhotoPathChanging(string value); - partial void OnPostalCodeChanged(); - partial void OnPostalCodeChanging(string value); - partial void OnRegionChanged(); - partial void OnRegionChanging(string value); - partial void OnReportsToChanged(); - partial void OnReportsToChanging(int? value); - partial void OnTitleChanged(); - partial void OnTitleChanging(string value); - partial void OnTitleOfCourtesyChanged(); - partial void OnTitleOfCourtesyChanging(string value); - - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] - public string Address - { - get - { - return _address; - } - set - { - if (value != _address) - { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); - } - } - } - - #endregion - - #region DateTime? BirthDate - - private DateTime? _birthDate; - [DebuggerNonUserCode] - [Column(Storage = "_birthDate", Name = "BirthDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? BirthDate - { - get - { - return _birthDate; - } - set - { - if (value != _birthDate) - { - OnBirthDateChanging(value); - SendPropertyChanging(); - _birthDate = value; - SendPropertyChanged("BirthDate"); - OnBirthDateChanged(); - } - } - } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string City - { - get - { - return _city; - } - set - { - if (value != _city) - { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); - } - } - } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string Country - { - get - { - return _country; - } - set - { - if (value != _country) - { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); - } - } - } - - #endregion - - #region int EmployeeID - - private int _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int EmployeeID - { - get - { - return _employeeID; - } - set - { - if (value != _employeeID) - { - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); - } - } - } - - #endregion - - #region string Extension - - private string _extension; - [DebuggerNonUserCode] - [Column(Storage = "_extension", Name = "Extension", DbType = "nvarchar (4)", AutoSync = AutoSync.Never)] - public string Extension - { - get - { - return _extension; - } - set - { - if (value != _extension) - { - OnExtensionChanging(value); - SendPropertyChanging(); - _extension = value; - SendPropertyChanged("Extension"); - OnExtensionChanged(); - } - } - } - - #endregion - - #region string FirstName - - private string _firstName; - [DebuggerNonUserCode] - [Column(Storage = "_firstName", Name = "FirstName", DbType = "nvarchar (10)", AutoSync = AutoSync.Never, CanBeNull = false)] - public string FirstName - { - get - { - return _firstName; - } - set - { - if (value != _firstName) - { - OnFirstNameChanging(value); - SendPropertyChanging(); - _firstName = value; - SendPropertyChanged("FirstName"); - OnFirstNameChanged(); - } - } - } - - #endregion - - #region DateTime? HireDate - - private DateTime? _hireDate; - [DebuggerNonUserCode] - [Column(Storage = "_hireDate", Name = "HireDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? HireDate - { - get - { - return _hireDate; - } - set - { - if (value != _hireDate) - { - OnHireDateChanging(value); - SendPropertyChanging(); - _hireDate = value; - SendPropertyChanged("HireDate"); - OnHireDateChanged(); - } - } - } - - #endregion - - #region string HomePhone - - private string _homePhone; - [DebuggerNonUserCode] - [Column(Storage = "_homePhone", Name = "HomePhone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] - public string HomePhone - { - get - { - return _homePhone; - } - set - { - if (value != _homePhone) - { - OnHomePhoneChanging(value); - SendPropertyChanging(); - _homePhone = value; - SendPropertyChanged("HomePhone"); - OnHomePhoneChanged(); - } - } - } - - #endregion - - #region string LastName - - private string _lastName; - [DebuggerNonUserCode] - [Column(Storage = "_lastName", Name = "LastName", DbType = "nvarchar (20)", AutoSync = AutoSync.Never, CanBeNull = false)] - public string LastName - { - get - { - return _lastName; - } - set - { - if (value != _lastName) - { - OnLastNameChanging(value); - SendPropertyChanging(); - _lastName = value; - SendPropertyChanged("LastName"); - OnLastNameChanged(); - } - } - } - - #endregion - - #region string Notes - - private string _notes; - [DebuggerNonUserCode] - [Column(Storage = "_notes", Name = "Notes", DbType = "ntext", AutoSync = AutoSync.Never)] - public string Notes - { - get - { - return _notes; - } - set - { - if (value != _notes) - { - OnNotesChanging(value); - SendPropertyChanging(); - _notes = value; - SendPropertyChanged("Notes"); - OnNotesChanged(); - } - } - } - - #endregion - - #region Byte[] Photo - - private Byte[] _photo; - [DebuggerNonUserCode] - [Column(Storage = "_photo", Name = "Photo", DbType = "image", AutoSync = AutoSync.Never)] - public Byte[] Photo - { - get - { - return _photo; - } - set - { - if (value != _photo) - { - OnPhotoChanging(value); - SendPropertyChanging(); - _photo = value; - SendPropertyChanged("Photo"); - OnPhotoChanged(); - } - } - } - - #endregion - - #region string PhotoPath - - private string _photoPath; - [DebuggerNonUserCode] - [Column(Storage = "_photoPath", Name = "PhotoPath", DbType = "nvarchar (255)", AutoSync = AutoSync.Never)] - public string PhotoPath - { - get - { - return _photoPath; - } - set - { - if (value != _photoPath) - { - OnPhotoPathChanging(value); - SendPropertyChanging(); - _photoPath = value; - SendPropertyChanged("PhotoPath"); - OnPhotoPathChanged(); - } - } - } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] - public string PostalCode - { - get - { - return _postalCode; - } - set - { - if (value != _postalCode) - { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); - } - } - } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string Region - { - get - { - return _region; - } - set - { - if (value != _region) - { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); - } - } - } - - #endregion - - #region int? ReportsTo - - private int? _reportsTo; - [DebuggerNonUserCode] - [Column(Storage = "_reportsTo", Name = "ReportsTo", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? ReportsTo - { - get - { - return _reportsTo; - } - set - { - if (value != _reportsTo) - { - if (_reportsToEmployee.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnReportsToChanging(value); - SendPropertyChanging(); - _reportsTo = value; - SendPropertyChanged("ReportsTo"); - OnReportsToChanged(); - } - } - } - - #endregion - - #region string Title - - private string _title; - [DebuggerNonUserCode] - [Column(Storage = "_title", Name = "Title", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] - public string Title - { - get - { - return _title; - } - set - { - if (value != _title) - { - OnTitleChanging(value); - SendPropertyChanging(); - _title = value; - SendPropertyChanged("Title"); - OnTitleChanged(); - } - } - } - - #endregion - - #region string TitleOfCourtesy - - private string _titleOfCourtesy; - [DebuggerNonUserCode] - [Column(Storage = "_titleOfCourtesy", Name = "TitleOfCourtesy", DbType = "nvarchar (25)", AutoSync = AutoSync.Never)] - public string TitleOfCourtesy - { - get - { - return _titleOfCourtesy; - } - set - { - if (value != _titleOfCourtesy) - { - OnTitleOfCourtesyChanging(value); - SendPropertyChanging(); - _titleOfCourtesy = value; - SendPropertyChanged("TitleOfCourtesy"); - OnTitleOfCourtesyChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_EmployeeTerritories_1")] - [DebuggerNonUserCode] - public EntitySet EmployeeTerritories - { - get - { - return _employeeTerritories; - } - set - { - _employeeTerritories = value; - } - } - - private EntitySet _employees; - [Association(Storage = "_employees", OtherKey = "ReportsTo", ThisKey = "EmployeeID", Name = "fk_Employees_0")] - [DebuggerNonUserCode] - public EntitySet Employees - { - get - { - return _employees; - } - set - { - _employees = value; - } - } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_Orders_1")] - [DebuggerNonUserCode] - public EntitySet Orders - { - get - { - return _orders; - } - set - { - _orders = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _reportsToEmployee; - [Association(Storage = "_reportsToEmployee", OtherKey = "EmployeeID", ThisKey = "ReportsTo", Name = "fk_Employees_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Employee ReportsToEmployee - { - get - { - return _reportsToEmployee.Entity; - } - set - { - if (value != _reportsToEmployee.Entity) - { - if (_reportsToEmployee.Entity != null) - { - var previousEmployee = _reportsToEmployee.Entity; - _reportsToEmployee.Entity = null; - previousEmployee.Employees.Remove(this); - } - _reportsToEmployee.Entity = value; - if (value != null) - { - value.Employees.Add(this); - _reportsTo = value.EmployeeID; - } - else - { - _reportsTo = null; - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void EmployeeTerritories_Attach(EmployeeTerritory entity) - { - entity.Employee = this; - } - - private void EmployeeTerritories_Detach(EmployeeTerritory entity) - { - entity.Employee = null; - } - - private void Employees_Attach(Employee entity) - { - entity.ReportsToEmployee = this; - } - - private void Employees_Detach(Employee entity) - { - entity.ReportsToEmployee = null; - } - - private void Orders_Attach(Order entity) - { - entity.Employee = this; - } - - private void Orders_Detach(Order entity) - { - entity.Employee = null; - } - - - #endregion - - #region ctor - - public Employee() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _employees = new EntitySet(Employees_Attach, Employees_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - _reportsToEmployee = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.EmployeeTerritories")] - public partial class EmployeeTerritory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(int value); - partial void OnTerritoryIDChanged(); - partial void OnTerritoryIDChanging(string value); - - #endregion - - #region int EmployeeID - - private int _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int EmployeeID - { - get - { - return _employeeID; - } - set - { - if (value != _employeeID) - { - if (_employee.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); - } - } - } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public string TerritoryID - { - get - { - return _territoryID; - } - set - { - if (value != _territoryID) - { - if (_territory.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); - } - } - } - - #endregion - - #region Parents - - private EntityRef _territory; - [Association(Storage = "_territory", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "fk_EmployeeTerritories_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Territory Territory - { - get - { - return _territory.Entity; - } - set - { - if (value != _territory.Entity) - { - if (_territory.Entity != null) - { - var previousTerritory = _territory.Entity; - _territory.Entity = null; - previousTerritory.EmployeeTerritories.Remove(this); - } - _territory.Entity = value; - if (value != null) - { - value.EmployeeTerritories.Add(this); - _territoryID = value.TerritoryID; - } - else - { - _territoryID = default(string); - } - } - } - } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_EmployeeTerritories_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public Employee Employee - { - get - { - return _employee.Entity; - } - set - { - if (value != _employee.Entity) - { - if (_employee.Entity != null) - { - var previousEmployee = _employee.Entity; - _employee.Entity = null; - previousEmployee.EmployeeTerritories.Remove(this); - } - _employee.Entity = value; - if (value != null) - { - value.EmployeeTerritories.Add(this); - _employeeID = value.EmployeeID; - } - else - { - _employeeID = default(int); - } - } - } - } - - - #endregion - - #region ctor - - public EmployeeTerritory() - { - _territory = new EntityRef(); - _employee = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Orders")] - public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCustomerIDChanged(); - partial void OnCustomerIDChanging(string value); - partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(int? value); - partial void OnFreightChanged(); - partial void OnFreightChanging(decimal? value); - partial void OnOrderDateChanged(); - partial void OnOrderDateChanging(DateTime? value); - partial void OnOrderIDChanged(); - partial void OnOrderIDChanging(int value); - partial void OnRequiredDateChanged(); - partial void OnRequiredDateChanging(DateTime? value); - partial void OnShipAddressChanged(); - partial void OnShipAddressChanging(string value); - partial void OnShipCityChanged(); - partial void OnShipCityChanging(string value); - partial void OnShipCountryChanged(); - partial void OnShipCountryChanging(string value); - partial void OnShipNameChanged(); - partial void OnShipNameChanging(string value); - partial void OnShippedDateChanged(); - partial void OnShippedDateChanging(DateTime? value); - partial void OnShipPostalCodeChanged(); - partial void OnShipPostalCodeChanging(string value); - partial void OnShipRegionChanged(); - partial void OnShipRegionChanging(string value); - partial void OnShipViaChanged(); - partial void OnShipViaChanging(int? value); - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", AutoSync = AutoSync.Never)] - public string CustomerID - { - get - { - return _customerID; - } - set - { - if (value != _customerID) - { - if (_customer.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); - } - } - } - - #endregion - - #region int? EmployeeID - - private int? _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? EmployeeID - { - get - { - return _employeeID; - } - set - { - if (value != _employeeID) - { - if (_employee.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); - } - } - } - - #endregion - - #region decimal? Freight - - private decimal? _freight; - [DebuggerNonUserCode] - [Column(Storage = "_freight", Name = "Freight", DbType = "money", AutoSync = AutoSync.Never)] - public decimal? Freight - { - get - { - return _freight; - } - set - { - if (value != _freight) - { - OnFreightChanging(value); - SendPropertyChanging(); - _freight = value; - SendPropertyChanged("Freight"); - OnFreightChanged(); - } - } - } - - #endregion - - #region DateTime? OrderDate - - private DateTime? _orderDate; - [DebuggerNonUserCode] - [Column(Storage = "_orderDate", Name = "OrderDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? OrderDate - { - get - { - return _orderDate; - } - set - { - if (value != _orderDate) - { - OnOrderDateChanging(value); - SendPropertyChanging(); - _orderDate = value; - SendPropertyChanged("OrderDate"); - OnOrderDateChanged(); - } - } - } - - #endregion - - #region int OrderID - - private int _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int OrderID - { - get - { - return _orderID; - } - set - { - if (value != _orderID) - { - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); - } - } - } - - #endregion - - #region DateTime? RequiredDate - - private DateTime? _requiredDate; - [DebuggerNonUserCode] - [Column(Storage = "_requiredDate", Name = "RequiredDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? RequiredDate - { - get - { - return _requiredDate; - } - set - { - if (value != _requiredDate) - { - OnRequiredDateChanging(value); - SendPropertyChanging(); - _requiredDate = value; - SendPropertyChanged("RequiredDate"); - OnRequiredDateChanged(); - } - } - } - - #endregion - - #region string ShipAddress - - private string _shipAddress; - [DebuggerNonUserCode] - [Column(Storage = "_shipAddress", Name = "ShipAddress", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] - public string ShipAddress - { - get - { - return _shipAddress; - } - set - { - if (value != _shipAddress) - { - OnShipAddressChanging(value); - SendPropertyChanging(); - _shipAddress = value; - SendPropertyChanged("ShipAddress"); - OnShipAddressChanged(); - } - } - } - - #endregion - - #region string ShipCity - - private string _shipCity; - [DebuggerNonUserCode] - [Column(Storage = "_shipCity", Name = "ShipCity", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string ShipCity - { - get - { - return _shipCity; - } - set - { - if (value != _shipCity) - { - OnShipCityChanging(value); - SendPropertyChanging(); - _shipCity = value; - SendPropertyChanged("ShipCity"); - OnShipCityChanged(); - } - } - } - - #endregion - - #region string ShipCountry - - private string _shipCountry; - [DebuggerNonUserCode] - [Column(Storage = "_shipCountry", Name = "ShipCountry", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string ShipCountry - { - get - { - return _shipCountry; - } - set - { - if (value != _shipCountry) - { - OnShipCountryChanging(value); - SendPropertyChanging(); - _shipCountry = value; - SendPropertyChanged("ShipCountry"); - OnShipCountryChanged(); - } - } - } - - #endregion - - #region string ShipName - - private string _shipName; - [DebuggerNonUserCode] - [Column(Storage = "_shipName", Name = "ShipName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never)] - public string ShipName - { - get - { - return _shipName; - } - set - { - if (value != _shipName) - { - OnShipNameChanging(value); - SendPropertyChanging(); - _shipName = value; - SendPropertyChanged("ShipName"); - OnShipNameChanged(); - } - } - } - - #endregion - - #region DateTime? ShippedDate - - private DateTime? _shippedDate; - [DebuggerNonUserCode] - [Column(Storage = "_shippedDate", Name = "ShippedDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? ShippedDate - { - get - { - return _shippedDate; - } - set - { - if (value != _shippedDate) - { - OnShippedDateChanging(value); - SendPropertyChanging(); - _shippedDate = value; - SendPropertyChanged("ShippedDate"); - OnShippedDateChanged(); - } - } - } - - #endregion - - #region string ShipPostalCode - - private string _shipPostalCode; - [DebuggerNonUserCode] - [Column(Storage = "_shipPostalCode", Name = "ShipPostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] - public string ShipPostalCode - { - get - { - return _shipPostalCode; - } - set - { - if (value != _shipPostalCode) - { - OnShipPostalCodeChanging(value); - SendPropertyChanging(); - _shipPostalCode = value; - SendPropertyChanged("ShipPostalCode"); - OnShipPostalCodeChanged(); - } - } - } - - #endregion - - #region string ShipRegion - - private string _shipRegion; - [DebuggerNonUserCode] - [Column(Storage = "_shipRegion", Name = "ShipRegion", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string ShipRegion - { - get - { - return _shipRegion; - } - set - { - if (value != _shipRegion) - { - OnShipRegionChanging(value); - SendPropertyChanging(); - _shipRegion = value; - SendPropertyChanged("ShipRegion"); - OnShipRegionChanged(); - } - } - } - - #endregion - - #region int? ShipVia - - private int? _shipVia; - [DebuggerNonUserCode] - [Column(Storage = "_shipVia", Name = "ShipVia", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? ShipVia - { - get - { - return _shipVia; - } - set - { - if (value != _shipVia) - { - if (_shipper.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnShipViaChanging(value); - SendPropertyChanging(); - _shipVia = value; - SendPropertyChanged("ShipVia"); - OnShipViaChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"fk_Order Details_1\"")] - [DebuggerNonUserCode] - public EntitySet OrderDetails - { - get - { - return _orderDetails; - } - set - { - _orderDetails = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _shipper; - [Association(Storage = "_shipper", OtherKey = "ShipperID", ThisKey = "ShipVia", Name = "fk_Orders_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Shipper Shipper - { - get - { - return _shipper.Entity; - } - set - { - if (value != _shipper.Entity) - { - if (_shipper.Entity != null) - { - var previousShipper = _shipper.Entity; - _shipper.Entity = null; - previousShipper.Orders.Remove(this); - } - _shipper.Entity = value; - if (value != null) - { - value.Orders.Add(this); - _shipVia = value.ShipperID; - } - else - { - _shipVia = null; - } - } - } - } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_Orders_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public Employee Employee - { - get - { - return _employee.Entity; - } - set - { - if (value != _employee.Entity) - { - if (_employee.Entity != null) - { - var previousEmployee = _employee.Entity; - _employee.Entity = null; - previousEmployee.Orders.Remove(this); - } - _employee.Entity = value; - if (value != null) - { - value.Orders.Add(this); - _employeeID = value.EmployeeID; - } - else - { - _employeeID = null; - } - } - } - } - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_Orders_2", IsForeignKey = true)] - [DebuggerNonUserCode] - public Customer Customer - { - get - { - return _customer.Entity; - } - set - { - if (value != _customer.Entity) - { - if (_customer.Entity != null) - { - var previousCustomer = _customer.Entity; - _customer.Entity = null; - previousCustomer.Orders.Remove(this); - } - _customer.Entity = value; - if (value != null) - { - value.Orders.Add(this); - _customerID = value.CustomerID; - } - else - { - _customerID = null; - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) - { - entity.Order = this; - } - - private void OrderDetails_Detach(OrderDetail entity) - { - entity.Order = null; - } - - - #endregion - - #region ctor - - public Order() - { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _shipper = new EntityRef(); - _employee = new EntityRef(); - _customer = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.\"Order Details\"")] - public partial class OrderDetail : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnDiscountChanged(); - partial void OnDiscountChanging(float value); - partial void OnOrderIDChanged(); - partial void OnOrderIDChanging(int value); - partial void OnProductIDChanged(); - partial void OnProductIDChanging(int value); - partial void OnQuantityChanged(); - partial void OnQuantityChanging(short value); - partial void OnUnitPriceChanged(); - partial void OnUnitPriceChanging(decimal value); - - #endregion - - #region float Discount - - private float _discount; - [DebuggerNonUserCode] - [Column(Storage = "_discount", Name = "Discount", DbType = "real", AutoSync = AutoSync.Never, CanBeNull = false)] - public float Discount - { - get - { - return _discount; - } - set - { - if (value != _discount) - { - OnDiscountChanging(value); - SendPropertyChanging(); - _discount = value; - SendPropertyChanged("Discount"); - OnDiscountChanged(); - } - } - } - - #endregion - - #region int OrderID - - private int _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int OrderID - { - get - { - return _orderID; - } - set - { - if (value != _orderID) - { - if (_order.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); - } - } - } - - #endregion - - #region int ProductID - - private int _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int ProductID - { - get - { - return _productID; - } - set - { - if (value != _productID) - { - if (_product.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); - } - } - } - - #endregion - - #region short Quantity - - private short _quantity; - [DebuggerNonUserCode] - [Column(Storage = "_quantity", Name = "Quantity", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = false)] - public short Quantity - { - get - { - return _quantity; - } - set - { - if (value != _quantity) - { - OnQuantityChanging(value); - SendPropertyChanging(); - _quantity = value; - SendPropertyChanged("Quantity"); - OnQuantityChanged(); - } - } - } - - #endregion - - #region decimal UnitPrice - - private decimal _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never, CanBeNull = false)] - public decimal UnitPrice - { - get - { - return _unitPrice; - } - set - { - if (value != _unitPrice) - { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); - } - } - } - - #endregion - - #region Parents - - private EntityRef _product; - [Association(Storage = "_product", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"fk_Order Details_0\"", IsForeignKey = true)] - [DebuggerNonUserCode] - public Product Product - { - get - { - return _product.Entity; - } - set - { - if (value != _product.Entity) - { - if (_product.Entity != null) - { - var previousProduct = _product.Entity; - _product.Entity = null; - previousProduct.OrderDetails.Remove(this); - } - _product.Entity = value; - if (value != null) - { - value.OrderDetails.Add(this); - _productID = value.ProductID; - } - else - { - _productID = default(int); - } - } - } - } - - private EntityRef _order; - [Association(Storage = "_order", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"fk_Order Details_1\"", IsForeignKey = true)] - [DebuggerNonUserCode] - public Order Order - { - get - { - return _order.Entity; - } - set - { - if (value != _order.Entity) - { - if (_order.Entity != null) - { - var previousOrder = _order.Entity; - _order.Entity = null; - previousOrder.OrderDetails.Remove(this); - } - _order.Entity = value; - if (value != null) - { - value.OrderDetails.Add(this); - _orderID = value.OrderID; - } - else - { - _orderID = default(int); - } - } - } - } - - - #endregion - - #region ctor - - public OrderDetail() - { - _product = new EntityRef(); - _order = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Products")] - public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCategoryIDChanged(); - partial void OnCategoryIDChanging(int? value); - partial void OnDiscontinuedChanged(); - partial void OnDiscontinuedChanging(bool value); - partial void OnProductIDChanged(); - partial void OnProductIDChanging(int value); - partial void OnProductNameChanged(); - partial void OnProductNameChanging(string value); - partial void OnQuantityPerUnitChanged(); - partial void OnQuantityPerUnitChanging(string value); - partial void OnReorderLevelChanged(); - partial void OnReorderLevelChanging(short? value); - partial void OnSupplierIDChanged(); - partial void OnSupplierIDChanging(int? value); - partial void OnUnitPriceChanged(); - partial void OnUnitPriceChanging(decimal? value); - partial void OnUnitsInStockChanged(); - partial void OnUnitsInStockChanging(short? value); - partial void OnUnitsOnOrderChanged(); - partial void OnUnitsOnOrderChanging(short? value); - - #endregion - - #region int? CategoryID - - private int? _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? CategoryID - { - get - { - return _categoryID; - } - set - { - if (value != _categoryID) - { - if (_category.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); - } - } - } - - #endregion - - #region bool Discontinued - - private bool _discontinued; - [DebuggerNonUserCode] - [Column(Storage = "_discontinued", Name = "Discontinued", DbType = "bit", AutoSync = AutoSync.Never, CanBeNull = false)] - public bool Discontinued - { - get - { - return _discontinued; - } - set - { - if (value != _discontinued) - { - OnDiscontinuedChanging(value); - SendPropertyChanging(); - _discontinued = value; - SendPropertyChanged("Discontinued"); - OnDiscontinuedChanged(); - } - } - } - - #endregion - - #region int ProductID - - private int _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int ProductID - { - get - { - return _productID; - } - set - { - if (value != _productID) - { - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); - } - } - } - - #endregion - - #region string ProductName - - private string _productName; - [DebuggerNonUserCode] - [Column(Storage = "_productName", Name = "ProductName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] - public string ProductName - { - get - { - return _productName; - } - set - { - if (value != _productName) - { - OnProductNameChanging(value); - SendPropertyChanging(); - _productName = value; - SendPropertyChanged("ProductName"); - OnProductNameChanged(); - } - } - } - - #endregion - - #region string QuantityPerUnit - - private string _quantityPerUnit; - [DebuggerNonUserCode] - [Column(Storage = "_quantityPerUnit", Name = "QuantityPerUnit", DbType = "nvarchar (20)", AutoSync = AutoSync.Never)] - public string QuantityPerUnit - { - get - { - return _quantityPerUnit; - } - set - { - if (value != _quantityPerUnit) - { - OnQuantityPerUnitChanging(value); - SendPropertyChanging(); - _quantityPerUnit = value; - SendPropertyChanged("QuantityPerUnit"); - OnQuantityPerUnitChanged(); - } - } - } - - #endregion - - #region short? ReorderLevel - - private short? _reorderLevel; - [DebuggerNonUserCode] - [Column(Storage = "_reorderLevel", Name = "ReorderLevel", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? ReorderLevel - { - get - { - return _reorderLevel; - } - set - { - if (value != _reorderLevel) - { - OnReorderLevelChanging(value); - SendPropertyChanging(); - _reorderLevel = value; - SendPropertyChanged("ReorderLevel"); - OnReorderLevelChanged(); - } - } - } - - #endregion - - #region int? SupplierID - - private int? _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int? SupplierID - { - get - { - return _supplierID; - } - set - { - if (value != _supplierID) - { - if (_supplier.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); - } - } - } - - #endregion - - #region decimal? UnitPrice - - private decimal? _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never)] - public decimal? UnitPrice - { - get - { - return _unitPrice; - } - set - { - if (value != _unitPrice) - { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); - } - } - } - - #endregion - - #region short? UnitsInStock - - private short? _unitsInStock; - [DebuggerNonUserCode] - [Column(Storage = "_unitsInStock", Name = "UnitsInStock", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? UnitsInStock - { - get - { - return _unitsInStock; - } - set - { - if (value != _unitsInStock) - { - OnUnitsInStockChanging(value); - SendPropertyChanging(); - _unitsInStock = value; - SendPropertyChanged("UnitsInStock"); - OnUnitsInStockChanged(); - } - } - } - - #endregion - - #region short? UnitsOnOrder - - private short? _unitsOnOrder; - [DebuggerNonUserCode] - [Column(Storage = "_unitsOnOrder", Name = "UnitsOnOrder", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? UnitsOnOrder - { - get - { - return _unitsOnOrder; - } - set - { - if (value != _unitsOnOrder) - { - OnUnitsOnOrderChanging(value); - SendPropertyChanging(); - _unitsOnOrder = value; - SendPropertyChanged("UnitsOnOrder"); - OnUnitsOnOrderChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"fk_Order Details_0\"")] - [DebuggerNonUserCode] - public EntitySet OrderDetails - { - get - { - return _orderDetails; - } - set - { - _orderDetails = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _supplier; - [Association(Storage = "_supplier", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "fk_Products_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Supplier Supplier - { - get - { - return _supplier.Entity; - } - set - { - if (value != _supplier.Entity) - { - if (_supplier.Entity != null) - { - var previousSupplier = _supplier.Entity; - _supplier.Entity = null; - previousSupplier.Products.Remove(this); - } - _supplier.Entity = value; - if (value != null) - { - value.Products.Add(this); - _supplierID = value.SupplierID; - } - else - { - _supplierID = null; - } - } - } - } - - private EntityRef _category; - [Association(Storage = "_category", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "fk_Products_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public Category Category - { - get - { - return _category.Entity; - } - set - { - if (value != _category.Entity) - { - if (_category.Entity != null) - { - var previousCategory = _category.Entity; - _category.Entity = null; - previousCategory.Products.Remove(this); - } - _category.Entity = value; - if (value != null) - { - value.Products.Add(this); - _categoryID = value.CategoryID; - } - else - { - _categoryID = null; - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) - { - entity.Product = this; - } - - private void OrderDetails_Detach(OrderDetail entity) - { - entity.Product = null; - } - - - #endregion - - #region ctor - - public Product() - { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _supplier = new EntityRef(); - _category = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Region")] - public partial class Region : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnRegionDescriptionChanged(); - partial void OnRegionDescriptionChanging(string value); - partial void OnRegionIDChanged(); - partial void OnRegionIDChanging(int value); - - #endregion - - #region string RegionDescription - - private string _regionDescription; - [DebuggerNonUserCode] - [Column(Storage = "_regionDescription", Name = "RegionDescription", DbType = "nchar", AutoSync = AutoSync.Never, CanBeNull = false)] - public string RegionDescription - { - get - { - return _regionDescription; - } - set - { - if (value != _regionDescription) - { - OnRegionDescriptionChanging(value); - SendPropertyChanging(); - _regionDescription = value; - SendPropertyChanged("RegionDescription"); - OnRegionDescriptionChanged(); - } - } - } - - #endregion - - #region int RegionID - - private int _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int RegionID - { - get - { - return _regionID; - } - set - { - if (value != _regionID) - { - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _territories; - [Association(Storage = "_territories", OtherKey = "RegionID", ThisKey = "RegionID", Name = "fk_Territories_0")] - [DebuggerNonUserCode] - public EntitySet Territories - { - get - { - return _territories; - } - set - { - _territories = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Territories_Attach(Territory entity) - { - entity.Region = this; - } - - private void Territories_Detach(Territory entity) - { - entity.Region = null; - } - - - #endregion - - #region ctor - - public Region() - { - _territories = new EntitySet(Territories_Attach, Territories_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Shippers")] - public partial class Shipper : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCompanyNameChanged(); - partial void OnCompanyNameChanging(string value); - partial void OnPhoneChanged(); - partial void OnPhoneChanging(string value); - partial void OnShipperIDChanged(); - partial void OnShipperIDChanging(int value); - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] - public string CompanyName - { - get - { - return _companyName; - } - set - { - if (value != _companyName) - { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); - } - } - } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] - public string Phone - { - get - { - return _phone; - } - set - { - if (value != _phone) - { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); - } - } - } - - #endregion - - #region int ShipperID - - private int _shipperID; - [DebuggerNonUserCode] - [Column(Storage = "_shipperID", Name = "ShipperID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int ShipperID - { - get - { - return _shipperID; - } - set - { - if (value != _shipperID) - { - OnShipperIDChanging(value); - SendPropertyChanging(); - _shipperID = value; - SendPropertyChanged("ShipperID"); - OnShipperIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "ShipVia", ThisKey = "ShipperID", Name = "fk_Orders_0")] - [DebuggerNonUserCode] - public EntitySet Orders - { - get - { - return _orders; - } - set - { - _orders = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Orders_Attach(Order entity) - { - entity.Shipper = this; - } - - private void Orders_Detach(Order entity) - { - entity.Shipper = null; - } - - - #endregion - - #region ctor - - public Shipper() - { - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Suppliers")] - public partial class Supplier : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnAddressChanged(); - partial void OnAddressChanging(string value); - partial void OnCityChanged(); - partial void OnCityChanging(string value); - partial void OnCompanyNameChanged(); - partial void OnCompanyNameChanging(string value); - partial void OnContactNameChanged(); - partial void OnContactNameChanging(string value); - partial void OnContactTitleChanged(); - partial void OnContactTitleChanging(string value); - partial void OnCountryChanged(); - partial void OnCountryChanging(string value); - partial void OnFaxChanged(); - partial void OnFaxChanging(string value); - partial void OnHomePageChanged(); - partial void OnHomePageChanging(string value); - partial void OnPhoneChanged(); - partial void OnPhoneChanging(string value); - partial void OnPostalCodeChanged(); - partial void OnPostalCodeChanging(string value); - partial void OnRegionChanged(); - partial void OnRegionChanging(string value); - partial void OnSupplierIDChanged(); - partial void OnSupplierIDChanging(int value); - - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never)] - public string Address - { - get - { - return _address; - } - set - { - if (value != _address) - { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); - } - } - } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string City - { - get - { - return _city; - } - set - { - if (value != _city) - { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); - } - } - } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = false)] - public string CompanyName - { - get - { - return _companyName; - } - set - { - if (value != _companyName) - { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); - } - } - } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] - public string ContactName - { - get - { - return _contactName; - } - set - { - if (value != _contactName) - { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); - } - } - } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar (30)", AutoSync = AutoSync.Never)] - public string ContactTitle - { - get - { - return _contactTitle; - } - set - { - if (value != _contactTitle) - { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); - } - } - } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string Country - { - get - { - return _country; - } - set - { - if (value != _country) - { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); - } - } - } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] - public string Fax - { - get - { - return _fax; - } - set - { - if (value != _fax) - { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); - } - } - } - - #endregion - - #region string HomePage - - private string _homePage; - [DebuggerNonUserCode] - [Column(Storage = "_homePage", Name = "HomePage", DbType = "ntext", AutoSync = AutoSync.Never)] - public string HomePage - { - get - { - return _homePage; - } - set - { - if (value != _homePage) - { - OnHomePageChanging(value); - SendPropertyChanging(); - _homePage = value; - SendPropertyChanged("HomePage"); - OnHomePageChanged(); - } - } - } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never)] - public string Phone - { - get - { - return _phone; - } - set - { - if (value != _phone) - { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); - } - } - } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] - public string PostalCode - { - get - { - return _postalCode; - } - set - { - if (value != _postalCode) - { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); - } - } - } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string Region - { - get - { - return _region; - } - set - { - if (value != _region) - { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); - } - } - } - - #endregion - - #region int SupplierID - - private int _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public int SupplierID - { - get - { - return _supplierID; - } - set - { - if (value != _supplierID) - { - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "fk_Products_0")] - [DebuggerNonUserCode] - public EntitySet Products - { - get - { - return _products; - } - set - { - _products = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) - { - entity.Supplier = this; - } - - private void Products_Detach(Product entity) - { - entity.Supplier = null; - } - - - #endregion - - #region ctor - - public Supplier() - { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Territories")] - public partial class Territory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnRegionIDChanged(); - partial void OnRegionIDChanging(int value); - partial void OnTerritoryDescriptionChanged(); - partial void OnTerritoryDescriptionChanging(string value); - partial void OnTerritoryIDChanged(); - partial void OnTerritoryIDChanging(string value); - - #endregion - - #region int RegionID - - private int _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "INTEGER", AutoSync = AutoSync.Never, CanBeNull = false)] - public int RegionID - { - get - { - return _regionID; - } - set - { - if (value != _regionID) - { - if (_region.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); - } - } - } - - #endregion - - #region string TerritoryDescription - - private string _territoryDescription; - [DebuggerNonUserCode] - [Column(Storage = "_territoryDescription", Name = "TerritoryDescription", DbType = "nchar", AutoSync = AutoSync.Never, CanBeNull = false)] - public string TerritoryDescription - { - get - { - return _territoryDescription; - } - set - { - if (value != _territoryDescription) - { - OnTerritoryDescriptionChanging(value); - SendPropertyChanging(); - _territoryDescription = value; - SendPropertyChanged("TerritoryDescription"); - OnTerritoryDescriptionChanged(); - } - } - } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] - public string TerritoryID - { - get - { - return _territoryID; - } - set - { - if (value != _territoryID) - { - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "fk_EmployeeTerritories_0")] - [DebuggerNonUserCode] - public EntitySet EmployeeTerritories - { - get - { - return _employeeTerritories; - } - set - { - _employeeTerritories = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _region; - [Association(Storage = "_region", OtherKey = "RegionID", ThisKey = "RegionID", Name = "fk_Territories_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Region Region - { - get - { - return _region.Entity; - } - set - { - if (value != _region.Entity) - { - if (_region.Entity != null) - { - var previousRegion = _region.Entity; - _region.Entity = null; - previousRegion.Territories.Remove(this); - } - _region.Entity = value; - if (value != null) - { - value.Territories.Add(this); - _regionID = value.RegionID; - } - else - { - _regionID = default(int); - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void EmployeeTerritories_Attach(EmployeeTerritory entity) - { - entity.Territory = this; - } - - private void EmployeeTerritories_Detach(EmployeeTerritory entity) - { - entity.Territory = null; - } - - - #endregion - - #region ctor - - public Territory() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _region = new EntityRef(); - OnCreated(); - } - - #endregion - - } -} diff --git a/mcs/class/System.Data.Linq/tests/Northwind.Expected.Sqlite-sqlmetal.cs b/mcs/class/System.Data.Linq/tests/Northwind.Expected.Sqlite-sqlmetal.cs deleted file mode 100755 index 54780960927..00000000000 --- a/mcs/class/System.Data.Linq/tests/Northwind.Expected.Sqlite-sqlmetal.cs +++ /dev/null @@ -1,4140 +0,0 @@ -#region Auto-generated classes for Northwind database on [TIMESTAMP] - -// -// ____ _ __ __ _ _ -// | _ \| |__ | \/ | ___| |_ __ _| | -// | | | | '_ \| |\/| |/ _ \ __/ _` | | -// | |_| | |_) | | | | __/ || (_| | | -// |____/|_.__/|_| |_|\___|\__\__,_|_| -// -// Auto-generated from Northwind on [TIMESTAMP] -// Please visit http://linq.to/db for more information - -#endregion - -using System; -using System.Data; -using System.Data.Linq.Mapping; -using System.Diagnostics; -using System.Reflection; -using System.Data.Linq; -using System.ComponentModel; - -namespace nwind -{ - public partial class Northwind : DataContext - { - #region Extensibility Method Definitions - - partial void OnCreated(); - - #endregion - - public Northwind(string connectionString) - : base(connectionString) - { - OnCreated(); - } - - public Northwind(IDbConnection connection) - : base(connection) - { - OnCreated(); - } - - public Northwind(string connection, MappingSource mappingSource) - : base(connection, mappingSource) - { - OnCreated(); - } - - public Northwind(IDbConnection connection, MappingSource mappingSource) - : base(connection, mappingSource) - { - OnCreated(); - } - - public Table Categories { get { return GetTable(); } } - public Table Customers { get { return GetTable(); } } - public Table CustomerCustomerDemo { get { return GetTable(); } } - public Table CustomerDemographics { get { return GetTable(); } } - public Table Employees { get { return GetTable(); } } - public Table EmployeeTerritories { get { return GetTable(); } } - public Table Orders { get { return GetTable(); } } - public Table OrderDetails { get { return GetTable(); } } - public Table Products { get { return GetTable(); } } - public Table Regions { get { return GetTable(); } } - public Table Shippers { get { return GetTable(); } } - public Table Suppliers { get { return GetTable(); } } - public Table Territories { get { return GetTable(); } } - - } - - [Table(Name = "main.Categories")] - public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCategoryIDChanged(); - partial void OnCategoryIDChanging(int value); - partial void OnCategoryNameChanged(); - partial void OnCategoryNameChanging(string value); - partial void OnDescriptionChanged(); - partial void OnDescriptionChanging(string value); - partial void OnPictureChanged(); - partial void OnPictureChanging(Byte[] value); - - #endregion - - #region int CategoryID - - private int _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int CategoryID - { - get - { - return _categoryID; - } - set - { - if (value != _categoryID) - { - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); - } - } - } - - #endregion - - #region string CategoryName - - private string _categoryName; - [DebuggerNonUserCode] - [Column(Storage = "_categoryName", Name = "CategoryName", DbType = "nvarchar (15)", AutoSync = AutoSync.Never)] - public string CategoryName - { - get - { - return _categoryName; - } - set - { - if (value != _categoryName) - { - OnCategoryNameChanging(value); - SendPropertyChanging(); - _categoryName = value; - SendPropertyChanged("CategoryName"); - OnCategoryNameChanged(); - } - } - } - - #endregion - - #region string Description - - private string _description; - [DebuggerNonUserCode] - [Column(Storage = "_description", Name = "Description", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Description - { - get - { - return _description; - } - set - { - if (value != _description) - { - OnDescriptionChanging(value); - SendPropertyChanging(); - _description = value; - SendPropertyChanged("Description"); - OnDescriptionChanged(); - } - } - } - - #endregion - - #region Byte[] Picture - - private Byte[] _picture; - [DebuggerNonUserCode] - [Column(Storage = "_picture", Name = "Picture", DbType = "image", AutoSync = AutoSync.Never, CanBeNull = true)] - public Byte[] Picture - { - get - { - return _picture; - } - set - { - if (value != _picture) - { - OnPictureChanging(value); - SendPropertyChanging(); - _picture = value; - SendPropertyChanged("Picture"); - OnPictureChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "fk_Products_1")] - [DebuggerNonUserCode] - public EntitySet Products - { - get - { - return _products; - } - set - { - _products = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) - { - entity.Category = this; - } - - private void Products_Detach(Product entity) - { - entity.Category = null; - } - - - #endregion - - #region ctor - - public Category() - { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Customers")] - public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnAddressChanged(); - partial void OnAddressChanging(string value); - partial void OnCityChanged(); - partial void OnCityChanging(string value); - partial void OnCompanyNameChanged(); - partial void OnCompanyNameChanging(string value); - partial void OnContactNameChanged(); - partial void OnContactNameChanging(string value); - partial void OnContactTitleChanged(); - partial void OnContactTitleChanging(string value); - partial void OnCountryChanged(); - partial void OnCountryChanging(string value); - partial void OnCustomerIDChanged(); - partial void OnCustomerIDChanging(string value); - partial void OnFaxChanged(); - partial void OnFaxChanging(string value); - partial void OnPhoneChanged(); - partial void OnPhoneChanging(string value); - partial void OnPostalCodeChanged(); - partial void OnPostalCodeChanging(string value); - partial void OnRegionChanged(); - partial void OnRegionChanging(string value); - - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Address - { - get - { - return _address; - } - set - { - if (value != _address) - { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); - } - } - } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string City - { - get - { - return _city; - } - set - { - if (value != _city) - { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); - } - } - } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never)] - public string CompanyName - { - get - { - return _companyName; - } - set - { - if (value != _companyName) - { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); - } - } - } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar (30)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ContactName - { - get - { - return _contactName; - } - set - { - if (value != _contactName) - { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); - } - } - } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar (30)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ContactTitle - { - get - { - return _contactTitle; - } - set - { - if (value != _contactTitle) - { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); - } - } - } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Country - { - get - { - return _country; - } - set - { - if (value != _country) - { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); - } - } - } - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", IsPrimaryKey = true, AutoSync = AutoSync.Never)] - public string CustomerID - { - get - { - return _customerID; - } - set - { - if (value != _customerID) - { - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); - } - } - } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar (24)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Fax - { - get - { - return _fax; - } - set - { - if (value != _fax) - { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); - } - } - } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Phone - { - get - { - return _phone; - } - set - { - if (value != _phone) - { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); - } - } - } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string PostalCode - { - get - { - return _postalCode; - } - set - { - if (value != _postalCode) - { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); - } - } - } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Region - { - get - { - return _region; - } - set - { - if (value != _region) - { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_CustomerCustomerDemo_0")] - [DebuggerNonUserCode] - public EntitySet CustomerCustomerDemo - { - get - { - return _customerCustomerDemo; - } - set - { - _customerCustomerDemo = value; - } - } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_Orders_2")] - [DebuggerNonUserCode] - public EntitySet Orders - { - get - { - return _orders; - } - set - { - _orders = value; - } - } - - - #endregion - - #region Attachement handlers - - private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) - { - entity.Customer = this; - } - - private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) - { - entity.Customer = null; - } - - private void Orders_Attach(Order entity) - { - entity.Customer = this; - } - - private void Orders_Detach(Order entity) - { - entity.Customer = null; - } - - - #endregion - - #region ctor - - public Customer() - { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.CustomerCustomerDemo")] - public partial class CustomerCustomerDemo : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCustomerIDChanged(); - partial void OnCustomerIDChanging(string value); - partial void OnCustomerTypeIDChanged(); - partial void OnCustomerTypeIDChanging(string value); - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", IsPrimaryKey = true, AutoSync = AutoSync.Never)] - public string CustomerID - { - get - { - return _customerID; - } - set - { - if (value != _customerID) - { - if (_customer.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); - } - } - } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] - public string CustomerTypeID - { - get - { - return _customerTypeID; - } - set - { - if (value != _customerTypeID) - { - if (_customerDemographic.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); - } - } - } - - #endregion - - #region Parents - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_CustomerCustomerDemo_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Customer Customer - { - get - { - return _customer.Entity; - } - set - { - if (value != _customer.Entity) - { - if (_customer.Entity != null) - { - var previousCustomer = _customer.Entity; - _customer.Entity = null; - previousCustomer.CustomerCustomerDemo.Remove(this); - } - _customer.Entity = value; - if (value != null) - { - value.CustomerCustomerDemo.Add(this); - _customerID = value.CustomerID; - } - else - { - _customerID = default(string); - } - } - } - } - - private EntityRef _customerDemographic; - [Association(Storage = "_customerDemographic", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "fk_CustomerCustomerDemo_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public CustomerDemographic CustomerDemographic - { - get - { - return _customerDemographic.Entity; - } - set - { - if (value != _customerDemographic.Entity) - { - if (_customerDemographic.Entity != null) - { - var previousCustomerDemographic = _customerDemographic.Entity; - _customerDemographic.Entity = null; - previousCustomerDemographic.CustomerCustomerDemo.Remove(this); - } - _customerDemographic.Entity = value; - if (value != null) - { - value.CustomerCustomerDemo.Add(this); - _customerTypeID = value.CustomerTypeID; - } - else - { - _customerTypeID = default(string); - } - } - } - } - - - #endregion - - #region ctor - - public CustomerCustomerDemo() - { - _customer = new EntityRef(); - _customerDemographic = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.CustomerDemographics")] - public partial class CustomerDemographic : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCustomerDescChanged(); - partial void OnCustomerDescChanging(string value); - partial void OnCustomerTypeIDChanged(); - partial void OnCustomerTypeIDChanging(string value); - - #endregion - - #region string CustomerDesc - - private string _customerDesc; - [DebuggerNonUserCode] - [Column(Storage = "_customerDesc", Name = "CustomerDesc", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] - public string CustomerDesc - { - get - { - return _customerDesc; - } - set - { - if (value != _customerDesc) - { - OnCustomerDescChanging(value); - SendPropertyChanging(); - _customerDesc = value; - SendPropertyChanged("CustomerDesc"); - OnCustomerDescChanged(); - } - } - } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] - public string CustomerTypeID - { - get - { - return _customerTypeID; - } - set - { - if (value != _customerTypeID) - { - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "fk_CustomerCustomerDemo_1")] - [DebuggerNonUserCode] - public EntitySet CustomerCustomerDemo - { - get - { - return _customerCustomerDemo; - } - set - { - _customerCustomerDemo = value; - } - } - - - #endregion - - #region Attachement handlers - - private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) - { - entity.CustomerDemographic = this; - } - - private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) - { - entity.CustomerDemographic = null; - } - - - #endregion - - #region ctor - - public CustomerDemographic() - { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Employees")] - public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnAddressChanged(); - partial void OnAddressChanging(string value); - partial void OnBirthDateChanged(); - partial void OnBirthDateChanging(DateTime? value); - partial void OnCityChanged(); - partial void OnCityChanging(string value); - partial void OnCountryChanged(); - partial void OnCountryChanging(string value); - partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(int value); - partial void OnExtensionChanged(); - partial void OnExtensionChanging(string value); - partial void OnFirstNameChanged(); - partial void OnFirstNameChanging(string value); - partial void OnHireDateChanged(); - partial void OnHireDateChanging(DateTime? value); - partial void OnHomePhoneChanged(); - partial void OnHomePhoneChanging(string value); - partial void OnLastNameChanged(); - partial void OnLastNameChanging(string value); - partial void OnNotesChanged(); - partial void OnNotesChanging(string value); - partial void OnPhotoChanged(); - partial void OnPhotoChanging(Byte[] value); - partial void OnPhotoPathChanged(); - partial void OnPhotoPathChanging(string value); - partial void OnPostalCodeChanged(); - partial void OnPostalCodeChanging(string value); - partial void OnRegionChanged(); - partial void OnRegionChanging(string value); - partial void OnReportsToChanged(); - partial void OnReportsToChanging(int? value); - partial void OnTitleChanged(); - partial void OnTitleChanging(string value); - partial void OnTitleOfCourtesyChanged(); - partial void OnTitleOfCourtesyChanging(string value); - - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Address - { - get - { - return _address; - } - set - { - if (value != _address) - { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); - } - } - } - - #endregion - - #region DateTime? BirthDate - - private DateTime? _birthDate; - [DebuggerNonUserCode] - [Column(Storage = "_birthDate", Name = "BirthDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? BirthDate - { - get - { - return _birthDate; - } - set - { - if (value != _birthDate) - { - OnBirthDateChanging(value); - SendPropertyChanging(); - _birthDate = value; - SendPropertyChanged("BirthDate"); - OnBirthDateChanged(); - } - } - } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string City - { - get - { - return _city; - } - set - { - if (value != _city) - { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); - } - } - } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Country - { - get - { - return _country; - } - set - { - if (value != _country) - { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); - } - } - } - - #endregion - - #region int EmployeeID - - private int _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int EmployeeID - { - get - { - return _employeeID; - } - set - { - if (value != _employeeID) - { - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); - } - } - } - - #endregion - - #region string Extension - - private string _extension; - [DebuggerNonUserCode] - [Column(Storage = "_extension", Name = "Extension", DbType = "nvarchar (4)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Extension - { - get - { - return _extension; - } - set - { - if (value != _extension) - { - OnExtensionChanging(value); - SendPropertyChanging(); - _extension = value; - SendPropertyChanged("Extension"); - OnExtensionChanged(); - } - } - } - - #endregion - - #region string FirstName - - private string _firstName; - [DebuggerNonUserCode] - [Column(Storage = "_firstName", Name = "FirstName", DbType = "nvarchar (10)", AutoSync = AutoSync.Never)] - public string FirstName - { - get - { - return _firstName; - } - set - { - if (value != _firstName) - { - OnFirstNameChanging(value); - SendPropertyChanging(); - _firstName = value; - SendPropertyChanged("FirstName"); - OnFirstNameChanged(); - } - } - } - - #endregion - - #region DateTime? HireDate - - private DateTime? _hireDate; - [DebuggerNonUserCode] - [Column(Storage = "_hireDate", Name = "HireDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? HireDate - { - get - { - return _hireDate; - } - set - { - if (value != _hireDate) - { - OnHireDateChanging(value); - SendPropertyChanging(); - _hireDate = value; - SendPropertyChanged("HireDate"); - OnHireDateChanged(); - } - } - } - - #endregion - - #region string HomePhone - - private string _homePhone; - [DebuggerNonUserCode] - [Column(Storage = "_homePhone", Name = "HomePhone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string HomePhone - { - get - { - return _homePhone; - } - set - { - if (value != _homePhone) - { - OnHomePhoneChanging(value); - SendPropertyChanging(); - _homePhone = value; - SendPropertyChanged("HomePhone"); - OnHomePhoneChanged(); - } - } - } - - #endregion - - #region string LastName - - private string _lastName; - [DebuggerNonUserCode] - [Column(Storage = "_lastName", Name = "LastName", DbType = "nvarchar (20)", AutoSync = AutoSync.Never)] - public string LastName - { - get - { - return _lastName; - } - set - { - if (value != _lastName) - { - OnLastNameChanging(value); - SendPropertyChanging(); - _lastName = value; - SendPropertyChanged("LastName"); - OnLastNameChanged(); - } - } - } - - #endregion - - #region string Notes - - private string _notes; - [DebuggerNonUserCode] - [Column(Storage = "_notes", Name = "Notes", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Notes - { - get - { - return _notes; - } - set - { - if (value != _notes) - { - OnNotesChanging(value); - SendPropertyChanging(); - _notes = value; - SendPropertyChanged("Notes"); - OnNotesChanged(); - } - } - } - - #endregion - - #region Byte[] Photo - - private Byte[] _photo; - [DebuggerNonUserCode] - [Column(Storage = "_photo", Name = "Photo", DbType = "image", AutoSync = AutoSync.Never, CanBeNull = true)] - public Byte[] Photo - { - get - { - return _photo; - } - set - { - if (value != _photo) - { - OnPhotoChanging(value); - SendPropertyChanging(); - _photo = value; - SendPropertyChanged("Photo"); - OnPhotoChanged(); - } - } - } - - #endregion - - #region string PhotoPath - - private string _photoPath; - [DebuggerNonUserCode] - [Column(Storage = "_photoPath", Name = "PhotoPath", DbType = "nvarchar (255)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string PhotoPath - { - get - { - return _photoPath; - } - set - { - if (value != _photoPath) - { - OnPhotoPathChanging(value); - SendPropertyChanging(); - _photoPath = value; - SendPropertyChanged("PhotoPath"); - OnPhotoPathChanged(); - } - } - } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string PostalCode - { - get - { - return _postalCode; - } - set - { - if (value != _postalCode) - { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); - } - } - } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Region - { - get - { - return _region; - } - set - { - if (value != _region) - { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); - } - } - } - - #endregion - - #region int? ReportsTo - - private int? _reportsTo; - [DebuggerNonUserCode] - [Column(Storage = "_reportsTo", Name = "ReportsTo", DbType = "INTEGER", AutoSync = AutoSync.Never, CanBeNull = true)] - public int? ReportsTo - { - get - { - return _reportsTo; - } - set - { - if (value != _reportsTo) - { - if (_reportsToEmployee.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnReportsToChanging(value); - SendPropertyChanging(); - _reportsTo = value; - SendPropertyChanged("ReportsTo"); - OnReportsToChanged(); - } - } - } - - #endregion - - #region string Title - - private string _title; - [DebuggerNonUserCode] - [Column(Storage = "_title", Name = "Title", DbType = "nvarchar (30)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Title - { - get - { - return _title; - } - set - { - if (value != _title) - { - OnTitleChanging(value); - SendPropertyChanging(); - _title = value; - SendPropertyChanged("Title"); - OnTitleChanged(); - } - } - } - - #endregion - - #region string TitleOfCourtesy - - private string _titleOfCourtesy; - [DebuggerNonUserCode] - [Column(Storage = "_titleOfCourtesy", Name = "TitleOfCourtesy", DbType = "nvarchar (25)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string TitleOfCourtesy - { - get - { - return _titleOfCourtesy; - } - set - { - if (value != _titleOfCourtesy) - { - OnTitleOfCourtesyChanging(value); - SendPropertyChanging(); - _titleOfCourtesy = value; - SendPropertyChanged("TitleOfCourtesy"); - OnTitleOfCourtesyChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_EmployeeTerritories_1")] - [DebuggerNonUserCode] - public EntitySet EmployeeTerritories - { - get - { - return _employeeTerritories; - } - set - { - _employeeTerritories = value; - } - } - - private EntitySet _employees; - [Association(Storage = "_employees", OtherKey = "ReportsTo", ThisKey = "EmployeeID", Name = "fk_Employees_0")] - [DebuggerNonUserCode] - public EntitySet Employees - { - get - { - return _employees; - } - set - { - _employees = value; - } - } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_Orders_1")] - [DebuggerNonUserCode] - public EntitySet Orders - { - get - { - return _orders; - } - set - { - _orders = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _reportsToEmployee; - [Association(Storage = "_reportsToEmployee", OtherKey = "EmployeeID", ThisKey = "ReportsTo", Name = "fk_Employees_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Employee ReportsToEmployee - { - get - { - return _reportsToEmployee.Entity; - } - set - { - if (value != _reportsToEmployee.Entity) - { - if (_reportsToEmployee.Entity != null) - { - var previousEmployee = _reportsToEmployee.Entity; - _reportsToEmployee.Entity = null; - previousEmployee.Employees.Remove(this); - } - _reportsToEmployee.Entity = value; - if (value != null) - { - value.Employees.Add(this); - _reportsTo = value.EmployeeID; - } - else - { - _reportsTo = null; - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void EmployeeTerritories_Attach(EmployeeTerritory entity) - { - entity.Employee = this; - } - - private void EmployeeTerritories_Detach(EmployeeTerritory entity) - { - entity.Employee = null; - } - - private void Employees_Attach(Employee entity) - { - entity.ReportsToEmployee = this; - } - - private void Employees_Detach(Employee entity) - { - entity.ReportsToEmployee = null; - } - - private void Orders_Attach(Order entity) - { - entity.Employee = this; - } - - private void Orders_Detach(Order entity) - { - entity.Employee = null; - } - - - #endregion - - #region ctor - - public Employee() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _employees = new EntitySet(Employees_Attach, Employees_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - _reportsToEmployee = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.EmployeeTerritories")] - public partial class EmployeeTerritory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(int value); - partial void OnTerritoryIDChanged(); - partial void OnTerritoryIDChanging(string value); - - #endregion - - #region int EmployeeID - - private int _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int EmployeeID - { - get - { - return _employeeID; - } - set - { - if (value != _employeeID) - { - if (_employee.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); - } - } - } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] - public string TerritoryID - { - get - { - return _territoryID; - } - set - { - if (value != _territoryID) - { - if (_territory.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); - } - } - } - - #endregion - - #region Parents - - private EntityRef _territory; - [Association(Storage = "_territory", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "fk_EmployeeTerritories_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Territory Territory - { - get - { - return _territory.Entity; - } - set - { - if (value != _territory.Entity) - { - if (_territory.Entity != null) - { - var previousTerritory = _territory.Entity; - _territory.Entity = null; - previousTerritory.EmployeeTerritories.Remove(this); - } - _territory.Entity = value; - if (value != null) - { - value.EmployeeTerritories.Add(this); - _territoryID = value.TerritoryID; - } - else - { - _territoryID = default(string); - } - } - } - } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_EmployeeTerritories_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public Employee Employee - { - get - { - return _employee.Entity; - } - set - { - if (value != _employee.Entity) - { - if (_employee.Entity != null) - { - var previousEmployee = _employee.Entity; - _employee.Entity = null; - previousEmployee.EmployeeTerritories.Remove(this); - } - _employee.Entity = value; - if (value != null) - { - value.EmployeeTerritories.Add(this); - _employeeID = value.EmployeeID; - } - else - { - _employeeID = default(int); - } - } - } - } - - - #endregion - - #region ctor - - public EmployeeTerritory() - { - _territory = new EntityRef(); - _employee = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Orders")] - public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCustomerIDChanged(); - partial void OnCustomerIDChanging(string value); - partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(int? value); - partial void OnFreightChanged(); - partial void OnFreightChanging(decimal? value); - partial void OnOrderDateChanged(); - partial void OnOrderDateChanging(DateTime? value); - partial void OnOrderIDChanged(); - partial void OnOrderIDChanging(int value); - partial void OnRequiredDateChanged(); - partial void OnRequiredDateChanging(DateTime? value); - partial void OnShipAddressChanged(); - partial void OnShipAddressChanging(string value); - partial void OnShipCityChanged(); - partial void OnShipCityChanging(string value); - partial void OnShipCountryChanged(); - partial void OnShipCountryChanging(string value); - partial void OnShipNameChanged(); - partial void OnShipNameChanging(string value); - partial void OnShippedDateChanged(); - partial void OnShippedDateChanging(DateTime? value); - partial void OnShipPostalCodeChanged(); - partial void OnShipPostalCodeChanging(string value); - partial void OnShipRegionChanged(); - partial void OnShipRegionChanging(string value); - partial void OnShipViaChanged(); - partial void OnShipViaChanging(int? value); - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar (5)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string CustomerID - { - get - { - return _customerID; - } - set - { - if (value != _customerID) - { - if (_customer.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); - } - } - } - - #endregion - - #region int? EmployeeID - - private int? _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "INTEGER", AutoSync = AutoSync.Never, CanBeNull = true)] - public int? EmployeeID - { - get - { - return _employeeID; - } - set - { - if (value != _employeeID) - { - if (_employee.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); - } - } - } - - #endregion - - #region decimal? Freight - - private decimal? _freight; - [DebuggerNonUserCode] - [Column(Storage = "_freight", Name = "Freight", DbType = "money", AutoSync = AutoSync.Never, CanBeNull = true)] - public decimal? Freight - { - get - { - return _freight; - } - set - { - if (value != _freight) - { - OnFreightChanging(value); - SendPropertyChanging(); - _freight = value; - SendPropertyChanged("Freight"); - OnFreightChanged(); - } - } - } - - #endregion - - #region DateTime? OrderDate - - private DateTime? _orderDate; - [DebuggerNonUserCode] - [Column(Storage = "_orderDate", Name = "OrderDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? OrderDate - { - get - { - return _orderDate; - } - set - { - if (value != _orderDate) - { - OnOrderDateChanging(value); - SendPropertyChanging(); - _orderDate = value; - SendPropertyChanged("OrderDate"); - OnOrderDateChanged(); - } - } - } - - #endregion - - #region int OrderID - - private int _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int OrderID - { - get - { - return _orderID; - } - set - { - if (value != _orderID) - { - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); - } - } - } - - #endregion - - #region DateTime? RequiredDate - - private DateTime? _requiredDate; - [DebuggerNonUserCode] - [Column(Storage = "_requiredDate", Name = "RequiredDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? RequiredDate - { - get - { - return _requiredDate; - } - set - { - if (value != _requiredDate) - { - OnRequiredDateChanging(value); - SendPropertyChanging(); - _requiredDate = value; - SendPropertyChanged("RequiredDate"); - OnRequiredDateChanged(); - } - } - } - - #endregion - - #region string ShipAddress - - private string _shipAddress; - [DebuggerNonUserCode] - [Column(Storage = "_shipAddress", Name = "ShipAddress", DbType = "nvarchar (60)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ShipAddress - { - get - { - return _shipAddress; - } - set - { - if (value != _shipAddress) - { - OnShipAddressChanging(value); - SendPropertyChanging(); - _shipAddress = value; - SendPropertyChanged("ShipAddress"); - OnShipAddressChanged(); - } - } - } - - #endregion - - #region string ShipCity - - private string _shipCity; - [DebuggerNonUserCode] - [Column(Storage = "_shipCity", Name = "ShipCity", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ShipCity - { - get - { - return _shipCity; - } - set - { - if (value != _shipCity) - { - OnShipCityChanging(value); - SendPropertyChanging(); - _shipCity = value; - SendPropertyChanged("ShipCity"); - OnShipCityChanged(); - } - } - } - - #endregion - - #region string ShipCountry - - private string _shipCountry; - [DebuggerNonUserCode] - [Column(Storage = "_shipCountry", Name = "ShipCountry", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ShipCountry - { - get - { - return _shipCountry; - } - set - { - if (value != _shipCountry) - { - OnShipCountryChanging(value); - SendPropertyChanging(); - _shipCountry = value; - SendPropertyChanged("ShipCountry"); - OnShipCountryChanged(); - } - } - } - - #endregion - - #region string ShipName - - private string _shipName; - [DebuggerNonUserCode] - [Column(Storage = "_shipName", Name = "ShipName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ShipName - { - get - { - return _shipName; - } - set - { - if (value != _shipName) - { - OnShipNameChanging(value); - SendPropertyChanging(); - _shipName = value; - SendPropertyChanged("ShipName"); - OnShipNameChanged(); - } - } - } - - #endregion - - #region DateTime? ShippedDate - - private DateTime? _shippedDate; - [DebuggerNonUserCode] - [Column(Storage = "_shippedDate", Name = "ShippedDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? ShippedDate - { - get - { - return _shippedDate; - } - set - { - if (value != _shippedDate) - { - OnShippedDateChanging(value); - SendPropertyChanging(); - _shippedDate = value; - SendPropertyChanged("ShippedDate"); - OnShippedDateChanged(); - } - } - } - - #endregion - - #region string ShipPostalCode - - private string _shipPostalCode; - [DebuggerNonUserCode] - [Column(Storage = "_shipPostalCode", Name = "ShipPostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ShipPostalCode - { - get - { - return _shipPostalCode; - } - set - { - if (value != _shipPostalCode) - { - OnShipPostalCodeChanging(value); - SendPropertyChanging(); - _shipPostalCode = value; - SendPropertyChanged("ShipPostalCode"); - OnShipPostalCodeChanged(); - } - } - } - - #endregion - - #region string ShipRegion - - private string _shipRegion; - [DebuggerNonUserCode] - [Column(Storage = "_shipRegion", Name = "ShipRegion", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ShipRegion - { - get - { - return _shipRegion; - } - set - { - if (value != _shipRegion) - { - OnShipRegionChanging(value); - SendPropertyChanging(); - _shipRegion = value; - SendPropertyChanged("ShipRegion"); - OnShipRegionChanged(); - } - } - } - - #endregion - - #region int? ShipVia - - private int? _shipVia; - [DebuggerNonUserCode] - [Column(Storage = "_shipVia", Name = "ShipVia", DbType = "INTEGER", AutoSync = AutoSync.Never, CanBeNull = true)] - public int? ShipVia - { - get - { - return _shipVia; - } - set - { - if (value != _shipVia) - { - if (_shipper.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnShipViaChanging(value); - SendPropertyChanging(); - _shipVia = value; - SendPropertyChanged("ShipVia"); - OnShipViaChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"fk_Order Details_1\"")] - [DebuggerNonUserCode] - public EntitySet OrderDetails - { - get - { - return _orderDetails; - } - set - { - _orderDetails = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _shipper; - [Association(Storage = "_shipper", OtherKey = "ShipperID", ThisKey = "ShipVia", Name = "fk_Orders_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Shipper Shipper - { - get - { - return _shipper.Entity; - } - set - { - if (value != _shipper.Entity) - { - if (_shipper.Entity != null) - { - var previousShipper = _shipper.Entity; - _shipper.Entity = null; - previousShipper.Orders.Remove(this); - } - _shipper.Entity = value; - if (value != null) - { - value.Orders.Add(this); - _shipVia = value.ShipperID; - } - else - { - _shipVia = null; - } - } - } - } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "fk_Orders_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public Employee Employee - { - get - { - return _employee.Entity; - } - set - { - if (value != _employee.Entity) - { - if (_employee.Entity != null) - { - var previousEmployee = _employee.Entity; - _employee.Entity = null; - previousEmployee.Orders.Remove(this); - } - _employee.Entity = value; - if (value != null) - { - value.Orders.Add(this); - _employeeID = value.EmployeeID; - } - else - { - _employeeID = null; - } - } - } - } - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "fk_Orders_2", IsForeignKey = true)] - [DebuggerNonUserCode] - public Customer Customer - { - get - { - return _customer.Entity; - } - set - { - if (value != _customer.Entity) - { - if (_customer.Entity != null) - { - var previousCustomer = _customer.Entity; - _customer.Entity = null; - previousCustomer.Orders.Remove(this); - } - _customer.Entity = value; - if (value != null) - { - value.Orders.Add(this); - _customerID = value.CustomerID; - } - else - { - _customerID = null; - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) - { - entity.Order = this; - } - - private void OrderDetails_Detach(OrderDetail entity) - { - entity.Order = null; - } - - - #endregion - - #region ctor - - public Order() - { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _shipper = new EntityRef(); - _employee = new EntityRef(); - _customer = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.\"Order Details\"")] - public partial class OrderDetail : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnDiscountChanged(); - partial void OnDiscountChanging(float value); - partial void OnOrderIDChanged(); - partial void OnOrderIDChanging(int value); - partial void OnProductIDChanged(); - partial void OnProductIDChanging(int value); - partial void OnQuantityChanged(); - partial void OnQuantityChanging(short value); - partial void OnUnitPriceChanged(); - partial void OnUnitPriceChanging(decimal value); - - #endregion - - #region float Discount - - private float _discount; - [DebuggerNonUserCode] - [Column(Storage = "_discount", Name = "Discount", DbType = "real", AutoSync = AutoSync.Never)] - public float Discount - { - get - { - return _discount; - } - set - { - if (value != _discount) - { - OnDiscountChanging(value); - SendPropertyChanging(); - _discount = value; - SendPropertyChanged("Discount"); - OnDiscountChanged(); - } - } - } - - #endregion - - #region int OrderID - - private int _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int OrderID - { - get - { - return _orderID; - } - set - { - if (value != _orderID) - { - if (_order.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); - } - } - } - - #endregion - - #region int ProductID - - private int _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int ProductID - { - get - { - return _productID; - } - set - { - if (value != _productID) - { - if (_product.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); - } - } - } - - #endregion - - #region short Quantity - - private short _quantity; - [DebuggerNonUserCode] - [Column(Storage = "_quantity", Name = "Quantity", DbType = "smallint", AutoSync = AutoSync.Never)] - public short Quantity - { - get - { - return _quantity; - } - set - { - if (value != _quantity) - { - OnQuantityChanging(value); - SendPropertyChanging(); - _quantity = value; - SendPropertyChanged("Quantity"); - OnQuantityChanged(); - } - } - } - - #endregion - - #region decimal UnitPrice - - private decimal _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never)] - public decimal UnitPrice - { - get - { - return _unitPrice; - } - set - { - if (value != _unitPrice) - { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); - } - } - } - - #endregion - - #region Parents - - private EntityRef _product; - [Association(Storage = "_product", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"fk_Order Details_0\"", IsForeignKey = true)] - [DebuggerNonUserCode] - public Product Product - { - get - { - return _product.Entity; - } - set - { - if (value != _product.Entity) - { - if (_product.Entity != null) - { - var previousProduct = _product.Entity; - _product.Entity = null; - previousProduct.OrderDetails.Remove(this); - } - _product.Entity = value; - if (value != null) - { - value.OrderDetails.Add(this); - _productID = value.ProductID; - } - else - { - _productID = default(int); - } - } - } - } - - private EntityRef _order; - [Association(Storage = "_order", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"fk_Order Details_1\"", IsForeignKey = true)] - [DebuggerNonUserCode] - public Order Order - { - get - { - return _order.Entity; - } - set - { - if (value != _order.Entity) - { - if (_order.Entity != null) - { - var previousOrder = _order.Entity; - _order.Entity = null; - previousOrder.OrderDetails.Remove(this); - } - _order.Entity = value; - if (value != null) - { - value.OrderDetails.Add(this); - _orderID = value.OrderID; - } - else - { - _orderID = default(int); - } - } - } - } - - - #endregion - - #region ctor - - public OrderDetail() - { - _product = new EntityRef(); - _order = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Products")] - public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCategoryIDChanged(); - partial void OnCategoryIDChanging(int? value); - partial void OnDiscontinuedChanged(); - partial void OnDiscontinuedChanging(bool value); - partial void OnProductIDChanged(); - partial void OnProductIDChanging(int value); - partial void OnProductNameChanged(); - partial void OnProductNameChanging(string value); - partial void OnQuantityPerUnitChanged(); - partial void OnQuantityPerUnitChanging(string value); - partial void OnReorderLevelChanged(); - partial void OnReorderLevelChanging(short? value); - partial void OnSupplierIDChanged(); - partial void OnSupplierIDChanging(int? value); - partial void OnUnitPriceChanged(); - partial void OnUnitPriceChanging(decimal? value); - partial void OnUnitsInStockChanged(); - partial void OnUnitsInStockChanging(short? value); - partial void OnUnitsOnOrderChanged(); - partial void OnUnitsOnOrderChanging(short? value); - - #endregion - - #region int? CategoryID - - private int? _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "INTEGER", AutoSync = AutoSync.Never, CanBeNull = true)] - public int? CategoryID - { - get - { - return _categoryID; - } - set - { - if (value != _categoryID) - { - if (_category.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); - } - } - } - - #endregion - - #region bool Discontinued - - private bool _discontinued; - [DebuggerNonUserCode] - [Column(Storage = "_discontinued", Name = "Discontinued", DbType = "bit", AutoSync = AutoSync.Never)] - public bool Discontinued - { - get - { - return _discontinued; - } - set - { - if (value != _discontinued) - { - OnDiscontinuedChanging(value); - SendPropertyChanging(); - _discontinued = value; - SendPropertyChanged("Discontinued"); - OnDiscontinuedChanged(); - } - } - } - - #endregion - - #region int ProductID - - private int _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int ProductID - { - get - { - return _productID; - } - set - { - if (value != _productID) - { - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); - } - } - } - - #endregion - - #region string ProductName - - private string _productName; - [DebuggerNonUserCode] - [Column(Storage = "_productName", Name = "ProductName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never)] - public string ProductName - { - get - { - return _productName; - } - set - { - if (value != _productName) - { - OnProductNameChanging(value); - SendPropertyChanging(); - _productName = value; - SendPropertyChanged("ProductName"); - OnProductNameChanged(); - } - } - } - - #endregion - - #region string QuantityPerUnit - - private string _quantityPerUnit; - [DebuggerNonUserCode] - [Column(Storage = "_quantityPerUnit", Name = "QuantityPerUnit", DbType = "nvarchar (20)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string QuantityPerUnit - { - get - { - return _quantityPerUnit; - } - set - { - if (value != _quantityPerUnit) - { - OnQuantityPerUnitChanging(value); - SendPropertyChanging(); - _quantityPerUnit = value; - SendPropertyChanged("QuantityPerUnit"); - OnQuantityPerUnitChanged(); - } - } - } - - #endregion - - #region short? ReorderLevel - - private short? _reorderLevel; - [DebuggerNonUserCode] - [Column(Storage = "_reorderLevel", Name = "ReorderLevel", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = true)] - public short? ReorderLevel - { - get - { - return _reorderLevel; - } - set - { - if (value != _reorderLevel) - { - OnReorderLevelChanging(value); - SendPropertyChanging(); - _reorderLevel = value; - SendPropertyChanged("ReorderLevel"); - OnReorderLevelChanged(); - } - } - } - - #endregion - - #region int? SupplierID - - private int? _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "INTEGER", AutoSync = AutoSync.Never, CanBeNull = true)] - public int? SupplierID - { - get - { - return _supplierID; - } - set - { - if (value != _supplierID) - { - if (_supplier.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); - } - } - } - - #endregion - - #region decimal? UnitPrice - - private decimal? _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never, CanBeNull = true)] - public decimal? UnitPrice - { - get - { - return _unitPrice; - } - set - { - if (value != _unitPrice) - { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); - } - } - } - - #endregion - - #region short? UnitsInStock - - private short? _unitsInStock; - [DebuggerNonUserCode] - [Column(Storage = "_unitsInStock", Name = "UnitsInStock", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = true)] - public short? UnitsInStock - { - get - { - return _unitsInStock; - } - set - { - if (value != _unitsInStock) - { - OnUnitsInStockChanging(value); - SendPropertyChanging(); - _unitsInStock = value; - SendPropertyChanged("UnitsInStock"); - OnUnitsInStockChanged(); - } - } - } - - #endregion - - #region short? UnitsOnOrder - - private short? _unitsOnOrder; - [DebuggerNonUserCode] - [Column(Storage = "_unitsOnOrder", Name = "UnitsOnOrder", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = true)] - public short? UnitsOnOrder - { - get - { - return _unitsOnOrder; - } - set - { - if (value != _unitsOnOrder) - { - OnUnitsOnOrderChanging(value); - SendPropertyChanging(); - _unitsOnOrder = value; - SendPropertyChanged("UnitsOnOrder"); - OnUnitsOnOrderChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"fk_Order Details_0\"")] - [DebuggerNonUserCode] - public EntitySet OrderDetails - { - get - { - return _orderDetails; - } - set - { - _orderDetails = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _supplier; - [Association(Storage = "_supplier", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "fk_Products_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Supplier Supplier - { - get - { - return _supplier.Entity; - } - set - { - if (value != _supplier.Entity) - { - if (_supplier.Entity != null) - { - var previousSupplier = _supplier.Entity; - _supplier.Entity = null; - previousSupplier.Products.Remove(this); - } - _supplier.Entity = value; - if (value != null) - { - value.Products.Add(this); - _supplierID = value.SupplierID; - } - else - { - _supplierID = null; - } - } - } - } - - private EntityRef _category; - [Association(Storage = "_category", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "fk_Products_1", IsForeignKey = true)] - [DebuggerNonUserCode] - public Category Category - { - get - { - return _category.Entity; - } - set - { - if (value != _category.Entity) - { - if (_category.Entity != null) - { - var previousCategory = _category.Entity; - _category.Entity = null; - previousCategory.Products.Remove(this); - } - _category.Entity = value; - if (value != null) - { - value.Products.Add(this); - _categoryID = value.CategoryID; - } - else - { - _categoryID = null; - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) - { - entity.Product = this; - } - - private void OrderDetails_Detach(OrderDetail entity) - { - entity.Product = null; - } - - - #endregion - - #region ctor - - public Product() - { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _supplier = new EntityRef(); - _category = new EntityRef(); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Region")] - public partial class Region : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnRegionDescriptionChanged(); - partial void OnRegionDescriptionChanging(string value); - partial void OnRegionIDChanged(); - partial void OnRegionIDChanging(int value); - - #endregion - - #region string RegionDescription - - private string _regionDescription; - [DebuggerNonUserCode] - [Column(Storage = "_regionDescription", Name = "RegionDescription", DbType = "nchar", AutoSync = AutoSync.Never)] - public string RegionDescription - { - get - { - return _regionDescription; - } - set - { - if (value != _regionDescription) - { - OnRegionDescriptionChanging(value); - SendPropertyChanging(); - _regionDescription = value; - SendPropertyChanged("RegionDescription"); - OnRegionDescriptionChanged(); - } - } - } - - #endregion - - #region int RegionID - - private int _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int RegionID - { - get - { - return _regionID; - } - set - { - if (value != _regionID) - { - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _territories; - [Association(Storage = "_territories", OtherKey = "RegionID", ThisKey = "RegionID", Name = "fk_Territories_0")] - [DebuggerNonUserCode] - public EntitySet Territories - { - get - { - return _territories; - } - set - { - _territories = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Territories_Attach(Territory entity) - { - entity.Region = this; - } - - private void Territories_Detach(Territory entity) - { - entity.Region = null; - } - - - #endregion - - #region ctor - - public Region() - { - _territories = new EntitySet(Territories_Attach, Territories_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Shippers")] - public partial class Shipper : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnCompanyNameChanged(); - partial void OnCompanyNameChanging(string value); - partial void OnPhoneChanged(); - partial void OnPhoneChanging(string value); - partial void OnShipperIDChanged(); - partial void OnShipperIDChanging(int value); - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never)] - public string CompanyName - { - get - { - return _companyName; - } - set - { - if (value != _companyName) - { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); - } - } - } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Phone - { - get - { - return _phone; - } - set - { - if (value != _phone) - { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); - } - } - } - - #endregion - - #region int ShipperID - - private int _shipperID; - [DebuggerNonUserCode] - [Column(Storage = "_shipperID", Name = "ShipperID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int ShipperID - { - get - { - return _shipperID; - } - set - { - if (value != _shipperID) - { - OnShipperIDChanging(value); - SendPropertyChanging(); - _shipperID = value; - SendPropertyChanged("ShipperID"); - OnShipperIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "ShipVia", ThisKey = "ShipperID", Name = "fk_Orders_0")] - [DebuggerNonUserCode] - public EntitySet Orders - { - get - { - return _orders; - } - set - { - _orders = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Orders_Attach(Order entity) - { - entity.Shipper = this; - } - - private void Orders_Detach(Order entity) - { - entity.Shipper = null; - } - - - #endregion - - #region ctor - - public Shipper() - { - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Suppliers")] - public partial class Supplier : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnAddressChanged(); - partial void OnAddressChanging(string value); - partial void OnCityChanged(); - partial void OnCityChanging(string value); - partial void OnCompanyNameChanged(); - partial void OnCompanyNameChanging(string value); - partial void OnContactNameChanged(); - partial void OnContactNameChanging(string value); - partial void OnContactTitleChanged(); - partial void OnContactTitleChanging(string value); - partial void OnCountryChanged(); - partial void OnCountryChanging(string value); - partial void OnFaxChanged(); - partial void OnFaxChanging(string value); - partial void OnHomePageChanged(); - partial void OnHomePageChanging(string value); - partial void OnPhoneChanged(); - partial void OnPhoneChanging(string value); - partial void OnPostalCodeChanged(); - partial void OnPostalCodeChanging(string value); - partial void OnRegionChanged(); - partial void OnRegionChanging(string value); - partial void OnSupplierIDChanged(); - partial void OnSupplierIDChanging(int value); - - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar (60)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Address - { - get - { - return _address; - } - set - { - if (value != _address) - { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); - } - } - } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string City - { - get - { - return _city; - } - set - { - if (value != _city) - { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); - } - } - } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar (40)", AutoSync = AutoSync.Never)] - public string CompanyName - { - get - { - return _companyName; - } - set - { - if (value != _companyName) - { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); - } - } - } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar (30)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ContactName - { - get - { - return _contactName; - } - set - { - if (value != _contactName) - { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); - } - } - } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar (30)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string ContactTitle - { - get - { - return _contactTitle; - } - set - { - if (value != _contactTitle) - { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); - } - } - } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Country - { - get - { - return _country; - } - set - { - if (value != _country) - { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); - } - } - } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar (24)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Fax - { - get - { - return _fax; - } - set - { - if (value != _fax) - { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); - } - } - } - - #endregion - - #region string HomePage - - private string _homePage; - [DebuggerNonUserCode] - [Column(Storage = "_homePage", Name = "HomePage", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] - public string HomePage - { - get - { - return _homePage; - } - set - { - if (value != _homePage) - { - OnHomePageChanging(value); - SendPropertyChanging(); - _homePage = value; - SendPropertyChanged("HomePage"); - OnHomePageChanged(); - } - } - } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar (24)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Phone - { - get - { - return _phone; - } - set - { - if (value != _phone) - { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); - } - } - } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar (10)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string PostalCode - { - get - { - return _postalCode; - } - set - { - if (value != _postalCode) - { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); - } - } - } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar (15)", AutoSync = AutoSync.Never, CanBeNull = true)] - public string Region - { - get - { - return _region; - } - set - { - if (value != _region) - { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); - } - } - } - - #endregion - - #region int SupplierID - - private int _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "INTEGER", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] - public int SupplierID - { - get - { - return _supplierID; - } - set - { - if (value != _supplierID) - { - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "fk_Products_0")] - [DebuggerNonUserCode] - public EntitySet Products - { - get - { - return _products; - } - set - { - _products = value; - } - } - - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) - { - entity.Supplier = this; - } - - private void Products_Detach(Product entity) - { - entity.Supplier = null; - } - - - #endregion - - #region ctor - - public Supplier() - { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); - } - - #endregion - - } - - [Table(Name = "main.Territories")] - public partial class Territory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - - partial void OnCreated(); - partial void OnRegionIDChanged(); - partial void OnRegionIDChanging(int value); - partial void OnTerritoryDescriptionChanged(); - partial void OnTerritoryDescriptionChanging(string value); - partial void OnTerritoryIDChanged(); - partial void OnTerritoryIDChanging(string value); - - #endregion - - #region int RegionID - - private int _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "INTEGER", AutoSync = AutoSync.Never)] - public int RegionID - { - get - { - return _regionID; - } - set - { - if (value != _regionID) - { - if (_region.HasLoadedOrAssignedValue) - { - throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); - } - } - } - - #endregion - - #region string TerritoryDescription - - private string _territoryDescription; - [DebuggerNonUserCode] - [Column(Storage = "_territoryDescription", Name = "TerritoryDescription", DbType = "nchar", AutoSync = AutoSync.Never)] - public string TerritoryDescription - { - get - { - return _territoryDescription; - } - set - { - if (value != _territoryDescription) - { - OnTerritoryDescriptionChanging(value); - SendPropertyChanging(); - _territoryDescription = value; - SendPropertyChanged("TerritoryDescription"); - OnTerritoryDescriptionChanged(); - } - } - } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] - public string TerritoryID - { - get - { - return _territoryID; - } - set - { - if (value != _territoryID) - { - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); - } - } - } - - #endregion - - #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "fk_EmployeeTerritories_0")] - [DebuggerNonUserCode] - public EntitySet EmployeeTerritories - { - get - { - return _employeeTerritories; - } - set - { - _employeeTerritories = value; - } - } - - - #endregion - - #region Parents - - private EntityRef _region; - [Association(Storage = "_region", OtherKey = "RegionID", ThisKey = "RegionID", Name = "fk_Territories_0", IsForeignKey = true)] - [DebuggerNonUserCode] - public Region Region - { - get - { - return _region.Entity; - } - set - { - if (value != _region.Entity) - { - if (_region.Entity != null) - { - var previousRegion = _region.Entity; - _region.Entity = null; - previousRegion.Territories.Remove(this); - } - _region.Entity = value; - if (value != null) - { - value.Territories.Add(this); - _regionID = value.RegionID; - } - else - { - _regionID = default(int); - } - } - } - } - - - #endregion - - #region Attachement handlers - - private void EmployeeTerritories_Attach(EmployeeTerritory entity) - { - entity.Territory = this; - } - - private void EmployeeTerritories_Detach(EmployeeTerritory entity) - { - entity.Territory = null; - } - - - #endregion - - #region ctor - - public Territory() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _region = new EntityRef(); - OnCreated(); - } - - #endregion - - } -} diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-DbMetal.cs b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-DbMetal.cs index e69be51da67..cab72c8ccdd 100755 --- a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-DbMetal.cs +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-DbMetal.cs @@ -1,841 +1,966 @@ -#region Auto-generated classes for Northwind database on [TIMESTAMP] - -// -// ____ _ __ __ _ _ +// +// ____ _ __ __ _ _ // | _ \| |__ | \/ | ___| |_ __ _| | // | | | | '_ \| |\/| |/ _ \ __/ _` | | // | |_| | |_) | | | | __/ || (_| | | // |____/|_.__/|_| |_|\___|\__\__,_|_| // -// Auto-generated from Northwind on [TIMESTAMP] -// Please visit http://linq.to/db for more information - -#endregion - -using System; -using System.Data; -using System.Data.Linq.Mapping; -using System.Diagnostics; -using System.Reflection; +// Auto-generated from Northwind on [TIMESTAMP]. +// Please visit http://code.google.com/p/dblinq2007/ for more information. +// +namespace nwind +{ + using System; + using System.ComponentModel; + using System.Data; #if MONO_STRICT -using System.Data.Linq; + using System.Data.Linq; #else // MONO_STRICT -using DbLinq.Data.Linq; -using DbLinq.Vendor; + using DbLinq.Data.Linq; + using DbLinq.Vendor; #endif // MONO_STRICT -using System.ComponentModel; - -namespace nwind -{ + using System.Data.Linq.Mapping; + using System.Diagnostics; + + public partial class Northwind : DataContext { - #region Extensibility Method Definitions - + + #region Extensibility Method Declarations partial void OnCreated(); - #endregion - - public Northwind(string connectionString) - : base(connectionString) + + + public Northwind(string connectionString) : + base(connectionString) { - OnCreated(); + this.OnCreated(); } - - public Northwind(IDbConnection connection) - #if MONO_STRICT - : base(connection) - #else // MONO_STRICT - : base(connection, new DbLinq.Sqlite.SqliteVendor()) - #endif // MONO_STRICT + + public Northwind(string connection, MappingSource mappingSource) : + base(connection, mappingSource) { - OnCreated(); + this.OnCreated(); } - - public Northwind(string connection, MappingSource mappingSource) - : base(connection, mappingSource) + + public Northwind(IDbConnection connection, MappingSource mappingSource) : + base(connection, mappingSource) { - OnCreated(); + this.OnCreated(); } - - public Northwind(IDbConnection connection, MappingSource mappingSource) - : base(connection, mappingSource) + + public Table Categories { - OnCreated(); + get + { + return this.GetTable(); + } } - - #if !MONO_STRICT - public Northwind(IDbConnection connection, IVendor vendor) - : base(connection, vendor) + + public Table Customers { - OnCreated(); + get + { + return this.GetTable(); + } } - #endif // !MONO_STRICT - - #if !MONO_STRICT - public Northwind(IDbConnection connection, MappingSource mappingSource, IVendor vendor) - : base(connection, mappingSource, vendor) + + public Table CustomerCustomerDemo { - OnCreated(); + get + { + return this.GetTable(); + } } - #endif // !MONO_STRICT - - public Table Categories { get { return GetTable(); } } - public Table Customers { get { return GetTable(); } } - public Table CustomerCustomerDemo { get { return GetTable(); } } - public Table CustomerDemographics { get { return GetTable(); } } - public Table Employees { get { return GetTable(); } } - public Table EmployeeTerritories { get { return GetTable(); } } - public Table Orders { get { return GetTable(); } } - public Table OrderDetails { get { return GetTable(); } } - public Table Products { get { return GetTable(); } } - public Table Regions { get { return GetTable(); } } - public Table Shippers { get { return GetTable(); } } - public Table Suppliers { get { return GetTable(); } } - public Table Territories { get { return GetTable(); } } - - } - - [Table(Name = "Categories")] - public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public Table CustomerDemographics { - if (PropertyChanging != null) + get { - PropertyChanging(this, emptyChangingEventArgs); + return this.GetTable(); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public Table Employees { - if (PropertyChanged != null) + get { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return this.GetTable(); } } + + public Table EmployeeTerritories + { + get + { + return this.GetTable(); + } + } + + public Table Orders + { + get + { + return this.GetTable(); + } + } + + public Table OrderDetails + { + get + { + return this.GetTable(); + } + } + + public Table Products + { + get + { + return this.GetTable(); + } + } + + public Table Regions + { + get + { + return this.GetTable(); + } + } + + public Table Shippers + { + get + { + return this.GetTable(); + } + } + + public Table Suppliers + { + get + { + return this.GetTable(); + } + } + + public Table Territories + { + get + { + return this.GetTable(); + } + } + } + + #region Start MONO_STRICT +#if MONO_STRICT - #endregion - - #region Extensibility Method Definitions - + public partial class Northwind + { + + public Northwind(IDbConnection connection) : + base(connection) + { + this.OnCreated(); + } + } + #region End MONO_STRICT + #endregion +#else // MONO_STRICT + + public partial class Northwind + { + + public Northwind(IDbConnection connection) : + base(connection, new DbLinq.Sqlite.SqliteVendor()) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, IVendor sqlDialect) : + base(connection, sqlDialect) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, MappingSource mappingSource, IVendor sqlDialect) : + base(connection, mappingSource, sqlDialect) + { + this.OnCreated(); + } + } + #region End Not MONO_STRICT + #endregion +#endif // MONO_STRICT + #endregion + + [Table(Name="Categories")] + public partial class Category : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private long _categoryID; + + private string _categoryName; + + private string _description; + + private byte[] _picture; + + private EntitySet _products; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCategoryIDChanged(); + partial void OnCategoryIDChanging(long value); + partial void OnCategoryNameChanged(); + partial void OnCategoryNameChanging(string value); + partial void OnDescriptionChanged(); + partial void OnDescriptionChanging(string value); + partial void OnPictureChanged(); - partial void OnPictureChanging(Byte[] value); - + + partial void OnPictureChanging(byte[] value); #endregion - - #region long CategoryID - - private long _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Category() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long CategoryID { get { - return _categoryID; + return this._categoryID; } set { - if (value != _categoryID) + if ((_categoryID != value)) { - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); } } } - - #endregion - - #region string CategoryName - - private string _categoryName; - [DebuggerNonUserCode] - [Column(Storage = "_categoryName", Name = "CategoryName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_categoryName", Name="CategoryName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CategoryName { get { - return _categoryName; + return this._categoryName; } set { - if (value != _categoryName) + if (((_categoryName == value) + == false)) { - OnCategoryNameChanging(value); - SendPropertyChanging(); - _categoryName = value; - SendPropertyChanged("CategoryName"); - OnCategoryNameChanged(); + this.OnCategoryNameChanging(value); + this.SendPropertyChanging(); + this._categoryName = value; + this.SendPropertyChanged("CategoryName"); + this.OnCategoryNameChanged(); } } } - - #endregion - - #region string Description - - private string _description; - [DebuggerNonUserCode] - [Column(Storage = "_description", Name = "Description", DbType = "ntext", AutoSync = AutoSync.Never)] + + [Column(Storage="_description", Name="Description", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Description { get { - return _description; + return this._description; } set { - if (value != _description) + if (((_description == value) + == false)) { - OnDescriptionChanging(value); - SendPropertyChanging(); - _description = value; - SendPropertyChanged("Description"); - OnDescriptionChanged(); + this.OnDescriptionChanging(value); + this.SendPropertyChanging(); + this._description = value; + this.SendPropertyChanged("Description"); + this.OnDescriptionChanged(); } } } - - #endregion - - #region Byte[] Picture - - private Byte[] _picture; - [DebuggerNonUserCode] - [Column(Storage = "_picture", Name = "Picture", DbType = "image", AutoSync = AutoSync.Never)] - public Byte[] Picture + + [Column(Storage="_picture", Name="Picture", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Picture { get { - return _picture; + return this._picture; } set { - if (value != _picture) + if (((_picture == value) + == false)) { - OnPictureChanging(value); - SendPropertyChanging(); - _picture = value; - SendPropertyChanged("Picture"); - OnPictureChanged(); + this.OnPictureChanging(value); + this.SendPropertyChanging(); + this._picture = value; + this.SendPropertyChanged("Picture"); + this.OnPictureChanged(); } } } - - #endregion - + #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "FK_Products_1")] - [DebuggerNonUserCode] + [Association(Storage="_products", OtherKey="CategoryID", ThisKey="CategoryID", Name="FK_Products_1")] + [DebuggerNonUserCode()] public EntitySet Products { get { - return _products; + return this._products; } set { - _products = value; + this._products = value; } } - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Category = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Products_Detach(Product entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Category = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Category() + + public override int GetHashCode() { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_categoryID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Customers")] - public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Category other = ((Category)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Category value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._categoryID, value._categoryID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Customers")] + public partial class Customer : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _customerID; + + private string _fax; + + private string _phone; + + private string _postalCode; + + private string _region; + + private EntitySet _orders; + + private EntitySet _customerCustomerDemo; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnContactNameChanged(); + partial void OnContactNameChanging(string value); + partial void OnContactTitleChanged(); + partial void OnContactTitleChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnFaxChanged(); + partial void OnFaxChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + + public Customer() + { + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_city", Name="City", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactName { get { - return _contactName; + return this._contactName; } set { - if (value != _contactName) + if (((_contactName == value) + == false)) { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); } } } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactTitle { get { - return _contactTitle; + return this._contactTitle; } set { - if (value != _contactTitle) + if (((_contactTitle == value) + == false)) { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Fax { get { - return _fax; + return this._fax; } set { - if (value != _fax) + if (((_fax == value) + == false)) { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_Orders_2")] - [DebuggerNonUserCode] + [Association(Storage="_orders", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_Orders_2")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_CustomerCustomerDemo_0")] - [DebuggerNonUserCode] + + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_CustomerCustomerDemo_0")] + [DebuggerNonUserCode()] public EntitySet CustomerCustomerDemo { get { - return _customerCustomerDemo; + return this._customerCustomerDemo; } set { - _customerCustomerDemo = value; + this._customerCustomerDemo = value; } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Customer other = ((Customer)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Customer value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID); + } + + #region Attachment handlers private void Orders_Attach(Order entity) { + this.SendPropertyChanging(); entity.Customer = this; } - + private void Orders_Detach(Order entity) { + this.SendPropertyChanging(); entity.Customer = null; } - + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) { + this.SendPropertyChanging(); entity.Customer = this; } - + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) { + this.SendPropertyChanging(); entity.Customer = null; } - - - #endregion - - #region ctor - - public Customer() - { - _orders = new EntitySet(Orders_Attach, Orders_Detach); - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - OnCreated(); - } - #endregion - } - - [Table(Name = "CustomerCustomerDemo")] - public partial class CustomerCustomerDemo : INotifyPropertyChanging, INotifyPropertyChanged + + [Table(Name="CustomerCustomerDemo")] + public partial class CustomerCustomerDemo : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private string _customerTypeID; + + private EntityRef _customer = new EntityRef(); + + private EntityRef _customerDemographic = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnCustomerTypeIDChanged(); + partial void OnCustomerTypeIDChanging(string value); - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + + public CustomerCustomerDemo() + { + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { if (_customer.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerTypeID { get { - return _customerTypeID; + return this._customerTypeID; } set { - if (value != _customerTypeID) + if (((_customerTypeID == value) + == false)) { if (_customerDemographic.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_CustomerCustomerDemo_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_CustomerCustomerDemo_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Customer Customer { get { - return _customer.Entity; + return this._customer.Entity; } set { - if (value != _customer.Entity) + if (((this._customer.Entity == value) + == false)) { - if (_customer.Entity != null) + if ((this._customer.Entity != null)) { - var previousCustomer = _customer.Entity; - _customer.Entity = null; + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; previousCustomer.CustomerCustomerDemo.Remove(this); } - _customer.Entity = value; - if (value != null) + this._customer.Entity = value; + if ((value != null)) { value.CustomerCustomerDemo.Add(this); _customerID = value.CustomerID; @@ -847,28 +972,28 @@ namespace nwind } } } - - private EntityRef _customerDemographic; - [Association(Storage = "_customerDemographic", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "FK_CustomerCustomerDemo_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_customerDemographic", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="FK_CustomerCustomerDemo_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public CustomerDemographic CustomerDemographic { get { - return _customerDemographic.Entity; + return this._customerDemographic.Entity; } set { - if (value != _customerDemographic.Entity) + if (((this._customerDemographic.Entity == value) + == false)) { - if (_customerDemographic.Entity != null) + if ((this._customerDemographic.Entity != null)) { - var previousCustomerDemographic = _customerDemographic.Entity; - _customerDemographic.Entity = null; + CustomerDemographic previousCustomerDemographic = this._customerDemographic.Entity; + this._customerDemographic.Entity = null; previousCustomerDemographic.CustomerCustomerDemo.Remove(this); } - _customerDemographic.Entity = value; - if (value != null) + this._customerDemographic.Entity = value; + if ((value != null)) { value.CustomerCustomerDemo.Add(this); _customerTypeID = value.CustomerTypeID; @@ -880,783 +1005,831 @@ namespace nwind } } } - - #endregion - - #region ctor - - public CustomerCustomerDemo() + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - _customer = new EntityRef(); - _customerDemographic = new EntityRef(); - OnCreated(); + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - #endregion - - } - - [Table(Name = "CustomerDemographics")] - public partial class CustomerDemographic : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + CustomerCustomerDemo other = ((CustomerCustomerDemo)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(CustomerCustomerDemo value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID)); } - - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="CustomerDemographics")] + public partial class CustomerDemographic : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerDesc; + + private string _customerTypeID; + + private EntitySet _customerCustomerDemo; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerDescChanged(); + partial void OnCustomerDescChanging(string value); + partial void OnCustomerTypeIDChanged(); + partial void OnCustomerTypeIDChanging(string value); - #endregion - - #region string CustomerDesc - - private string _customerDesc; - [DebuggerNonUserCode] - [Column(Storage = "_customerDesc", Name = "CustomerDesc", DbType = "ntext", AutoSync = AutoSync.Never)] + + + public CustomerDemographic() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerDesc", Name="CustomerDesc", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string CustomerDesc { get { - return _customerDesc; + return this._customerDesc; } set { - if (value != _customerDesc) + if (((_customerDesc == value) + == false)) { - OnCustomerDescChanging(value); - SendPropertyChanging(); - _customerDesc = value; - SendPropertyChanged("CustomerDesc"); - OnCustomerDescChanged(); + this.OnCustomerDescChanging(value); + this.SendPropertyChanging(); + this._customerDesc = value; + this.SendPropertyChanged("CustomerDesc"); + this.OnCustomerDescChanged(); } } } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerTypeID { get { - return _customerTypeID; + return this._customerTypeID; } set { - if (value != _customerTypeID) + if (((_customerTypeID == value) + == false)) { - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "FK_CustomerCustomerDemo_1")] - [DebuggerNonUserCode] + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="FK_CustomerCustomerDemo_1")] + [DebuggerNonUserCode()] public EntitySet CustomerCustomerDemo { get { - return _customerCustomerDemo; + return this._customerCustomerDemo; } set { - _customerCustomerDemo = value; + this._customerCustomerDemo = value; } } - - #endregion - - #region Attachement handlers - - private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.CustomerDemographic = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.CustomerDemographic = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public CustomerDemographic() + + public override int GetHashCode() { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - OnCreated(); + int hc = 0; + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 1)); + } + return hc; } - - #endregion - - } - - [Table(Name = "Employees")] - public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + CustomerDemographic other = ((CustomerDemographic)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(CustomerDemographic value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID); + } + + #region Attachment handlers + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = this; + } + + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Employees")] + public partial class Employee : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private System.Nullable _birthDate; + + private string _city; + + private string _country; + + private long _employeeID; + + private string _extension; + + private string _firstName; + + private System.Nullable _hireDate; + + private string _homePhone; + + private string _lastName; + + private string _notes; + + private byte[] _photo; + + private string _photoPath; + + private string _postalCode; + + private string _region; + + private System.Nullable _reportsTo; + + private string _title; + + private string _titleOfCourtesy; + + private EntitySet _employees; + + private EntitySet _orders; + + private EntitySet _employeeTerritories; + + private EntityRef _reportsToEmployee = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnBirthDateChanged(); - partial void OnBirthDateChanging(DateTime? value); + + partial void OnBirthDateChanging(System.Nullable value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnEmployeeIDChanged(); + partial void OnEmployeeIDChanging(long value); + partial void OnExtensionChanged(); + partial void OnExtensionChanging(string value); + partial void OnFirstNameChanged(); + partial void OnFirstNameChanging(string value); + partial void OnHireDateChanged(); - partial void OnHireDateChanging(DateTime? value); + + partial void OnHireDateChanging(System.Nullable value); + partial void OnHomePhoneChanged(); + partial void OnHomePhoneChanging(string value); + partial void OnLastNameChanged(); + partial void OnLastNameChanging(string value); + partial void OnNotesChanged(); + partial void OnNotesChanging(string value); + partial void OnPhotoChanged(); - partial void OnPhotoChanging(Byte[] value); + + partial void OnPhotoChanging(byte[] value); + partial void OnPhotoPathChanged(); + partial void OnPhotoPathChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); + partial void OnReportsToChanged(); - partial void OnReportsToChanging(long? value); + + partial void OnReportsToChanging(System.Nullable value); + partial void OnTitleChanged(); + partial void OnTitleChanging(string value); + partial void OnTitleOfCourtesyChanged(); + partial void OnTitleOfCourtesyChanging(string value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + + public Employee() + { + _employees = new EntitySet(new Action(this.Employees_Attach), new Action(this.Employees_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region DateTime? BirthDate - - private DateTime? _birthDate; - [DebuggerNonUserCode] - [Column(Storage = "_birthDate", Name = "BirthDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? BirthDate + + [Column(Storage="_birthDate", Name="BirthDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable BirthDate { get { - return _birthDate; + return this._birthDate; } set { - if (value != _birthDate) + if ((_birthDate != value)) { - OnBirthDateChanging(value); - SendPropertyChanging(); - _birthDate = value; - SendPropertyChanged("BirthDate"); - OnBirthDateChanged(); + this.OnBirthDateChanging(value); + this.SendPropertyChanging(); + this._birthDate = value; + this.SendPropertyChanged("BirthDate"); + this.OnBirthDateChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_city", Name="City", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region long EmployeeID - - private long _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region string Extension - - private string _extension; - [DebuggerNonUserCode] - [Column(Storage = "_extension", Name = "Extension", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_extension", Name="Extension", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Extension { get { - return _extension; + return this._extension; } set { - if (value != _extension) + if (((_extension == value) + == false)) { - OnExtensionChanging(value); - SendPropertyChanging(); - _extension = value; - SendPropertyChanged("Extension"); - OnExtensionChanged(); + this.OnExtensionChanging(value); + this.SendPropertyChanging(); + this._extension = value; + this.SendPropertyChanged("Extension"); + this.OnExtensionChanged(); } } } - - #endregion - - #region string FirstName - - private string _firstName; - [DebuggerNonUserCode] - [Column(Storage = "_firstName", Name = "FirstName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_firstName", Name="FirstName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string FirstName { get { - return _firstName; + return this._firstName; } set { - if (value != _firstName) + if (((_firstName == value) + == false)) { - OnFirstNameChanging(value); - SendPropertyChanging(); - _firstName = value; - SendPropertyChanged("FirstName"); - OnFirstNameChanged(); + this.OnFirstNameChanging(value); + this.SendPropertyChanging(); + this._firstName = value; + this.SendPropertyChanged("FirstName"); + this.OnFirstNameChanged(); } } } - - #endregion - - #region DateTime? HireDate - - private DateTime? _hireDate; - [DebuggerNonUserCode] - [Column(Storage = "_hireDate", Name = "HireDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? HireDate + + [Column(Storage="_hireDate", Name="HireDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable HireDate { get { - return _hireDate; + return this._hireDate; } set { - if (value != _hireDate) + if ((_hireDate != value)) { - OnHireDateChanging(value); - SendPropertyChanging(); - _hireDate = value; - SendPropertyChanged("HireDate"); - OnHireDateChanged(); + this.OnHireDateChanging(value); + this.SendPropertyChanging(); + this._hireDate = value; + this.SendPropertyChanged("HireDate"); + this.OnHireDateChanged(); } } } - - #endregion - - #region string HomePhone - - private string _homePhone; - [DebuggerNonUserCode] - [Column(Storage = "_homePhone", Name = "HomePhone", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_homePhone", Name="HomePhone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string HomePhone { get { - return _homePhone; + return this._homePhone; } set { - if (value != _homePhone) + if (((_homePhone == value) + == false)) { - OnHomePhoneChanging(value); - SendPropertyChanging(); - _homePhone = value; - SendPropertyChanged("HomePhone"); - OnHomePhoneChanged(); + this.OnHomePhoneChanging(value); + this.SendPropertyChanging(); + this._homePhone = value; + this.SendPropertyChanged("HomePhone"); + this.OnHomePhoneChanged(); } } } - - #endregion - - #region string LastName - - private string _lastName; - [DebuggerNonUserCode] - [Column(Storage = "_lastName", Name = "LastName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_lastName", Name="LastName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string LastName { get { - return _lastName; + return this._lastName; } set { - if (value != _lastName) + if (((_lastName == value) + == false)) { - OnLastNameChanging(value); - SendPropertyChanging(); - _lastName = value; - SendPropertyChanged("LastName"); - OnLastNameChanged(); + this.OnLastNameChanging(value); + this.SendPropertyChanging(); + this._lastName = value; + this.SendPropertyChanged("LastName"); + this.OnLastNameChanged(); } } } - - #endregion - - #region string Notes - - private string _notes; - [DebuggerNonUserCode] - [Column(Storage = "_notes", Name = "Notes", DbType = "ntext", AutoSync = AutoSync.Never)] + + [Column(Storage="_notes", Name="Notes", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Notes { get { - return _notes; + return this._notes; } set { - if (value != _notes) + if (((_notes == value) + == false)) { - OnNotesChanging(value); - SendPropertyChanging(); - _notes = value; - SendPropertyChanged("Notes"); - OnNotesChanged(); + this.OnNotesChanging(value); + this.SendPropertyChanging(); + this._notes = value; + this.SendPropertyChanged("Notes"); + this.OnNotesChanged(); } } } - - #endregion - - #region Byte[] Photo - - private Byte[] _photo; - [DebuggerNonUserCode] - [Column(Storage = "_photo", Name = "Photo", DbType = "image", AutoSync = AutoSync.Never)] - public Byte[] Photo + + [Column(Storage="_photo", Name="Photo", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Photo { get { - return _photo; + return this._photo; } set { - if (value != _photo) + if (((_photo == value) + == false)) { - OnPhotoChanging(value); - SendPropertyChanging(); - _photo = value; - SendPropertyChanged("Photo"); - OnPhotoChanged(); + this.OnPhotoChanging(value); + this.SendPropertyChanging(); + this._photo = value; + this.SendPropertyChanged("Photo"); + this.OnPhotoChanged(); } } } - - #endregion - - #region string PhotoPath - - private string _photoPath; - [DebuggerNonUserCode] - [Column(Storage = "_photoPath", Name = "PhotoPath", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_photoPath", Name="PhotoPath", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PhotoPath { get { - return _photoPath; + return this._photoPath; } set { - if (value != _photoPath) + if (((_photoPath == value) + == false)) { - OnPhotoPathChanging(value); - SendPropertyChanging(); - _photoPath = value; - SendPropertyChanged("PhotoPath"); - OnPhotoPathChanged(); + this.OnPhotoPathChanging(value); + this.SendPropertyChanging(); + this._photoPath = value; + this.SendPropertyChanged("PhotoPath"); + this.OnPhotoPathChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - - #region long? ReportsTo - - private long? _reportsTo; - [DebuggerNonUserCode] - [Column(Storage = "_reportsTo", Name = "ReportsTo", DbType = "integer", AutoSync = AutoSync.Never)] - public long? ReportsTo + + [Column(Storage="_reportsTo", Name="ReportsTo", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReportsTo { get { - return _reportsTo; + return this._reportsTo; } set { - if (value != _reportsTo) + if ((_reportsTo != value)) { if (_reportsToEmployee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnReportsToChanging(value); - SendPropertyChanging(); - _reportsTo = value; - SendPropertyChanged("ReportsTo"); - OnReportsToChanged(); + this.OnReportsToChanging(value); + this.SendPropertyChanging(); + this._reportsTo = value; + this.SendPropertyChanged("ReportsTo"); + this.OnReportsToChanged(); } } } - - #endregion - - #region string Title - - private string _title; - [DebuggerNonUserCode] - [Column(Storage = "_title", Name = "Title", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_title", Name="Title", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Title { get { - return _title; + return this._title; } set { - if (value != _title) + if (((_title == value) + == false)) { - OnTitleChanging(value); - SendPropertyChanging(); - _title = value; - SendPropertyChanged("Title"); - OnTitleChanged(); + this.OnTitleChanging(value); + this.SendPropertyChanging(); + this._title = value; + this.SendPropertyChanged("Title"); + this.OnTitleChanged(); } } } - - #endregion - - #region string TitleOfCourtesy - - private string _titleOfCourtesy; - [DebuggerNonUserCode] - [Column(Storage = "_titleOfCourtesy", Name = "TitleOfCourtesy", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_titleOfCourtesy", Name="TitleOfCourtesy", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string TitleOfCourtesy { get { - return _titleOfCourtesy; + return this._titleOfCourtesy; } set { - if (value != _titleOfCourtesy) + if (((_titleOfCourtesy == value) + == false)) { - OnTitleOfCourtesyChanging(value); - SendPropertyChanging(); - _titleOfCourtesy = value; - SendPropertyChanged("TitleOfCourtesy"); - OnTitleOfCourtesyChanged(); + this.OnTitleOfCourtesyChanging(value); + this.SendPropertyChanging(); + this._titleOfCourtesy = value; + this.SendPropertyChanged("TitleOfCourtesy"); + this.OnTitleOfCourtesyChanged(); } } } - - #endregion - + #region Children - - private EntitySet _employees; - [Association(Storage = "_employees", OtherKey = "ReportsTo", ThisKey = "EmployeeID", Name = "FK_Employees_0")] - [DebuggerNonUserCode] + [Association(Storage="_employees", OtherKey="ReportsTo", ThisKey="EmployeeID", Name="FK_Employees_0")] + [DebuggerNonUserCode()] public EntitySet Employees { get { - return _employees; + return this._employees; } set { - _employees = value; + this._employees = value; } } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_Orders_1")] - [DebuggerNonUserCode] + + [Association(Storage="_orders", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_Orders_1")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_EmployeeTerritories_1")] - [DebuggerNonUserCode] + + [Association(Storage="_employeeTerritories", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_EmployeeTerritories_1")] + [DebuggerNonUserCode()] public EntitySet EmployeeTerritories { get { - return _employeeTerritories; + return this._employeeTerritories; } set { - _employeeTerritories = value; + this._employeeTerritories = value; } } - - #endregion - + #region Parents - - private EntityRef _reportsToEmployee; - [Association(Storage = "_reportsToEmployee", OtherKey = "EmployeeID", ThisKey = "ReportsTo", Name = "FK_Employees_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_reportsToEmployee", OtherKey="EmployeeID", ThisKey="ReportsTo", Name="FK_Employees_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee ReportsToEmployee { get { - return _reportsToEmployee.Entity; + return this._reportsToEmployee.Entity; } set { - if (value != _reportsToEmployee.Entity) + if (((this._reportsToEmployee.Entity == value) + == false)) { - if (_reportsToEmployee.Entity != null) + if ((this._reportsToEmployee.Entity != null)) { - var previousEmployee = _reportsToEmployee.Entity; - _reportsToEmployee.Entity = null; + Employee previousEmployee = this._reportsToEmployee.Entity; + this._reportsToEmployee.Entity = null; previousEmployee.Employees.Remove(this); } - _reportsToEmployee.Entity = value; - if (value != null) + this._reportsToEmployee.Entity = value; + if ((value != null)) { value.Employees.Add(this); _reportsTo = value.EmployeeID; @@ -1668,185 +1841,206 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Employee other = ((Employee)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Employee value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID); + } + + #region Attachment handlers private void Employees_Attach(Employee entity) { + this.SendPropertyChanging(); entity.ReportsToEmployee = this; } - + private void Employees_Detach(Employee entity) { + this.SendPropertyChanging(); entity.ReportsToEmployee = null; } - + private void Orders_Attach(Order entity) { + this.SendPropertyChanging(); entity.Employee = this; } - + private void Orders_Detach(Order entity) { - entity.Employee = null; - } - - private void EmployeeTerritories_Attach(EmployeeTerritory entity) - { - entity.Employee = this; - } - - private void EmployeeTerritories_Detach(EmployeeTerritory entity) - { - entity.Employee = null; - } - - - #endregion - - #region ctor - - public Employee() - { - _employees = new EntitySet(Employees_Attach, Employees_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _reportsToEmployee = new EntityRef(); - OnCreated(); + this.SendPropertyChanging(); + entity.Employee = null; } - - #endregion - - } - - [Table(Name = "EmployeeTerritories")] - public partial class EmployeeTerritory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + private void EmployeeTerritories_Attach(EmployeeTerritory entity) { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } + this.SendPropertyChanging(); + entity.Employee = this; } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + private void EmployeeTerritories_Detach(EmployeeTerritory entity) { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } + this.SendPropertyChanging(); + entity.Employee = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="EmployeeTerritories")] + public partial class EmployeeTerritory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private long _employeeID; + + private string _territoryID; + + private EntityRef _territory = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnEmployeeIDChanged(); + partial void OnEmployeeIDChanging(long value); + partial void OnTerritoryIDChanged(); + partial void OnTerritoryIDChanging(string value); - #endregion - - #region long EmployeeID - - private long _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + + public EmployeeTerritory() + { + this.OnCreated(); + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { if (_employee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryID { get { - return _territoryID; + return this._territoryID; } set { - if (value != _territoryID) + if (((_territoryID == value) + == false)) { if (_territory.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _territory; - [Association(Storage = "_territory", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "FK_EmployeeTerritories_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_territory", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="FK_EmployeeTerritories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Territory Territory { get { - return _territory.Entity; + return this._territory.Entity; } set { - if (value != _territory.Entity) + if (((this._territory.Entity == value) + == false)) { - if (_territory.Entity != null) + if ((this._territory.Entity != null)) { - var previousTerritory = _territory.Entity; - _territory.Entity = null; + Territory previousTerritory = this._territory.Entity; + this._territory.Entity = null; previousTerritory.EmployeeTerritories.Remove(this); } - _territory.Entity = value; - if (value != null) + this._territory.Entity = value; + if ((value != null)) { value.EmployeeTerritories.Add(this); _territoryID = value.TerritoryID; @@ -1858,28 +2052,28 @@ namespace nwind } } } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_EmployeeTerritories_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_EmployeeTerritories_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee Employee { get { - return _employee.Entity; + return this._employee.Entity; } set { - if (value != _employee.Entity) + if (((this._employee.Entity == value) + == false)) { - if (_employee.Entity != null) + if ((this._employee.Entity != null)) { - var previousEmployee = _employee.Entity; - _employee.Entity = null; + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; previousEmployee.EmployeeTerritories.Remove(this); } - _employee.Entity = value; - if (value != null) + this._employee.Entity = value; + if ((value != null)) { value.EmployeeTerritories.Add(this); _employeeID = value.EmployeeID; @@ -1891,508 +2085,528 @@ namespace nwind } } } - - - #endregion - - #region ctor - - public EmployeeTerritory() - { - _territory = new EntityRef(); - _employee = new EntityRef(); - OnCreated(); - } - #endregion - - } - - [Table(Name = "Orders")] - public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - - #endregion - - #region Extensibility Method Definitions - + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + EmployeeTerritory other = ((EmployeeTerritory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(EmployeeTerritory value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID)); + } + } + + [Table(Name="Orders")] + public partial class Order : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private System.Nullable _employeeID; + + private System.Nullable _freight; + + private System.Nullable _orderDate; + + private long _orderID; + + private System.Nullable _requiredDate; + + private string _shipAddress; + + private string _shipCity; + + private string _shipCountry; + + private string _shipName; + + private System.Nullable _shippedDate; + + private string _shipPostalCode; + + private string _shipRegion; + + private System.Nullable _shipVia; + + private EntitySet _orderDetails; + + private EntityRef _shipper = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + private EntityRef _customer = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(long? value); + + partial void OnEmployeeIDChanging(System.Nullable value); + partial void OnFreightChanged(); - partial void OnFreightChanging(decimal? value); + + partial void OnFreightChanging(System.Nullable value); + partial void OnOrderDateChanged(); - partial void OnOrderDateChanging(DateTime? value); + + partial void OnOrderDateChanging(System.Nullable value); + partial void OnOrderIDChanged(); + partial void OnOrderIDChanging(long value); + partial void OnRequiredDateChanged(); - partial void OnRequiredDateChanging(DateTime? value); + + partial void OnRequiredDateChanging(System.Nullable value); + partial void OnShipAddressChanged(); + partial void OnShipAddressChanging(string value); + partial void OnShipCityChanged(); + partial void OnShipCityChanging(string value); + partial void OnShipCountryChanged(); + partial void OnShipCountryChanging(string value); + partial void OnShipNameChanged(); + partial void OnShipNameChanging(string value); + partial void OnShippedDateChanged(); - partial void OnShippedDateChanging(DateTime? value); + + partial void OnShippedDateChanging(System.Nullable value); + partial void OnShipPostalCodeChanged(); + partial void OnShipPostalCodeChanging(string value); + partial void OnShipRegionChanged(); + partial void OnShipRegionChanging(string value); + partial void OnShipViaChanged(); - partial void OnShipViaChanging(long? value); - + + partial void OnShipViaChanging(System.Nullable value); #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar", AutoSync = AutoSync.Never)] + + + public Order() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { if (_customer.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region long? EmployeeID - - private long? _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "integer", AutoSync = AutoSync.Never)] - public long? EmployeeID + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { if (_employee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region decimal? Freight - - private decimal? _freight; - [DebuggerNonUserCode] - [Column(Storage = "_freight", Name = "Freight", DbType = "money", AutoSync = AutoSync.Never)] - public decimal? Freight + + [Column(Storage="_freight", Name="Freight", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable Freight { get { - return _freight; + return this._freight; } set { - if (value != _freight) + if ((_freight != value)) { - OnFreightChanging(value); - SendPropertyChanging(); - _freight = value; - SendPropertyChanged("Freight"); - OnFreightChanged(); + this.OnFreightChanging(value); + this.SendPropertyChanging(); + this._freight = value; + this.SendPropertyChanged("Freight"); + this.OnFreightChanged(); } } } - - #endregion - - #region DateTime? OrderDate - - private DateTime? _orderDate; - [DebuggerNonUserCode] - [Column(Storage = "_orderDate", Name = "OrderDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? OrderDate + + [Column(Storage="_orderDate", Name="OrderDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable OrderDate { get { - return _orderDate; + return this._orderDate; } set { - if (value != _orderDate) + if ((_orderDate != value)) { - OnOrderDateChanging(value); - SendPropertyChanging(); - _orderDate = value; - SendPropertyChanged("OrderDate"); - OnOrderDateChanged(); + this.OnOrderDateChanging(value); + this.SendPropertyChanging(); + this._orderDate = value; + this.SendPropertyChanged("OrderDate"); + this.OnOrderDateChanged(); } } } - - #endregion - - #region long OrderID - - private long _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_orderID", Name="OrderID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long OrderID { get { - return _orderID; + return this._orderID; } set { - if (value != _orderID) + if ((_orderID != value)) { - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); } } } - - #endregion - - #region DateTime? RequiredDate - - private DateTime? _requiredDate; - [DebuggerNonUserCode] - [Column(Storage = "_requiredDate", Name = "RequiredDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? RequiredDate + + [Column(Storage="_requiredDate", Name="RequiredDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable RequiredDate { get { - return _requiredDate; + return this._requiredDate; } set { - if (value != _requiredDate) + if ((_requiredDate != value)) { - OnRequiredDateChanging(value); - SendPropertyChanging(); - _requiredDate = value; - SendPropertyChanged("RequiredDate"); - OnRequiredDateChanged(); + this.OnRequiredDateChanging(value); + this.SendPropertyChanging(); + this._requiredDate = value; + this.SendPropertyChanged("RequiredDate"); + this.OnRequiredDateChanged(); } } } - - #endregion - - #region string ShipAddress - - private string _shipAddress; - [DebuggerNonUserCode] - [Column(Storage = "_shipAddress", Name = "ShipAddress", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipAddress", Name="ShipAddress", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipAddress { get { - return _shipAddress; + return this._shipAddress; } set { - if (value != _shipAddress) + if (((_shipAddress == value) + == false)) { - OnShipAddressChanging(value); - SendPropertyChanging(); - _shipAddress = value; - SendPropertyChanged("ShipAddress"); - OnShipAddressChanged(); + this.OnShipAddressChanging(value); + this.SendPropertyChanging(); + this._shipAddress = value; + this.SendPropertyChanged("ShipAddress"); + this.OnShipAddressChanged(); } } } - - #endregion - - #region string ShipCity - - private string _shipCity; - [DebuggerNonUserCode] - [Column(Storage = "_shipCity", Name = "ShipCity", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipCity", Name="ShipCity", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipCity { get { - return _shipCity; + return this._shipCity; } set { - if (value != _shipCity) + if (((_shipCity == value) + == false)) { - OnShipCityChanging(value); - SendPropertyChanging(); - _shipCity = value; - SendPropertyChanged("ShipCity"); - OnShipCityChanged(); + this.OnShipCityChanging(value); + this.SendPropertyChanging(); + this._shipCity = value; + this.SendPropertyChanged("ShipCity"); + this.OnShipCityChanged(); } } } - - #endregion - - #region string ShipCountry - - private string _shipCountry; - [DebuggerNonUserCode] - [Column(Storage = "_shipCountry", Name = "ShipCountry", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipCountry", Name="ShipCountry", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipCountry { get { - return _shipCountry; + return this._shipCountry; } set { - if (value != _shipCountry) + if (((_shipCountry == value) + == false)) { - OnShipCountryChanging(value); - SendPropertyChanging(); - _shipCountry = value; - SendPropertyChanged("ShipCountry"); - OnShipCountryChanged(); + this.OnShipCountryChanging(value); + this.SendPropertyChanging(); + this._shipCountry = value; + this.SendPropertyChanged("ShipCountry"); + this.OnShipCountryChanged(); } } } - - #endregion - - #region string ShipName - - private string _shipName; - [DebuggerNonUserCode] - [Column(Storage = "_shipName", Name = "ShipName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipName", Name="ShipName", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipName { get { - return _shipName; + return this._shipName; } set { - if (value != _shipName) + if (((_shipName == value) + == false)) { - OnShipNameChanging(value); - SendPropertyChanging(); - _shipName = value; - SendPropertyChanged("ShipName"); - OnShipNameChanged(); + this.OnShipNameChanging(value); + this.SendPropertyChanging(); + this._shipName = value; + this.SendPropertyChanged("ShipName"); + this.OnShipNameChanged(); } } } - - #endregion - - #region DateTime? ShippedDate - - private DateTime? _shippedDate; - [DebuggerNonUserCode] - [Column(Storage = "_shippedDate", Name = "ShippedDate", DbType = "datetime", AutoSync = AutoSync.Never)] - public DateTime? ShippedDate + + [Column(Storage="_shippedDate", Name="ShippedDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShippedDate { get { - return _shippedDate; + return this._shippedDate; } set { - if (value != _shippedDate) + if ((_shippedDate != value)) { - OnShippedDateChanging(value); - SendPropertyChanging(); - _shippedDate = value; - SendPropertyChanged("ShippedDate"); - OnShippedDateChanged(); + this.OnShippedDateChanging(value); + this.SendPropertyChanging(); + this._shippedDate = value; + this.SendPropertyChanged("ShippedDate"); + this.OnShippedDateChanged(); } } } - - #endregion - - #region string ShipPostalCode - - private string _shipPostalCode; - [DebuggerNonUserCode] - [Column(Storage = "_shipPostalCode", Name = "ShipPostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipPostalCode", Name="ShipPostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipPostalCode { get { - return _shipPostalCode; + return this._shipPostalCode; } set { - if (value != _shipPostalCode) + if (((_shipPostalCode == value) + == false)) { - OnShipPostalCodeChanging(value); - SendPropertyChanging(); - _shipPostalCode = value; - SendPropertyChanged("ShipPostalCode"); - OnShipPostalCodeChanged(); + this.OnShipPostalCodeChanging(value); + this.SendPropertyChanging(); + this._shipPostalCode = value; + this.SendPropertyChanged("ShipPostalCode"); + this.OnShipPostalCodeChanged(); } } } - - #endregion - - #region string ShipRegion - - private string _shipRegion; - [DebuggerNonUserCode] - [Column(Storage = "_shipRegion", Name = "ShipRegion", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_shipRegion", Name="ShipRegion", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipRegion { get { - return _shipRegion; + return this._shipRegion; } set { - if (value != _shipRegion) + if (((_shipRegion == value) + == false)) { - OnShipRegionChanging(value); - SendPropertyChanging(); - _shipRegion = value; - SendPropertyChanged("ShipRegion"); - OnShipRegionChanged(); + this.OnShipRegionChanging(value); + this.SendPropertyChanging(); + this._shipRegion = value; + this.SendPropertyChanged("ShipRegion"); + this.OnShipRegionChanged(); } } } - - #endregion - - #region long? ShipVia - - private long? _shipVia; - [DebuggerNonUserCode] - [Column(Storage = "_shipVia", Name = "ShipVia", DbType = "integer", AutoSync = AutoSync.Never)] - public long? ShipVia + + [Column(Storage="_shipVia", Name="ShipVia", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShipVia { get { - return _shipVia; + return this._shipVia; } set { - if (value != _shipVia) + if ((_shipVia != value)) { if (_shipper.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnShipViaChanging(value); - SendPropertyChanging(); - _shipVia = value; - SendPropertyChanged("ShipVia"); - OnShipViaChanged(); + this.OnShipViaChanging(value); + this.SendPropertyChanging(); + this._shipVia = value; + this.SendPropertyChanged("ShipVia"); + this.OnShipViaChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"FK_Order Details_1\"")] - [DebuggerNonUserCode] + [Association(Storage="_orderDetails", OtherKey="OrderID", ThisKey="OrderID", Name="FK_Order Details_1")] + [DebuggerNonUserCode()] public EntitySet OrderDetails { get { - return _orderDetails; + return this._orderDetails; } set { - _orderDetails = value; + this._orderDetails = value; } } - - #endregion - + #region Parents - - private EntityRef _shipper; - [Association(Storage = "_shipper", OtherKey = "ShipperID", ThisKey = "ShipVia", Name = "FK_Orders_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_shipper", OtherKey="ShipperID", ThisKey="ShipVia", Name="FK_Orders_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Shipper Shipper { get { - return _shipper.Entity; + return this._shipper.Entity; } set { - if (value != _shipper.Entity) + if (((this._shipper.Entity == value) + == false)) { - if (_shipper.Entity != null) + if ((this._shipper.Entity != null)) { - var previousShipper = _shipper.Entity; - _shipper.Entity = null; + Shipper previousShipper = this._shipper.Entity; + this._shipper.Entity = null; previousShipper.Orders.Remove(this); } - _shipper.Entity = value; - if (value != null) + this._shipper.Entity = value; + if ((value != null)) { value.Orders.Add(this); _shipVia = value.ShipperID; @@ -2404,28 +2618,28 @@ namespace nwind } } } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_Orders_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_Orders_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee Employee { get { - return _employee.Entity; + return this._employee.Entity; } set { - if (value != _employee.Entity) + if (((this._employee.Entity == value) + == false)) { - if (_employee.Entity != null) + if ((this._employee.Entity != null)) { - var previousEmployee = _employee.Entity; - _employee.Entity = null; + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; previousEmployee.Orders.Remove(this); } - _employee.Entity = value; - if (value != null) + this._employee.Entity = value; + if ((value != null)) { value.Orders.Add(this); _employeeID = value.EmployeeID; @@ -2437,28 +2651,28 @@ namespace nwind } } } - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_Orders_2", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_Orders_2", IsForeignKey=true)] + [DebuggerNonUserCode()] public Customer Customer { get { - return _customer.Entity; + return this._customer.Entity; } set { - if (value != _customer.Entity) + if (((this._customer.Entity == value) + == false)) { - if (_customer.Entity != null) + if ((this._customer.Entity != null)) { - var previousCustomer = _customer.Entity; - _customer.Entity = null; + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; previousCustomer.Orders.Remove(this); } - _customer.Entity = value; - if (value != null) + this._customer.Entity = value; + if ((value != null)) { value.Orders.Add(this); _customerID = value.CustomerID; @@ -2470,249 +2684,262 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Order = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void OrderDetails_Detach(OrderDetail entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Order = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Order() + + public override int GetHashCode() { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _shipper = new EntityRef(); - _employee = new EntityRef(); - _customer = new EntityRef(); - OnCreated(); + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "\"Order Details\"")] - public partial class OrderDetail : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Order other = ((Order)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Order value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Order Details")] + public partial class OrderDetail : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private float _discount; + + private long _orderID; + + private long _productID; + + private short _quantity; + + private decimal _unitPrice; + + private EntityRef _product = new EntityRef(); + + private EntityRef _order = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnDiscountChanged(); + partial void OnDiscountChanging(float value); + partial void OnOrderIDChanged(); + partial void OnOrderIDChanging(long value); + partial void OnProductIDChanged(); + partial void OnProductIDChanging(long value); + partial void OnQuantityChanged(); + partial void OnQuantityChanging(short value); + partial void OnUnitPriceChanged(); + partial void OnUnitPriceChanging(decimal value); - #endregion - - #region float Discount - - private float _discount; - [DebuggerNonUserCode] - [Column(Storage = "_discount", Name = "Discount", DbType = "real", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public OrderDetail() + { + this.OnCreated(); + } + + [Column(Storage="_discount", Name="Discount", DbType="real", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public float Discount { get { - return _discount; + return this._discount; } set { - if (value != _discount) + if ((_discount != value)) { - OnDiscountChanging(value); - SendPropertyChanging(); - _discount = value; - SendPropertyChanged("Discount"); - OnDiscountChanged(); + this.OnDiscountChanging(value); + this.SendPropertyChanging(); + this._discount = value; + this.SendPropertyChanged("Discount"); + this.OnDiscountChanged(); } } } - - #endregion - - #region long OrderID - - private long _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_orderID", Name="OrderID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long OrderID { get { - return _orderID; + return this._orderID; } set { - if (value != _orderID) + if ((_orderID != value)) { if (_order.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); } } } - - #endregion - - #region long ProductID - - private long _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_productID", Name="ProductID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long ProductID { get { - return _productID; + return this._productID; } set { - if (value != _productID) + if ((_productID != value)) { if (_product.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); - } - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); - } - } - } - - #endregion - - #region short Quantity - - private short _quantity; - [DebuggerNonUserCode] - [Column(Storage = "_quantity", Name = "Quantity", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = false)] + } + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); + } + } + } + + [Column(Storage="_quantity", Name="Quantity", DbType="smallint", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public short Quantity { get { - return _quantity; + return this._quantity; } set { - if (value != _quantity) + if ((_quantity != value)) { - OnQuantityChanging(value); - SendPropertyChanging(); - _quantity = value; - SendPropertyChanged("Quantity"); - OnQuantityChanged(); + this.OnQuantityChanging(value); + this.SendPropertyChanging(); + this._quantity = value; + this.SendPropertyChanged("Quantity"); + this.OnQuantityChanged(); } } } - - #endregion - - #region decimal UnitPrice - - private decimal _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public decimal UnitPrice { get { - return _unitPrice; + return this._unitPrice; } set { - if (value != _unitPrice) + if ((_unitPrice != value)) { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _product; - [Association(Storage = "_product", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"FK_Order Details_0\"", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_product", OtherKey="ProductID", ThisKey="ProductID", Name="FK_Order Details_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Product Product { get { - return _product.Entity; + return this._product.Entity; } set { - if (value != _product.Entity) + if (((this._product.Entity == value) + == false)) { - if (_product.Entity != null) + if ((this._product.Entity != null)) { - var previousProduct = _product.Entity; - _product.Entity = null; + Product previousProduct = this._product.Entity; + this._product.Entity = null; previousProduct.OrderDetails.Remove(this); } - _product.Entity = value; - if (value != null) + this._product.Entity = value; + if ((value != null)) { value.OrderDetails.Add(this); _productID = value.ProductID; @@ -2724,28 +2951,28 @@ namespace nwind } } } - - private EntityRef _order; - [Association(Storage = "_order", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"FK_Order Details_1\"", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_order", OtherKey="OrderID", ThisKey="OrderID", Name="FK_Order Details_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Order Order { get { - return _order.Entity; + return this._order.Entity; } set { - if (value != _order.Entity) + if (((this._order.Entity == value) + == false)) { - if (_order.Entity != null) + if ((this._order.Entity != null)) { - var previousOrder = _order.Entity; - _order.Entity = null; + Order previousOrder = this._order.Entity; + this._order.Entity = null; previousOrder.OrderDetails.Remove(this); } - _order.Entity = value; - if (value != null) + this._order.Entity = value; + if ((value != null)) { value.OrderDetails.Add(this); _orderID = value.OrderID; @@ -2757,392 +2984,406 @@ namespace nwind } } } - - - #endregion - - #region ctor - - public OrderDetail() - { - _product = new EntityRef(); - _order = new EntityRef(); - OnCreated(); - } - #endregion - - } - - [Table(Name = "Products")] - public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - - #endregion - - #region Extensibility Method Definitions - + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + hc = (hc + | (_productID.GetHashCode() * 65536)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + OrderDetail other = ((OrderDetail)(value)); + return this.Equals(other); + } + + public virtual bool Equals(OrderDetail value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID)); + } + } + + [Table(Name="Products")] + public partial class Product : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private System.Nullable _categoryID; + + private bool _discontinued; + + private long _productID; + + private string _productName; + + private string _quantityPerUnit; + + private System.Nullable _reorderLevel; + + private System.Nullable _supplierID; + + private System.Nullable _unitPrice; + + private System.Nullable _unitsInStock; + + private System.Nullable _unitsOnOrder; + + private EntitySet _orderDetails; + + private EntityRef _supplier = new EntityRef(); + + private EntityRef _category = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCategoryIDChanged(); - partial void OnCategoryIDChanging(long? value); + + partial void OnCategoryIDChanging(System.Nullable value); + partial void OnDiscontinuedChanged(); + partial void OnDiscontinuedChanging(bool value); + partial void OnProductIDChanged(); + partial void OnProductIDChanging(long value); + partial void OnProductNameChanged(); + partial void OnProductNameChanging(string value); + partial void OnQuantityPerUnitChanged(); + partial void OnQuantityPerUnitChanging(string value); + partial void OnReorderLevelChanged(); - partial void OnReorderLevelChanging(short? value); + + partial void OnReorderLevelChanging(System.Nullable value); + partial void OnSupplierIDChanged(); - partial void OnSupplierIDChanging(long? value); + + partial void OnSupplierIDChanging(System.Nullable value); + partial void OnUnitPriceChanged(); - partial void OnUnitPriceChanging(decimal? value); + + partial void OnUnitPriceChanging(System.Nullable value); + partial void OnUnitsInStockChanged(); - partial void OnUnitsInStockChanging(short? value); + + partial void OnUnitsInStockChanging(System.Nullable value); + partial void OnUnitsOnOrderChanged(); - partial void OnUnitsOnOrderChanging(short? value); - + + partial void OnUnitsOnOrderChanging(System.Nullable value); #endregion - - #region long? CategoryID - - private long? _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "integer", AutoSync = AutoSync.Never)] - public long? CategoryID + + + public Product() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable CategoryID { get { - return _categoryID; + return this._categoryID; } set { - if (value != _categoryID) + if ((_categoryID != value)) { if (_category.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); } } } - - #endregion - - #region bool Discontinued - - private bool _discontinued; - [DebuggerNonUserCode] - [Column(Storage = "_discontinued", Name = "Discontinued", DbType = "bit", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_discontinued", Name="Discontinued", DbType="bit", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public bool Discontinued { get { - return _discontinued; + return this._discontinued; } set { - if (value != _discontinued) + if ((_discontinued != value)) { - OnDiscontinuedChanging(value); - SendPropertyChanging(); - _discontinued = value; - SendPropertyChanged("Discontinued"); - OnDiscontinuedChanged(); + this.OnDiscontinuedChanging(value); + this.SendPropertyChanging(); + this._discontinued = value; + this.SendPropertyChanged("Discontinued"); + this.OnDiscontinuedChanged(); } } } - - #endregion - - #region long ProductID - - private long _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_productID", Name="ProductID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long ProductID { get { - return _productID; + return this._productID; } set { - if (value != _productID) + if ((_productID != value)) { - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); } } } - - #endregion - - #region string ProductName - - private string _productName; - [DebuggerNonUserCode] - [Column(Storage = "_productName", Name = "ProductName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_productName", Name="ProductName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string ProductName { get { - return _productName; + return this._productName; } set { - if (value != _productName) + if (((_productName == value) + == false)) { - OnProductNameChanging(value); - SendPropertyChanging(); - _productName = value; - SendPropertyChanged("ProductName"); - OnProductNameChanged(); + this.OnProductNameChanging(value); + this.SendPropertyChanging(); + this._productName = value; + this.SendPropertyChanged("ProductName"); + this.OnProductNameChanged(); } } } - - #endregion - - #region string QuantityPerUnit - - private string _quantityPerUnit; - [DebuggerNonUserCode] - [Column(Storage = "_quantityPerUnit", Name = "QuantityPerUnit", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_quantityPerUnit", Name="QuantityPerUnit", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string QuantityPerUnit { get { - return _quantityPerUnit; + return this._quantityPerUnit; } set { - if (value != _quantityPerUnit) + if (((_quantityPerUnit == value) + == false)) { - OnQuantityPerUnitChanging(value); - SendPropertyChanging(); - _quantityPerUnit = value; - SendPropertyChanged("QuantityPerUnit"); - OnQuantityPerUnitChanged(); + this.OnQuantityPerUnitChanging(value); + this.SendPropertyChanging(); + this._quantityPerUnit = value; + this.SendPropertyChanged("QuantityPerUnit"); + this.OnQuantityPerUnitChanged(); } } } - - #endregion - - #region short? ReorderLevel - - private short? _reorderLevel; - [DebuggerNonUserCode] - [Column(Storage = "_reorderLevel", Name = "ReorderLevel", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? ReorderLevel + + [Column(Storage="_reorderLevel", Name="ReorderLevel", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReorderLevel { get { - return _reorderLevel; + return this._reorderLevel; } set { - if (value != _reorderLevel) + if ((_reorderLevel != value)) { - OnReorderLevelChanging(value); - SendPropertyChanging(); - _reorderLevel = value; - SendPropertyChanged("ReorderLevel"); - OnReorderLevelChanged(); + this.OnReorderLevelChanging(value); + this.SendPropertyChanging(); + this._reorderLevel = value; + this.SendPropertyChanged("ReorderLevel"); + this.OnReorderLevelChanged(); } } } - - #endregion - - #region long? SupplierID - - private long? _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "integer", AutoSync = AutoSync.Never)] - public long? SupplierID + + [Column(Storage="_supplierID", Name="SupplierID", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable SupplierID { get { - return _supplierID; + return this._supplierID; } set { - if (value != _supplierID) + if ((_supplierID != value)) { if (_supplier.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); } } } - - #endregion - - #region decimal? UnitPrice - - private decimal? _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never)] - public decimal? UnitPrice + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitPrice { get { - return _unitPrice; + return this._unitPrice; } set { - if (value != _unitPrice) + if ((_unitPrice != value)) { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); } } } - - #endregion - - #region short? UnitsInStock - - private short? _unitsInStock; - [DebuggerNonUserCode] - [Column(Storage = "_unitsInStock", Name = "UnitsInStock", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? UnitsInStock + + [Column(Storage="_unitsInStock", Name="UnitsInStock", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsInStock { get { - return _unitsInStock; + return this._unitsInStock; } set { - if (value != _unitsInStock) + if ((_unitsInStock != value)) { - OnUnitsInStockChanging(value); - SendPropertyChanging(); - _unitsInStock = value; - SendPropertyChanged("UnitsInStock"); - OnUnitsInStockChanged(); + this.OnUnitsInStockChanging(value); + this.SendPropertyChanging(); + this._unitsInStock = value; + this.SendPropertyChanged("UnitsInStock"); + this.OnUnitsInStockChanged(); } } } - - #endregion - - #region short? UnitsOnOrder - - private short? _unitsOnOrder; - [DebuggerNonUserCode] - [Column(Storage = "_unitsOnOrder", Name = "UnitsOnOrder", DbType = "smallint", AutoSync = AutoSync.Never)] - public short? UnitsOnOrder + + [Column(Storage="_unitsOnOrder", Name="UnitsOnOrder", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsOnOrder { get { - return _unitsOnOrder; + return this._unitsOnOrder; } set { - if (value != _unitsOnOrder) + if ((_unitsOnOrder != value)) { - OnUnitsOnOrderChanging(value); - SendPropertyChanging(); - _unitsOnOrder = value; - SendPropertyChanged("UnitsOnOrder"); - OnUnitsOnOrderChanged(); + this.OnUnitsOnOrderChanging(value); + this.SendPropertyChanging(); + this._unitsOnOrder = value; + this.SendPropertyChanged("UnitsOnOrder"); + this.OnUnitsOnOrderChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"FK_Order Details_0\"")] - [DebuggerNonUserCode] + [Association(Storage="_orderDetails", OtherKey="ProductID", ThisKey="ProductID", Name="FK_Order Details_0")] + [DebuggerNonUserCode()] public EntitySet OrderDetails { get { - return _orderDetails; + return this._orderDetails; } set { - _orderDetails = value; + this._orderDetails = value; } } - - #endregion - + #region Parents - - private EntityRef _supplier; - [Association(Storage = "_supplier", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "FK_Products_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_supplier", OtherKey="SupplierID", ThisKey="SupplierID", Name="FK_Products_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Supplier Supplier { get { - return _supplier.Entity; + return this._supplier.Entity; } set { - if (value != _supplier.Entity) + if (((this._supplier.Entity == value) + == false)) { - if (_supplier.Entity != null) + if ((this._supplier.Entity != null)) { - var previousSupplier = _supplier.Entity; - _supplier.Entity = null; + Supplier previousSupplier = this._supplier.Entity; + this._supplier.Entity = null; previousSupplier.Products.Remove(this); } - _supplier.Entity = value; - if (value != null) + this._supplier.Entity = value; + if ((value != null)) { value.Products.Add(this); _supplierID = value.SupplierID; @@ -3154,28 +3395,28 @@ namespace nwind } } } - - private EntityRef _category; - [Association(Storage = "_category", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "FK_Products_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_category", OtherKey="CategoryID", ThisKey="CategoryID", Name="FK_Products_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Category Category { get { - return _category.Entity; + return this._category.Entity; } set { - if (value != _category.Entity) + if (((this._category.Entity == value) + == false)) { - if (_category.Entity != null) + if ((this._category.Entity != null)) { - var previousCategory = _category.Entity; - _category.Entity = null; + Category previousCategory = this._category.Entity; + this._category.Entity = null; previousCategory.Products.Remove(this); } - _category.Entity = value; - if (value != null) + this._category.Entity = value; + if ((value != null)) { value.Products.Add(this); _categoryID = value.CategoryID; @@ -3187,939 +3428,1008 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Product = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void OrderDetails_Detach(OrderDetail entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Product = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Product() + + public override int GetHashCode() { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _supplier = new EntityRef(); - _category = new EntityRef(); - OnCreated(); + int hc = 0; + hc = (hc + | (_productID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Region")] - public partial class Region : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Product other = ((Product)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Product value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Region")] + public partial class Region : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _regionDescription; + + private long _regionID; + + private EntitySet _territories; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnRegionDescriptionChanged(); + partial void OnRegionDescriptionChanging(string value); + partial void OnRegionIDChanged(); + partial void OnRegionIDChanging(long value); - #endregion - - #region string RegionDescription - - private string _regionDescription; - [DebuggerNonUserCode] - [Column(Storage = "_regionDescription", Name = "RegionDescription", DbType = "nchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Region() + { + _territories = new EntitySet(new Action(this.Territories_Attach), new Action(this.Territories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionDescription", Name="RegionDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string RegionDescription { get { - return _regionDescription; + return this._regionDescription; } set { - if (value != _regionDescription) + if (((_regionDescription == value) + == false)) { - OnRegionDescriptionChanging(value); - SendPropertyChanging(); - _regionDescription = value; - SendPropertyChanged("RegionDescription"); - OnRegionDescriptionChanged(); + this.OnRegionDescriptionChanging(value); + this.SendPropertyChanging(); + this._regionDescription = value; + this.SendPropertyChanged("RegionDescription"); + this.OnRegionDescriptionChanged(); } } } - - #endregion - - #region long RegionID - - private long _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_regionID", Name="RegionID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long RegionID { get { - return _regionID; + return this._regionID; } set { - if (value != _regionID) + if ((_regionID != value)) { - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _territories; - [Association(Storage = "_territories", OtherKey = "RegionID", ThisKey = "RegionID", Name = "FK_Territories_0")] - [DebuggerNonUserCode] + [Association(Storage="_territories", OtherKey="RegionID", ThisKey="RegionID", Name="FK_Territories_0")] + [DebuggerNonUserCode()] public EntitySet Territories { get { - return _territories; + return this._territories; } set { - _territories = value; + this._territories = value; } } - - #endregion - - #region Attachement handlers - - private void Territories_Attach(Territory entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Region = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Territories_Detach(Territory entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Region = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Region() + + public override int GetHashCode() { - _territories = new EntitySet(Territories_Attach, Territories_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_regionID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Shippers")] - public partial class Shipper : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Region other = ((Region)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Region value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._regionID, value._regionID); + } + + #region Attachment handlers + private void Territories_Attach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = this; + } + + private void Territories_Detach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Shippers")] + public partial class Shipper : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _companyName; + + private string _phone; + + private long _shipperID; + + private EntitySet _orders; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnShipperIDChanged(); + partial void OnShipperIDChanging(long value); - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Shipper() + { + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region long ShipperID - - private long _shipperID; - [DebuggerNonUserCode] - [Column(Storage = "_shipperID", Name = "ShipperID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_shipperID", Name="ShipperID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long ShipperID { get { - return _shipperID; + return this._shipperID; } set { - if (value != _shipperID) + if ((_shipperID != value)) { - OnShipperIDChanging(value); - SendPropertyChanging(); - _shipperID = value; - SendPropertyChanged("ShipperID"); - OnShipperIDChanged(); + this.OnShipperIDChanging(value); + this.SendPropertyChanging(); + this._shipperID = value; + this.SendPropertyChanged("ShipperID"); + this.OnShipperIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "ShipVia", ThisKey = "ShipperID", Name = "FK_Orders_0")] - [DebuggerNonUserCode] + [Association(Storage="_orders", OtherKey="ShipVia", ThisKey="ShipperID", Name="FK_Orders_0")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - #endregion - - #region Attachement handlers - - private void Orders_Attach(Order entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Shipper = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Orders_Detach(Order entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Shipper = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Shipper() + + public override int GetHashCode() { - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_shipperID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Suppliers")] - public partial class Supplier : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Shipper other = ((Shipper)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Shipper value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._shipperID, value._shipperID); + } + + #region Attachment handlers + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Suppliers")] + public partial class Supplier : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _fax; + + private string _homePage; + + private string _phone; + + private string _postalCode; + + private string _region; + + private long _supplierID; + + private EntitySet _products; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnContactNameChanged(); + partial void OnContactNameChanging(string value); + partial void OnContactTitleChanged(); + partial void OnContactTitleChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnFaxChanged(); + partial void OnFaxChanging(string value); + partial void OnHomePageChanged(); + partial void OnHomePageChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); + partial void OnSupplierIDChanged(); + partial void OnSupplierIDChanging(long value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + + public Supplier() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_city", Name="City", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactName { get { - return _contactName; + return this._contactName; } set { - if (value != _contactName) + if (((_contactName == value) + == false)) { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); } } } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactTitle { get { - return _contactTitle; + return this._contactTitle; } set { - if (value != _contactTitle) + if (((_contactTitle == value) + == false)) { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Fax { get { - return _fax; + return this._fax; } set { - if (value != _fax) + if (((_fax == value) + == false)) { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); } } } - - #endregion - - #region string HomePage - - private string _homePage; - [DebuggerNonUserCode] - [Column(Storage = "_homePage", Name = "HomePage", DbType = "ntext", AutoSync = AutoSync.Never)] + + [Column(Storage="_homePage", Name="HomePage", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string HomePage { get { - return _homePage; + return this._homePage; } set { - if (value != _homePage) + if (((_homePage == value) + == false)) { - OnHomePageChanging(value); - SendPropertyChanging(); - _homePage = value; - SendPropertyChanged("HomePage"); - OnHomePageChanged(); + this.OnHomePageChanging(value); + this.SendPropertyChanging(); + this._homePage = value; + this.SendPropertyChanged("HomePage"); + this.OnHomePageChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - - #region long SupplierID - - private long _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_supplierID", Name="SupplierID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long SupplierID { get { - return _supplierID; + return this._supplierID; } set { - if (value != _supplierID) + if ((_supplierID != value)) { - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "FK_Products_0")] - [DebuggerNonUserCode] + [Association(Storage="_products", OtherKey="SupplierID", ThisKey="SupplierID", Name="FK_Products_0")] + [DebuggerNonUserCode()] public EntitySet Products { get { - return _products; + return this._products; } set { - _products = value; + this._products = value; } } - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Supplier = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Products_Detach(Product entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Supplier = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Supplier() + + public override int GetHashCode() { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_supplierID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Territories")] - public partial class Territory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Supplier other = ((Supplier)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Supplier value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._supplierID, value._supplierID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Territories")] + public partial class Territory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private long _regionID; + + private string _territoryDescription; + + private string _territoryID; + + private EntitySet _employeeTerritories; + + private EntityRef _region = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnRegionIDChanged(); + partial void OnRegionIDChanging(long value); + partial void OnTerritoryDescriptionChanged(); + partial void OnTerritoryDescriptionChanging(string value); + partial void OnTerritoryIDChanged(); + partial void OnTerritoryIDChanging(string value); - #endregion - - #region long RegionID - - private long _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "integer", AutoSync = AutoSync.Never, CanBeNull = false)] + + + public Territory() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionID", Name="RegionID", DbType="integer", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long RegionID { get { - return _regionID; + return this._regionID; } set { - if (value != _regionID) + if ((_regionID != value)) { if (_region.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); } } } - - #endregion - - #region string TerritoryDescription - - private string _territoryDescription; - [DebuggerNonUserCode] - [Column(Storage = "_territoryDescription", Name = "TerritoryDescription", DbType = "nchar", AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_territoryDescription", Name="TerritoryDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryDescription { get { - return _territoryDescription; + return this._territoryDescription; } set { - if (value != _territoryDescription) + if (((_territoryDescription == value) + == false)) { - OnTerritoryDescriptionChanging(value); - SendPropertyChanging(); - _territoryDescription = value; - SendPropertyChanged("TerritoryDescription"); - OnTerritoryDescriptionChanged(); + this.OnTerritoryDescriptionChanging(value); + this.SendPropertyChanging(); + this._territoryDescription = value; + this.SendPropertyChanged("TerritoryDescription"); + this.OnTerritoryDescriptionChanged(); } } } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never, CanBeNull = false)] + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryID { get { - return _territoryID; + return this._territoryID; } set { - if (value != _territoryID) + if (((_territoryID == value) + == false)) { - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "FK_EmployeeTerritories_0")] - [DebuggerNonUserCode] + [Association(Storage="_employeeTerritories", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="FK_EmployeeTerritories_0")] + [DebuggerNonUserCode()] public EntitySet EmployeeTerritories { get { - return _employeeTerritories; + return this._employeeTerritories; } set { - _employeeTerritories = value; + this._employeeTerritories = value; } } - - #endregion - + #region Parents - - private EntityRef _region; - [Association(Storage = "_region", OtherKey = "RegionID", ThisKey = "RegionID", Name = "FK_Territories_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_region", OtherKey="RegionID", ThisKey="RegionID", Name="FK_Territories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Region Region { get { - return _region.Entity; + return this._region.Entity; } set { - if (value != _region.Entity) + if (((this._region.Entity == value) + == false)) { - if (_region.Entity != null) + if ((this._region.Entity != null)) { - var previousRegion = _region.Entity; - _region.Entity = null; + Region previousRegion = this._region.Entity; + this._region.Entity = null; previousRegion.Territories.Remove(this); } - _region.Entity = value; - if (value != null) + this._region.Entity = value; + if ((value != null)) { value.Territories.Add(this); _regionID = value.RegionID; @@ -4131,35 +4441,77 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Territory other = ((Territory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Territory value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID); + } + + #region Attachment handlers private void EmployeeTerritories_Attach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Territory = this; } - + private void EmployeeTerritories_Detach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Territory = null; } - - - #endregion - - #region ctor - - public Territory() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _region = new EntityRef(); - OnCreated(); - } - #endregion - } } diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-DbMetal.dbml b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-DbMetal.dbml new file mode 100755 index 00000000000..4cf331665d1 --- /dev/null +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-DbMetal.dbml @@ -0,0 +1,169 @@ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
\ No newline at end of file diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-sqlmetal.cs b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-sqlmetal.cs index 1474d2b070c..12413849806 100755 --- a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-sqlmetal.cs +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-sqlmetal.cs @@ -1,816 +1,925 @@ -#region Auto-generated classes for Northwind database on [TIMESTAMP] - -// -// ____ _ __ __ _ _ +// +// ____ _ __ __ _ _ // | _ \| |__ | \/ | ___| |_ __ _| | // | | | | '_ \| |\/| |/ _ \ __/ _` | | // | |_| | |_) | | | | __/ || (_| | | // |____/|_.__/|_| |_|\___|\__\__,_|_| // -// Auto-generated from Northwind on [TIMESTAMP] -// Please visit http://linq.to/db for more information - -#endregion - -using System; -using System.Data; -using System.Data.Linq.Mapping; -using System.Diagnostics; -using System.Reflection; -using System.Data.Linq; -using System.ComponentModel; - +// Auto-generated from Northwind on [TIMESTAMP]. +// Please visit http://code.google.com/p/dblinq2007/ for more information. +// namespace nwind { + using System; + using System.ComponentModel; + using System.Data; + using System.Data.Linq; + using System.Data.Linq.Mapping; + using System.Diagnostics; + + public partial class Northwind : DataContext { - #region Extensibility Method Definitions - + + #region Extensibility Method Declarations partial void OnCreated(); - #endregion - - public Northwind(string connectionString) - : base(connectionString) - { - OnCreated(); - } - - public Northwind(IDbConnection connection) - : base(connection) - { - OnCreated(); - } - - public Northwind(string connection, MappingSource mappingSource) - : base(connection, mappingSource) - { - OnCreated(); - } - - public Northwind(IDbConnection connection, MappingSource mappingSource) - : base(connection, mappingSource) - { - OnCreated(); - } - - public Table Categories { get { return GetTable(); } } - public Table Customers { get { return GetTable(); } } - public Table CustomerCustomerDemo { get { return GetTable(); } } - public Table CustomerDemographics { get { return GetTable(); } } - public Table Employees { get { return GetTable(); } } - public Table EmployeeTerritories { get { return GetTable(); } } - public Table Orders { get { return GetTable(); } } - public Table OrderDetails { get { return GetTable(); } } - public Table Products { get { return GetTable(); } } - public Table Regions { get { return GetTable(); } } - public Table Shippers { get { return GetTable(); } } - public Table Suppliers { get { return GetTable(); } } - public Table Territories { get { return GetTable(); } } - - } - - [Table(Name = "Categories")] - public partial class Category : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + + public Northwind(string connectionString) : + base(connectionString) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection) : + base(connection) + { + this.OnCreated(); + } + + public Northwind(string connection, MappingSource mappingSource) : + base(connection, mappingSource) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, MappingSource mappingSource) : + base(connection, mappingSource) + { + this.OnCreated(); + } + + public Table Categories { - if (PropertyChanging != null) + get { - PropertyChanging(this, emptyChangingEventArgs); + return this.GetTable(); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public Table Customers { - if (PropertyChanged != null) + get { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return this.GetTable(); } } - - #endregion - - #region Extensibility Method Definitions - + + public Table CustomerCustomerDemo + { + get + { + return this.GetTable(); + } + } + + public Table CustomerDemographics + { + get + { + return this.GetTable(); + } + } + + public Table Employees + { + get + { + return this.GetTable(); + } + } + + public Table EmployeeTerritories + { + get + { + return this.GetTable(); + } + } + + public Table Orders + { + get + { + return this.GetTable(); + } + } + + public Table OrderDetails + { + get + { + return this.GetTable(); + } + } + + public Table Products + { + get + { + return this.GetTable(); + } + } + + public Table Regions + { + get + { + return this.GetTable(); + } + } + + public Table Shippers + { + get + { + return this.GetTable(); + } + } + + public Table Suppliers + { + get + { + return this.GetTable(); + } + } + + public Table Territories + { + get + { + return this.GetTable(); + } + } + } + + [Table(Name="Categories")] + public partial class Category : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private long _categoryID; + + private string _categoryName; + + private string _description; + + private byte[] _picture; + + private EntitySet _products; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCategoryIDChanged(); + partial void OnCategoryIDChanging(long value); + partial void OnCategoryNameChanged(); + partial void OnCategoryNameChanging(string value); + partial void OnDescriptionChanged(); + partial void OnDescriptionChanging(string value); + partial void OnPictureChanged(); - partial void OnPictureChanging(Byte[] value); - + + partial void OnPictureChanging(byte[] value); #endregion - - #region long CategoryID - - private long _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + + public Category() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long CategoryID { get { - return _categoryID; + return this._categoryID; } set { - if (value != _categoryID) + if ((_categoryID != value)) { - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); } } } - - #endregion - - #region string CategoryName - - private string _categoryName; - [DebuggerNonUserCode] - [Column(Storage = "_categoryName", Name = "CategoryName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_categoryName", Name="CategoryName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CategoryName { get { - return _categoryName; + return this._categoryName; } set { - if (value != _categoryName) + if (((_categoryName == value) + == false)) { - OnCategoryNameChanging(value); - SendPropertyChanging(); - _categoryName = value; - SendPropertyChanged("CategoryName"); - OnCategoryNameChanged(); + this.OnCategoryNameChanging(value); + this.SendPropertyChanging(); + this._categoryName = value; + this.SendPropertyChanged("CategoryName"); + this.OnCategoryNameChanged(); } } } - - #endregion - - #region string Description - - private string _description; - [DebuggerNonUserCode] - [Column(Storage = "_description", Name = "Description", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_description", Name="Description", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Description { get { - return _description; + return this._description; } set { - if (value != _description) + if (((_description == value) + == false)) { - OnDescriptionChanging(value); - SendPropertyChanging(); - _description = value; - SendPropertyChanged("Description"); - OnDescriptionChanged(); + this.OnDescriptionChanging(value); + this.SendPropertyChanging(); + this._description = value; + this.SendPropertyChanged("Description"); + this.OnDescriptionChanged(); } } } - - #endregion - - #region Byte[] Picture - - private Byte[] _picture; - [DebuggerNonUserCode] - [Column(Storage = "_picture", Name = "Picture", DbType = "image", AutoSync = AutoSync.Never, CanBeNull = true)] - public Byte[] Picture + + [Column(Storage="_picture", Name="Picture", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Picture { get { - return _picture; + return this._picture; } set { - if (value != _picture) + if (((_picture == value) + == false)) { - OnPictureChanging(value); - SendPropertyChanging(); - _picture = value; - SendPropertyChanged("Picture"); - OnPictureChanged(); + this.OnPictureChanging(value); + this.SendPropertyChanging(); + this._picture = value; + this.SendPropertyChanged("Picture"); + this.OnPictureChanged(); } } } - - #endregion - + #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "FK_Products_1")] - [DebuggerNonUserCode] + [Association(Storage="_products", OtherKey="CategoryID", ThisKey="CategoryID", Name="FK_Products_1")] + [DebuggerNonUserCode()] public EntitySet Products { get { - return _products; + return this._products; } set { - _products = value; + this._products = value; } } - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Category = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Products_Detach(Product entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Category = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Category() + + public override int GetHashCode() { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_categoryID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Customers")] - public partial class Customer : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Category other = ((Category)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Category value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._categoryID, value._categoryID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Customers")] + public partial class Customer : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _customerID; + + private string _fax; + + private string _phone; + + private string _postalCode; + + private string _region; + + private EntitySet _orders; + + private EntitySet _customerCustomerDemo; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnContactNameChanged(); + partial void OnContactNameChanging(string value); + partial void OnContactTitleChanged(); + partial void OnContactTitleChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnFaxChanged(); + partial void OnFaxChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + + public Customer() + { + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_city", Name="City", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactName { get { - return _contactName; + return this._contactName; } set { - if (value != _contactName) + if (((_contactName == value) + == false)) { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); } } } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactTitle { get { - return _contactTitle; + return this._contactTitle; } set { - if (value != _contactTitle) + if (((_contactTitle == value) + == false)) { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Fax { get { - return _fax; + return this._fax; } set { - if (value != _fax) + if (((_fax == value) + == false)) { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_Orders_2")] - [DebuggerNonUserCode] + [Association(Storage="_orders", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_Orders_2")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_CustomerCustomerDemo_0")] - [DebuggerNonUserCode] + + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_CustomerCustomerDemo_0")] + [DebuggerNonUserCode()] public EntitySet CustomerCustomerDemo { get { - return _customerCustomerDemo; + return this._customerCustomerDemo; } set { - _customerCustomerDemo = value; + this._customerCustomerDemo = value; } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Customer other = ((Customer)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Customer value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID); + } + + #region Attachment handlers private void Orders_Attach(Order entity) { + this.SendPropertyChanging(); entity.Customer = this; } - + private void Orders_Detach(Order entity) { + this.SendPropertyChanging(); entity.Customer = null; } - + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) { + this.SendPropertyChanging(); entity.Customer = this; } - + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) { + this.SendPropertyChanging(); entity.Customer = null; } - - #endregion - - #region ctor - - public Customer() - { - _orders = new EntitySet(Orders_Attach, Orders_Detach); - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - OnCreated(); - } - - #endregion - } - - [Table(Name = "CustomerCustomerDemo")] - public partial class CustomerCustomerDemo : INotifyPropertyChanging, INotifyPropertyChanged + + [Table(Name="CustomerCustomerDemo")] + public partial class CustomerCustomerDemo : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private string _customerTypeID; + + private EntityRef _customer = new EntityRef(); + + private EntityRef _customerDemographic = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnCustomerTypeIDChanged(); + partial void OnCustomerTypeIDChanging(string value); - #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] + + + public CustomerCustomerDemo() + { + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { if (_customer.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerTypeID { get { - return _customerTypeID; + return this._customerTypeID; } set { - if (value != _customerTypeID) + if (((_customerTypeID == value) + == false)) { if (_customerDemographic.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_CustomerCustomerDemo_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_CustomerCustomerDemo_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Customer Customer { get { - return _customer.Entity; + return this._customer.Entity; } set { - if (value != _customer.Entity) + if (((this._customer.Entity == value) + == false)) { - if (_customer.Entity != null) + if ((this._customer.Entity != null)) { - var previousCustomer = _customer.Entity; - _customer.Entity = null; + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; previousCustomer.CustomerCustomerDemo.Remove(this); } - _customer.Entity = value; - if (value != null) + this._customer.Entity = value; + if ((value != null)) { value.CustomerCustomerDemo.Add(this); _customerID = value.CustomerID; @@ -822,28 +931,28 @@ namespace nwind } } } - - private EntityRef _customerDemographic; - [Association(Storage = "_customerDemographic", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "FK_CustomerCustomerDemo_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_customerDemographic", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="FK_CustomerCustomerDemo_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public CustomerDemographic CustomerDemographic { get { - return _customerDemographic.Entity; + return this._customerDemographic.Entity; } set { - if (value != _customerDemographic.Entity) + if (((this._customerDemographic.Entity == value) + == false)) { - if (_customerDemographic.Entity != null) + if ((this._customerDemographic.Entity != null)) { - var previousCustomerDemographic = _customerDemographic.Entity; - _customerDemographic.Entity = null; + CustomerDemographic previousCustomerDemographic = this._customerDemographic.Entity; + this._customerDemographic.Entity = null; previousCustomerDemographic.CustomerCustomerDemo.Remove(this); } - _customerDemographic.Entity = value; - if (value != null) + this._customerDemographic.Entity = value; + if ((value != null)) { value.CustomerCustomerDemo.Add(this); _customerTypeID = value.CustomerTypeID; @@ -855,783 +964,831 @@ namespace nwind } } } - - - #endregion - - #region ctor - - public CustomerCustomerDemo() - { - _customer = new EntityRef(); - _customerDemographic = new EntityRef(); - OnCreated(); - } - #endregion - - } - - [Table(Name = "CustomerDemographics")] - public partial class CustomerDemographic : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - - #endregion - - #region Extensibility Method Definitions - + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + CustomerCustomerDemo other = ((CustomerCustomerDemo)(value)); + return this.Equals(other); + } + + public virtual bool Equals(CustomerCustomerDemo value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID)); + } + } + + [Table(Name="CustomerDemographics")] + public partial class CustomerDemographic : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerDesc; + + private string _customerTypeID; + + private EntitySet _customerCustomerDemo; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerDescChanged(); + partial void OnCustomerDescChanging(string value); + partial void OnCustomerTypeIDChanged(); + partial void OnCustomerTypeIDChanging(string value); - #endregion - - #region string CustomerDesc - - private string _customerDesc; - [DebuggerNonUserCode] - [Column(Storage = "_customerDesc", Name = "CustomerDesc", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] + + + public CustomerDemographic() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerDesc", Name="CustomerDesc", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string CustomerDesc { get { - return _customerDesc; + return this._customerDesc; } set { - if (value != _customerDesc) + if (((_customerDesc == value) + == false)) { - OnCustomerDescChanging(value); - SendPropertyChanging(); - _customerDesc = value; - SendPropertyChanged("CustomerDesc"); - OnCustomerDescChanged(); + this.OnCustomerDescChanging(value); + this.SendPropertyChanging(); + this._customerDesc = value; + this.SendPropertyChanged("CustomerDesc"); + this.OnCustomerDescChanged(); } } } - - #endregion - - #region string CustomerTypeID - - private string _customerTypeID; - [DebuggerNonUserCode] - [Column(Storage = "_customerTypeID", Name = "CustomerTypeID", DbType = "nchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CustomerTypeID { get { - return _customerTypeID; + return this._customerTypeID; } set { - if (value != _customerTypeID) + if (((_customerTypeID == value) + == false)) { - OnCustomerTypeIDChanging(value); - SendPropertyChanging(); - _customerTypeID = value; - SendPropertyChanged("CustomerTypeID"); - OnCustomerTypeIDChanged(); + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _customerCustomerDemo; - [Association(Storage = "_customerCustomerDemo", OtherKey = "CustomerTypeID", ThisKey = "CustomerTypeID", Name = "FK_CustomerCustomerDemo_1")] - [DebuggerNonUserCode] + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="FK_CustomerCustomerDemo_1")] + [DebuggerNonUserCode()] public EntitySet CustomerCustomerDemo { get { - return _customerCustomerDemo; + return this._customerCustomerDemo; } set { - _customerCustomerDemo = value; + this._customerCustomerDemo = value; } } - - #endregion - - #region Attachement handlers - - private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.CustomerDemographic = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.CustomerDemographic = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public CustomerDemographic() + + public override int GetHashCode() { - _customerCustomerDemo = new EntitySet(CustomerCustomerDemo_Attach, CustomerCustomerDemo_Detach); - OnCreated(); + int hc = 0; + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 1)); + } + return hc; } - - #endregion - - } - - [Table(Name = "Employees")] - public partial class Employee : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + CustomerDemographic other = ((CustomerDemographic)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(CustomerDemographic value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID); + } + + #region Attachment handlers + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = this; + } + + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Employees")] + public partial class Employee : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private System.Nullable _birthDate; + + private string _city; + + private string _country; + + private long _employeeID; + + private string _extension; + + private string _firstName; + + private System.Nullable _hireDate; + + private string _homePhone; + + private string _lastName; + + private string _notes; + + private byte[] _photo; + + private string _photoPath; + + private string _postalCode; + + private string _region; + + private System.Nullable _reportsTo; + + private string _title; + + private string _titleOfCourtesy; + + private EntitySet _employees; + + private EntitySet _orders; + + private EntitySet _employeeTerritories; + + private EntityRef _reportsToEmployee = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnBirthDateChanged(); - partial void OnBirthDateChanging(DateTime? value); + + partial void OnBirthDateChanging(System.Nullable value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnEmployeeIDChanged(); + partial void OnEmployeeIDChanging(long value); + partial void OnExtensionChanged(); + partial void OnExtensionChanging(string value); + partial void OnFirstNameChanged(); + partial void OnFirstNameChanging(string value); + partial void OnHireDateChanged(); - partial void OnHireDateChanging(DateTime? value); + + partial void OnHireDateChanging(System.Nullable value); + partial void OnHomePhoneChanged(); + partial void OnHomePhoneChanging(string value); + partial void OnLastNameChanged(); + partial void OnLastNameChanging(string value); + partial void OnNotesChanged(); + partial void OnNotesChanging(string value); + partial void OnPhotoChanged(); - partial void OnPhotoChanging(Byte[] value); + + partial void OnPhotoChanging(byte[] value); + partial void OnPhotoPathChanged(); + partial void OnPhotoPathChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); + partial void OnReportsToChanged(); - partial void OnReportsToChanging(long? value); + + partial void OnReportsToChanging(System.Nullable value); + partial void OnTitleChanged(); + partial void OnTitleChanging(string value); + partial void OnTitleOfCourtesyChanged(); + partial void OnTitleOfCourtesyChanging(string value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + + public Employee() + { + _employees = new EntitySet(new Action(this.Employees_Attach), new Action(this.Employees_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region DateTime? BirthDate - - private DateTime? _birthDate; - [DebuggerNonUserCode] - [Column(Storage = "_birthDate", Name = "BirthDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? BirthDate + + [Column(Storage="_birthDate", Name="BirthDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable BirthDate { get { - return _birthDate; + return this._birthDate; } set { - if (value != _birthDate) + if ((_birthDate != value)) { - OnBirthDateChanging(value); - SendPropertyChanging(); - _birthDate = value; - SendPropertyChanged("BirthDate"); - OnBirthDateChanged(); + this.OnBirthDateChanging(value); + this.SendPropertyChanging(); + this._birthDate = value; + this.SendPropertyChanged("BirthDate"); + this.OnBirthDateChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_city", Name="City", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region long EmployeeID - - private long _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region string Extension - - private string _extension; - [DebuggerNonUserCode] - [Column(Storage = "_extension", Name = "Extension", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_extension", Name="Extension", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Extension { get { - return _extension; + return this._extension; } set { - if (value != _extension) + if (((_extension == value) + == false)) { - OnExtensionChanging(value); - SendPropertyChanging(); - _extension = value; - SendPropertyChanged("Extension"); - OnExtensionChanged(); + this.OnExtensionChanging(value); + this.SendPropertyChanging(); + this._extension = value; + this.SendPropertyChanged("Extension"); + this.OnExtensionChanged(); } } } - - #endregion - - #region string FirstName - - private string _firstName; - [DebuggerNonUserCode] - [Column(Storage = "_firstName", Name = "FirstName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_firstName", Name="FirstName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string FirstName { get { - return _firstName; + return this._firstName; } set { - if (value != _firstName) + if (((_firstName == value) + == false)) { - OnFirstNameChanging(value); - SendPropertyChanging(); - _firstName = value; - SendPropertyChanged("FirstName"); - OnFirstNameChanged(); + this.OnFirstNameChanging(value); + this.SendPropertyChanging(); + this._firstName = value; + this.SendPropertyChanged("FirstName"); + this.OnFirstNameChanged(); } } } - - #endregion - - #region DateTime? HireDate - - private DateTime? _hireDate; - [DebuggerNonUserCode] - [Column(Storage = "_hireDate", Name = "HireDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? HireDate + + [Column(Storage="_hireDate", Name="HireDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable HireDate { get { - return _hireDate; + return this._hireDate; } set { - if (value != _hireDate) + if ((_hireDate != value)) { - OnHireDateChanging(value); - SendPropertyChanging(); - _hireDate = value; - SendPropertyChanged("HireDate"); - OnHireDateChanged(); + this.OnHireDateChanging(value); + this.SendPropertyChanging(); + this._hireDate = value; + this.SendPropertyChanged("HireDate"); + this.OnHireDateChanged(); } } } - - #endregion - - #region string HomePhone - - private string _homePhone; - [DebuggerNonUserCode] - [Column(Storage = "_homePhone", Name = "HomePhone", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_homePhone", Name="HomePhone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string HomePhone { get { - return _homePhone; + return this._homePhone; } set { - if (value != _homePhone) + if (((_homePhone == value) + == false)) { - OnHomePhoneChanging(value); - SendPropertyChanging(); - _homePhone = value; - SendPropertyChanged("HomePhone"); - OnHomePhoneChanged(); + this.OnHomePhoneChanging(value); + this.SendPropertyChanging(); + this._homePhone = value; + this.SendPropertyChanged("HomePhone"); + this.OnHomePhoneChanged(); } } } - - #endregion - - #region string LastName - - private string _lastName; - [DebuggerNonUserCode] - [Column(Storage = "_lastName", Name = "LastName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_lastName", Name="LastName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string LastName { get { - return _lastName; + return this._lastName; } set { - if (value != _lastName) + if (((_lastName == value) + == false)) { - OnLastNameChanging(value); - SendPropertyChanging(); - _lastName = value; - SendPropertyChanged("LastName"); - OnLastNameChanged(); + this.OnLastNameChanging(value); + this.SendPropertyChanging(); + this._lastName = value; + this.SendPropertyChanged("LastName"); + this.OnLastNameChanged(); } } } - - #endregion - - #region string Notes - - private string _notes; - [DebuggerNonUserCode] - [Column(Storage = "_notes", Name = "Notes", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_notes", Name="Notes", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Notes { get { - return _notes; + return this._notes; } set { - if (value != _notes) + if (((_notes == value) + == false)) { - OnNotesChanging(value); - SendPropertyChanging(); - _notes = value; - SendPropertyChanged("Notes"); - OnNotesChanged(); + this.OnNotesChanging(value); + this.SendPropertyChanging(); + this._notes = value; + this.SendPropertyChanged("Notes"); + this.OnNotesChanged(); } } } - - #endregion - - #region Byte[] Photo - - private Byte[] _photo; - [DebuggerNonUserCode] - [Column(Storage = "_photo", Name = "Photo", DbType = "image", AutoSync = AutoSync.Never, CanBeNull = true)] - public Byte[] Photo + + [Column(Storage="_photo", Name="Photo", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Photo { get { - return _photo; + return this._photo; } set { - if (value != _photo) + if (((_photo == value) + == false)) { - OnPhotoChanging(value); - SendPropertyChanging(); - _photo = value; - SendPropertyChanged("Photo"); - OnPhotoChanged(); + this.OnPhotoChanging(value); + this.SendPropertyChanging(); + this._photo = value; + this.SendPropertyChanged("Photo"); + this.OnPhotoChanged(); } } } - - #endregion - - #region string PhotoPath - - private string _photoPath; - [DebuggerNonUserCode] - [Column(Storage = "_photoPath", Name = "PhotoPath", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_photoPath", Name="PhotoPath", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PhotoPath { get { - return _photoPath; + return this._photoPath; } set { - if (value != _photoPath) + if (((_photoPath == value) + == false)) { - OnPhotoPathChanging(value); - SendPropertyChanging(); - _photoPath = value; - SendPropertyChanged("PhotoPath"); - OnPhotoPathChanged(); + this.OnPhotoPathChanging(value); + this.SendPropertyChanging(); + this._photoPath = value; + this.SendPropertyChanged("PhotoPath"); + this.OnPhotoPathChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - - #region long? ReportsTo - - private long? _reportsTo; - [DebuggerNonUserCode] - [Column(Storage = "_reportsTo", Name = "ReportsTo", DbType = "integer", AutoSync = AutoSync.Never, CanBeNull = true)] - public long? ReportsTo + + [Column(Storage="_reportsTo", Name="ReportsTo", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReportsTo { get { - return _reportsTo; + return this._reportsTo; } set { - if (value != _reportsTo) + if ((_reportsTo != value)) { if (_reportsToEmployee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnReportsToChanging(value); - SendPropertyChanging(); - _reportsTo = value; - SendPropertyChanged("ReportsTo"); - OnReportsToChanged(); + this.OnReportsToChanging(value); + this.SendPropertyChanging(); + this._reportsTo = value; + this.SendPropertyChanged("ReportsTo"); + this.OnReportsToChanged(); } } } - - #endregion - - #region string Title - - private string _title; - [DebuggerNonUserCode] - [Column(Storage = "_title", Name = "Title", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_title", Name="Title", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Title { get { - return _title; + return this._title; } set { - if (value != _title) + if (((_title == value) + == false)) { - OnTitleChanging(value); - SendPropertyChanging(); - _title = value; - SendPropertyChanged("Title"); - OnTitleChanged(); + this.OnTitleChanging(value); + this.SendPropertyChanging(); + this._title = value; + this.SendPropertyChanged("Title"); + this.OnTitleChanged(); } } } - - #endregion - - #region string TitleOfCourtesy - - private string _titleOfCourtesy; - [DebuggerNonUserCode] - [Column(Storage = "_titleOfCourtesy", Name = "TitleOfCourtesy", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_titleOfCourtesy", Name="TitleOfCourtesy", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string TitleOfCourtesy { get { - return _titleOfCourtesy; + return this._titleOfCourtesy; } set { - if (value != _titleOfCourtesy) + if (((_titleOfCourtesy == value) + == false)) { - OnTitleOfCourtesyChanging(value); - SendPropertyChanging(); - _titleOfCourtesy = value; - SendPropertyChanged("TitleOfCourtesy"); - OnTitleOfCourtesyChanged(); + this.OnTitleOfCourtesyChanging(value); + this.SendPropertyChanging(); + this._titleOfCourtesy = value; + this.SendPropertyChanged("TitleOfCourtesy"); + this.OnTitleOfCourtesyChanged(); } } } - - #endregion - + #region Children - - private EntitySet _employees; - [Association(Storage = "_employees", OtherKey = "ReportsTo", ThisKey = "EmployeeID", Name = "FK_Employees_0")] - [DebuggerNonUserCode] + [Association(Storage="_employees", OtherKey="ReportsTo", ThisKey="EmployeeID", Name="FK_Employees_0")] + [DebuggerNonUserCode()] public EntitySet Employees { get { - return _employees; + return this._employees; } set { - _employees = value; + this._employees = value; } } - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_Orders_1")] - [DebuggerNonUserCode] + + [Association(Storage="_orders", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_Orders_1")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_EmployeeTerritories_1")] - [DebuggerNonUserCode] + + [Association(Storage="_employeeTerritories", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_EmployeeTerritories_1")] + [DebuggerNonUserCode()] public EntitySet EmployeeTerritories { get { - return _employeeTerritories; + return this._employeeTerritories; } set { - _employeeTerritories = value; + this._employeeTerritories = value; } } - - #endregion - + #region Parents - - private EntityRef _reportsToEmployee; - [Association(Storage = "_reportsToEmployee", OtherKey = "EmployeeID", ThisKey = "ReportsTo", Name = "FK_Employees_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_reportsToEmployee", OtherKey="EmployeeID", ThisKey="ReportsTo", Name="FK_Employees_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee ReportsToEmployee { get { - return _reportsToEmployee.Entity; + return this._reportsToEmployee.Entity; } set { - if (value != _reportsToEmployee.Entity) + if (((this._reportsToEmployee.Entity == value) + == false)) { - if (_reportsToEmployee.Entity != null) + if ((this._reportsToEmployee.Entity != null)) { - var previousEmployee = _reportsToEmployee.Entity; - _reportsToEmployee.Entity = null; + Employee previousEmployee = this._reportsToEmployee.Entity; + this._reportsToEmployee.Entity = null; previousEmployee.Employees.Remove(this); } - _reportsToEmployee.Entity = value; - if (value != null) + this._reportsToEmployee.Entity = value; + if ((value != null)) { value.Employees.Add(this); _reportsTo = value.EmployeeID; @@ -1643,185 +1800,206 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Employee other = ((Employee)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Employee value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID); + } + + #region Attachment handlers private void Employees_Attach(Employee entity) { + this.SendPropertyChanging(); entity.ReportsToEmployee = this; } - + private void Employees_Detach(Employee entity) { + this.SendPropertyChanging(); entity.ReportsToEmployee = null; } - + private void Orders_Attach(Order entity) { + this.SendPropertyChanging(); entity.Employee = this; } - + private void Orders_Detach(Order entity) { + this.SendPropertyChanging(); entity.Employee = null; } - + private void EmployeeTerritories_Attach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Employee = this; } - + private void EmployeeTerritories_Detach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Employee = null; } - - #endregion - - #region ctor - - public Employee() - { - _employees = new EntitySet(Employees_Attach, Employees_Detach); - _orders = new EntitySet(Orders_Attach, Orders_Detach); - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _reportsToEmployee = new EntityRef(); - OnCreated(); - } - - #endregion - } - - [Table(Name = "EmployeeTerritories")] - public partial class EmployeeTerritory : INotifyPropertyChanging, INotifyPropertyChanged + + [Table(Name="EmployeeTerritories")] + public partial class EmployeeTerritory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() - { - if (PropertyChanging != null) - { - PropertyChanging(this, emptyChangingEventArgs); - } - } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) - { - if (PropertyChanged != null) - { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); - } - } - - #endregion - - #region Extensibility Method Definitions - + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private long _employeeID; + + private string _territoryID; + + private EntityRef _territory = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnEmployeeIDChanged(); + partial void OnEmployeeIDChanging(long value); + partial void OnTerritoryIDChanged(); + partial void OnTerritoryIDChanging(string value); - #endregion - - #region long EmployeeID - - private long _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + + public EmployeeTerritory() + { + this.OnCreated(); + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { if (_employee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryID { get { - return _territoryID; + return this._territoryID; } set { - if (value != _territoryID) + if (((_territoryID == value) + == false)) { if (_territory.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _territory; - [Association(Storage = "_territory", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "FK_EmployeeTerritories_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_territory", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="FK_EmployeeTerritories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Territory Territory { get { - return _territory.Entity; + return this._territory.Entity; } set { - if (value != _territory.Entity) + if (((this._territory.Entity == value) + == false)) { - if (_territory.Entity != null) + if ((this._territory.Entity != null)) { - var previousTerritory = _territory.Entity; - _territory.Entity = null; + Territory previousTerritory = this._territory.Entity; + this._territory.Entity = null; previousTerritory.EmployeeTerritories.Remove(this); } - _territory.Entity = value; - if (value != null) + this._territory.Entity = value; + if ((value != null)) { value.EmployeeTerritories.Add(this); _territoryID = value.TerritoryID; @@ -1833,28 +2011,28 @@ namespace nwind } } } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_EmployeeTerritories_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_EmployeeTerritories_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee Employee { get { - return _employee.Entity; + return this._employee.Entity; } set { - if (value != _employee.Entity) + if (((this._employee.Entity == value) + == false)) { - if (_employee.Entity != null) + if ((this._employee.Entity != null)) { - var previousEmployee = _employee.Entity; - _employee.Entity = null; + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; previousEmployee.EmployeeTerritories.Remove(this); } - _employee.Entity = value; - if (value != null) + this._employee.Entity = value; + if ((value != null)) { value.EmployeeTerritories.Add(this); _employeeID = value.EmployeeID; @@ -1866,508 +2044,528 @@ namespace nwind } } } - - - #endregion - - #region ctor - - public EmployeeTerritory() - { - _territory = new EntityRef(); - _employee = new EntityRef(); - OnCreated(); - } - #endregion - - } - - [Table(Name = "Orders")] - public partial class Order : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + protected virtual void SendPropertyChanging() { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) { - PropertyChanging(this, emptyChangingEventArgs); + h(this, emptyChangingEventArgs); } } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanged != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } - - #endregion - - #region Extensibility Method Definitions - + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + EmployeeTerritory other = ((EmployeeTerritory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(EmployeeTerritory value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID)); + } + } + + [Table(Name="Orders")] + public partial class Order : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private System.Nullable _employeeID; + + private System.Nullable _freight; + + private System.Nullable _orderDate; + + private long _orderID; + + private System.Nullable _requiredDate; + + private string _shipAddress; + + private string _shipCity; + + private string _shipCountry; + + private string _shipName; + + private System.Nullable _shippedDate; + + private string _shipPostalCode; + + private string _shipRegion; + + private System.Nullable _shipVia; + + private EntitySet _orderDetails; + + private EntityRef _shipper = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + private EntityRef _customer = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCustomerIDChanged(); + partial void OnCustomerIDChanging(string value); + partial void OnEmployeeIDChanged(); - partial void OnEmployeeIDChanging(long? value); + + partial void OnEmployeeIDChanging(System.Nullable value); + partial void OnFreightChanged(); - partial void OnFreightChanging(decimal? value); + + partial void OnFreightChanging(System.Nullable value); + partial void OnOrderDateChanged(); - partial void OnOrderDateChanging(DateTime? value); + + partial void OnOrderDateChanging(System.Nullable value); + partial void OnOrderIDChanged(); + partial void OnOrderIDChanging(long value); + partial void OnRequiredDateChanged(); - partial void OnRequiredDateChanging(DateTime? value); + + partial void OnRequiredDateChanging(System.Nullable value); + partial void OnShipAddressChanged(); + partial void OnShipAddressChanging(string value); + partial void OnShipCityChanged(); + partial void OnShipCityChanging(string value); + partial void OnShipCountryChanged(); + partial void OnShipCountryChanging(string value); + partial void OnShipNameChanged(); + partial void OnShipNameChanging(string value); + partial void OnShippedDateChanged(); - partial void OnShippedDateChanging(DateTime? value); + + partial void OnShippedDateChanging(System.Nullable value); + partial void OnShipPostalCodeChanged(); + partial void OnShipPostalCodeChanging(string value); + partial void OnShipRegionChanged(); + partial void OnShipRegionChanging(string value); + partial void OnShipViaChanged(); - partial void OnShipViaChanging(long? value); - + + partial void OnShipViaChanging(System.Nullable value); #endregion - - #region string CustomerID - - private string _customerID; - [DebuggerNonUserCode] - [Column(Storage = "_customerID", Name = "CustomerID", DbType = "nchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + + public Order() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string CustomerID { get { - return _customerID; + return this._customerID; } set { - if (value != _customerID) + if (((_customerID == value) + == false)) { if (_customer.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCustomerIDChanging(value); - SendPropertyChanging(); - _customerID = value; - SendPropertyChanged("CustomerID"); - OnCustomerIDChanged(); + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); } } } - - #endregion - - #region long? EmployeeID - - private long? _employeeID; - [DebuggerNonUserCode] - [Column(Storage = "_employeeID", Name = "EmployeeID", DbType = "integer", AutoSync = AutoSync.Never, CanBeNull = true)] - public long? EmployeeID + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable EmployeeID { get { - return _employeeID; + return this._employeeID; } set { - if (value != _employeeID) + if ((_employeeID != value)) { if (_employee.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnEmployeeIDChanging(value); - SendPropertyChanging(); - _employeeID = value; - SendPropertyChanged("EmployeeID"); - OnEmployeeIDChanged(); + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); } } } - - #endregion - - #region decimal? Freight - - private decimal? _freight; - [DebuggerNonUserCode] - [Column(Storage = "_freight", Name = "Freight", DbType = "money", AutoSync = AutoSync.Never, CanBeNull = true)] - public decimal? Freight + + [Column(Storage="_freight", Name="Freight", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable Freight { get { - return _freight; + return this._freight; } set { - if (value != _freight) + if ((_freight != value)) { - OnFreightChanging(value); - SendPropertyChanging(); - _freight = value; - SendPropertyChanged("Freight"); - OnFreightChanged(); + this.OnFreightChanging(value); + this.SendPropertyChanging(); + this._freight = value; + this.SendPropertyChanged("Freight"); + this.OnFreightChanged(); } } } - - #endregion - - #region DateTime? OrderDate - - private DateTime? _orderDate; - [DebuggerNonUserCode] - [Column(Storage = "_orderDate", Name = "OrderDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? OrderDate + + [Column(Storage="_orderDate", Name="OrderDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable OrderDate { get { - return _orderDate; + return this._orderDate; } set { - if (value != _orderDate) + if ((_orderDate != value)) { - OnOrderDateChanging(value); - SendPropertyChanging(); - _orderDate = value; - SendPropertyChanged("OrderDate"); - OnOrderDateChanged(); + this.OnOrderDateChanging(value); + this.SendPropertyChanging(); + this._orderDate = value; + this.SendPropertyChanged("OrderDate"); + this.OnOrderDateChanged(); } } } - - #endregion - - #region long OrderID - - private long _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_orderID", Name="OrderID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long OrderID { get { - return _orderID; + return this._orderID; } set { - if (value != _orderID) + if ((_orderID != value)) { - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); } } } - - #endregion - - #region DateTime? RequiredDate - - private DateTime? _requiredDate; - [DebuggerNonUserCode] - [Column(Storage = "_requiredDate", Name = "RequiredDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? RequiredDate + + [Column(Storage="_requiredDate", Name="RequiredDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable RequiredDate { get { - return _requiredDate; + return this._requiredDate; } set { - if (value != _requiredDate) + if ((_requiredDate != value)) { - OnRequiredDateChanging(value); - SendPropertyChanging(); - _requiredDate = value; - SendPropertyChanged("RequiredDate"); - OnRequiredDateChanged(); + this.OnRequiredDateChanging(value); + this.SendPropertyChanging(); + this._requiredDate = value; + this.SendPropertyChanged("RequiredDate"); + this.OnRequiredDateChanged(); } } } - - #endregion - - #region string ShipAddress - - private string _shipAddress; - [DebuggerNonUserCode] - [Column(Storage = "_shipAddress", Name = "ShipAddress", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_shipAddress", Name="ShipAddress", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipAddress { get { - return _shipAddress; + return this._shipAddress; } set { - if (value != _shipAddress) + if (((_shipAddress == value) + == false)) { - OnShipAddressChanging(value); - SendPropertyChanging(); - _shipAddress = value; - SendPropertyChanged("ShipAddress"); - OnShipAddressChanged(); + this.OnShipAddressChanging(value); + this.SendPropertyChanging(); + this._shipAddress = value; + this.SendPropertyChanged("ShipAddress"); + this.OnShipAddressChanged(); } } } - - #endregion - - #region string ShipCity - - private string _shipCity; - [DebuggerNonUserCode] - [Column(Storage = "_shipCity", Name = "ShipCity", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_shipCity", Name="ShipCity", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipCity { get { - return _shipCity; + return this._shipCity; } set { - if (value != _shipCity) + if (((_shipCity == value) + == false)) { - OnShipCityChanging(value); - SendPropertyChanging(); - _shipCity = value; - SendPropertyChanged("ShipCity"); - OnShipCityChanged(); + this.OnShipCityChanging(value); + this.SendPropertyChanging(); + this._shipCity = value; + this.SendPropertyChanged("ShipCity"); + this.OnShipCityChanged(); } } } - - #endregion - - #region string ShipCountry - - private string _shipCountry; - [DebuggerNonUserCode] - [Column(Storage = "_shipCountry", Name = "ShipCountry", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_shipCountry", Name="ShipCountry", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipCountry { get { - return _shipCountry; + return this._shipCountry; } set { - if (value != _shipCountry) + if (((_shipCountry == value) + == false)) { - OnShipCountryChanging(value); - SendPropertyChanging(); - _shipCountry = value; - SendPropertyChanged("ShipCountry"); - OnShipCountryChanged(); + this.OnShipCountryChanging(value); + this.SendPropertyChanging(); + this._shipCountry = value; + this.SendPropertyChanged("ShipCountry"); + this.OnShipCountryChanged(); } } } - - #endregion - - #region string ShipName - - private string _shipName; - [DebuggerNonUserCode] - [Column(Storage = "_shipName", Name = "ShipName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_shipName", Name="ShipName", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipName { get { - return _shipName; + return this._shipName; } set { - if (value != _shipName) + if (((_shipName == value) + == false)) { - OnShipNameChanging(value); - SendPropertyChanging(); - _shipName = value; - SendPropertyChanged("ShipName"); - OnShipNameChanged(); + this.OnShipNameChanging(value); + this.SendPropertyChanging(); + this._shipName = value; + this.SendPropertyChanged("ShipName"); + this.OnShipNameChanged(); } } } - - #endregion - - #region DateTime? ShippedDate - - private DateTime? _shippedDate; - [DebuggerNonUserCode] - [Column(Storage = "_shippedDate", Name = "ShippedDate", DbType = "datetime", AutoSync = AutoSync.Never, CanBeNull = true)] - public DateTime? ShippedDate + + [Column(Storage="_shippedDate", Name="ShippedDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShippedDate { get { - return _shippedDate; + return this._shippedDate; } set { - if (value != _shippedDate) + if ((_shippedDate != value)) { - OnShippedDateChanging(value); - SendPropertyChanging(); - _shippedDate = value; - SendPropertyChanged("ShippedDate"); - OnShippedDateChanged(); + this.OnShippedDateChanging(value); + this.SendPropertyChanging(); + this._shippedDate = value; + this.SendPropertyChanged("ShippedDate"); + this.OnShippedDateChanged(); } } } - - #endregion - - #region string ShipPostalCode - - private string _shipPostalCode; - [DebuggerNonUserCode] - [Column(Storage = "_shipPostalCode", Name = "ShipPostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_shipPostalCode", Name="ShipPostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipPostalCode { get { - return _shipPostalCode; + return this._shipPostalCode; } set { - if (value != _shipPostalCode) + if (((_shipPostalCode == value) + == false)) { - OnShipPostalCodeChanging(value); - SendPropertyChanging(); - _shipPostalCode = value; - SendPropertyChanged("ShipPostalCode"); - OnShipPostalCodeChanged(); + this.OnShipPostalCodeChanging(value); + this.SendPropertyChanging(); + this._shipPostalCode = value; + this.SendPropertyChanged("ShipPostalCode"); + this.OnShipPostalCodeChanged(); } } } - - #endregion - - #region string ShipRegion - - private string _shipRegion; - [DebuggerNonUserCode] - [Column(Storage = "_shipRegion", Name = "ShipRegion", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_shipRegion", Name="ShipRegion", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ShipRegion { get { - return _shipRegion; + return this._shipRegion; } set { - if (value != _shipRegion) + if (((_shipRegion == value) + == false)) { - OnShipRegionChanging(value); - SendPropertyChanging(); - _shipRegion = value; - SendPropertyChanged("ShipRegion"); - OnShipRegionChanged(); + this.OnShipRegionChanging(value); + this.SendPropertyChanging(); + this._shipRegion = value; + this.SendPropertyChanged("ShipRegion"); + this.OnShipRegionChanged(); } } } - - #endregion - - #region long? ShipVia - - private long? _shipVia; - [DebuggerNonUserCode] - [Column(Storage = "_shipVia", Name = "ShipVia", DbType = "integer", AutoSync = AutoSync.Never, CanBeNull = true)] - public long? ShipVia + + [Column(Storage="_shipVia", Name="ShipVia", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShipVia { get { - return _shipVia; + return this._shipVia; } set { - if (value != _shipVia) + if ((_shipVia != value)) { if (_shipper.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnShipViaChanging(value); - SendPropertyChanging(); - _shipVia = value; - SendPropertyChanged("ShipVia"); - OnShipViaChanged(); + this.OnShipViaChanging(value); + this.SendPropertyChanging(); + this._shipVia = value; + this.SendPropertyChanged("ShipVia"); + this.OnShipViaChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"FK_Order Details_1\"")] - [DebuggerNonUserCode] + [Association(Storage="_orderDetails", OtherKey="OrderID", ThisKey="OrderID", Name="FK_Order Details_1")] + [DebuggerNonUserCode()] public EntitySet OrderDetails { get { - return _orderDetails; + return this._orderDetails; } set { - _orderDetails = value; + this._orderDetails = value; } } - - #endregion - + #region Parents - - private EntityRef _shipper; - [Association(Storage = "_shipper", OtherKey = "ShipperID", ThisKey = "ShipVia", Name = "FK_Orders_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_shipper", OtherKey="ShipperID", ThisKey="ShipVia", Name="FK_Orders_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Shipper Shipper { get { - return _shipper.Entity; + return this._shipper.Entity; } set { - if (value != _shipper.Entity) + if (((this._shipper.Entity == value) + == false)) { - if (_shipper.Entity != null) + if ((this._shipper.Entity != null)) { - var previousShipper = _shipper.Entity; - _shipper.Entity = null; + Shipper previousShipper = this._shipper.Entity; + this._shipper.Entity = null; previousShipper.Orders.Remove(this); } - _shipper.Entity = value; - if (value != null) + this._shipper.Entity = value; + if ((value != null)) { value.Orders.Add(this); _shipVia = value.ShipperID; @@ -2379,28 +2577,28 @@ namespace nwind } } } - - private EntityRef _employee; - [Association(Storage = "_employee", OtherKey = "EmployeeID", ThisKey = "EmployeeID", Name = "FK_Orders_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="FK_Orders_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Employee Employee { get { - return _employee.Entity; + return this._employee.Entity; } set { - if (value != _employee.Entity) + if (((this._employee.Entity == value) + == false)) { - if (_employee.Entity != null) + if ((this._employee.Entity != null)) { - var previousEmployee = _employee.Entity; - _employee.Entity = null; + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; previousEmployee.Orders.Remove(this); } - _employee.Entity = value; - if (value != null) + this._employee.Entity = value; + if ((value != null)) { value.Orders.Add(this); _employeeID = value.EmployeeID; @@ -2412,28 +2610,28 @@ namespace nwind } } } - - private EntityRef _customer; - [Association(Storage = "_customer", OtherKey = "CustomerID", ThisKey = "CustomerID", Name = "FK_Orders_2", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="FK_Orders_2", IsForeignKey=true)] + [DebuggerNonUserCode()] public Customer Customer { get { - return _customer.Entity; + return this._customer.Entity; } set { - if (value != _customer.Entity) + if (((this._customer.Entity == value) + == false)) { - if (_customer.Entity != null) + if ((this._customer.Entity != null)) { - var previousCustomer = _customer.Entity; - _customer.Entity = null; + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; previousCustomer.Orders.Remove(this); } - _customer.Entity = value; - if (value != null) + this._customer.Entity = value; + if ((value != null)) { value.Orders.Add(this); _customerID = value.CustomerID; @@ -2445,249 +2643,262 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Order = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void OrderDetails_Detach(OrderDetail entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Order = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Order() + + public override int GetHashCode() { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _shipper = new EntityRef(); - _employee = new EntityRef(); - _customer = new EntityRef(); - OnCreated(); + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "\"Order Details\"")] - public partial class OrderDetail : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Order other = ((Order)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Order value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Order Details")] + public partial class OrderDetail : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private float _discount; + + private long _orderID; + + private long _productID; + + private short _quantity; + + private decimal _unitPrice; + + private EntityRef _product = new EntityRef(); + + private EntityRef _order = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnDiscountChanged(); + partial void OnDiscountChanging(float value); + partial void OnOrderIDChanged(); + partial void OnOrderIDChanging(long value); + partial void OnProductIDChanged(); + partial void OnProductIDChanging(long value); + partial void OnQuantityChanged(); + partial void OnQuantityChanging(short value); + partial void OnUnitPriceChanged(); + partial void OnUnitPriceChanging(decimal value); - #endregion - - #region float Discount - - private float _discount; - [DebuggerNonUserCode] - [Column(Storage = "_discount", Name = "Discount", DbType = "real", AutoSync = AutoSync.Never)] + + + public OrderDetail() + { + this.OnCreated(); + } + + [Column(Storage="_discount", Name="Discount", DbType="real", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public float Discount { get { - return _discount; + return this._discount; } set { - if (value != _discount) + if ((_discount != value)) { - OnDiscountChanging(value); - SendPropertyChanging(); - _discount = value; - SendPropertyChanged("Discount"); - OnDiscountChanged(); + this.OnDiscountChanging(value); + this.SendPropertyChanging(); + this._discount = value; + this.SendPropertyChanged("Discount"); + this.OnDiscountChanged(); } } } - - #endregion - - #region long OrderID - - private long _orderID; - [DebuggerNonUserCode] - [Column(Storage = "_orderID", Name = "OrderID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_orderID", Name="OrderID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long OrderID { get { - return _orderID; + return this._orderID; } set { - if (value != _orderID) + if ((_orderID != value)) { if (_order.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnOrderIDChanging(value); - SendPropertyChanging(); - _orderID = value; - SendPropertyChanged("OrderID"); - OnOrderIDChanged(); + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); } } } - - #endregion - - #region long ProductID - - private long _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_productID", Name="ProductID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long ProductID { get { - return _productID; + return this._productID; } set { - if (value != _productID) + if ((_productID != value)) { if (_product.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); } } } - - #endregion - - #region short Quantity - - private short _quantity; - [DebuggerNonUserCode] - [Column(Storage = "_quantity", Name = "Quantity", DbType = "smallint", AutoSync = AutoSync.Never)] + + [Column(Storage="_quantity", Name="Quantity", DbType="smallint", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public short Quantity { get { - return _quantity; + return this._quantity; } set { - if (value != _quantity) + if ((_quantity != value)) { - OnQuantityChanging(value); - SendPropertyChanging(); - _quantity = value; - SendPropertyChanged("Quantity"); - OnQuantityChanged(); + this.OnQuantityChanging(value); + this.SendPropertyChanging(); + this._quantity = value; + this.SendPropertyChanged("Quantity"); + this.OnQuantityChanged(); } } } - - #endregion - - #region decimal UnitPrice - - private decimal _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never)] + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public decimal UnitPrice { get { - return _unitPrice; + return this._unitPrice; } set { - if (value != _unitPrice) + if ((_unitPrice != value)) { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); } } } - - #endregion - + #region Parents - - private EntityRef _product; - [Association(Storage = "_product", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"FK_Order Details_0\"", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_product", OtherKey="ProductID", ThisKey="ProductID", Name="FK_Order Details_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Product Product { get { - return _product.Entity; + return this._product.Entity; } set { - if (value != _product.Entity) + if (((this._product.Entity == value) + == false)) { - if (_product.Entity != null) + if ((this._product.Entity != null)) { - var previousProduct = _product.Entity; - _product.Entity = null; + Product previousProduct = this._product.Entity; + this._product.Entity = null; previousProduct.OrderDetails.Remove(this); } - _product.Entity = value; - if (value != null) + this._product.Entity = value; + if ((value != null)) { value.OrderDetails.Add(this); _productID = value.ProductID; @@ -2699,28 +2910,28 @@ namespace nwind } } } - - private EntityRef _order; - [Association(Storage = "_order", OtherKey = "OrderID", ThisKey = "OrderID", Name = "\"FK_Order Details_1\"", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_order", OtherKey="OrderID", ThisKey="OrderID", Name="FK_Order Details_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Order Order { get { - return _order.Entity; + return this._order.Entity; } set { - if (value != _order.Entity) + if (((this._order.Entity == value) + == false)) { - if (_order.Entity != null) + if ((this._order.Entity != null)) { - var previousOrder = _order.Entity; - _order.Entity = null; + Order previousOrder = this._order.Entity; + this._order.Entity = null; previousOrder.OrderDetails.Remove(this); } - _order.Entity = value; - if (value != null) + this._order.Entity = value; + if ((value != null)) { value.OrderDetails.Add(this); _orderID = value.OrderID; @@ -2732,392 +2943,406 @@ namespace nwind } } } - - #endregion - - #region ctor - - public OrderDetail() + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - _product = new EntityRef(); - _order = new EntityRef(); - OnCreated(); + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - #endregion - - } - - [Table(Name = "Products")] - public partial class Product : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + protected virtual void SendPropertyChanged(string propertyName) { - if (PropertyChanging != null) + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + hc = (hc + | (_productID.GetHashCode() * 65536)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + OrderDetail other = ((OrderDetail)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(OrderDetail value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID)); } - - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Products")] + public partial class Product : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private System.Nullable _categoryID; + + private bool _discontinued; + + private long _productID; + + private string _productName; + + private string _quantityPerUnit; + + private System.Nullable _reorderLevel; + + private System.Nullable _supplierID; + + private System.Nullable _unitPrice; + + private System.Nullable _unitsInStock; + + private System.Nullable _unitsOnOrder; + + private EntitySet _orderDetails; + + private EntityRef _supplier = new EntityRef(); + + private EntityRef _category = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCategoryIDChanged(); - partial void OnCategoryIDChanging(long? value); + + partial void OnCategoryIDChanging(System.Nullable value); + partial void OnDiscontinuedChanged(); + partial void OnDiscontinuedChanging(bool value); + partial void OnProductIDChanged(); + partial void OnProductIDChanging(long value); + partial void OnProductNameChanged(); + partial void OnProductNameChanging(string value); + partial void OnQuantityPerUnitChanged(); + partial void OnQuantityPerUnitChanging(string value); + partial void OnReorderLevelChanged(); - partial void OnReorderLevelChanging(short? value); + + partial void OnReorderLevelChanging(System.Nullable value); + partial void OnSupplierIDChanged(); - partial void OnSupplierIDChanging(long? value); + + partial void OnSupplierIDChanging(System.Nullable value); + partial void OnUnitPriceChanged(); - partial void OnUnitPriceChanging(decimal? value); + + partial void OnUnitPriceChanging(System.Nullable value); + partial void OnUnitsInStockChanged(); - partial void OnUnitsInStockChanging(short? value); + + partial void OnUnitsInStockChanging(System.Nullable value); + partial void OnUnitsOnOrderChanged(); - partial void OnUnitsOnOrderChanging(short? value); - + + partial void OnUnitsOnOrderChanging(System.Nullable value); #endregion - - #region long? CategoryID - - private long? _categoryID; - [DebuggerNonUserCode] - [Column(Storage = "_categoryID", Name = "CategoryID", DbType = "integer", AutoSync = AutoSync.Never, CanBeNull = true)] - public long? CategoryID + + + public Product() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable CategoryID { get { - return _categoryID; + return this._categoryID; } set { - if (value != _categoryID) + if ((_categoryID != value)) { if (_category.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnCategoryIDChanging(value); - SendPropertyChanging(); - _categoryID = value; - SendPropertyChanged("CategoryID"); - OnCategoryIDChanged(); + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); } } } - - #endregion - - #region bool Discontinued - - private bool _discontinued; - [DebuggerNonUserCode] - [Column(Storage = "_discontinued", Name = "Discontinued", DbType = "bit", AutoSync = AutoSync.Never)] + + [Column(Storage="_discontinued", Name="Discontinued", DbType="bit", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public bool Discontinued { get { - return _discontinued; + return this._discontinued; } set { - if (value != _discontinued) + if ((_discontinued != value)) { - OnDiscontinuedChanging(value); - SendPropertyChanging(); - _discontinued = value; - SendPropertyChanged("Discontinued"); - OnDiscontinuedChanged(); + this.OnDiscontinuedChanging(value); + this.SendPropertyChanging(); + this._discontinued = value; + this.SendPropertyChanged("Discontinued"); + this.OnDiscontinuedChanged(); } } } - - #endregion - - #region long ProductID - - private long _productID; - [DebuggerNonUserCode] - [Column(Storage = "_productID", Name = "ProductID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_productID", Name="ProductID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long ProductID { get { - return _productID; + return this._productID; } set { - if (value != _productID) + if ((_productID != value)) { - OnProductIDChanging(value); - SendPropertyChanging(); - _productID = value; - SendPropertyChanged("ProductID"); - OnProductIDChanged(); + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); } } } - - #endregion - - #region string ProductName - - private string _productName; - [DebuggerNonUserCode] - [Column(Storage = "_productName", Name = "ProductName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_productName", Name="ProductName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string ProductName { get { - return _productName; + return this._productName; } set { - if (value != _productName) + if (((_productName == value) + == false)) { - OnProductNameChanging(value); - SendPropertyChanging(); - _productName = value; - SendPropertyChanged("ProductName"); - OnProductNameChanged(); + this.OnProductNameChanging(value); + this.SendPropertyChanging(); + this._productName = value; + this.SendPropertyChanged("ProductName"); + this.OnProductNameChanged(); } } } - - #endregion - - #region string QuantityPerUnit - - private string _quantityPerUnit; - [DebuggerNonUserCode] - [Column(Storage = "_quantityPerUnit", Name = "QuantityPerUnit", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_quantityPerUnit", Name="QuantityPerUnit", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string QuantityPerUnit { get { - return _quantityPerUnit; + return this._quantityPerUnit; } set { - if (value != _quantityPerUnit) + if (((_quantityPerUnit == value) + == false)) { - OnQuantityPerUnitChanging(value); - SendPropertyChanging(); - _quantityPerUnit = value; - SendPropertyChanged("QuantityPerUnit"); - OnQuantityPerUnitChanged(); + this.OnQuantityPerUnitChanging(value); + this.SendPropertyChanging(); + this._quantityPerUnit = value; + this.SendPropertyChanged("QuantityPerUnit"); + this.OnQuantityPerUnitChanged(); } } } - - #endregion - - #region short? ReorderLevel - - private short? _reorderLevel; - [DebuggerNonUserCode] - [Column(Storage = "_reorderLevel", Name = "ReorderLevel", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = true)] - public short? ReorderLevel + + [Column(Storage="_reorderLevel", Name="ReorderLevel", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReorderLevel { get { - return _reorderLevel; + return this._reorderLevel; } set { - if (value != _reorderLevel) + if ((_reorderLevel != value)) { - OnReorderLevelChanging(value); - SendPropertyChanging(); - _reorderLevel = value; - SendPropertyChanged("ReorderLevel"); - OnReorderLevelChanged(); + this.OnReorderLevelChanging(value); + this.SendPropertyChanging(); + this._reorderLevel = value; + this.SendPropertyChanged("ReorderLevel"); + this.OnReorderLevelChanged(); } } } - - #endregion - - #region long? SupplierID - - private long? _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "integer", AutoSync = AutoSync.Never, CanBeNull = true)] - public long? SupplierID + + [Column(Storage="_supplierID", Name="SupplierID", DbType="integer", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable SupplierID { get { - return _supplierID; + return this._supplierID; } set { - if (value != _supplierID) + if ((_supplierID != value)) { if (_supplier.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); } } } - - #endregion - - #region decimal? UnitPrice - - private decimal? _unitPrice; - [DebuggerNonUserCode] - [Column(Storage = "_unitPrice", Name = "UnitPrice", DbType = "money", AutoSync = AutoSync.Never, CanBeNull = true)] - public decimal? UnitPrice + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitPrice { get { - return _unitPrice; + return this._unitPrice; } set { - if (value != _unitPrice) + if ((_unitPrice != value)) { - OnUnitPriceChanging(value); - SendPropertyChanging(); - _unitPrice = value; - SendPropertyChanged("UnitPrice"); - OnUnitPriceChanged(); + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); } } } - - #endregion - - #region short? UnitsInStock - - private short? _unitsInStock; - [DebuggerNonUserCode] - [Column(Storage = "_unitsInStock", Name = "UnitsInStock", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = true)] - public short? UnitsInStock + + [Column(Storage="_unitsInStock", Name="UnitsInStock", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsInStock { get { - return _unitsInStock; + return this._unitsInStock; } set { - if (value != _unitsInStock) + if ((_unitsInStock != value)) { - OnUnitsInStockChanging(value); - SendPropertyChanging(); - _unitsInStock = value; - SendPropertyChanged("UnitsInStock"); - OnUnitsInStockChanged(); + this.OnUnitsInStockChanging(value); + this.SendPropertyChanging(); + this._unitsInStock = value; + this.SendPropertyChanged("UnitsInStock"); + this.OnUnitsInStockChanged(); } } } - - #endregion - - #region short? UnitsOnOrder - - private short? _unitsOnOrder; - [DebuggerNonUserCode] - [Column(Storage = "_unitsOnOrder", Name = "UnitsOnOrder", DbType = "smallint", AutoSync = AutoSync.Never, CanBeNull = true)] - public short? UnitsOnOrder + + [Column(Storage="_unitsOnOrder", Name="UnitsOnOrder", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsOnOrder { get { - return _unitsOnOrder; + return this._unitsOnOrder; } set { - if (value != _unitsOnOrder) + if ((_unitsOnOrder != value)) { - OnUnitsOnOrderChanging(value); - SendPropertyChanging(); - _unitsOnOrder = value; - SendPropertyChanged("UnitsOnOrder"); - OnUnitsOnOrderChanged(); + this.OnUnitsOnOrderChanging(value); + this.SendPropertyChanging(); + this._unitsOnOrder = value; + this.SendPropertyChanged("UnitsOnOrder"); + this.OnUnitsOnOrderChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orderDetails; - [Association(Storage = "_orderDetails", OtherKey = "ProductID", ThisKey = "ProductID", Name = "\"FK_Order Details_0\"")] - [DebuggerNonUserCode] + [Association(Storage="_orderDetails", OtherKey="ProductID", ThisKey="ProductID", Name="FK_Order Details_0")] + [DebuggerNonUserCode()] public EntitySet OrderDetails { get { - return _orderDetails; + return this._orderDetails; } set { - _orderDetails = value; + this._orderDetails = value; } } - - #endregion - + #region Parents - - private EntityRef _supplier; - [Association(Storage = "_supplier", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "FK_Products_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_supplier", OtherKey="SupplierID", ThisKey="SupplierID", Name="FK_Products_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Supplier Supplier { get { - return _supplier.Entity; + return this._supplier.Entity; } set { - if (value != _supplier.Entity) + if (((this._supplier.Entity == value) + == false)) { - if (_supplier.Entity != null) + if ((this._supplier.Entity != null)) { - var previousSupplier = _supplier.Entity; - _supplier.Entity = null; + Supplier previousSupplier = this._supplier.Entity; + this._supplier.Entity = null; previousSupplier.Products.Remove(this); } - _supplier.Entity = value; - if (value != null) + this._supplier.Entity = value; + if ((value != null)) { value.Products.Add(this); _supplierID = value.SupplierID; @@ -3129,28 +3354,28 @@ namespace nwind } } } - - private EntityRef _category; - [Association(Storage = "_category", OtherKey = "CategoryID", ThisKey = "CategoryID", Name = "FK_Products_1", IsForeignKey = true)] - [DebuggerNonUserCode] + + [Association(Storage="_category", OtherKey="CategoryID", ThisKey="CategoryID", Name="FK_Products_1", IsForeignKey=true)] + [DebuggerNonUserCode()] public Category Category { get { - return _category.Entity; + return this._category.Entity; } set { - if (value != _category.Entity) + if (((this._category.Entity == value) + == false)) { - if (_category.Entity != null) + if ((this._category.Entity != null)) { - var previousCategory = _category.Entity; - _category.Entity = null; + Category previousCategory = this._category.Entity; + this._category.Entity = null; previousCategory.Products.Remove(this); } - _category.Entity = value; - if (value != null) + this._category.Entity = value; + if ((value != null)) { value.Products.Add(this); _categoryID = value.CategoryID; @@ -3162,939 +3387,1008 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - - private void OrderDetails_Attach(OrderDetail entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Product = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void OrderDetails_Detach(OrderDetail entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Product = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Product() + + public override int GetHashCode() { - _orderDetails = new EntitySet(OrderDetails_Attach, OrderDetails_Detach); - _supplier = new EntityRef(); - _category = new EntityRef(); - OnCreated(); + int hc = 0; + hc = (hc + | (_productID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Region")] - public partial class Region : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Product other = ((Product)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Product value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Region")] + public partial class Region : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _regionDescription; + + private long _regionID; + + private EntitySet _territories; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnRegionDescriptionChanged(); + partial void OnRegionDescriptionChanging(string value); + partial void OnRegionIDChanged(); + partial void OnRegionIDChanging(long value); - #endregion - - #region string RegionDescription - - private string _regionDescription; - [DebuggerNonUserCode] - [Column(Storage = "_regionDescription", Name = "RegionDescription", DbType = "nchar", AutoSync = AutoSync.Never)] + + + public Region() + { + _territories = new EntitySet(new Action(this.Territories_Attach), new Action(this.Territories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionDescription", Name="RegionDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string RegionDescription { get { - return _regionDescription; + return this._regionDescription; } set { - if (value != _regionDescription) + if (((_regionDescription == value) + == false)) { - OnRegionDescriptionChanging(value); - SendPropertyChanging(); - _regionDescription = value; - SendPropertyChanged("RegionDescription"); - OnRegionDescriptionChanged(); + this.OnRegionDescriptionChanging(value); + this.SendPropertyChanging(); + this._regionDescription = value; + this.SendPropertyChanged("RegionDescription"); + this.OnRegionDescriptionChanged(); } } } - - #endregion - - #region long RegionID - - private long _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_regionID", Name="RegionID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long RegionID { get { - return _regionID; + return this._regionID; } set { - if (value != _regionID) + if ((_regionID != value)) { - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _territories; - [Association(Storage = "_territories", OtherKey = "RegionID", ThisKey = "RegionID", Name = "FK_Territories_0")] - [DebuggerNonUserCode] + [Association(Storage="_territories", OtherKey="RegionID", ThisKey="RegionID", Name="FK_Territories_0")] + [DebuggerNonUserCode()] public EntitySet Territories { get { - return _territories; + return this._territories; } set { - _territories = value; + this._territories = value; } } - - #endregion - - #region Attachement handlers - - private void Territories_Attach(Territory entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Region = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Territories_Detach(Territory entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Region = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Region() + + public override int GetHashCode() { - _territories = new EntitySet(Territories_Attach, Territories_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_regionID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Shippers")] - public partial class Shipper : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Region other = ((Region)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Region value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._regionID, value._regionID); + } + + #region Attachment handlers + private void Territories_Attach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = this; + } + + private void Territories_Detach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Shippers")] + public partial class Shipper : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _companyName; + + private string _phone; + + private long _shipperID; + + private EntitySet _orders; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnShipperIDChanged(); + partial void OnShipperIDChanging(long value); - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + + public Shipper() + { + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region long ShipperID - - private long _shipperID; - [DebuggerNonUserCode] - [Column(Storage = "_shipperID", Name = "ShipperID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_shipperID", Name="ShipperID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long ShipperID { get { - return _shipperID; + return this._shipperID; } set { - if (value != _shipperID) + if ((_shipperID != value)) { - OnShipperIDChanging(value); - SendPropertyChanging(); - _shipperID = value; - SendPropertyChanged("ShipperID"); - OnShipperIDChanged(); + this.OnShipperIDChanging(value); + this.SendPropertyChanging(); + this._shipperID = value; + this.SendPropertyChanged("ShipperID"); + this.OnShipperIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _orders; - [Association(Storage = "_orders", OtherKey = "ShipVia", ThisKey = "ShipperID", Name = "FK_Orders_0")] - [DebuggerNonUserCode] + [Association(Storage="_orders", OtherKey="ShipVia", ThisKey="ShipperID", Name="FK_Orders_0")] + [DebuggerNonUserCode()] public EntitySet Orders { get { - return _orders; + return this._orders; } set { - _orders = value; + this._orders = value; } } - - #endregion - - #region Attachement handlers - - private void Orders_Attach(Order entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Shipper = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Orders_Detach(Order entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Shipper = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Shipper() + + public override int GetHashCode() { - _orders = new EntitySet(Orders_Attach, Orders_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_shipperID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Suppliers")] - public partial class Supplier : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + Shipper other = ((Shipper)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Shipper value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._shipperID, value._shipperID); + } + + #region Attachment handlers + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Suppliers")] + public partial class Supplier : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _fax; + + private string _homePage; + + private string _phone; + + private string _postalCode; + + private string _region; + + private long _supplierID; + + private EntitySet _products; + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnAddressChanged(); + partial void OnAddressChanging(string value); + partial void OnCityChanged(); + partial void OnCityChanging(string value); + partial void OnCompanyNameChanged(); + partial void OnCompanyNameChanging(string value); + partial void OnContactNameChanged(); + partial void OnContactNameChanging(string value); + partial void OnContactTitleChanged(); + partial void OnContactTitleChanging(string value); + partial void OnCountryChanged(); + partial void OnCountryChanging(string value); + partial void OnFaxChanged(); + partial void OnFaxChanging(string value); + partial void OnHomePageChanged(); + partial void OnHomePageChanging(string value); + partial void OnPhoneChanged(); + partial void OnPhoneChanging(string value); + partial void OnPostalCodeChanged(); + partial void OnPostalCodeChanging(string value); + partial void OnRegionChanged(); + partial void OnRegionChanging(string value); + partial void OnSupplierIDChanged(); + partial void OnSupplierIDChanging(long value); - #endregion - - #region string Address - - private string _address; - [DebuggerNonUserCode] - [Column(Storage = "_address", Name = "Address", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + + public Supplier() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Address { get { - return _address; + return this._address; } set { - if (value != _address) + if (((_address == value) + == false)) { - OnAddressChanging(value); - SendPropertyChanging(); - _address = value; - SendPropertyChanged("Address"); - OnAddressChanged(); + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); } } } - - #endregion - - #region string City - - private string _city; - [DebuggerNonUserCode] - [Column(Storage = "_city", Name = "City", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_city", Name="City", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string City { get { - return _city; + return this._city; } set { - if (value != _city) + if (((_city == value) + == false)) { - OnCityChanging(value); - SendPropertyChanging(); - _city = value; - SendPropertyChanged("City"); - OnCityChanged(); + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); } } } - - #endregion - - #region string CompanyName - - private string _companyName; - [DebuggerNonUserCode] - [Column(Storage = "_companyName", Name = "CompanyName", DbType = "nvarchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string CompanyName { get { - return _companyName; + return this._companyName; } set { - if (value != _companyName) + if (((_companyName == value) + == false)) { - OnCompanyNameChanging(value); - SendPropertyChanging(); - _companyName = value; - SendPropertyChanged("CompanyName"); - OnCompanyNameChanged(); + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); } } } - - #endregion - - #region string ContactName - - private string _contactName; - [DebuggerNonUserCode] - [Column(Storage = "_contactName", Name = "ContactName", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactName { get { - return _contactName; + return this._contactName; } set { - if (value != _contactName) + if (((_contactName == value) + == false)) { - OnContactNameChanging(value); - SendPropertyChanging(); - _contactName = value; - SendPropertyChanged("ContactName"); - OnContactNameChanged(); + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); } } } - - #endregion - - #region string ContactTitle - - private string _contactTitle; - [DebuggerNonUserCode] - [Column(Storage = "_contactTitle", Name = "ContactTitle", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string ContactTitle { get { - return _contactTitle; + return this._contactTitle; } set { - if (value != _contactTitle) + if (((_contactTitle == value) + == false)) { - OnContactTitleChanging(value); - SendPropertyChanging(); - _contactTitle = value; - SendPropertyChanged("ContactTitle"); - OnContactTitleChanged(); + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); } } } - - #endregion - - #region string Country - - private string _country; - [DebuggerNonUserCode] - [Column(Storage = "_country", Name = "Country", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_country", Name="Country", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Country { get { - return _country; + return this._country; } set { - if (value != _country) + if (((_country == value) + == false)) { - OnCountryChanging(value); - SendPropertyChanging(); - _country = value; - SendPropertyChanged("Country"); - OnCountryChanged(); + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); } } } - - #endregion - - #region string Fax - - private string _fax; - [DebuggerNonUserCode] - [Column(Storage = "_fax", Name = "Fax", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Fax { get { - return _fax; + return this._fax; } set { - if (value != _fax) + if (((_fax == value) + == false)) { - OnFaxChanging(value); - SendPropertyChanging(); - _fax = value; - SendPropertyChanged("Fax"); - OnFaxChanged(); + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); } } } - - #endregion - - #region string HomePage - - private string _homePage; - [DebuggerNonUserCode] - [Column(Storage = "_homePage", Name = "HomePage", DbType = "ntext", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_homePage", Name="HomePage", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string HomePage { get { - return _homePage; + return this._homePage; } set { - if (value != _homePage) + if (((_homePage == value) + == false)) { - OnHomePageChanging(value); - SendPropertyChanging(); - _homePage = value; - SendPropertyChanged("HomePage"); - OnHomePageChanged(); + this.OnHomePageChanging(value); + this.SendPropertyChanging(); + this._homePage = value; + this.SendPropertyChanged("HomePage"); + this.OnHomePageChanged(); } } } - - #endregion - - #region string Phone - - private string _phone; - [DebuggerNonUserCode] - [Column(Storage = "_phone", Name = "Phone", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Phone { get { - return _phone; + return this._phone; } set { - if (value != _phone) + if (((_phone == value) + == false)) { - OnPhoneChanging(value); - SendPropertyChanging(); - _phone = value; - SendPropertyChanged("Phone"); - OnPhoneChanged(); + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); } } } - - #endregion - - #region string PostalCode - - private string _postalCode; - [DebuggerNonUserCode] - [Column(Storage = "_postalCode", Name = "PostalCode", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string PostalCode { get { - return _postalCode; + return this._postalCode; } set { - if (value != _postalCode) + if (((_postalCode == value) + == false)) { - OnPostalCodeChanging(value); - SendPropertyChanging(); - _postalCode = value; - SendPropertyChanged("PostalCode"); - OnPostalCodeChanged(); + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); } } } - - #endregion - - #region string Region - - private string _region; - [DebuggerNonUserCode] - [Column(Storage = "_region", Name = "Region", DbType = "nvarchar", AutoSync = AutoSync.Never, CanBeNull = true)] + + [Column(Storage="_region", Name="Region", DbType="nvarchar", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] public string Region { get { - return _region; + return this._region; } set { - if (value != _region) + if (((_region == value) + == false)) { - OnRegionChanging(value); - SendPropertyChanging(); - _region = value; - SendPropertyChanged("Region"); - OnRegionChanged(); + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); } } } - - #endregion - - #region long SupplierID - - private long _supplierID; - [DebuggerNonUserCode] - [Column(Storage = "_supplierID", Name = "SupplierID", DbType = "integer", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_supplierID", Name="SupplierID", DbType="integer", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long SupplierID { get { - return _supplierID; + return this._supplierID; } set { - if (value != _supplierID) + if ((_supplierID != value)) { - OnSupplierIDChanging(value); - SendPropertyChanging(); - _supplierID = value; - SendPropertyChanged("SupplierID"); - OnSupplierIDChanged(); + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _products; - [Association(Storage = "_products", OtherKey = "SupplierID", ThisKey = "SupplierID", Name = "FK_Products_0")] - [DebuggerNonUserCode] + [Association(Storage="_products", OtherKey="SupplierID", ThisKey="SupplierID", Name="FK_Products_0")] + [DebuggerNonUserCode()] public EntitySet Products { get { - return _products; + return this._products; } set { - _products = value; + this._products = value; } } - - #endregion - - #region Attachement handlers - - private void Products_Attach(Product entity) + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() { - entity.Supplier = this; + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } } - - private void Products_Detach(Product entity) + + protected virtual void SendPropertyChanged(string propertyName) { - entity.Supplier = null; + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } } - - - #endregion - - #region ctor - - public Supplier() + + public override int GetHashCode() { - _products = new EntitySet(Products_Attach, Products_Detach); - OnCreated(); + int hc = 0; + hc = (hc + | (_supplierID.GetHashCode() * 1)); + return hc; } - - #endregion - - } - - [Table(Name = "Territories")] - public partial class Territory : INotifyPropertyChanging, INotifyPropertyChanged - { - #region INotifyPropertyChanging handling - - public event PropertyChangingEventHandler PropertyChanging; - - private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(""); - protected virtual void SendPropertyChanging() + + public override bool Equals(object value) { - if (PropertyChanging != null) + if ((value == null)) { - PropertyChanging(this, emptyChangingEventArgs); + return false; } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Supplier other = ((Supplier)(value)); + return this.Equals(other); } - - #endregion - - #region INotifyPropertyChanged handling - - public event PropertyChangedEventHandler PropertyChanged; - - protected virtual void SendPropertyChanged(string propertyName) + + public virtual bool Equals(Supplier value) { - if (PropertyChanged != null) + if ((value == null)) { - PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + return false; } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._supplierID, value._supplierID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = null; } - #endregion - - #region Extensibility Method Definitions - + } + + [Table(Name="Territories")] + public partial class Territory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private long _regionID; + + private string _territoryDescription; + + private string _territoryID; + + private EntitySet _employeeTerritories; + + private EntityRef _region = new EntityRef(); + + #region Extensibility Method Declarations partial void OnCreated(); + partial void OnRegionIDChanged(); + partial void OnRegionIDChanging(long value); + partial void OnTerritoryDescriptionChanged(); + partial void OnTerritoryDescriptionChanging(string value); + partial void OnTerritoryIDChanged(); + partial void OnTerritoryIDChanging(string value); - #endregion - - #region long RegionID - - private long _regionID; - [DebuggerNonUserCode] - [Column(Storage = "_regionID", Name = "RegionID", DbType = "integer", AutoSync = AutoSync.Never)] + + + public Territory() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionID", Name="RegionID", DbType="integer", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public long RegionID { get { - return _regionID; + return this._regionID; } set { - if (value != _regionID) + if ((_regionID != value)) { if (_region.HasLoadedOrAssignedValue) { throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); } - OnRegionIDChanging(value); - SendPropertyChanging(); - _regionID = value; - SendPropertyChanged("RegionID"); - OnRegionIDChanged(); + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); } } } - - #endregion - - #region string TerritoryDescription - - private string _territoryDescription; - [DebuggerNonUserCode] - [Column(Storage = "_territoryDescription", Name = "TerritoryDescription", DbType = "nchar", AutoSync = AutoSync.Never)] + + [Column(Storage="_territoryDescription", Name="TerritoryDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryDescription { get { - return _territoryDescription; + return this._territoryDescription; } set { - if (value != _territoryDescription) + if (((_territoryDescription == value) + == false)) { - OnTerritoryDescriptionChanging(value); - SendPropertyChanging(); - _territoryDescription = value; - SendPropertyChanged("TerritoryDescription"); - OnTerritoryDescriptionChanged(); + this.OnTerritoryDescriptionChanging(value); + this.SendPropertyChanging(); + this._territoryDescription = value; + this.SendPropertyChanged("TerritoryDescription"); + this.OnTerritoryDescriptionChanged(); } } } - - #endregion - - #region string TerritoryID - - private string _territoryID; - [DebuggerNonUserCode] - [Column(Storage = "_territoryID", Name = "TerritoryID", DbType = "nvarchar", IsPrimaryKey = true, AutoSync = AutoSync.Never)] + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] public string TerritoryID { get { - return _territoryID; + return this._territoryID; } set { - if (value != _territoryID) + if (((_territoryID == value) + == false)) { - OnTerritoryIDChanging(value); - SendPropertyChanging(); - _territoryID = value; - SendPropertyChanged("TerritoryID"); - OnTerritoryIDChanged(); + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); } } } - - #endregion - + #region Children - - private EntitySet _employeeTerritories; - [Association(Storage = "_employeeTerritories", OtherKey = "TerritoryID", ThisKey = "TerritoryID", Name = "FK_EmployeeTerritories_0")] - [DebuggerNonUserCode] + [Association(Storage="_employeeTerritories", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="FK_EmployeeTerritories_0")] + [DebuggerNonUserCode()] public EntitySet EmployeeTerritories { get { - return _employeeTerritories; + return this._employeeTerritories; } set { - _employeeTerritories = value; + this._employeeTerritories = value; } } - - #endregion - + #region Parents - - private EntityRef _region; - [Association(Storage = "_region", OtherKey = "RegionID", ThisKey = "RegionID", Name = "FK_Territories_0", IsForeignKey = true)] - [DebuggerNonUserCode] + [Association(Storage="_region", OtherKey="RegionID", ThisKey="RegionID", Name="FK_Territories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] public Region Region { get { - return _region.Entity; + return this._region.Entity; } set { - if (value != _region.Entity) + if (((this._region.Entity == value) + == false)) { - if (_region.Entity != null) + if ((this._region.Entity != null)) { - var previousRegion = _region.Entity; - _region.Entity = null; + Region previousRegion = this._region.Entity; + this._region.Entity = null; previousRegion.Territories.Remove(this); } - _region.Entity = value; - if (value != null) + this._region.Entity = value; + if ((value != null)) { value.Territories.Add(this); _regionID = value.RegionID; @@ -4106,35 +4400,77 @@ namespace nwind } } } - - #endregion - - #region Attachement handlers - + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Territory other = ((Territory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Territory value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID); + } + + #region Attachment handlers private void EmployeeTerritories_Attach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Territory = this; } - + private void EmployeeTerritories_Detach(EmployeeTerritory entity) { + this.SendPropertyChanging(); entity.Territory = null; } - - - #endregion - - #region ctor - - public Territory() - { - _employeeTerritories = new EntitySet(EmployeeTerritories_Attach, EmployeeTerritories_Detach); - _region = new EntityRef(); - OnCreated(); - } - #endregion - } } diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-sqlmetal.dbml b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-sqlmetal.dbml new file mode 100755 index 00000000000..c8b443ab3ea --- /dev/null +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite+DbSchemaLoader-sqlmetal.dbml @@ -0,0 +1,169 @@ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
\ No newline at end of file diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-DbMetal.cs b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-DbMetal.cs new file mode 100755 index 00000000000..bdca1d93927 --- /dev/null +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-DbMetal.cs @@ -0,0 +1,4517 @@ +// +// ____ _ __ __ _ _ +// | _ \| |__ | \/ | ___| |_ __ _| | +// | | | | '_ \| |\/| |/ _ \ __/ _` | | +// | |_| | |_) | | | | __/ || (_| | | +// |____/|_.__/|_| |_|\___|\__\__,_|_| +// +// Auto-generated from Northwind on [TIMESTAMP]. +// Please visit http://code.google.com/p/dblinq2007/ for more information. +// +namespace nwind +{ + using System; + using System.ComponentModel; + using System.Data; +#if MONO_STRICT + using System.Data.Linq; +#else // MONO_STRICT + using DbLinq.Data.Linq; + using DbLinq.Vendor; +#endif // MONO_STRICT + using System.Data.Linq.Mapping; + using System.Diagnostics; + + + public partial class Northwind : DataContext + { + + #region Extensibility Method Declarations + partial void OnCreated(); + #endregion + + + public Northwind(string connectionString) : + base(connectionString) + { + this.OnCreated(); + } + + public Northwind(string connection, MappingSource mappingSource) : + base(connection, mappingSource) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, MappingSource mappingSource) : + base(connection, mappingSource) + { + this.OnCreated(); + } + + public Table Categories + { + get + { + return this.GetTable(); + } + } + + public Table Customers + { + get + { + return this.GetTable(); + } + } + + public Table CustomerCustomerDemo + { + get + { + return this.GetTable(); + } + } + + public Table CustomerDemographics + { + get + { + return this.GetTable(); + } + } + + public Table Employees + { + get + { + return this.GetTable(); + } + } + + public Table EmployeeTerritories + { + get + { + return this.GetTable(); + } + } + + public Table Orders + { + get + { + return this.GetTable(); + } + } + + public Table OrderDetails + { + get + { + return this.GetTable(); + } + } + + public Table Products + { + get + { + return this.GetTable(); + } + } + + public Table Regions + { + get + { + return this.GetTable(); + } + } + + public Table Shippers + { + get + { + return this.GetTable(); + } + } + + public Table Suppliers + { + get + { + return this.GetTable(); + } + } + + public Table Territories + { + get + { + return this.GetTable(); + } + } + } + + #region Start MONO_STRICT +#if MONO_STRICT + + public partial class Northwind + { + + public Northwind(IDbConnection connection) : + base(connection) + { + this.OnCreated(); + } + } + #region End MONO_STRICT + #endregion +#else // MONO_STRICT + + public partial class Northwind + { + + public Northwind(IDbConnection connection) : + base(connection, new DbLinq.Sqlite.SqliteVendor()) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, IVendor sqlDialect) : + base(connection, sqlDialect) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, MappingSource mappingSource, IVendor sqlDialect) : + base(connection, mappingSource, sqlDialect) + { + this.OnCreated(); + } + } + #region End Not MONO_STRICT + #endregion +#endif // MONO_STRICT + #endregion + + [Table(Name="main.Categories")] + public partial class Category : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _categoryID; + + private string _categoryName; + + private string _description; + + private byte[] _picture; + + private EntitySet _products; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCategoryIDChanged(); + + partial void OnCategoryIDChanging(int value); + + partial void OnCategoryNameChanged(); + + partial void OnCategoryNameChanging(string value); + + partial void OnDescriptionChanged(); + + partial void OnDescriptionChanging(string value); + + partial void OnPictureChanged(); + + partial void OnPictureChanging(byte[] value); + #endregion + + + public Category() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int CategoryID + { + get + { + return this._categoryID; + } + set + { + if ((_categoryID != value)) + { + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); + } + } + } + + [Column(Storage="_categoryName", Name="CategoryName", DbType="nvarchar (15)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CategoryName + { + get + { + return this._categoryName; + } + set + { + if (((_categoryName == value) + == false)) + { + this.OnCategoryNameChanging(value); + this.SendPropertyChanging(); + this._categoryName = value; + this.SendPropertyChanged("CategoryName"); + this.OnCategoryNameChanged(); + } + } + } + + [Column(Storage="_description", Name="Description", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Description + { + get + { + return this._description; + } + set + { + if (((_description == value) + == false)) + { + this.OnDescriptionChanging(value); + this.SendPropertyChanging(); + this._description = value; + this.SendPropertyChanged("Description"); + this.OnDescriptionChanged(); + } + } + } + + [Column(Storage="_picture", Name="Picture", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Picture + { + get + { + return this._picture; + } + set + { + if (((_picture == value) + == false)) + { + this.OnPictureChanging(value); + this.SendPropertyChanging(); + this._picture = value; + this.SendPropertyChanged("Picture"); + this.OnPictureChanged(); + } + } + } + + #region Children + [Association(Storage="_products", OtherKey="CategoryID", ThisKey="CategoryID", Name="fk_Products_1")] + [DebuggerNonUserCode()] + public EntitySet Products + { + get + { + return this._products; + } + set + { + this._products = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_categoryID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Category other = ((Category)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Category value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._categoryID, value._categoryID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = null; + } + #endregion + } + + [Table(Name="main.Customers")] + public partial class Customer : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _customerID; + + private string _fax; + + private string _phone; + + private string _postalCode; + + private string _region; + + private EntitySet _customerCustomerDemo; + + private EntitySet _orders; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnAddressChanged(); + + partial void OnAddressChanging(string value); + + partial void OnCityChanged(); + + partial void OnCityChanging(string value); + + partial void OnCompanyNameChanged(); + + partial void OnCompanyNameChanging(string value); + + partial void OnContactNameChanged(); + + partial void OnContactNameChanging(string value); + + partial void OnContactTitleChanged(); + + partial void OnContactTitleChanging(string value); + + partial void OnCountryChanged(); + + partial void OnCountryChanging(string value); + + partial void OnCustomerIDChanged(); + + partial void OnCustomerIDChanging(string value); + + partial void OnFaxChanged(); + + partial void OnFaxChanging(string value); + + partial void OnPhoneChanged(); + + partial void OnPhoneChanging(string value); + + partial void OnPostalCodeChanged(); + + partial void OnPostalCodeChanging(string value); + + partial void OnRegionChanged(); + + partial void OnRegionChanging(string value); + #endregion + + + public Customer() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Address + { + get + { + return this._address; + } + set + { + if (((_address == value) + == false)) + { + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); + } + } + } + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string City + { + get + { + return this._city; + } + set + { + if (((_city == value) + == false)) + { + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); + } + } + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CompanyName + { + get + { + return this._companyName; + } + set + { + if (((_companyName == value) + == false)) + { + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); + } + } + } + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactName + { + get + { + return this._contactName; + } + set + { + if (((_contactName == value) + == false)) + { + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); + } + } + } + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactTitle + { + get + { + return this._contactTitle; + } + set + { + if (((_contactTitle == value) + == false)) + { + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); + } + } + } + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Country + { + get + { + return this._country; + } + set + { + if (((_country == value) + == false)) + { + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); + } + } + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerID + { + get + { + return this._customerID; + } + set + { + if (((_customerID == value) + == false)) + { + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + } + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Fax + { + get + { + return this._fax; + } + set + { + if (((_fax == value) + == false)) + { + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); + } + } + } + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Phone + { + get + { + return this._phone; + } + set + { + if (((_phone == value) + == false)) + { + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); + } + } + } + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PostalCode + { + get + { + return this._postalCode; + } + set + { + if (((_postalCode == value) + == false)) + { + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); + } + } + } + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Region + { + get + { + return this._region; + } + set + { + if (((_region == value) + == false)) + { + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); + } + } + } + + #region Children + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_CustomerCustomerDemo_0")] + [DebuggerNonUserCode()] + public EntitySet CustomerCustomerDemo + { + get + { + return this._customerCustomerDemo; + } + set + { + this._customerCustomerDemo = value; + } + } + + [Association(Storage="_orders", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_Orders_2")] + [DebuggerNonUserCode()] + public EntitySet Orders + { + get + { + return this._orders; + } + set + { + this._orders = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Customer other = ((Customer)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Customer value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID); + } + + #region Attachment handlers + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.Customer = this; + } + + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.Customer = null; + } + + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Customer = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Customer = null; + } + #endregion + } + + [Table(Name="main.CustomerCustomerDemo")] + public partial class CustomerCustomerDemo : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private string _customerTypeID; + + private EntityRef _customer = new EntityRef(); + + private EntityRef _customerDemographic = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCustomerIDChanged(); + + partial void OnCustomerIDChanging(string value); + + partial void OnCustomerTypeIDChanged(); + + partial void OnCustomerTypeIDChanging(string value); + #endregion + + + public CustomerCustomerDemo() + { + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerID + { + get + { + return this._customerID; + } + set + { + if (((_customerID == value) + == false)) + { + if (_customer.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + } + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerTypeID + { + get + { + return this._customerTypeID; + } + set + { + if (((_customerTypeID == value) + == false)) + { + if (_customerDemographic.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); + } + } + } + + #region Parents + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_CustomerCustomerDemo_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Customer Customer + { + get + { + return this._customer.Entity; + } + set + { + if (((this._customer.Entity == value) + == false)) + { + if ((this._customer.Entity != null)) + { + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; + previousCustomer.CustomerCustomerDemo.Remove(this); + } + this._customer.Entity = value; + if ((value != null)) + { + value.CustomerCustomerDemo.Add(this); + _customerID = value.CustomerID; + } + else + { + _customerID = default(string); + } + } + } + } + + [Association(Storage="_customerDemographic", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="fk_CustomerCustomerDemo_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public CustomerDemographic CustomerDemographic + { + get + { + return this._customerDemographic.Entity; + } + set + { + if (((this._customerDemographic.Entity == value) + == false)) + { + if ((this._customerDemographic.Entity != null)) + { + CustomerDemographic previousCustomerDemographic = this._customerDemographic.Entity; + this._customerDemographic.Entity = null; + previousCustomerDemographic.CustomerCustomerDemo.Remove(this); + } + this._customerDemographic.Entity = value; + if ((value != null)) + { + value.CustomerCustomerDemo.Add(this); + _customerTypeID = value.CustomerTypeID; + } + else + { + _customerTypeID = default(string); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + CustomerCustomerDemo other = ((CustomerCustomerDemo)(value)); + return this.Equals(other); + } + + public virtual bool Equals(CustomerCustomerDemo value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID)); + } + } + + [Table(Name="main.CustomerDemographics")] + public partial class CustomerDemographic : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerDesc; + + private string _customerTypeID; + + private EntitySet _customerCustomerDemo; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCustomerDescChanged(); + + partial void OnCustomerDescChanging(string value); + + partial void OnCustomerTypeIDChanged(); + + partial void OnCustomerTypeIDChanging(string value); + #endregion + + + public CustomerDemographic() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerDesc", Name="CustomerDesc", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string CustomerDesc + { + get + { + return this._customerDesc; + } + set + { + if (((_customerDesc == value) + == false)) + { + this.OnCustomerDescChanging(value); + this.SendPropertyChanging(); + this._customerDesc = value; + this.SendPropertyChanged("CustomerDesc"); + this.OnCustomerDescChanged(); + } + } + } + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerTypeID + { + get + { + return this._customerTypeID; + } + set + { + if (((_customerTypeID == value) + == false)) + { + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); + } + } + } + + #region Children + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="fk_CustomerCustomerDemo_1")] + [DebuggerNonUserCode()] + public EntitySet CustomerCustomerDemo + { + get + { + return this._customerCustomerDemo; + } + set + { + this._customerCustomerDemo = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + CustomerDemographic other = ((CustomerDemographic)(value)); + return this.Equals(other); + } + + public virtual bool Equals(CustomerDemographic value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID); + } + + #region Attachment handlers + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = this; + } + + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = null; + } + #endregion + } + + [Table(Name="main.Employees")] + public partial class Employee : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private System.Nullable _birthDate; + + private string _city; + + private string _country; + + private int _employeeID; + + private string _extension; + + private string _firstName; + + private System.Nullable _hireDate; + + private string _homePhone; + + private string _lastName; + + private string _notes; + + private byte[] _photo; + + private string _photoPath; + + private string _postalCode; + + private string _region; + + private System.Nullable _reportsTo; + + private string _title; + + private string _titleOfCourtesy; + + private EntitySet _employeeTerritories; + + private EntitySet _employees; + + private EntitySet _orders; + + private EntityRef _reportsToEmployee = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnAddressChanged(); + + partial void OnAddressChanging(string value); + + partial void OnBirthDateChanged(); + + partial void OnBirthDateChanging(System.Nullable value); + + partial void OnCityChanged(); + + partial void OnCityChanging(string value); + + partial void OnCountryChanged(); + + partial void OnCountryChanging(string value); + + partial void OnEmployeeIDChanged(); + + partial void OnEmployeeIDChanging(int value); + + partial void OnExtensionChanged(); + + partial void OnExtensionChanging(string value); + + partial void OnFirstNameChanged(); + + partial void OnFirstNameChanging(string value); + + partial void OnHireDateChanged(); + + partial void OnHireDateChanging(System.Nullable value); + + partial void OnHomePhoneChanged(); + + partial void OnHomePhoneChanging(string value); + + partial void OnLastNameChanged(); + + partial void OnLastNameChanging(string value); + + partial void OnNotesChanged(); + + partial void OnNotesChanging(string value); + + partial void OnPhotoChanged(); + + partial void OnPhotoChanging(byte[] value); + + partial void OnPhotoPathChanged(); + + partial void OnPhotoPathChanging(string value); + + partial void OnPostalCodeChanged(); + + partial void OnPostalCodeChanging(string value); + + partial void OnRegionChanged(); + + partial void OnRegionChanging(string value); + + partial void OnReportsToChanged(); + + partial void OnReportsToChanging(System.Nullable value); + + partial void OnTitleChanged(); + + partial void OnTitleChanging(string value); + + partial void OnTitleOfCourtesyChanged(); + + partial void OnTitleOfCourtesyChanging(string value); + #endregion + + + public Employee() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + _employees = new EntitySet(new Action(this.Employees_Attach), new Action(this.Employees_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Address + { + get + { + return this._address; + } + set + { + if (((_address == value) + == false)) + { + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); + } + } + } + + [Column(Storage="_birthDate", Name="BirthDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable BirthDate + { + get + { + return this._birthDate; + } + set + { + if ((_birthDate != value)) + { + this.OnBirthDateChanging(value); + this.SendPropertyChanging(); + this._birthDate = value; + this.SendPropertyChanged("BirthDate"); + this.OnBirthDateChanged(); + } + } + } + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string City + { + get + { + return this._city; + } + set + { + if (((_city == value) + == false)) + { + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); + } + } + } + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Country + { + get + { + return this._country; + } + set + { + if (((_country == value) + == false)) + { + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); + } + } + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int EmployeeID + { + get + { + return this._employeeID; + } + set + { + if ((_employeeID != value)) + { + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); + } + } + } + + [Column(Storage="_extension", Name="Extension", DbType="nvarchar (4)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Extension + { + get + { + return this._extension; + } + set + { + if (((_extension == value) + == false)) + { + this.OnExtensionChanging(value); + this.SendPropertyChanging(); + this._extension = value; + this.SendPropertyChanged("Extension"); + this.OnExtensionChanged(); + } + } + } + + [Column(Storage="_firstName", Name="FirstName", DbType="nvarchar (10)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string FirstName + { + get + { + return this._firstName; + } + set + { + if (((_firstName == value) + == false)) + { + this.OnFirstNameChanging(value); + this.SendPropertyChanging(); + this._firstName = value; + this.SendPropertyChanged("FirstName"); + this.OnFirstNameChanged(); + } + } + } + + [Column(Storage="_hireDate", Name="HireDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable HireDate + { + get + { + return this._hireDate; + } + set + { + if ((_hireDate != value)) + { + this.OnHireDateChanging(value); + this.SendPropertyChanging(); + this._hireDate = value; + this.SendPropertyChanged("HireDate"); + this.OnHireDateChanged(); + } + } + } + + [Column(Storage="_homePhone", Name="HomePhone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string HomePhone + { + get + { + return this._homePhone; + } + set + { + if (((_homePhone == value) + == false)) + { + this.OnHomePhoneChanging(value); + this.SendPropertyChanging(); + this._homePhone = value; + this.SendPropertyChanged("HomePhone"); + this.OnHomePhoneChanged(); + } + } + } + + [Column(Storage="_lastName", Name="LastName", DbType="nvarchar (20)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string LastName + { + get + { + return this._lastName; + } + set + { + if (((_lastName == value) + == false)) + { + this.OnLastNameChanging(value); + this.SendPropertyChanging(); + this._lastName = value; + this.SendPropertyChanged("LastName"); + this.OnLastNameChanged(); + } + } + } + + [Column(Storage="_notes", Name="Notes", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Notes + { + get + { + return this._notes; + } + set + { + if (((_notes == value) + == false)) + { + this.OnNotesChanging(value); + this.SendPropertyChanging(); + this._notes = value; + this.SendPropertyChanged("Notes"); + this.OnNotesChanged(); + } + } + } + + [Column(Storage="_photo", Name="Photo", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Photo + { + get + { + return this._photo; + } + set + { + if (((_photo == value) + == false)) + { + this.OnPhotoChanging(value); + this.SendPropertyChanging(); + this._photo = value; + this.SendPropertyChanged("Photo"); + this.OnPhotoChanged(); + } + } + } + + [Column(Storage="_photoPath", Name="PhotoPath", DbType="nvarchar (255)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PhotoPath + { + get + { + return this._photoPath; + } + set + { + if (((_photoPath == value) + == false)) + { + this.OnPhotoPathChanging(value); + this.SendPropertyChanging(); + this._photoPath = value; + this.SendPropertyChanged("PhotoPath"); + this.OnPhotoPathChanged(); + } + } + } + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PostalCode + { + get + { + return this._postalCode; + } + set + { + if (((_postalCode == value) + == false)) + { + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); + } + } + } + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Region + { + get + { + return this._region; + } + set + { + if (((_region == value) + == false)) + { + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); + } + } + } + + [Column(Storage="_reportsTo", Name="ReportsTo", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReportsTo + { + get + { + return this._reportsTo; + } + set + { + if ((_reportsTo != value)) + { + if (_reportsToEmployee.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnReportsToChanging(value); + this.SendPropertyChanging(); + this._reportsTo = value; + this.SendPropertyChanged("ReportsTo"); + this.OnReportsToChanged(); + } + } + } + + [Column(Storage="_title", Name="Title", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Title + { + get + { + return this._title; + } + set + { + if (((_title == value) + == false)) + { + this.OnTitleChanging(value); + this.SendPropertyChanging(); + this._title = value; + this.SendPropertyChanged("Title"); + this.OnTitleChanged(); + } + } + } + + [Column(Storage="_titleOfCourtesy", Name="TitleOfCourtesy", DbType="nvarchar (25)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string TitleOfCourtesy + { + get + { + return this._titleOfCourtesy; + } + set + { + if (((_titleOfCourtesy == value) + == false)) + { + this.OnTitleOfCourtesyChanging(value); + this.SendPropertyChanging(); + this._titleOfCourtesy = value; + this.SendPropertyChanged("TitleOfCourtesy"); + this.OnTitleOfCourtesyChanged(); + } + } + } + + #region Children + [Association(Storage="_employeeTerritories", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_EmployeeTerritories_1")] + [DebuggerNonUserCode()] + public EntitySet EmployeeTerritories + { + get + { + return this._employeeTerritories; + } + set + { + this._employeeTerritories = value; + } + } + + [Association(Storage="_employees", OtherKey="ReportsTo", ThisKey="EmployeeID", Name="fk_Employees_0")] + [DebuggerNonUserCode()] + public EntitySet Employees + { + get + { + return this._employees; + } + set + { + this._employees = value; + } + } + + [Association(Storage="_orders", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_Orders_1")] + [DebuggerNonUserCode()] + public EntitySet Orders + { + get + { + return this._orders; + } + set + { + this._orders = value; + } + } + #endregion + + #region Parents + [Association(Storage="_reportsToEmployee", OtherKey="EmployeeID", ThisKey="ReportsTo", Name="fk_Employees_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Employee ReportsToEmployee + { + get + { + return this._reportsToEmployee.Entity; + } + set + { + if (((this._reportsToEmployee.Entity == value) + == false)) + { + if ((this._reportsToEmployee.Entity != null)) + { + Employee previousEmployee = this._reportsToEmployee.Entity; + this._reportsToEmployee.Entity = null; + previousEmployee.Employees.Remove(this); + } + this._reportsToEmployee.Entity = value; + if ((value != null)) + { + value.Employees.Add(this); + _reportsTo = value.EmployeeID; + } + else + { + _reportsTo = null; + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Employee other = ((Employee)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Employee value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID); + } + + #region Attachment handlers + private void EmployeeTerritories_Attach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Employee = this; + } + + private void EmployeeTerritories_Detach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Employee = null; + } + + private void Employees_Attach(Employee entity) + { + this.SendPropertyChanging(); + entity.ReportsToEmployee = this; + } + + private void Employees_Detach(Employee entity) + { + this.SendPropertyChanging(); + entity.ReportsToEmployee = null; + } + + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Employee = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Employee = null; + } + #endregion + } + + [Table(Name="main.EmployeeTerritories")] + public partial class EmployeeTerritory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _employeeID; + + private string _territoryID; + + private EntityRef _territory = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnEmployeeIDChanged(); + + partial void OnEmployeeIDChanging(int value); + + partial void OnTerritoryIDChanged(); + + partial void OnTerritoryIDChanging(string value); + #endregion + + + public EmployeeTerritory() + { + this.OnCreated(); + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int EmployeeID + { + get + { + return this._employeeID; + } + set + { + if ((_employeeID != value)) + { + if (_employee.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); + } + } + } + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string TerritoryID + { + get + { + return this._territoryID; + } + set + { + if (((_territoryID == value) + == false)) + { + if (_territory.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); + } + } + } + + #region Parents + [Association(Storage="_territory", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="fk_EmployeeTerritories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Territory Territory + { + get + { + return this._territory.Entity; + } + set + { + if (((this._territory.Entity == value) + == false)) + { + if ((this._territory.Entity != null)) + { + Territory previousTerritory = this._territory.Entity; + this._territory.Entity = null; + previousTerritory.EmployeeTerritories.Remove(this); + } + this._territory.Entity = value; + if ((value != null)) + { + value.EmployeeTerritories.Add(this); + _territoryID = value.TerritoryID; + } + else + { + _territoryID = default(string); + } + } + } + } + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_EmployeeTerritories_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Employee Employee + { + get + { + return this._employee.Entity; + } + set + { + if (((this._employee.Entity == value) + == false)) + { + if ((this._employee.Entity != null)) + { + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; + previousEmployee.EmployeeTerritories.Remove(this); + } + this._employee.Entity = value; + if ((value != null)) + { + value.EmployeeTerritories.Add(this); + _employeeID = value.EmployeeID; + } + else + { + _employeeID = default(int); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + EmployeeTerritory other = ((EmployeeTerritory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(EmployeeTerritory value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID)); + } + } + + [Table(Name="main.Orders")] + public partial class Order : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private System.Nullable _employeeID; + + private System.Nullable _freight; + + private System.Nullable _orderDate; + + private int _orderID; + + private System.Nullable _requiredDate; + + private string _shipAddress; + + private string _shipCity; + + private string _shipCountry; + + private string _shipName; + + private System.Nullable _shippedDate; + + private string _shipPostalCode; + + private string _shipRegion; + + private System.Nullable _shipVia; + + private EntitySet _orderDetails; + + private EntityRef _shipper = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + private EntityRef _customer = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCustomerIDChanged(); + + partial void OnCustomerIDChanging(string value); + + partial void OnEmployeeIDChanged(); + + partial void OnEmployeeIDChanging(System.Nullable value); + + partial void OnFreightChanged(); + + partial void OnFreightChanging(System.Nullable value); + + partial void OnOrderDateChanged(); + + partial void OnOrderDateChanging(System.Nullable value); + + partial void OnOrderIDChanged(); + + partial void OnOrderIDChanging(int value); + + partial void OnRequiredDateChanged(); + + partial void OnRequiredDateChanging(System.Nullable value); + + partial void OnShipAddressChanged(); + + partial void OnShipAddressChanging(string value); + + partial void OnShipCityChanged(); + + partial void OnShipCityChanging(string value); + + partial void OnShipCountryChanged(); + + partial void OnShipCountryChanging(string value); + + partial void OnShipNameChanged(); + + partial void OnShipNameChanging(string value); + + partial void OnShippedDateChanged(); + + partial void OnShippedDateChanging(System.Nullable value); + + partial void OnShipPostalCodeChanged(); + + partial void OnShipPostalCodeChanging(string value); + + partial void OnShipRegionChanged(); + + partial void OnShipRegionChanging(string value); + + partial void OnShipViaChanged(); + + partial void OnShipViaChanging(System.Nullable value); + #endregion + + + public Order() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string CustomerID + { + get + { + return this._customerID; + } + set + { + if (((_customerID == value) + == false)) + { + if (_customer.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable EmployeeID + { + get + { + return this._employeeID; + } + set + { + if ((_employeeID != value)) + { + if (_employee.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); + } + } + } + + [Column(Storage="_freight", Name="Freight", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable Freight + { + get + { + return this._freight; + } + set + { + if ((_freight != value)) + { + this.OnFreightChanging(value); + this.SendPropertyChanging(); + this._freight = value; + this.SendPropertyChanged("Freight"); + this.OnFreightChanged(); + } + } + } + + [Column(Storage="_orderDate", Name="OrderDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable OrderDate + { + get + { + return this._orderDate; + } + set + { + if ((_orderDate != value)) + { + this.OnOrderDateChanging(value); + this.SendPropertyChanging(); + this._orderDate = value; + this.SendPropertyChanged("OrderDate"); + this.OnOrderDateChanged(); + } + } + } + + [Column(Storage="_orderID", Name="OrderID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int OrderID + { + get + { + return this._orderID; + } + set + { + if ((_orderID != value)) + { + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); + } + } + } + + [Column(Storage="_requiredDate", Name="RequiredDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable RequiredDate + { + get + { + return this._requiredDate; + } + set + { + if ((_requiredDate != value)) + { + this.OnRequiredDateChanging(value); + this.SendPropertyChanging(); + this._requiredDate = value; + this.SendPropertyChanged("RequiredDate"); + this.OnRequiredDateChanged(); + } + } + } + + [Column(Storage="_shipAddress", Name="ShipAddress", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipAddress + { + get + { + return this._shipAddress; + } + set + { + if (((_shipAddress == value) + == false)) + { + this.OnShipAddressChanging(value); + this.SendPropertyChanging(); + this._shipAddress = value; + this.SendPropertyChanged("ShipAddress"); + this.OnShipAddressChanged(); + } + } + } + + [Column(Storage="_shipCity", Name="ShipCity", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipCity + { + get + { + return this._shipCity; + } + set + { + if (((_shipCity == value) + == false)) + { + this.OnShipCityChanging(value); + this.SendPropertyChanging(); + this._shipCity = value; + this.SendPropertyChanged("ShipCity"); + this.OnShipCityChanged(); + } + } + } + + [Column(Storage="_shipCountry", Name="ShipCountry", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipCountry + { + get + { + return this._shipCountry; + } + set + { + if (((_shipCountry == value) + == false)) + { + this.OnShipCountryChanging(value); + this.SendPropertyChanging(); + this._shipCountry = value; + this.SendPropertyChanged("ShipCountry"); + this.OnShipCountryChanged(); + } + } + } + + [Column(Storage="_shipName", Name="ShipName", DbType="nvarchar (40)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipName + { + get + { + return this._shipName; + } + set + { + if (((_shipName == value) + == false)) + { + this.OnShipNameChanging(value); + this.SendPropertyChanging(); + this._shipName = value; + this.SendPropertyChanged("ShipName"); + this.OnShipNameChanged(); + } + } + } + + [Column(Storage="_shippedDate", Name="ShippedDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShippedDate + { + get + { + return this._shippedDate; + } + set + { + if ((_shippedDate != value)) + { + this.OnShippedDateChanging(value); + this.SendPropertyChanging(); + this._shippedDate = value; + this.SendPropertyChanged("ShippedDate"); + this.OnShippedDateChanged(); + } + } + } + + [Column(Storage="_shipPostalCode", Name="ShipPostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipPostalCode + { + get + { + return this._shipPostalCode; + } + set + { + if (((_shipPostalCode == value) + == false)) + { + this.OnShipPostalCodeChanging(value); + this.SendPropertyChanging(); + this._shipPostalCode = value; + this.SendPropertyChanged("ShipPostalCode"); + this.OnShipPostalCodeChanged(); + } + } + } + + [Column(Storage="_shipRegion", Name="ShipRegion", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipRegion + { + get + { + return this._shipRegion; + } + set + { + if (((_shipRegion == value) + == false)) + { + this.OnShipRegionChanging(value); + this.SendPropertyChanging(); + this._shipRegion = value; + this.SendPropertyChanged("ShipRegion"); + this.OnShipRegionChanged(); + } + } + } + + [Column(Storage="_shipVia", Name="ShipVia", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShipVia + { + get + { + return this._shipVia; + } + set + { + if ((_shipVia != value)) + { + if (_shipper.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnShipViaChanging(value); + this.SendPropertyChanging(); + this._shipVia = value; + this.SendPropertyChanged("ShipVia"); + this.OnShipViaChanged(); + } + } + } + + #region Children + [Association(Storage="_orderDetails", OtherKey="OrderID", ThisKey="OrderID", Name="fk_Order Details_1")] + [DebuggerNonUserCode()] + public EntitySet OrderDetails + { + get + { + return this._orderDetails; + } + set + { + this._orderDetails = value; + } + } + #endregion + + #region Parents + [Association(Storage="_shipper", OtherKey="ShipperID", ThisKey="ShipVia", Name="fk_Orders_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Shipper Shipper + { + get + { + return this._shipper.Entity; + } + set + { + if (((this._shipper.Entity == value) + == false)) + { + if ((this._shipper.Entity != null)) + { + Shipper previousShipper = this._shipper.Entity; + this._shipper.Entity = null; + previousShipper.Orders.Remove(this); + } + this._shipper.Entity = value; + if ((value != null)) + { + value.Orders.Add(this); + _shipVia = value.ShipperID; + } + else + { + _shipVia = null; + } + } + } + } + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_Orders_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Employee Employee + { + get + { + return this._employee.Entity; + } + set + { + if (((this._employee.Entity == value) + == false)) + { + if ((this._employee.Entity != null)) + { + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; + previousEmployee.Orders.Remove(this); + } + this._employee.Entity = value; + if ((value != null)) + { + value.Orders.Add(this); + _employeeID = value.EmployeeID; + } + else + { + _employeeID = null; + } + } + } + } + + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_Orders_2", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Customer Customer + { + get + { + return this._customer.Entity; + } + set + { + if (((this._customer.Entity == value) + == false)) + { + if ((this._customer.Entity != null)) + { + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; + previousCustomer.Orders.Remove(this); + } + this._customer.Entity = value; + if ((value != null)) + { + value.Orders.Add(this); + _customerID = value.CustomerID; + } + else + { + _customerID = null; + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Order other = ((Order)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Order value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = null; + } + #endregion + } + + [Table(Name="main.Order Details")] + public partial class OrderDetail : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private float _discount; + + private int _orderID; + + private int _productID; + + private short _quantity; + + private decimal _unitPrice; + + private EntityRef _product = new EntityRef(); + + private EntityRef _order = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnDiscountChanged(); + + partial void OnDiscountChanging(float value); + + partial void OnOrderIDChanged(); + + partial void OnOrderIDChanging(int value); + + partial void OnProductIDChanged(); + + partial void OnProductIDChanging(int value); + + partial void OnQuantityChanged(); + + partial void OnQuantityChanging(short value); + + partial void OnUnitPriceChanged(); + + partial void OnUnitPriceChanging(decimal value); + #endregion + + + public OrderDetail() + { + this.OnCreated(); + } + + [Column(Storage="_discount", Name="Discount", DbType="real", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public float Discount + { + get + { + return this._discount; + } + set + { + if ((_discount != value)) + { + this.OnDiscountChanging(value); + this.SendPropertyChanging(); + this._discount = value; + this.SendPropertyChanged("Discount"); + this.OnDiscountChanged(); + } + } + } + + [Column(Storage="_orderID", Name="OrderID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int OrderID + { + get + { + return this._orderID; + } + set + { + if ((_orderID != value)) + { + if (_order.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); + } + } + } + + [Column(Storage="_productID", Name="ProductID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int ProductID + { + get + { + return this._productID; + } + set + { + if ((_productID != value)) + { + if (_product.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); + } + } + } + + [Column(Storage="_quantity", Name="Quantity", DbType="smallint", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public short Quantity + { + get + { + return this._quantity; + } + set + { + if ((_quantity != value)) + { + this.OnQuantityChanging(value); + this.SendPropertyChanging(); + this._quantity = value; + this.SendPropertyChanged("Quantity"); + this.OnQuantityChanged(); + } + } + } + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public decimal UnitPrice + { + get + { + return this._unitPrice; + } + set + { + if ((_unitPrice != value)) + { + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); + } + } + } + + #region Parents + [Association(Storage="_product", OtherKey="ProductID", ThisKey="ProductID", Name="fk_Order Details_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Product Product + { + get + { + return this._product.Entity; + } + set + { + if (((this._product.Entity == value) + == false)) + { + if ((this._product.Entity != null)) + { + Product previousProduct = this._product.Entity; + this._product.Entity = null; + previousProduct.OrderDetails.Remove(this); + } + this._product.Entity = value; + if ((value != null)) + { + value.OrderDetails.Add(this); + _productID = value.ProductID; + } + else + { + _productID = default(int); + } + } + } + } + + [Association(Storage="_order", OtherKey="OrderID", ThisKey="OrderID", Name="fk_Order Details_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Order Order + { + get + { + return this._order.Entity; + } + set + { + if (((this._order.Entity == value) + == false)) + { + if ((this._order.Entity != null)) + { + Order previousOrder = this._order.Entity; + this._order.Entity = null; + previousOrder.OrderDetails.Remove(this); + } + this._order.Entity = value; + if ((value != null)) + { + value.OrderDetails.Add(this); + _orderID = value.OrderID; + } + else + { + _orderID = default(int); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + hc = (hc + | (_productID.GetHashCode() * 65536)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + OrderDetail other = ((OrderDetail)(value)); + return this.Equals(other); + } + + public virtual bool Equals(OrderDetail value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID)); + } + } + + [Table(Name="main.Products")] + public partial class Product : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private System.Nullable _categoryID; + + private bool _discontinued; + + private int _productID; + + private string _productName; + + private string _quantityPerUnit; + + private System.Nullable _reorderLevel; + + private System.Nullable _supplierID; + + private System.Nullable _unitPrice; + + private System.Nullable _unitsInStock; + + private System.Nullable _unitsOnOrder; + + private EntitySet _orderDetails; + + private EntityRef _supplier = new EntityRef(); + + private EntityRef _category = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCategoryIDChanged(); + + partial void OnCategoryIDChanging(System.Nullable value); + + partial void OnDiscontinuedChanged(); + + partial void OnDiscontinuedChanging(bool value); + + partial void OnProductIDChanged(); + + partial void OnProductIDChanging(int value); + + partial void OnProductNameChanged(); + + partial void OnProductNameChanging(string value); + + partial void OnQuantityPerUnitChanged(); + + partial void OnQuantityPerUnitChanging(string value); + + partial void OnReorderLevelChanged(); + + partial void OnReorderLevelChanging(System.Nullable value); + + partial void OnSupplierIDChanged(); + + partial void OnSupplierIDChanging(System.Nullable value); + + partial void OnUnitPriceChanged(); + + partial void OnUnitPriceChanging(System.Nullable value); + + partial void OnUnitsInStockChanged(); + + partial void OnUnitsInStockChanging(System.Nullable value); + + partial void OnUnitsOnOrderChanged(); + + partial void OnUnitsOnOrderChanging(System.Nullable value); + #endregion + + + public Product() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable CategoryID + { + get + { + return this._categoryID; + } + set + { + if ((_categoryID != value)) + { + if (_category.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); + } + } + } + + [Column(Storage="_discontinued", Name="Discontinued", DbType="bit", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public bool Discontinued + { + get + { + return this._discontinued; + } + set + { + if ((_discontinued != value)) + { + this.OnDiscontinuedChanging(value); + this.SendPropertyChanging(); + this._discontinued = value; + this.SendPropertyChanged("Discontinued"); + this.OnDiscontinuedChanged(); + } + } + } + + [Column(Storage="_productID", Name="ProductID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int ProductID + { + get + { + return this._productID; + } + set + { + if ((_productID != value)) + { + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); + } + } + } + + [Column(Storage="_productName", Name="ProductName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string ProductName + { + get + { + return this._productName; + } + set + { + if (((_productName == value) + == false)) + { + this.OnProductNameChanging(value); + this.SendPropertyChanging(); + this._productName = value; + this.SendPropertyChanged("ProductName"); + this.OnProductNameChanged(); + } + } + } + + [Column(Storage="_quantityPerUnit", Name="QuantityPerUnit", DbType="nvarchar (20)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string QuantityPerUnit + { + get + { + return this._quantityPerUnit; + } + set + { + if (((_quantityPerUnit == value) + == false)) + { + this.OnQuantityPerUnitChanging(value); + this.SendPropertyChanging(); + this._quantityPerUnit = value; + this.SendPropertyChanged("QuantityPerUnit"); + this.OnQuantityPerUnitChanged(); + } + } + } + + [Column(Storage="_reorderLevel", Name="ReorderLevel", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReorderLevel + { + get + { + return this._reorderLevel; + } + set + { + if ((_reorderLevel != value)) + { + this.OnReorderLevelChanging(value); + this.SendPropertyChanging(); + this._reorderLevel = value; + this.SendPropertyChanged("ReorderLevel"); + this.OnReorderLevelChanged(); + } + } + } + + [Column(Storage="_supplierID", Name="SupplierID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable SupplierID + { + get + { + return this._supplierID; + } + set + { + if ((_supplierID != value)) + { + if (_supplier.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); + } + } + } + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitPrice + { + get + { + return this._unitPrice; + } + set + { + if ((_unitPrice != value)) + { + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); + } + } + } + + [Column(Storage="_unitsInStock", Name="UnitsInStock", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsInStock + { + get + { + return this._unitsInStock; + } + set + { + if ((_unitsInStock != value)) + { + this.OnUnitsInStockChanging(value); + this.SendPropertyChanging(); + this._unitsInStock = value; + this.SendPropertyChanged("UnitsInStock"); + this.OnUnitsInStockChanged(); + } + } + } + + [Column(Storage="_unitsOnOrder", Name="UnitsOnOrder", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsOnOrder + { + get + { + return this._unitsOnOrder; + } + set + { + if ((_unitsOnOrder != value)) + { + this.OnUnitsOnOrderChanging(value); + this.SendPropertyChanging(); + this._unitsOnOrder = value; + this.SendPropertyChanged("UnitsOnOrder"); + this.OnUnitsOnOrderChanged(); + } + } + } + + #region Children + [Association(Storage="_orderDetails", OtherKey="ProductID", ThisKey="ProductID", Name="fk_Order Details_0")] + [DebuggerNonUserCode()] + public EntitySet OrderDetails + { + get + { + return this._orderDetails; + } + set + { + this._orderDetails = value; + } + } + #endregion + + #region Parents + [Association(Storage="_supplier", OtherKey="SupplierID", ThisKey="SupplierID", Name="fk_Products_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Supplier Supplier + { + get + { + return this._supplier.Entity; + } + set + { + if (((this._supplier.Entity == value) + == false)) + { + if ((this._supplier.Entity != null)) + { + Supplier previousSupplier = this._supplier.Entity; + this._supplier.Entity = null; + previousSupplier.Products.Remove(this); + } + this._supplier.Entity = value; + if ((value != null)) + { + value.Products.Add(this); + _supplierID = value.SupplierID; + } + else + { + _supplierID = null; + } + } + } + } + + [Association(Storage="_category", OtherKey="CategoryID", ThisKey="CategoryID", Name="fk_Products_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Category Category + { + get + { + return this._category.Entity; + } + set + { + if (((this._category.Entity == value) + == false)) + { + if ((this._category.Entity != null)) + { + Category previousCategory = this._category.Entity; + this._category.Entity = null; + previousCategory.Products.Remove(this); + } + this._category.Entity = value; + if ((value != null)) + { + value.Products.Add(this); + _categoryID = value.CategoryID; + } + else + { + _categoryID = null; + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_productID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Product other = ((Product)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Product value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = null; + } + #endregion + } + + [Table(Name="main.Region")] + public partial class Region : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _regionDescription; + + private int _regionID; + + private EntitySet _territories; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnRegionDescriptionChanged(); + + partial void OnRegionDescriptionChanging(string value); + + partial void OnRegionIDChanged(); + + partial void OnRegionIDChanging(int value); + #endregion + + + public Region() + { + _territories = new EntitySet(new Action(this.Territories_Attach), new Action(this.Territories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionDescription", Name="RegionDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string RegionDescription + { + get + { + return this._regionDescription; + } + set + { + if (((_regionDescription == value) + == false)) + { + this.OnRegionDescriptionChanging(value); + this.SendPropertyChanging(); + this._regionDescription = value; + this.SendPropertyChanged("RegionDescription"); + this.OnRegionDescriptionChanged(); + } + } + } + + [Column(Storage="_regionID", Name="RegionID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int RegionID + { + get + { + return this._regionID; + } + set + { + if ((_regionID != value)) + { + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); + } + } + } + + #region Children + [Association(Storage="_territories", OtherKey="RegionID", ThisKey="RegionID", Name="fk_Territories_0")] + [DebuggerNonUserCode()] + public EntitySet Territories + { + get + { + return this._territories; + } + set + { + this._territories = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_regionID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Region other = ((Region)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Region value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._regionID, value._regionID); + } + + #region Attachment handlers + private void Territories_Attach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = this; + } + + private void Territories_Detach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = null; + } + #endregion + } + + [Table(Name="main.Shippers")] + public partial class Shipper : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _companyName; + + private string _phone; + + private int _shipperID; + + private EntitySet _orders; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCompanyNameChanged(); + + partial void OnCompanyNameChanging(string value); + + partial void OnPhoneChanged(); + + partial void OnPhoneChanging(string value); + + partial void OnShipperIDChanged(); + + partial void OnShipperIDChanging(int value); + #endregion + + + public Shipper() + { + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CompanyName + { + get + { + return this._companyName; + } + set + { + if (((_companyName == value) + == false)) + { + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); + } + } + } + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Phone + { + get + { + return this._phone; + } + set + { + if (((_phone == value) + == false)) + { + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); + } + } + } + + [Column(Storage="_shipperID", Name="ShipperID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int ShipperID + { + get + { + return this._shipperID; + } + set + { + if ((_shipperID != value)) + { + this.OnShipperIDChanging(value); + this.SendPropertyChanging(); + this._shipperID = value; + this.SendPropertyChanged("ShipperID"); + this.OnShipperIDChanged(); + } + } + } + + #region Children + [Association(Storage="_orders", OtherKey="ShipVia", ThisKey="ShipperID", Name="fk_Orders_0")] + [DebuggerNonUserCode()] + public EntitySet Orders + { + get + { + return this._orders; + } + set + { + this._orders = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_shipperID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Shipper other = ((Shipper)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Shipper value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._shipperID, value._shipperID); + } + + #region Attachment handlers + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = null; + } + #endregion + } + + [Table(Name="main.Suppliers")] + public partial class Supplier : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _fax; + + private string _homePage; + + private string _phone; + + private string _postalCode; + + private string _region; + + private int _supplierID; + + private EntitySet _products; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnAddressChanged(); + + partial void OnAddressChanging(string value); + + partial void OnCityChanged(); + + partial void OnCityChanging(string value); + + partial void OnCompanyNameChanged(); + + partial void OnCompanyNameChanging(string value); + + partial void OnContactNameChanged(); + + partial void OnContactNameChanging(string value); + + partial void OnContactTitleChanged(); + + partial void OnContactTitleChanging(string value); + + partial void OnCountryChanged(); + + partial void OnCountryChanging(string value); + + partial void OnFaxChanged(); + + partial void OnFaxChanging(string value); + + partial void OnHomePageChanged(); + + partial void OnHomePageChanging(string value); + + partial void OnPhoneChanged(); + + partial void OnPhoneChanging(string value); + + partial void OnPostalCodeChanged(); + + partial void OnPostalCodeChanging(string value); + + partial void OnRegionChanged(); + + partial void OnRegionChanging(string value); + + partial void OnSupplierIDChanged(); + + partial void OnSupplierIDChanging(int value); + #endregion + + + public Supplier() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Address + { + get + { + return this._address; + } + set + { + if (((_address == value) + == false)) + { + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); + } + } + } + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string City + { + get + { + return this._city; + } + set + { + if (((_city == value) + == false)) + { + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); + } + } + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CompanyName + { + get + { + return this._companyName; + } + set + { + if (((_companyName == value) + == false)) + { + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); + } + } + } + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactName + { + get + { + return this._contactName; + } + set + { + if (((_contactName == value) + == false)) + { + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); + } + } + } + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactTitle + { + get + { + return this._contactTitle; + } + set + { + if (((_contactTitle == value) + == false)) + { + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); + } + } + } + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Country + { + get + { + return this._country; + } + set + { + if (((_country == value) + == false)) + { + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); + } + } + } + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Fax + { + get + { + return this._fax; + } + set + { + if (((_fax == value) + == false)) + { + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); + } + } + } + + [Column(Storage="_homePage", Name="HomePage", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string HomePage + { + get + { + return this._homePage; + } + set + { + if (((_homePage == value) + == false)) + { + this.OnHomePageChanging(value); + this.SendPropertyChanging(); + this._homePage = value; + this.SendPropertyChanged("HomePage"); + this.OnHomePageChanged(); + } + } + } + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Phone + { + get + { + return this._phone; + } + set + { + if (((_phone == value) + == false)) + { + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); + } + } + } + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PostalCode + { + get + { + return this._postalCode; + } + set + { + if (((_postalCode == value) + == false)) + { + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); + } + } + } + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Region + { + get + { + return this._region; + } + set + { + if (((_region == value) + == false)) + { + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); + } + } + } + + [Column(Storage="_supplierID", Name="SupplierID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int SupplierID + { + get + { + return this._supplierID; + } + set + { + if ((_supplierID != value)) + { + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); + } + } + } + + #region Children + [Association(Storage="_products", OtherKey="SupplierID", ThisKey="SupplierID", Name="fk_Products_0")] + [DebuggerNonUserCode()] + public EntitySet Products + { + get + { + return this._products; + } + set + { + this._products = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_supplierID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Supplier other = ((Supplier)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Supplier value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._supplierID, value._supplierID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = null; + } + #endregion + } + + [Table(Name="main.Territories")] + public partial class Territory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _regionID; + + private string _territoryDescription; + + private string _territoryID; + + private EntitySet _employeeTerritories; + + private EntityRef _region = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnRegionIDChanged(); + + partial void OnRegionIDChanging(int value); + + partial void OnTerritoryDescriptionChanged(); + + partial void OnTerritoryDescriptionChanging(string value); + + partial void OnTerritoryIDChanged(); + + partial void OnTerritoryIDChanging(string value); + #endregion + + + public Territory() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionID", Name="RegionID", DbType="INTEGER", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int RegionID + { + get + { + return this._regionID; + } + set + { + if ((_regionID != value)) + { + if (_region.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); + } + } + } + + [Column(Storage="_territoryDescription", Name="TerritoryDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string TerritoryDescription + { + get + { + return this._territoryDescription; + } + set + { + if (((_territoryDescription == value) + == false)) + { + this.OnTerritoryDescriptionChanging(value); + this.SendPropertyChanging(); + this._territoryDescription = value; + this.SendPropertyChanged("TerritoryDescription"); + this.OnTerritoryDescriptionChanged(); + } + } + } + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string TerritoryID + { + get + { + return this._territoryID; + } + set + { + if (((_territoryID == value) + == false)) + { + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); + } + } + } + + #region Children + [Association(Storage="_employeeTerritories", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="fk_EmployeeTerritories_0")] + [DebuggerNonUserCode()] + public EntitySet EmployeeTerritories + { + get + { + return this._employeeTerritories; + } + set + { + this._employeeTerritories = value; + } + } + #endregion + + #region Parents + [Association(Storage="_region", OtherKey="RegionID", ThisKey="RegionID", Name="fk_Territories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Region Region + { + get + { + return this._region.Entity; + } + set + { + if (((this._region.Entity == value) + == false)) + { + if ((this._region.Entity != null)) + { + Region previousRegion = this._region.Entity; + this._region.Entity = null; + previousRegion.Territories.Remove(this); + } + this._region.Entity = value; + if ((value != null)) + { + value.Territories.Add(this); + _regionID = value.RegionID; + } + else + { + _regionID = default(int); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Territory other = ((Territory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Territory value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID); + } + + #region Attachment handlers + private void EmployeeTerritories_Attach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Territory = this; + } + + private void EmployeeTerritories_Detach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Territory = null; + } + #endregion + } +} diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-DbMetal.dbml b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-DbMetal.dbml new file mode 100755 index 00000000000..41249a07b9b --- /dev/null +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-DbMetal.dbml @@ -0,0 +1,169 @@ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
\ No newline at end of file diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-sqlmetal.cs b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-sqlmetal.cs new file mode 100755 index 00000000000..53472a08c80 --- /dev/null +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-sqlmetal.cs @@ -0,0 +1,4476 @@ +// +// ____ _ __ __ _ _ +// | _ \| |__ | \/ | ___| |_ __ _| | +// | | | | '_ \| |\/| |/ _ \ __/ _` | | +// | |_| | |_) | | | | __/ || (_| | | +// |____/|_.__/|_| |_|\___|\__\__,_|_| +// +// Auto-generated from Northwind on [TIMESTAMP]. +// Please visit http://code.google.com/p/dblinq2007/ for more information. +// +namespace nwind +{ + using System; + using System.ComponentModel; + using System.Data; + using System.Data.Linq; + using System.Data.Linq.Mapping; + using System.Diagnostics; + + + public partial class Northwind : DataContext + { + + #region Extensibility Method Declarations + partial void OnCreated(); + #endregion + + + public Northwind(string connectionString) : + base(connectionString) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection) : + base(connection) + { + this.OnCreated(); + } + + public Northwind(string connection, MappingSource mappingSource) : + base(connection, mappingSource) + { + this.OnCreated(); + } + + public Northwind(IDbConnection connection, MappingSource mappingSource) : + base(connection, mappingSource) + { + this.OnCreated(); + } + + public Table Categories + { + get + { + return this.GetTable(); + } + } + + public Table Customers + { + get + { + return this.GetTable(); + } + } + + public Table CustomerCustomerDemo + { + get + { + return this.GetTable(); + } + } + + public Table CustomerDemographics + { + get + { + return this.GetTable(); + } + } + + public Table Employees + { + get + { + return this.GetTable(); + } + } + + public Table EmployeeTerritories + { + get + { + return this.GetTable(); + } + } + + public Table Orders + { + get + { + return this.GetTable(); + } + } + + public Table OrderDetails + { + get + { + return this.GetTable(); + } + } + + public Table Products + { + get + { + return this.GetTable(); + } + } + + public Table Regions + { + get + { + return this.GetTable(); + } + } + + public Table Shippers + { + get + { + return this.GetTable(); + } + } + + public Table Suppliers + { + get + { + return this.GetTable(); + } + } + + public Table Territories + { + get + { + return this.GetTable(); + } + } + } + + [Table(Name="main.Categories")] + public partial class Category : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _categoryID; + + private string _categoryName; + + private string _description; + + private byte[] _picture; + + private EntitySet _products; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCategoryIDChanged(); + + partial void OnCategoryIDChanging(int value); + + partial void OnCategoryNameChanged(); + + partial void OnCategoryNameChanging(string value); + + partial void OnDescriptionChanged(); + + partial void OnDescriptionChanging(string value); + + partial void OnPictureChanged(); + + partial void OnPictureChanging(byte[] value); + #endregion + + + public Category() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int CategoryID + { + get + { + return this._categoryID; + } + set + { + if ((_categoryID != value)) + { + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); + } + } + } + + [Column(Storage="_categoryName", Name="CategoryName", DbType="nvarchar (15)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CategoryName + { + get + { + return this._categoryName; + } + set + { + if (((_categoryName == value) + == false)) + { + this.OnCategoryNameChanging(value); + this.SendPropertyChanging(); + this._categoryName = value; + this.SendPropertyChanged("CategoryName"); + this.OnCategoryNameChanged(); + } + } + } + + [Column(Storage="_description", Name="Description", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Description + { + get + { + return this._description; + } + set + { + if (((_description == value) + == false)) + { + this.OnDescriptionChanging(value); + this.SendPropertyChanging(); + this._description = value; + this.SendPropertyChanged("Description"); + this.OnDescriptionChanged(); + } + } + } + + [Column(Storage="_picture", Name="Picture", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Picture + { + get + { + return this._picture; + } + set + { + if (((_picture == value) + == false)) + { + this.OnPictureChanging(value); + this.SendPropertyChanging(); + this._picture = value; + this.SendPropertyChanged("Picture"); + this.OnPictureChanged(); + } + } + } + + #region Children + [Association(Storage="_products", OtherKey="CategoryID", ThisKey="CategoryID", Name="fk_Products_1")] + [DebuggerNonUserCode()] + public EntitySet Products + { + get + { + return this._products; + } + set + { + this._products = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_categoryID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Category other = ((Category)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Category value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._categoryID, value._categoryID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Category = null; + } + #endregion + } + + [Table(Name="main.Customers")] + public partial class Customer : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _customerID; + + private string _fax; + + private string _phone; + + private string _postalCode; + + private string _region; + + private EntitySet _customerCustomerDemo; + + private EntitySet _orders; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnAddressChanged(); + + partial void OnAddressChanging(string value); + + partial void OnCityChanged(); + + partial void OnCityChanging(string value); + + partial void OnCompanyNameChanged(); + + partial void OnCompanyNameChanging(string value); + + partial void OnContactNameChanged(); + + partial void OnContactNameChanging(string value); + + partial void OnContactTitleChanged(); + + partial void OnContactTitleChanging(string value); + + partial void OnCountryChanged(); + + partial void OnCountryChanging(string value); + + partial void OnCustomerIDChanged(); + + partial void OnCustomerIDChanging(string value); + + partial void OnFaxChanged(); + + partial void OnFaxChanging(string value); + + partial void OnPhoneChanged(); + + partial void OnPhoneChanging(string value); + + partial void OnPostalCodeChanged(); + + partial void OnPostalCodeChanging(string value); + + partial void OnRegionChanged(); + + partial void OnRegionChanging(string value); + #endregion + + + public Customer() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Address + { + get + { + return this._address; + } + set + { + if (((_address == value) + == false)) + { + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); + } + } + } + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string City + { + get + { + return this._city; + } + set + { + if (((_city == value) + == false)) + { + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); + } + } + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CompanyName + { + get + { + return this._companyName; + } + set + { + if (((_companyName == value) + == false)) + { + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); + } + } + } + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactName + { + get + { + return this._contactName; + } + set + { + if (((_contactName == value) + == false)) + { + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); + } + } + } + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactTitle + { + get + { + return this._contactTitle; + } + set + { + if (((_contactTitle == value) + == false)) + { + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); + } + } + } + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Country + { + get + { + return this._country; + } + set + { + if (((_country == value) + == false)) + { + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); + } + } + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerID + { + get + { + return this._customerID; + } + set + { + if (((_customerID == value) + == false)) + { + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + } + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Fax + { + get + { + return this._fax; + } + set + { + if (((_fax == value) + == false)) + { + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); + } + } + } + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Phone + { + get + { + return this._phone; + } + set + { + if (((_phone == value) + == false)) + { + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); + } + } + } + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PostalCode + { + get + { + return this._postalCode; + } + set + { + if (((_postalCode == value) + == false)) + { + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); + } + } + } + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Region + { + get + { + return this._region; + } + set + { + if (((_region == value) + == false)) + { + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); + } + } + } + + #region Children + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_CustomerCustomerDemo_0")] + [DebuggerNonUserCode()] + public EntitySet CustomerCustomerDemo + { + get + { + return this._customerCustomerDemo; + } + set + { + this._customerCustomerDemo = value; + } + } + + [Association(Storage="_orders", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_Orders_2")] + [DebuggerNonUserCode()] + public EntitySet Orders + { + get + { + return this._orders; + } + set + { + this._orders = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Customer other = ((Customer)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Customer value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID); + } + + #region Attachment handlers + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.Customer = this; + } + + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.Customer = null; + } + + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Customer = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Customer = null; + } + #endregion + } + + [Table(Name="main.CustomerCustomerDemo")] + public partial class CustomerCustomerDemo : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private string _customerTypeID; + + private EntityRef _customer = new EntityRef(); + + private EntityRef _customerDemographic = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCustomerIDChanged(); + + partial void OnCustomerIDChanging(string value); + + partial void OnCustomerTypeIDChanged(); + + partial void OnCustomerTypeIDChanging(string value); + #endregion + + + public CustomerCustomerDemo() + { + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerID + { + get + { + return this._customerID; + } + set + { + if (((_customerID == value) + == false)) + { + if (_customer.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + } + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerTypeID + { + get + { + return this._customerTypeID; + } + set + { + if (((_customerTypeID == value) + == false)) + { + if (_customerDemographic.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); + } + } + } + + #region Parents + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_CustomerCustomerDemo_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Customer Customer + { + get + { + return this._customer.Entity; + } + set + { + if (((this._customer.Entity == value) + == false)) + { + if ((this._customer.Entity != null)) + { + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; + previousCustomer.CustomerCustomerDemo.Remove(this); + } + this._customer.Entity = value; + if ((value != null)) + { + value.CustomerCustomerDemo.Add(this); + _customerID = value.CustomerID; + } + else + { + _customerID = default(string); + } + } + } + } + + [Association(Storage="_customerDemographic", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="fk_CustomerCustomerDemo_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public CustomerDemographic CustomerDemographic + { + get + { + return this._customerDemographic.Entity; + } + set + { + if (((this._customerDemographic.Entity == value) + == false)) + { + if ((this._customerDemographic.Entity != null)) + { + CustomerDemographic previousCustomerDemographic = this._customerDemographic.Entity; + this._customerDemographic.Entity = null; + previousCustomerDemographic.CustomerCustomerDemo.Remove(this); + } + this._customerDemographic.Entity = value; + if ((value != null)) + { + value.CustomerCustomerDemo.Add(this); + _customerTypeID = value.CustomerTypeID; + } + else + { + _customerTypeID = default(string); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerID != null)) + { + hc = (hc + | (_customerID.GetHashCode() * 1)); + } + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + CustomerCustomerDemo other = ((CustomerCustomerDemo)(value)); + return this.Equals(other); + } + + public virtual bool Equals(CustomerCustomerDemo value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._customerID, value._customerID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID)); + } + } + + [Table(Name="main.CustomerDemographics")] + public partial class CustomerDemographic : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerDesc; + + private string _customerTypeID; + + private EntitySet _customerCustomerDemo; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCustomerDescChanged(); + + partial void OnCustomerDescChanging(string value); + + partial void OnCustomerTypeIDChanged(); + + partial void OnCustomerTypeIDChanging(string value); + #endregion + + + public CustomerDemographic() + { + _customerCustomerDemo = new EntitySet(new Action(this.CustomerCustomerDemo_Attach), new Action(this.CustomerCustomerDemo_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerDesc", Name="CustomerDesc", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string CustomerDesc + { + get + { + return this._customerDesc; + } + set + { + if (((_customerDesc == value) + == false)) + { + this.OnCustomerDescChanging(value); + this.SendPropertyChanging(); + this._customerDesc = value; + this.SendPropertyChanged("CustomerDesc"); + this.OnCustomerDescChanged(); + } + } + } + + [Column(Storage="_customerTypeID", Name="CustomerTypeID", DbType="nchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CustomerTypeID + { + get + { + return this._customerTypeID; + } + set + { + if (((_customerTypeID == value) + == false)) + { + this.OnCustomerTypeIDChanging(value); + this.SendPropertyChanging(); + this._customerTypeID = value; + this.SendPropertyChanged("CustomerTypeID"); + this.OnCustomerTypeIDChanged(); + } + } + } + + #region Children + [Association(Storage="_customerCustomerDemo", OtherKey="CustomerTypeID", ThisKey="CustomerTypeID", Name="fk_CustomerCustomerDemo_1")] + [DebuggerNonUserCode()] + public EntitySet CustomerCustomerDemo + { + get + { + return this._customerCustomerDemo; + } + set + { + this._customerCustomerDemo = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_customerTypeID != null)) + { + hc = (hc + | (_customerTypeID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + CustomerDemographic other = ((CustomerDemographic)(value)); + return this.Equals(other); + } + + public virtual bool Equals(CustomerDemographic value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._customerTypeID, value._customerTypeID); + } + + #region Attachment handlers + private void CustomerCustomerDemo_Attach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = this; + } + + private void CustomerCustomerDemo_Detach(CustomerCustomerDemo entity) + { + this.SendPropertyChanging(); + entity.CustomerDemographic = null; + } + #endregion + } + + [Table(Name="main.Employees")] + public partial class Employee : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private System.Nullable _birthDate; + + private string _city; + + private string _country; + + private int _employeeID; + + private string _extension; + + private string _firstName; + + private System.Nullable _hireDate; + + private string _homePhone; + + private string _lastName; + + private string _notes; + + private byte[] _photo; + + private string _photoPath; + + private string _postalCode; + + private string _region; + + private System.Nullable _reportsTo; + + private string _title; + + private string _titleOfCourtesy; + + private EntitySet _employeeTerritories; + + private EntitySet _employees; + + private EntitySet _orders; + + private EntityRef _reportsToEmployee = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnAddressChanged(); + + partial void OnAddressChanging(string value); + + partial void OnBirthDateChanged(); + + partial void OnBirthDateChanging(System.Nullable value); + + partial void OnCityChanged(); + + partial void OnCityChanging(string value); + + partial void OnCountryChanged(); + + partial void OnCountryChanging(string value); + + partial void OnEmployeeIDChanged(); + + partial void OnEmployeeIDChanging(int value); + + partial void OnExtensionChanged(); + + partial void OnExtensionChanging(string value); + + partial void OnFirstNameChanged(); + + partial void OnFirstNameChanging(string value); + + partial void OnHireDateChanged(); + + partial void OnHireDateChanging(System.Nullable value); + + partial void OnHomePhoneChanged(); + + partial void OnHomePhoneChanging(string value); + + partial void OnLastNameChanged(); + + partial void OnLastNameChanging(string value); + + partial void OnNotesChanged(); + + partial void OnNotesChanging(string value); + + partial void OnPhotoChanged(); + + partial void OnPhotoChanging(byte[] value); + + partial void OnPhotoPathChanged(); + + partial void OnPhotoPathChanging(string value); + + partial void OnPostalCodeChanged(); + + partial void OnPostalCodeChanging(string value); + + partial void OnRegionChanged(); + + partial void OnRegionChanging(string value); + + partial void OnReportsToChanged(); + + partial void OnReportsToChanging(System.Nullable value); + + partial void OnTitleChanged(); + + partial void OnTitleChanging(string value); + + partial void OnTitleOfCourtesyChanged(); + + partial void OnTitleOfCourtesyChanging(string value); + #endregion + + + public Employee() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + _employees = new EntitySet(new Action(this.Employees_Attach), new Action(this.Employees_Detach)); + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Address + { + get + { + return this._address; + } + set + { + if (((_address == value) + == false)) + { + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); + } + } + } + + [Column(Storage="_birthDate", Name="BirthDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable BirthDate + { + get + { + return this._birthDate; + } + set + { + if ((_birthDate != value)) + { + this.OnBirthDateChanging(value); + this.SendPropertyChanging(); + this._birthDate = value; + this.SendPropertyChanged("BirthDate"); + this.OnBirthDateChanged(); + } + } + } + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string City + { + get + { + return this._city; + } + set + { + if (((_city == value) + == false)) + { + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); + } + } + } + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Country + { + get + { + return this._country; + } + set + { + if (((_country == value) + == false)) + { + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); + } + } + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int EmployeeID + { + get + { + return this._employeeID; + } + set + { + if ((_employeeID != value)) + { + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); + } + } + } + + [Column(Storage="_extension", Name="Extension", DbType="nvarchar (4)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Extension + { + get + { + return this._extension; + } + set + { + if (((_extension == value) + == false)) + { + this.OnExtensionChanging(value); + this.SendPropertyChanging(); + this._extension = value; + this.SendPropertyChanged("Extension"); + this.OnExtensionChanged(); + } + } + } + + [Column(Storage="_firstName", Name="FirstName", DbType="nvarchar (10)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string FirstName + { + get + { + return this._firstName; + } + set + { + if (((_firstName == value) + == false)) + { + this.OnFirstNameChanging(value); + this.SendPropertyChanging(); + this._firstName = value; + this.SendPropertyChanged("FirstName"); + this.OnFirstNameChanged(); + } + } + } + + [Column(Storage="_hireDate", Name="HireDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable HireDate + { + get + { + return this._hireDate; + } + set + { + if ((_hireDate != value)) + { + this.OnHireDateChanging(value); + this.SendPropertyChanging(); + this._hireDate = value; + this.SendPropertyChanged("HireDate"); + this.OnHireDateChanged(); + } + } + } + + [Column(Storage="_homePhone", Name="HomePhone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string HomePhone + { + get + { + return this._homePhone; + } + set + { + if (((_homePhone == value) + == false)) + { + this.OnHomePhoneChanging(value); + this.SendPropertyChanging(); + this._homePhone = value; + this.SendPropertyChanged("HomePhone"); + this.OnHomePhoneChanged(); + } + } + } + + [Column(Storage="_lastName", Name="LastName", DbType="nvarchar (20)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string LastName + { + get + { + return this._lastName; + } + set + { + if (((_lastName == value) + == false)) + { + this.OnLastNameChanging(value); + this.SendPropertyChanging(); + this._lastName = value; + this.SendPropertyChanged("LastName"); + this.OnLastNameChanged(); + } + } + } + + [Column(Storage="_notes", Name="Notes", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Notes + { + get + { + return this._notes; + } + set + { + if (((_notes == value) + == false)) + { + this.OnNotesChanging(value); + this.SendPropertyChanging(); + this._notes = value; + this.SendPropertyChanged("Notes"); + this.OnNotesChanged(); + } + } + } + + [Column(Storage="_photo", Name="Photo", DbType="image", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public byte[] Photo + { + get + { + return this._photo; + } + set + { + if (((_photo == value) + == false)) + { + this.OnPhotoChanging(value); + this.SendPropertyChanging(); + this._photo = value; + this.SendPropertyChanged("Photo"); + this.OnPhotoChanged(); + } + } + } + + [Column(Storage="_photoPath", Name="PhotoPath", DbType="nvarchar (255)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PhotoPath + { + get + { + return this._photoPath; + } + set + { + if (((_photoPath == value) + == false)) + { + this.OnPhotoPathChanging(value); + this.SendPropertyChanging(); + this._photoPath = value; + this.SendPropertyChanged("PhotoPath"); + this.OnPhotoPathChanged(); + } + } + } + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PostalCode + { + get + { + return this._postalCode; + } + set + { + if (((_postalCode == value) + == false)) + { + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); + } + } + } + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Region + { + get + { + return this._region; + } + set + { + if (((_region == value) + == false)) + { + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); + } + } + } + + [Column(Storage="_reportsTo", Name="ReportsTo", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReportsTo + { + get + { + return this._reportsTo; + } + set + { + if ((_reportsTo != value)) + { + if (_reportsToEmployee.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnReportsToChanging(value); + this.SendPropertyChanging(); + this._reportsTo = value; + this.SendPropertyChanged("ReportsTo"); + this.OnReportsToChanged(); + } + } + } + + [Column(Storage="_title", Name="Title", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Title + { + get + { + return this._title; + } + set + { + if (((_title == value) + == false)) + { + this.OnTitleChanging(value); + this.SendPropertyChanging(); + this._title = value; + this.SendPropertyChanged("Title"); + this.OnTitleChanged(); + } + } + } + + [Column(Storage="_titleOfCourtesy", Name="TitleOfCourtesy", DbType="nvarchar (25)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string TitleOfCourtesy + { + get + { + return this._titleOfCourtesy; + } + set + { + if (((_titleOfCourtesy == value) + == false)) + { + this.OnTitleOfCourtesyChanging(value); + this.SendPropertyChanging(); + this._titleOfCourtesy = value; + this.SendPropertyChanged("TitleOfCourtesy"); + this.OnTitleOfCourtesyChanged(); + } + } + } + + #region Children + [Association(Storage="_employeeTerritories", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_EmployeeTerritories_1")] + [DebuggerNonUserCode()] + public EntitySet EmployeeTerritories + { + get + { + return this._employeeTerritories; + } + set + { + this._employeeTerritories = value; + } + } + + [Association(Storage="_employees", OtherKey="ReportsTo", ThisKey="EmployeeID", Name="fk_Employees_0")] + [DebuggerNonUserCode()] + public EntitySet Employees + { + get + { + return this._employees; + } + set + { + this._employees = value; + } + } + + [Association(Storage="_orders", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_Orders_1")] + [DebuggerNonUserCode()] + public EntitySet Orders + { + get + { + return this._orders; + } + set + { + this._orders = value; + } + } + #endregion + + #region Parents + [Association(Storage="_reportsToEmployee", OtherKey="EmployeeID", ThisKey="ReportsTo", Name="fk_Employees_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Employee ReportsToEmployee + { + get + { + return this._reportsToEmployee.Entity; + } + set + { + if (((this._reportsToEmployee.Entity == value) + == false)) + { + if ((this._reportsToEmployee.Entity != null)) + { + Employee previousEmployee = this._reportsToEmployee.Entity; + this._reportsToEmployee.Entity = null; + previousEmployee.Employees.Remove(this); + } + this._reportsToEmployee.Entity = value; + if ((value != null)) + { + value.Employees.Add(this); + _reportsTo = value.EmployeeID; + } + else + { + _reportsTo = null; + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Employee other = ((Employee)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Employee value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID); + } + + #region Attachment handlers + private void EmployeeTerritories_Attach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Employee = this; + } + + private void EmployeeTerritories_Detach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Employee = null; + } + + private void Employees_Attach(Employee entity) + { + this.SendPropertyChanging(); + entity.ReportsToEmployee = this; + } + + private void Employees_Detach(Employee entity) + { + this.SendPropertyChanging(); + entity.ReportsToEmployee = null; + } + + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Employee = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Employee = null; + } + #endregion + } + + [Table(Name="main.EmployeeTerritories")] + public partial class EmployeeTerritory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _employeeID; + + private string _territoryID; + + private EntityRef _territory = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnEmployeeIDChanged(); + + partial void OnEmployeeIDChanging(int value); + + partial void OnTerritoryIDChanged(); + + partial void OnTerritoryIDChanging(string value); + #endregion + + + public EmployeeTerritory() + { + this.OnCreated(); + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int EmployeeID + { + get + { + return this._employeeID; + } + set + { + if ((_employeeID != value)) + { + if (_employee.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); + } + } + } + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string TerritoryID + { + get + { + return this._territoryID; + } + set + { + if (((_territoryID == value) + == false)) + { + if (_territory.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); + } + } + } + + #region Parents + [Association(Storage="_territory", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="fk_EmployeeTerritories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Territory Territory + { + get + { + return this._territory.Entity; + } + set + { + if (((this._territory.Entity == value) + == false)) + { + if ((this._territory.Entity != null)) + { + Territory previousTerritory = this._territory.Entity; + this._territory.Entity = null; + previousTerritory.EmployeeTerritories.Remove(this); + } + this._territory.Entity = value; + if ((value != null)) + { + value.EmployeeTerritories.Add(this); + _territoryID = value.TerritoryID; + } + else + { + _territoryID = default(string); + } + } + } + } + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_EmployeeTerritories_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Employee Employee + { + get + { + return this._employee.Entity; + } + set + { + if (((this._employee.Entity == value) + == false)) + { + if ((this._employee.Entity != null)) + { + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; + previousEmployee.EmployeeTerritories.Remove(this); + } + this._employee.Entity = value; + if ((value != null)) + { + value.EmployeeTerritories.Add(this); + _employeeID = value.EmployeeID; + } + else + { + _employeeID = default(int); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_employeeID.GetHashCode() * 1)); + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 65536)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + EmployeeTerritory other = ((EmployeeTerritory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(EmployeeTerritory value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._employeeID, value._employeeID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID)); + } + } + + [Table(Name="main.Orders")] + public partial class Order : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _customerID; + + private System.Nullable _employeeID; + + private System.Nullable _freight; + + private System.Nullable _orderDate; + + private int _orderID; + + private System.Nullable _requiredDate; + + private string _shipAddress; + + private string _shipCity; + + private string _shipCountry; + + private string _shipName; + + private System.Nullable _shippedDate; + + private string _shipPostalCode; + + private string _shipRegion; + + private System.Nullable _shipVia; + + private EntitySet _orderDetails; + + private EntityRef _shipper = new EntityRef(); + + private EntityRef _employee = new EntityRef(); + + private EntityRef _customer = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCustomerIDChanged(); + + partial void OnCustomerIDChanging(string value); + + partial void OnEmployeeIDChanged(); + + partial void OnEmployeeIDChanging(System.Nullable value); + + partial void OnFreightChanged(); + + partial void OnFreightChanging(System.Nullable value); + + partial void OnOrderDateChanged(); + + partial void OnOrderDateChanging(System.Nullable value); + + partial void OnOrderIDChanged(); + + partial void OnOrderIDChanging(int value); + + partial void OnRequiredDateChanged(); + + partial void OnRequiredDateChanging(System.Nullable value); + + partial void OnShipAddressChanged(); + + partial void OnShipAddressChanging(string value); + + partial void OnShipCityChanged(); + + partial void OnShipCityChanging(string value); + + partial void OnShipCountryChanged(); + + partial void OnShipCountryChanging(string value); + + partial void OnShipNameChanged(); + + partial void OnShipNameChanging(string value); + + partial void OnShippedDateChanged(); + + partial void OnShippedDateChanging(System.Nullable value); + + partial void OnShipPostalCodeChanged(); + + partial void OnShipPostalCodeChanging(string value); + + partial void OnShipRegionChanged(); + + partial void OnShipRegionChanging(string value); + + partial void OnShipViaChanged(); + + partial void OnShipViaChanging(System.Nullable value); + #endregion + + + public Order() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_customerID", Name="CustomerID", DbType="nchar (5)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string CustomerID + { + get + { + return this._customerID; + } + set + { + if (((_customerID == value) + == false)) + { + if (_customer.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCustomerIDChanging(value); + this.SendPropertyChanging(); + this._customerID = value; + this.SendPropertyChanged("CustomerID"); + this.OnCustomerIDChanged(); + } + } + } + + [Column(Storage="_employeeID", Name="EmployeeID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable EmployeeID + { + get + { + return this._employeeID; + } + set + { + if ((_employeeID != value)) + { + if (_employee.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnEmployeeIDChanging(value); + this.SendPropertyChanging(); + this._employeeID = value; + this.SendPropertyChanged("EmployeeID"); + this.OnEmployeeIDChanged(); + } + } + } + + [Column(Storage="_freight", Name="Freight", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable Freight + { + get + { + return this._freight; + } + set + { + if ((_freight != value)) + { + this.OnFreightChanging(value); + this.SendPropertyChanging(); + this._freight = value; + this.SendPropertyChanged("Freight"); + this.OnFreightChanged(); + } + } + } + + [Column(Storage="_orderDate", Name="OrderDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable OrderDate + { + get + { + return this._orderDate; + } + set + { + if ((_orderDate != value)) + { + this.OnOrderDateChanging(value); + this.SendPropertyChanging(); + this._orderDate = value; + this.SendPropertyChanged("OrderDate"); + this.OnOrderDateChanged(); + } + } + } + + [Column(Storage="_orderID", Name="OrderID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int OrderID + { + get + { + return this._orderID; + } + set + { + if ((_orderID != value)) + { + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); + } + } + } + + [Column(Storage="_requiredDate", Name="RequiredDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable RequiredDate + { + get + { + return this._requiredDate; + } + set + { + if ((_requiredDate != value)) + { + this.OnRequiredDateChanging(value); + this.SendPropertyChanging(); + this._requiredDate = value; + this.SendPropertyChanged("RequiredDate"); + this.OnRequiredDateChanged(); + } + } + } + + [Column(Storage="_shipAddress", Name="ShipAddress", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipAddress + { + get + { + return this._shipAddress; + } + set + { + if (((_shipAddress == value) + == false)) + { + this.OnShipAddressChanging(value); + this.SendPropertyChanging(); + this._shipAddress = value; + this.SendPropertyChanged("ShipAddress"); + this.OnShipAddressChanged(); + } + } + } + + [Column(Storage="_shipCity", Name="ShipCity", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipCity + { + get + { + return this._shipCity; + } + set + { + if (((_shipCity == value) + == false)) + { + this.OnShipCityChanging(value); + this.SendPropertyChanging(); + this._shipCity = value; + this.SendPropertyChanged("ShipCity"); + this.OnShipCityChanged(); + } + } + } + + [Column(Storage="_shipCountry", Name="ShipCountry", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipCountry + { + get + { + return this._shipCountry; + } + set + { + if (((_shipCountry == value) + == false)) + { + this.OnShipCountryChanging(value); + this.SendPropertyChanging(); + this._shipCountry = value; + this.SendPropertyChanged("ShipCountry"); + this.OnShipCountryChanged(); + } + } + } + + [Column(Storage="_shipName", Name="ShipName", DbType="nvarchar (40)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipName + { + get + { + return this._shipName; + } + set + { + if (((_shipName == value) + == false)) + { + this.OnShipNameChanging(value); + this.SendPropertyChanging(); + this._shipName = value; + this.SendPropertyChanged("ShipName"); + this.OnShipNameChanged(); + } + } + } + + [Column(Storage="_shippedDate", Name="ShippedDate", DbType="datetime", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShippedDate + { + get + { + return this._shippedDate; + } + set + { + if ((_shippedDate != value)) + { + this.OnShippedDateChanging(value); + this.SendPropertyChanging(); + this._shippedDate = value; + this.SendPropertyChanged("ShippedDate"); + this.OnShippedDateChanged(); + } + } + } + + [Column(Storage="_shipPostalCode", Name="ShipPostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipPostalCode + { + get + { + return this._shipPostalCode; + } + set + { + if (((_shipPostalCode == value) + == false)) + { + this.OnShipPostalCodeChanging(value); + this.SendPropertyChanging(); + this._shipPostalCode = value; + this.SendPropertyChanged("ShipPostalCode"); + this.OnShipPostalCodeChanged(); + } + } + } + + [Column(Storage="_shipRegion", Name="ShipRegion", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ShipRegion + { + get + { + return this._shipRegion; + } + set + { + if (((_shipRegion == value) + == false)) + { + this.OnShipRegionChanging(value); + this.SendPropertyChanging(); + this._shipRegion = value; + this.SendPropertyChanged("ShipRegion"); + this.OnShipRegionChanged(); + } + } + } + + [Column(Storage="_shipVia", Name="ShipVia", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ShipVia + { + get + { + return this._shipVia; + } + set + { + if ((_shipVia != value)) + { + if (_shipper.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnShipViaChanging(value); + this.SendPropertyChanging(); + this._shipVia = value; + this.SendPropertyChanged("ShipVia"); + this.OnShipViaChanged(); + } + } + } + + #region Children + [Association(Storage="_orderDetails", OtherKey="OrderID", ThisKey="OrderID", Name="fk_Order Details_1")] + [DebuggerNonUserCode()] + public EntitySet OrderDetails + { + get + { + return this._orderDetails; + } + set + { + this._orderDetails = value; + } + } + #endregion + + #region Parents + [Association(Storage="_shipper", OtherKey="ShipperID", ThisKey="ShipVia", Name="fk_Orders_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Shipper Shipper + { + get + { + return this._shipper.Entity; + } + set + { + if (((this._shipper.Entity == value) + == false)) + { + if ((this._shipper.Entity != null)) + { + Shipper previousShipper = this._shipper.Entity; + this._shipper.Entity = null; + previousShipper.Orders.Remove(this); + } + this._shipper.Entity = value; + if ((value != null)) + { + value.Orders.Add(this); + _shipVia = value.ShipperID; + } + else + { + _shipVia = null; + } + } + } + } + + [Association(Storage="_employee", OtherKey="EmployeeID", ThisKey="EmployeeID", Name="fk_Orders_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Employee Employee + { + get + { + return this._employee.Entity; + } + set + { + if (((this._employee.Entity == value) + == false)) + { + if ((this._employee.Entity != null)) + { + Employee previousEmployee = this._employee.Entity; + this._employee.Entity = null; + previousEmployee.Orders.Remove(this); + } + this._employee.Entity = value; + if ((value != null)) + { + value.Orders.Add(this); + _employeeID = value.EmployeeID; + } + else + { + _employeeID = null; + } + } + } + } + + [Association(Storage="_customer", OtherKey="CustomerID", ThisKey="CustomerID", Name="fk_Orders_2", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Customer Customer + { + get + { + return this._customer.Entity; + } + set + { + if (((this._customer.Entity == value) + == false)) + { + if ((this._customer.Entity != null)) + { + Customer previousCustomer = this._customer.Entity; + this._customer.Entity = null; + previousCustomer.Orders.Remove(this); + } + this._customer.Entity = value; + if ((value != null)) + { + value.Orders.Add(this); + _customerID = value.CustomerID; + } + else + { + _customerID = null; + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Order other = ((Order)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Order value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Order = null; + } + #endregion + } + + [Table(Name="main.Order Details")] + public partial class OrderDetail : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private float _discount; + + private int _orderID; + + private int _productID; + + private short _quantity; + + private decimal _unitPrice; + + private EntityRef _product = new EntityRef(); + + private EntityRef _order = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnDiscountChanged(); + + partial void OnDiscountChanging(float value); + + partial void OnOrderIDChanged(); + + partial void OnOrderIDChanging(int value); + + partial void OnProductIDChanged(); + + partial void OnProductIDChanging(int value); + + partial void OnQuantityChanged(); + + partial void OnQuantityChanging(short value); + + partial void OnUnitPriceChanged(); + + partial void OnUnitPriceChanging(decimal value); + #endregion + + + public OrderDetail() + { + this.OnCreated(); + } + + [Column(Storage="_discount", Name="Discount", DbType="real", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public float Discount + { + get + { + return this._discount; + } + set + { + if ((_discount != value)) + { + this.OnDiscountChanging(value); + this.SendPropertyChanging(); + this._discount = value; + this.SendPropertyChanged("Discount"); + this.OnDiscountChanged(); + } + } + } + + [Column(Storage="_orderID", Name="OrderID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int OrderID + { + get + { + return this._orderID; + } + set + { + if ((_orderID != value)) + { + if (_order.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnOrderIDChanging(value); + this.SendPropertyChanging(); + this._orderID = value; + this.SendPropertyChanged("OrderID"); + this.OnOrderIDChanged(); + } + } + } + + [Column(Storage="_productID", Name="ProductID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int ProductID + { + get + { + return this._productID; + } + set + { + if ((_productID != value)) + { + if (_product.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); + } + } + } + + [Column(Storage="_quantity", Name="Quantity", DbType="smallint", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public short Quantity + { + get + { + return this._quantity; + } + set + { + if ((_quantity != value)) + { + this.OnQuantityChanging(value); + this.SendPropertyChanging(); + this._quantity = value; + this.SendPropertyChanged("Quantity"); + this.OnQuantityChanged(); + } + } + } + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public decimal UnitPrice + { + get + { + return this._unitPrice; + } + set + { + if ((_unitPrice != value)) + { + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); + } + } + } + + #region Parents + [Association(Storage="_product", OtherKey="ProductID", ThisKey="ProductID", Name="fk_Order Details_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Product Product + { + get + { + return this._product.Entity; + } + set + { + if (((this._product.Entity == value) + == false)) + { + if ((this._product.Entity != null)) + { + Product previousProduct = this._product.Entity; + this._product.Entity = null; + previousProduct.OrderDetails.Remove(this); + } + this._product.Entity = value; + if ((value != null)) + { + value.OrderDetails.Add(this); + _productID = value.ProductID; + } + else + { + _productID = default(int); + } + } + } + } + + [Association(Storage="_order", OtherKey="OrderID", ThisKey="OrderID", Name="fk_Order Details_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Order Order + { + get + { + return this._order.Entity; + } + set + { + if (((this._order.Entity == value) + == false)) + { + if ((this._order.Entity != null)) + { + Order previousOrder = this._order.Entity; + this._order.Entity = null; + previousOrder.OrderDetails.Remove(this); + } + this._order.Entity = value; + if ((value != null)) + { + value.OrderDetails.Add(this); + _orderID = value.OrderID; + } + else + { + _orderID = default(int); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_orderID.GetHashCode() * 1)); + hc = (hc + | (_productID.GetHashCode() * 65536)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + OrderDetail other = ((OrderDetail)(value)); + return this.Equals(other); + } + + public virtual bool Equals(OrderDetail value) + { + if ((value == null)) + { + return false; + } + return (System.Collections.Generic.EqualityComparer.Default.Equals(this._orderID, value._orderID) && System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID)); + } + } + + [Table(Name="main.Products")] + public partial class Product : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private System.Nullable _categoryID; + + private bool _discontinued; + + private int _productID; + + private string _productName; + + private string _quantityPerUnit; + + private System.Nullable _reorderLevel; + + private System.Nullable _supplierID; + + private System.Nullable _unitPrice; + + private System.Nullable _unitsInStock; + + private System.Nullable _unitsOnOrder; + + private EntitySet _orderDetails; + + private EntityRef _supplier = new EntityRef(); + + private EntityRef _category = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCategoryIDChanged(); + + partial void OnCategoryIDChanging(System.Nullable value); + + partial void OnDiscontinuedChanged(); + + partial void OnDiscontinuedChanging(bool value); + + partial void OnProductIDChanged(); + + partial void OnProductIDChanging(int value); + + partial void OnProductNameChanged(); + + partial void OnProductNameChanging(string value); + + partial void OnQuantityPerUnitChanged(); + + partial void OnQuantityPerUnitChanging(string value); + + partial void OnReorderLevelChanged(); + + partial void OnReorderLevelChanging(System.Nullable value); + + partial void OnSupplierIDChanged(); + + partial void OnSupplierIDChanging(System.Nullable value); + + partial void OnUnitPriceChanged(); + + partial void OnUnitPriceChanging(System.Nullable value); + + partial void OnUnitsInStockChanged(); + + partial void OnUnitsInStockChanging(System.Nullable value); + + partial void OnUnitsOnOrderChanged(); + + partial void OnUnitsOnOrderChanging(System.Nullable value); + #endregion + + + public Product() + { + _orderDetails = new EntitySet(new Action(this.OrderDetails_Attach), new Action(this.OrderDetails_Detach)); + this.OnCreated(); + } + + [Column(Storage="_categoryID", Name="CategoryID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable CategoryID + { + get + { + return this._categoryID; + } + set + { + if ((_categoryID != value)) + { + if (_category.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnCategoryIDChanging(value); + this.SendPropertyChanging(); + this._categoryID = value; + this.SendPropertyChanged("CategoryID"); + this.OnCategoryIDChanged(); + } + } + } + + [Column(Storage="_discontinued", Name="Discontinued", DbType="bit", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public bool Discontinued + { + get + { + return this._discontinued; + } + set + { + if ((_discontinued != value)) + { + this.OnDiscontinuedChanging(value); + this.SendPropertyChanging(); + this._discontinued = value; + this.SendPropertyChanged("Discontinued"); + this.OnDiscontinuedChanged(); + } + } + } + + [Column(Storage="_productID", Name="ProductID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int ProductID + { + get + { + return this._productID; + } + set + { + if ((_productID != value)) + { + this.OnProductIDChanging(value); + this.SendPropertyChanging(); + this._productID = value; + this.SendPropertyChanged("ProductID"); + this.OnProductIDChanged(); + } + } + } + + [Column(Storage="_productName", Name="ProductName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string ProductName + { + get + { + return this._productName; + } + set + { + if (((_productName == value) + == false)) + { + this.OnProductNameChanging(value); + this.SendPropertyChanging(); + this._productName = value; + this.SendPropertyChanged("ProductName"); + this.OnProductNameChanged(); + } + } + } + + [Column(Storage="_quantityPerUnit", Name="QuantityPerUnit", DbType="nvarchar (20)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string QuantityPerUnit + { + get + { + return this._quantityPerUnit; + } + set + { + if (((_quantityPerUnit == value) + == false)) + { + this.OnQuantityPerUnitChanging(value); + this.SendPropertyChanging(); + this._quantityPerUnit = value; + this.SendPropertyChanged("QuantityPerUnit"); + this.OnQuantityPerUnitChanged(); + } + } + } + + [Column(Storage="_reorderLevel", Name="ReorderLevel", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable ReorderLevel + { + get + { + return this._reorderLevel; + } + set + { + if ((_reorderLevel != value)) + { + this.OnReorderLevelChanging(value); + this.SendPropertyChanging(); + this._reorderLevel = value; + this.SendPropertyChanged("ReorderLevel"); + this.OnReorderLevelChanged(); + } + } + } + + [Column(Storage="_supplierID", Name="SupplierID", DbType="INTEGER", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable SupplierID + { + get + { + return this._supplierID; + } + set + { + if ((_supplierID != value)) + { + if (_supplier.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); + } + } + } + + [Column(Storage="_unitPrice", Name="UnitPrice", DbType="money", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitPrice + { + get + { + return this._unitPrice; + } + set + { + if ((_unitPrice != value)) + { + this.OnUnitPriceChanging(value); + this.SendPropertyChanging(); + this._unitPrice = value; + this.SendPropertyChanged("UnitPrice"); + this.OnUnitPriceChanged(); + } + } + } + + [Column(Storage="_unitsInStock", Name="UnitsInStock", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsInStock + { + get + { + return this._unitsInStock; + } + set + { + if ((_unitsInStock != value)) + { + this.OnUnitsInStockChanging(value); + this.SendPropertyChanging(); + this._unitsInStock = value; + this.SendPropertyChanged("UnitsInStock"); + this.OnUnitsInStockChanged(); + } + } + } + + [Column(Storage="_unitsOnOrder", Name="UnitsOnOrder", DbType="smallint", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public System.Nullable UnitsOnOrder + { + get + { + return this._unitsOnOrder; + } + set + { + if ((_unitsOnOrder != value)) + { + this.OnUnitsOnOrderChanging(value); + this.SendPropertyChanging(); + this._unitsOnOrder = value; + this.SendPropertyChanged("UnitsOnOrder"); + this.OnUnitsOnOrderChanged(); + } + } + } + + #region Children + [Association(Storage="_orderDetails", OtherKey="ProductID", ThisKey="ProductID", Name="fk_Order Details_0")] + [DebuggerNonUserCode()] + public EntitySet OrderDetails + { + get + { + return this._orderDetails; + } + set + { + this._orderDetails = value; + } + } + #endregion + + #region Parents + [Association(Storage="_supplier", OtherKey="SupplierID", ThisKey="SupplierID", Name="fk_Products_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Supplier Supplier + { + get + { + return this._supplier.Entity; + } + set + { + if (((this._supplier.Entity == value) + == false)) + { + if ((this._supplier.Entity != null)) + { + Supplier previousSupplier = this._supplier.Entity; + this._supplier.Entity = null; + previousSupplier.Products.Remove(this); + } + this._supplier.Entity = value; + if ((value != null)) + { + value.Products.Add(this); + _supplierID = value.SupplierID; + } + else + { + _supplierID = null; + } + } + } + } + + [Association(Storage="_category", OtherKey="CategoryID", ThisKey="CategoryID", Name="fk_Products_1", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Category Category + { + get + { + return this._category.Entity; + } + set + { + if (((this._category.Entity == value) + == false)) + { + if ((this._category.Entity != null)) + { + Category previousCategory = this._category.Entity; + this._category.Entity = null; + previousCategory.Products.Remove(this); + } + this._category.Entity = value; + if ((value != null)) + { + value.Products.Add(this); + _categoryID = value.CategoryID; + } + else + { + _categoryID = null; + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_productID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Product other = ((Product)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Product value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._productID, value._productID); + } + + #region Attachment handlers + private void OrderDetails_Attach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = this; + } + + private void OrderDetails_Detach(OrderDetail entity) + { + this.SendPropertyChanging(); + entity.Product = null; + } + #endregion + } + + [Table(Name="main.Region")] + public partial class Region : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _regionDescription; + + private int _regionID; + + private EntitySet _territories; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnRegionDescriptionChanged(); + + partial void OnRegionDescriptionChanging(string value); + + partial void OnRegionIDChanged(); + + partial void OnRegionIDChanging(int value); + #endregion + + + public Region() + { + _territories = new EntitySet(new Action(this.Territories_Attach), new Action(this.Territories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionDescription", Name="RegionDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string RegionDescription + { + get + { + return this._regionDescription; + } + set + { + if (((_regionDescription == value) + == false)) + { + this.OnRegionDescriptionChanging(value); + this.SendPropertyChanging(); + this._regionDescription = value; + this.SendPropertyChanged("RegionDescription"); + this.OnRegionDescriptionChanged(); + } + } + } + + [Column(Storage="_regionID", Name="RegionID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int RegionID + { + get + { + return this._regionID; + } + set + { + if ((_regionID != value)) + { + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); + } + } + } + + #region Children + [Association(Storage="_territories", OtherKey="RegionID", ThisKey="RegionID", Name="fk_Territories_0")] + [DebuggerNonUserCode()] + public EntitySet Territories + { + get + { + return this._territories; + } + set + { + this._territories = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_regionID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Region other = ((Region)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Region value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._regionID, value._regionID); + } + + #region Attachment handlers + private void Territories_Attach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = this; + } + + private void Territories_Detach(Territory entity) + { + this.SendPropertyChanging(); + entity.Region = null; + } + #endregion + } + + [Table(Name="main.Shippers")] + public partial class Shipper : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _companyName; + + private string _phone; + + private int _shipperID; + + private EntitySet _orders; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnCompanyNameChanged(); + + partial void OnCompanyNameChanging(string value); + + partial void OnPhoneChanged(); + + partial void OnPhoneChanging(string value); + + partial void OnShipperIDChanged(); + + partial void OnShipperIDChanging(int value); + #endregion + + + public Shipper() + { + _orders = new EntitySet(new Action(this.Orders_Attach), new Action(this.Orders_Detach)); + this.OnCreated(); + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CompanyName + { + get + { + return this._companyName; + } + set + { + if (((_companyName == value) + == false)) + { + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); + } + } + } + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Phone + { + get + { + return this._phone; + } + set + { + if (((_phone == value) + == false)) + { + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); + } + } + } + + [Column(Storage="_shipperID", Name="ShipperID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int ShipperID + { + get + { + return this._shipperID; + } + set + { + if ((_shipperID != value)) + { + this.OnShipperIDChanging(value); + this.SendPropertyChanging(); + this._shipperID = value; + this.SendPropertyChanged("ShipperID"); + this.OnShipperIDChanged(); + } + } + } + + #region Children + [Association(Storage="_orders", OtherKey="ShipVia", ThisKey="ShipperID", Name="fk_Orders_0")] + [DebuggerNonUserCode()] + public EntitySet Orders + { + get + { + return this._orders; + } + set + { + this._orders = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_shipperID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Shipper other = ((Shipper)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Shipper value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._shipperID, value._shipperID); + } + + #region Attachment handlers + private void Orders_Attach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = this; + } + + private void Orders_Detach(Order entity) + { + this.SendPropertyChanging(); + entity.Shipper = null; + } + #endregion + } + + [Table(Name="main.Suppliers")] + public partial class Supplier : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private string _address; + + private string _city; + + private string _companyName; + + private string _contactName; + + private string _contactTitle; + + private string _country; + + private string _fax; + + private string _homePage; + + private string _phone; + + private string _postalCode; + + private string _region; + + private int _supplierID; + + private EntitySet _products; + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnAddressChanged(); + + partial void OnAddressChanging(string value); + + partial void OnCityChanged(); + + partial void OnCityChanging(string value); + + partial void OnCompanyNameChanged(); + + partial void OnCompanyNameChanging(string value); + + partial void OnContactNameChanged(); + + partial void OnContactNameChanging(string value); + + partial void OnContactTitleChanged(); + + partial void OnContactTitleChanging(string value); + + partial void OnCountryChanged(); + + partial void OnCountryChanging(string value); + + partial void OnFaxChanged(); + + partial void OnFaxChanging(string value); + + partial void OnHomePageChanged(); + + partial void OnHomePageChanging(string value); + + partial void OnPhoneChanged(); + + partial void OnPhoneChanging(string value); + + partial void OnPostalCodeChanged(); + + partial void OnPostalCodeChanging(string value); + + partial void OnRegionChanged(); + + partial void OnRegionChanging(string value); + + partial void OnSupplierIDChanged(); + + partial void OnSupplierIDChanging(int value); + #endregion + + + public Supplier() + { + _products = new EntitySet(new Action(this.Products_Attach), new Action(this.Products_Detach)); + this.OnCreated(); + } + + [Column(Storage="_address", Name="Address", DbType="nvarchar (60)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Address + { + get + { + return this._address; + } + set + { + if (((_address == value) + == false)) + { + this.OnAddressChanging(value); + this.SendPropertyChanging(); + this._address = value; + this.SendPropertyChanged("Address"); + this.OnAddressChanged(); + } + } + } + + [Column(Storage="_city", Name="City", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string City + { + get + { + return this._city; + } + set + { + if (((_city == value) + == false)) + { + this.OnCityChanging(value); + this.SendPropertyChanging(); + this._city = value; + this.SendPropertyChanged("City"); + this.OnCityChanged(); + } + } + } + + [Column(Storage="_companyName", Name="CompanyName", DbType="nvarchar (40)", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string CompanyName + { + get + { + return this._companyName; + } + set + { + if (((_companyName == value) + == false)) + { + this.OnCompanyNameChanging(value); + this.SendPropertyChanging(); + this._companyName = value; + this.SendPropertyChanged("CompanyName"); + this.OnCompanyNameChanged(); + } + } + } + + [Column(Storage="_contactName", Name="ContactName", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactName + { + get + { + return this._contactName; + } + set + { + if (((_contactName == value) + == false)) + { + this.OnContactNameChanging(value); + this.SendPropertyChanging(); + this._contactName = value; + this.SendPropertyChanged("ContactName"); + this.OnContactNameChanged(); + } + } + } + + [Column(Storage="_contactTitle", Name="ContactTitle", DbType="nvarchar (30)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string ContactTitle + { + get + { + return this._contactTitle; + } + set + { + if (((_contactTitle == value) + == false)) + { + this.OnContactTitleChanging(value); + this.SendPropertyChanging(); + this._contactTitle = value; + this.SendPropertyChanged("ContactTitle"); + this.OnContactTitleChanged(); + } + } + } + + [Column(Storage="_country", Name="Country", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Country + { + get + { + return this._country; + } + set + { + if (((_country == value) + == false)) + { + this.OnCountryChanging(value); + this.SendPropertyChanging(); + this._country = value; + this.SendPropertyChanged("Country"); + this.OnCountryChanged(); + } + } + } + + [Column(Storage="_fax", Name="Fax", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Fax + { + get + { + return this._fax; + } + set + { + if (((_fax == value) + == false)) + { + this.OnFaxChanging(value); + this.SendPropertyChanging(); + this._fax = value; + this.SendPropertyChanged("Fax"); + this.OnFaxChanged(); + } + } + } + + [Column(Storage="_homePage", Name="HomePage", DbType="ntext", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string HomePage + { + get + { + return this._homePage; + } + set + { + if (((_homePage == value) + == false)) + { + this.OnHomePageChanging(value); + this.SendPropertyChanging(); + this._homePage = value; + this.SendPropertyChanged("HomePage"); + this.OnHomePageChanged(); + } + } + } + + [Column(Storage="_phone", Name="Phone", DbType="nvarchar (24)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Phone + { + get + { + return this._phone; + } + set + { + if (((_phone == value) + == false)) + { + this.OnPhoneChanging(value); + this.SendPropertyChanging(); + this._phone = value; + this.SendPropertyChanged("Phone"); + this.OnPhoneChanged(); + } + } + } + + [Column(Storage="_postalCode", Name="PostalCode", DbType="nvarchar (10)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string PostalCode + { + get + { + return this._postalCode; + } + set + { + if (((_postalCode == value) + == false)) + { + this.OnPostalCodeChanging(value); + this.SendPropertyChanging(); + this._postalCode = value; + this.SendPropertyChanged("PostalCode"); + this.OnPostalCodeChanged(); + } + } + } + + [Column(Storage="_region", Name="Region", DbType="nvarchar (15)", AutoSync=AutoSync.Never)] + [DebuggerNonUserCode()] + public string Region + { + get + { + return this._region; + } + set + { + if (((_region == value) + == false)) + { + this.OnRegionChanging(value); + this.SendPropertyChanging(); + this._region = value; + this.SendPropertyChanged("Region"); + this.OnRegionChanged(); + } + } + } + + [Column(Storage="_supplierID", Name="SupplierID", DbType="INTEGER", IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int SupplierID + { + get + { + return this._supplierID; + } + set + { + if ((_supplierID != value)) + { + this.OnSupplierIDChanging(value); + this.SendPropertyChanging(); + this._supplierID = value; + this.SendPropertyChanged("SupplierID"); + this.OnSupplierIDChanged(); + } + } + } + + #region Children + [Association(Storage="_products", OtherKey="SupplierID", ThisKey="SupplierID", Name="fk_Products_0")] + [DebuggerNonUserCode()] + public EntitySet Products + { + get + { + return this._products; + } + set + { + this._products = value; + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + hc = (hc + | (_supplierID.GetHashCode() * 1)); + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Supplier other = ((Supplier)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Supplier value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._supplierID, value._supplierID); + } + + #region Attachment handlers + private void Products_Attach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = this; + } + + private void Products_Detach(Product entity) + { + this.SendPropertyChanging(); + entity.Supplier = null; + } + #endregion + } + + [Table(Name="main.Territories")] + public partial class Territory : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged, System.IEquatable + { + + private static System.ComponentModel.PropertyChangingEventArgs emptyChangingEventArgs = new System.ComponentModel.PropertyChangingEventArgs(""); + + private int _regionID; + + private string _territoryDescription; + + private string _territoryID; + + private EntitySet _employeeTerritories; + + private EntityRef _region = new EntityRef(); + + #region Extensibility Method Declarations + partial void OnCreated(); + + partial void OnRegionIDChanged(); + + partial void OnRegionIDChanging(int value); + + partial void OnTerritoryDescriptionChanged(); + + partial void OnTerritoryDescriptionChanging(string value); + + partial void OnTerritoryIDChanged(); + + partial void OnTerritoryIDChanging(string value); + #endregion + + + public Territory() + { + _employeeTerritories = new EntitySet(new Action(this.EmployeeTerritories_Attach), new Action(this.EmployeeTerritories_Detach)); + this.OnCreated(); + } + + [Column(Storage="_regionID", Name="RegionID", DbType="INTEGER", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public int RegionID + { + get + { + return this._regionID; + } + set + { + if ((_regionID != value)) + { + if (_region.HasLoadedOrAssignedValue) + { + throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); + } + this.OnRegionIDChanging(value); + this.SendPropertyChanging(); + this._regionID = value; + this.SendPropertyChanged("RegionID"); + this.OnRegionIDChanged(); + } + } + } + + [Column(Storage="_territoryDescription", Name="TerritoryDescription", DbType="nchar", AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string TerritoryDescription + { + get + { + return this._territoryDescription; + } + set + { + if (((_territoryDescription == value) + == false)) + { + this.OnTerritoryDescriptionChanging(value); + this.SendPropertyChanging(); + this._territoryDescription = value; + this.SendPropertyChanged("TerritoryDescription"); + this.OnTerritoryDescriptionChanged(); + } + } + } + + [Column(Storage="_territoryID", Name="TerritoryID", DbType="nvarchar", IsPrimaryKey=true, AutoSync=AutoSync.Never, CanBeNull=false)] + [DebuggerNonUserCode()] + public string TerritoryID + { + get + { + return this._territoryID; + } + set + { + if (((_territoryID == value) + == false)) + { + this.OnTerritoryIDChanging(value); + this.SendPropertyChanging(); + this._territoryID = value; + this.SendPropertyChanged("TerritoryID"); + this.OnTerritoryIDChanged(); + } + } + } + + #region Children + [Association(Storage="_employeeTerritories", OtherKey="TerritoryID", ThisKey="TerritoryID", Name="fk_EmployeeTerritories_0")] + [DebuggerNonUserCode()] + public EntitySet EmployeeTerritories + { + get + { + return this._employeeTerritories; + } + set + { + this._employeeTerritories = value; + } + } + #endregion + + #region Parents + [Association(Storage="_region", OtherKey="RegionID", ThisKey="RegionID", Name="fk_Territories_0", IsForeignKey=true)] + [DebuggerNonUserCode()] + public Region Region + { + get + { + return this._region.Entity; + } + set + { + if (((this._region.Entity == value) + == false)) + { + if ((this._region.Entity != null)) + { + Region previousRegion = this._region.Entity; + this._region.Entity = null; + previousRegion.Territories.Remove(this); + } + this._region.Entity = value; + if ((value != null)) + { + value.Territories.Add(this); + _regionID = value.RegionID; + } + else + { + _regionID = default(int); + } + } + } + } + #endregion + + public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging; + + public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; + + protected virtual void SendPropertyChanging() + { + System.ComponentModel.PropertyChangingEventHandler h = this.PropertyChanging; + if ((h != null)) + { + h(this, emptyChangingEventArgs); + } + } + + protected virtual void SendPropertyChanged(string propertyName) + { + System.ComponentModel.PropertyChangedEventHandler h = this.PropertyChanged; + if ((h != null)) + { + h(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); + } + } + + public override int GetHashCode() + { + int hc = 0; + if ((_territoryID != null)) + { + hc = (hc + | (_territoryID.GetHashCode() * 1)); + } + return hc; + } + + public override bool Equals(object value) + { + if ((value == null)) + { + return false; + } + if (((value.GetType() == this.GetType()) + == false)) + { + return false; + } + Territory other = ((Territory)(value)); + return this.Equals(other); + } + + public virtual bool Equals(Territory value) + { + if ((value == null)) + { + return false; + } + return System.Collections.Generic.EqualityComparer.Default.Equals(this._territoryID, value._territoryID); + } + + #region Attachment handlers + private void EmployeeTerritories_Attach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Territory = this; + } + + private void EmployeeTerritories_Detach(EmployeeTerritory entity) + { + this.SendPropertyChanging(); + entity.Territory = null; + } + #endregion + } +} diff --git a/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-sqlmetal.dbml b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-sqlmetal.dbml new file mode 100755 index 00000000000..62f31893e02 --- /dev/null +++ b/mcs/class/System.Data.Linq/tests/expected/Northwind.Sqlite-sqlmetal.dbml @@ -0,0 +1,169 @@ + + + + + + + + + + +
+ + + + + + + +
+ + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
\ No newline at end of file diff --git a/mcs/class/System.Data.Services/ChangeLog b/mcs/class/System.Data.Services/ChangeLog index 22dccc68f7a..0842a2ae138 100644 --- a/mcs/class/System.Data.Services/ChangeLog +++ b/mcs/class/System.Data.Services/ChangeLog @@ -1,3 +1,7 @@ +2010-04-03 Jb Evain + + * Makefile: System.Data.Services is a .net 3.5 assembly. + 2009-11-07 Zoltan Varga *: Move .cs files to the System.Data.Services subdir to match their namespace, diff --git a/mcs/class/System.Data.Services/Makefile b/mcs/class/System.Data.Services/Makefile index cb4482befcb..db307f0e67a 100644 --- a/mcs/class/System.Data.Services/Makefile +++ b/mcs/class/System.Data.Services/Makefile @@ -7,7 +7,8 @@ LIBRARY = System.Data.Services.dll LIBRARY_SNK = ../mono.snk LIBRARY_PACKAGE = none -LIB_MCS_FLAGS = \ +LIB_MCS_FLAGS = \ + -d:NET_3_5 \ -r:System.dll \ -r:System.Core.dll \ -r:System.ServiceModel.dll \ diff --git a/mcs/class/System.Data/System.Data.Common/ChangeLog b/mcs/class/System.Data/System.Data.Common/ChangeLog index 5f732499b2a..dbab2e7dbd1 100644 --- a/mcs/class/System.Data/System.Data.Common/ChangeLog +++ b/mcs/class/System.Data/System.Data.Common/ChangeLog @@ -1,3 +1,10 @@ +2010-03-26 Veerapuram Varadhan + + ** Fixes #564833/580736 + * DbDataAdapter.cs (*Command): Fix for .NET compatibility which + supports both type of adapters with/without discrete command + instances. + 2009-10-28 Veerapuram Varadhan ** Fixes #385028/#385029 diff --git a/mcs/class/System.Data/System.Data.Common/DbDataAdapter.cs b/mcs/class/System.Data/System.Data.Common/DbDataAdapter.cs index f6699ea93b3..3fdc3ca1105 100644 --- a/mcs/class/System.Data/System.Data.Common/DbDataAdapter.cs +++ b/mcs/class/System.Data/System.Data.Common/DbDataAdapter.cs @@ -85,51 +85,83 @@ namespace System.Data.Common } IDbCommand IDbDataAdapter.SelectCommand { - get { return _selectCommand; } - set { _selectCommand = value; } + get { return ((DbDataAdapter)this).SelectCommand; } + set { ((DbDataAdapter)this).SelectCommand = (DbCommand)value; } } IDbCommand IDbDataAdapter.UpdateCommand{ - get { return _updateCommand; } - set { _updateCommand = value; } + get { return ((DbDataAdapter)this).UpdateCommand; } + set { ((DbDataAdapter)this).UpdateCommand = (DbCommand)value; } } - + IDbCommand IDbDataAdapter.DeleteCommand{ - get { return _deleteCommand; } - set { _deleteCommand = value; } + get { return ((DbDataAdapter)this).DeleteCommand; } + set { ((DbDataAdapter)this).DeleteCommand = (DbCommand)value; } } IDbCommand IDbDataAdapter.InsertCommand{ - get { return _insertCommand; } - set { _insertCommand = value; } + get { return ((DbDataAdapter)this).InsertCommand; } + set { ((DbDataAdapter)this).InsertCommand = (DbCommand)value; } } [Browsable (false)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public DbCommand SelectCommand { - get { return (DbCommand) _selectCommand; } - set { _selectCommand = value; } + get { + return (DbCommand) _selectCommand; + //return (DbCommand) ((IDbDataAdapter)this).SelectCommand; + } + set { + if (_selectCommand != value) { + _selectCommand = value; + ((IDbDataAdapter)this).SelectCommand = value; + } + } } [Browsable (false)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public DbCommand DeleteCommand { - get { return (DbCommand) _deleteCommand; } - set { _deleteCommand = value; } + get { + return (DbCommand) _deleteCommand; + //return (DbCommand) ((IDbDataAdapter)this).DeleteCommand; + } + set { + if (_deleteCommand != value) { + _deleteCommand = value; + ((IDbDataAdapter)this).DeleteCommand = value; + } + } } [Browsable (false)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public DbCommand InsertCommand { - get { return (DbCommand)_insertCommand; } - set { _insertCommand = value; } + get { + return (DbCommand) _insertCommand; + //return (DbCommand) ((IDbDataAdapter)this).InsertCommand; + } + set { + if (_insertCommand != value) { + _insertCommand = value; + ((IDbDataAdapter)this).InsertCommand = value; + } + } } [Browsable (false)] [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] public DbCommand UpdateCommand { - get { return (DbCommand)_updateCommand; } - set { _updateCommand = value; } + get { + return (DbCommand) _updateCommand; + //return (DbCommand) ((IDbDataAdapter)this).DeleteCommand; + } + set { + if (_updateCommand != value) { + _updateCommand = value; + ((IDbDataAdapter)this).UpdateCommand = value; + } + } } [DefaultValue (1)] diff --git a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog index 09279a138a9..658095b3926 100644 --- a/mcs/class/System.Data/System.Data.SqlClient/ChangeLog +++ b/mcs/class/System.Data/System.Data.SqlClient/ChangeLog @@ -1,3 +1,7 @@ +2010-03-26 Veerapuram Varadhan + + * SqlDataAdapter.cs: 2.0 profile changes + 2009-12-03 Jonathan Pobst * SortOrder.cs: Add enum. diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlDataAdapter.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlDataAdapter.cs index d14df461f0a..a8bc4aef436 100644 --- a/mcs/class/System.Data/System.Data.SqlClient/SqlDataAdapter.cs +++ b/mcs/class/System.Data/System.Data.SqlClient/SqlDataAdapter.cs @@ -97,11 +97,7 @@ namespace System.Data.SqlClient { #endif [DefaultValue (null)] [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DBCommandEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )] - public -#if ONLY_1_1 - new -#endif - SqlCommand DeleteCommand { + public new SqlCommand DeleteCommand { get { #if NET_2_0 return (SqlCommand)base.DeleteCommand; @@ -123,11 +119,7 @@ namespace System.Data.SqlClient { #endif [DefaultValue (null)] [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DBCommandEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )] - public -#if ONLY_1_1 - new -#endif - SqlCommand InsertCommand { + public new SqlCommand InsertCommand { get { #if NET_2_0 return (SqlCommand)base.InsertCommand; @@ -149,11 +141,7 @@ namespace System.Data.SqlClient { #endif [DefaultValue (null)] [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DBCommandEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )] - public -#if ONLY_1_1 - new -#endif - SqlCommand SelectCommand { + public new SqlCommand SelectCommand { get { #if NET_2_0 return (SqlCommand)base.SelectCommand; @@ -175,11 +163,7 @@ namespace System.Data.SqlClient { #endif [DefaultValue (null)] [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DBCommandEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )] - public -#if ONLY_1_1 - new -#endif - SqlCommand UpdateCommand { + public new SqlCommand UpdateCommand { get { #if NET_2_0 return (SqlCommand)base.UpdateCommand; diff --git a/mcs/class/System.Data/System.Data/ChangeLog b/mcs/class/System.Data/System.Data/ChangeLog index 666aa0f4dc5..82240e38714 100644 --- a/mcs/class/System.Data/System.Data/ChangeLog +++ b/mcs/class/System.Data/System.Data/ChangeLog @@ -1,3 +1,25 @@ +2010-04-11 Veerapuram Varadhan + + ** Fixes #591443 + * DataColumn.cs (Clone): Use propert to clone Expression as it builds + compiled expression also, if any. + +2010-04-10 Veerapuram Varadhan + + ** Fixes #589482 + * DataColumn.cs (set_DataType): Preserve autoIncrement value + for Decimal types as well. + +2010-04-09 Veerapuram Varadhan + + ** Fixes #576520 - Based on a patch by Greg SIROU + * DataSet.cs (WriteColumnAsElement): Handle system.object types sanely. + +2010-04-09 Veerapuram Varadhan + + ** Fixes #590232 + * DataColumn.cs (Clone): Clone extended properties as well + 2010-02-10 Marek Habersack * XmlSchemaDataImporter.cs: the element might be diff --git a/mcs/class/System.Data/System.Data/DataColumn.cs b/mcs/class/System.Data/System.Data/DataColumn.cs index ecdc4a5f194..f5d84c56220 100644 --- a/mcs/class/System.Data/System.Data/DataColumn.cs +++ b/mcs/class/System.Data/System.Data/DataColumn.cs @@ -405,15 +405,9 @@ namespace System.Data { //Check AutoIncrement status, make compatible datatype if(AutoIncrement == true) { - // we want to check that the datatype is supported? - // TODO: Is this the same as CanAutoIncrement or was the omission of Decimal intended? - TypeCode typeCode = Type.GetTypeCode(value); - - if (typeCode != TypeCode.Int16 && - typeCode != TypeCode.Int32 && - typeCode != TypeCode.Int64) { + // we want to check that the datatype is supported? + if (!CanAutoIncrement (value)) AutoIncrement = false; - } } if (DefaultValue != GetDefaultValueForType (prevType)) @@ -707,7 +701,8 @@ namespace System.Data { //Copy.Container copy.DataType = DataType; copy._defaultValue = _defaultValue; - copy._expression = _expression; + // Use the property to set the expression as it updates compiledExpression, if any. + copy.Expression = _expression; //Copy.ExtendedProperties copy._maxLength = _maxLength; copy._nameSpace = _nameSpace; @@ -720,6 +715,7 @@ namespace System.Data { if (DataType == typeof (DateTime)) copy.DateTimeMode = _datetimeMode; #endif + copy._extendedProperties = _extendedProperties; return copy; } diff --git a/mcs/class/System.Data/System.Data/DataSet.cs b/mcs/class/System.Data/System.Data/DataSet.cs index cb447a2c41c..b62aff1e4d7 100644 --- a/mcs/class/System.Data/System.Data/DataSet.cs +++ b/mcs/class/System.Data/System.Data/DataSet.cs @@ -1402,8 +1402,12 @@ namespace System.Data //TODO check if I can get away with write element string WriteStartElement (writer, mode, colnspc, col.Prefix, XmlHelper.Encode (col.ColumnName)); - if (typeof (IXmlSerializable).IsAssignableFrom (col.DataType)) { - ((IXmlSerializable)rowObject).WriteXml (writer); + if (typeof (IXmlSerializable).IsAssignableFrom (col.DataType) + || col.DataType == typeof (object)) { + IXmlSerializable serializableObj = rowObject as IXmlSerializable; + if (serializableObj == null) + throw new InvalidOperationException (); + ((IXmlSerializable)rowObject).WriteXml (writer); } else { writer.WriteString (WriteObjectXml (rowObject)); } diff --git a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog index ef4dab6eb63..579c7219b68 100644 --- a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog +++ b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/ChangeLog @@ -1,3 +1,7 @@ +2010-04-21 Veerapuram Varadhan + + * SqlParameterTest.cs: Add test for bug#595918. + 2009-08-01 Gert Driesen * SqlDataReaderTest.cs: Fixes for SQL Server 7.0 / TDS 7. Avoid diff --git a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlParameterTest.cs b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlParameterTest.cs index e0e987246cd..f521d3e369e 100644 --- a/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlParameterTest.cs +++ b/mcs/class/System.Data/Test/ProviderTests/System.Data.SqlClient/SqlParameterTest.cs @@ -402,6 +402,96 @@ namespace MonoTests.System.Data.SqlClient } } + [Test] // bug #595918 + public void DecimalDefaultScaleTest () + { + string create_tbl = "CREATE TABLE #decimalScaleCheck (decsclcheck DECIMAL (19, 5) null)"; + string create_sp = "CREATE PROCEDURE #sp_bug595918(@decsclcheck decimal(19,5) OUT)" + + "AS " + Environment.NewLine + + "BEGIN" + Environment.NewLine + + "INSERT INTO #decimalScaleCheck values (@decsclcheck)" + Environment.NewLine + + "SELECT @decsclcheck=decsclcheck from #decimalScaleCheck" + Environment.NewLine + + "END"; + + cmd = new SqlCommand (create_tbl, conn); + cmd.ExecuteNonQuery (); + + cmd.CommandText = create_sp; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "[#sp_bug595918]"; + cmd.CommandType = CommandType.StoredProcedure; + SqlParameter pValue = new SqlParameter("@decsclcheck", SqlDbType.Decimal); + pValue.Value = 128.425; + pValue.Precision = 19; + pValue.Scale = 3; + pValue.Direction = ParameterDirection.InputOutput; + cmd.Parameters.Add(pValue); + cmd.ExecuteNonQuery(); + + Assert.AreEqual (128.425, pValue.Value, "Stored decimal value is incorrect - DS - Bug#595918"); + } + + [Test] // bug #595918 + public void DecimalGreaterScaleTest () + { + string create_tbl = "CREATE TABLE #decimalScaleCheck (decsclcheck DECIMAL (19, 5) null)"; + string create_sp = "CREATE PROCEDURE #sp_bug595918(@decsclcheck decimal(19,5) OUT)" + + "AS " + Environment.NewLine + + "BEGIN" + Environment.NewLine + + "INSERT INTO #decimalScaleCheck values (@decsclcheck)" + Environment.NewLine + + "SELECT @decsclcheck=decsclcheck from #decimalScaleCheck" + Environment.NewLine + + "END"; + + cmd = new SqlCommand (create_tbl, conn); + cmd.ExecuteNonQuery (); + + cmd.CommandText = create_sp; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "[#sp_bug595918]"; + cmd.CommandType = CommandType.StoredProcedure; + SqlParameter pValue = new SqlParameter("@decsclcheck", SqlDbType.Decimal); + pValue.Value = 128.425; + pValue.Precision = 19; + pValue.Scale = 5; + pValue.Direction = ParameterDirection.InputOutput; + cmd.Parameters.Add(pValue); + cmd.ExecuteNonQuery(); + + Assert.AreEqual (128.42500, pValue.Value, "Stored decimal value is incorrect - GS - Bug#595918"); + } + + [Test] // bug #595918 + public void DecimalLesserScaleTest () + { + string create_tbl = "CREATE TABLE #decimalScaleCheck (decsclcheck DECIMAL (19, 5) null)"; + string create_sp = "CREATE PROCEDURE #sp_bug595918(@decsclcheck decimal(19,5) OUT)" + + "AS " + Environment.NewLine + + "BEGIN" + Environment.NewLine + + "INSERT INTO #decimalScaleCheck values (@decsclcheck)" + Environment.NewLine + + "SELECT @decsclcheck=decsclcheck from #decimalScaleCheck" + Environment.NewLine + + "END"; + + cmd = new SqlCommand (create_tbl, conn); + cmd.ExecuteNonQuery (); + + cmd.CommandText = create_sp; + cmd.ExecuteNonQuery (); + + cmd.CommandText = "[#sp_bug595918]"; + cmd.CommandType = CommandType.StoredProcedure; + SqlParameter pValue = new SqlParameter("@decsclcheck", SqlDbType.Decimal); + pValue.Value = 128.425; + pValue.Precision = 19; + pValue.Scale = 2; + pValue.Direction = ParameterDirection.InputOutput; + cmd.Parameters.Add(pValue); + cmd.ExecuteNonQuery(); + + Assert.AreEqual (128.42, pValue.Value, "Stored decimal value is incorrect - LS - Bug#595918"); + } + int ClientVersion { get { return (engine.ClientVersion); diff --git a/mcs/class/System.Data/Test/ProviderTests/app-net_2_0.config b/mcs/class/System.Data/Test/ProviderTests/app-net_2_0.config index 9553bd2ee11..a7d90214dac 100644 --- a/mcs/class/System.Data/Test/ProviderTests/app-net_2_0.config +++ b/mcs/class/System.Data/Test/ProviderTests/app-net_2_0.config @@ -73,7 +73,7 @@ + + * JsonValue.cs: We need to use Convert.ToXXXX for numbers as we + always end up reporting the value JsonType.Number regardless of + the underlying storage (int, long or decimal). The parser + picks the best storage suitable for the data, and can end up using + "ints" for values that sometimes use longs. + + This causes problems when derefercing the data for example, if you + have an int and try to get it out as a long you end up with an + invalid cast exception. + 2010-03-10 Atsushi Enomoto * System.Json.dll.sources : remove JsonReader.cs. diff --git a/mcs/class/System.Json/System.Json/JsonValue.cs b/mcs/class/System.Json/System.Json/JsonValue.cs index 35e61de526c..7b7d9a3717d 100644 --- a/mcs/class/System.Json/System.Json/JsonValue.cs +++ b/mcs/class/System.Json/System.Json/JsonValue.cs @@ -322,70 +322,70 @@ namespace System.Json { if (value == null) throw new ArgumentNullException ("value"); - return (bool) ((JsonPrimitive) value).Value; + return Convert.ToBoolean (((JsonPrimitive) value).Value); } public static implicit operator byte (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (byte) ((JsonPrimitive) value).Value; + return Convert.ToByte (((JsonPrimitive) value).Value); } public static implicit operator char (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (char) ((JsonPrimitive) value).Value; + return Convert.ToChar (((JsonPrimitive) value).Value); } public static implicit operator decimal (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (decimal) ((JsonPrimitive) value).Value; + return Convert.ToDecimal (((JsonPrimitive) value).Value); } public static implicit operator double (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (double) ((JsonPrimitive) value).Value; + return Convert.ToDouble (((JsonPrimitive) value).Value); } public static implicit operator float (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (float) ((JsonPrimitive) value).Value; + return Convert.ToSingle (((JsonPrimitive) value).Value); } public static implicit operator int (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (int) ((JsonPrimitive) value).Value; + return Convert.ToInt32 (((JsonPrimitive) value).Value); } public static implicit operator long (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (long) ((JsonPrimitive) value).Value; + return Convert.ToInt64 (((JsonPrimitive) value).Value); } public static implicit operator sbyte (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (sbyte) ((JsonPrimitive) value).Value; + return Convert.ToSByte (((JsonPrimitive) value).Value); } public static implicit operator short (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (short) ((JsonPrimitive) value).Value; + return Convert.ToInt16 (((JsonPrimitive) value).Value); } public static implicit operator string (JsonValue value) @@ -399,21 +399,21 @@ namespace System.Json { if (value == null) throw new ArgumentNullException ("value"); - return (uint) ((JsonPrimitive) value).Value; + return Convert.ToUInt16 (((JsonPrimitive) value).Value); } public static implicit operator ulong (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (ulong) ((JsonPrimitive) value).Value; + return Convert.ToUInt64(((JsonPrimitive) value).Value); } public static implicit operator ushort (JsonValue value) { if (value == null) throw new ArgumentNullException ("value"); - return (ushort) ((JsonPrimitive) value).Value; + return Convert.ToUInt16 (((JsonPrimitive) value).Value); } public static implicit operator DateTime (JsonValue value) diff --git a/mcs/class/System.Net/ChangeLog b/mcs/class/System.Net/ChangeLog index db2a5875fd9..b6f43ac63bc 100644 --- a/mcs/class/System.Net/ChangeLog +++ b/mcs/class/System.Net/ChangeLog @@ -1,3 +1,17 @@ +2010-04-21 Sebastien Pouliot + + * moonlight_raw_System.Net.dll.sources: Add System.Net.Sockets/ + SocketClientAccessPolicyProtocol.cs to the build + +2010-04-05 Sebastien Pouliot + + * moonlight_raw_System.Net.dll.sources: Move InternalWebRequest + StreamWrapper.cs back to System.Windows.dll + +2010-03-16 Jb Evain + + * net_2_1_*.dll.sources: rename to moonlight_*.dll.sources. + 2010-03-10 Sebastien Pouliot * net_2_1_raw_System.Net.dll.sources: Add types from (new internal) diff --git a/mcs/class/System.Net/System.Net.Policy/BaseDomainPolicy.cs b/mcs/class/System.Net/System.Net.Policy/BaseDomainPolicy.cs index 3eda246ad41..ec35c24781e 100644 --- a/mcs/class/System.Net/System.Net.Policy/BaseDomainPolicy.cs +++ b/mcs/class/System.Net/System.Net.Policy/BaseDomainPolicy.cs @@ -128,12 +128,7 @@ namespace System.Net.Policy { } } - public bool IsAllowed (WebRequest request) - { - return IsAllowed (request.RequestUri, request.Headers.AllKeys); - } - - abstract public bool IsAllowed (Uri uri, params string [] headerKeys); + abstract public bool IsAllowed (WebRequest request); } } diff --git a/mcs/class/System.Net/System.Net.Policy/ChangeLog b/mcs/class/System.Net/System.Net.Policy/ChangeLog index 06bd21c8177..3866d2b4f72 100644 --- a/mcs/class/System.Net/System.Net.Policy/ChangeLog +++ b/mcs/class/System.Net/System.Net.Policy/ChangeLog @@ -1,3 +1,50 @@ +2010-04-13 Sebastien Pouliot + + * CrossDomainPolicyManager.cs: Fix previous change since it + breaks several valid cases (e.g. text/*, text/xml; charset=utf-8) + and does not completely covers the application/xml case. + Avoid possible ArgumentException while adding policies since it + confuse the logs. + +2010-04-13 Andreia Gaita + + * CrossDomainPolicyManager.cs: make the contentType detection + look for /xml at the end, it's more reliable + (fixes olympics for moonlight) + +2010-04-07 Sebastien Pouliot + + * ClientAccessPolicy.cs: Fake a "GET" method when applying a + policy to sockets + +2010-04-07 Sebastien Pouliot + + * BaseDomainPolicy.cs: Abstract-fy IsAllowed(WebRequest) and + remove abstract IsAllowed(Uri,string[]) since it cannot provide + enough information for the client access policy. + * ClientAccessPolicy.cs: Replace IsAllowed(Uri,string[]) with + IsAllowed(WebRequest) and add logic for AllowAnyMethod + * ClientAccessPolicyParser.cs: Read "http-methods" attribute (new + in SL3) and set the new AllowAnyMethod property if the value is + "*" (the only legal value if the attribute is present). + * FlashCrossDomainPolicy.cs: Add IsAllowed(WebRequest) since it's + not part of BaseDomainPolicy anymore. + +2010-04-06 Sebastien Pouliot + + * ClientAccessPolicyParser.cs: Don't forget "http-request-headers" + as a valid attribute + +2010-04-06 Sebastien Pouliot + + * ClientAccessPolicyParser.cs: Catch extra attributes that + leads to an invalid (no-access) policy. Fix parts of DRT#666 + * CrossDomainPolicyManager.cs: Ignore policies sent with a + Content-Type different than "text/*". Fix DRT#667 + * FlashCrossDomainPolicyParser.cs: Catch extra attributes and + the case where a second policy is present (invalid xml). Fix + parts of DRT#666 + 2010-03-10 Sebastien Pouliot * BaseDomainPolicy.cs, ClientAccessPolicy[Parser].cs, diff --git a/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicy.cs b/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicy.cs index 576dddc1fe6..3e223a911a0 100644 --- a/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicy.cs +++ b/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicy.cs @@ -74,7 +74,8 @@ namespace System.Net.Policy { foreach (AccessPolicy policy in AccessPolicyList) { // does something allow our URI in this policy ? foreach (AllowFrom af in policy.AllowedServices) { - if (af.IsAllowed (ApplicationUri, null)) { + // fake "GET" as method as this does not apply to sockets + if (af.IsAllowed (ApplicationUri, "GET", null)) { // if so, is our request port allowed ? if (policy.PortAllowed (endpoint.Port)) return true; @@ -114,7 +115,12 @@ namespace System.Net.Policy { return true; } - public override bool IsAllowed (Uri uri, params string [] headerKeys) + public override bool IsAllowed (WebRequest request) + { + return IsAllowed (request.RequestUri, request.Method, request.Headers.AllKeys); + } + + public bool IsAllowed (Uri uri, string method, params string [] headerKeys) { // at this stage the URI has removed the "offending" characters so we need to look at the original if (!CheckOriginalPath (uri)) @@ -124,7 +130,7 @@ namespace System.Net.Policy { // does something allow our URI in this policy ? foreach (AllowFrom af in policy.AllowedServices) { // is the application (XAP) URI allowed by the policy ? - if (af.IsAllowed (ApplicationUri, headerKeys)) { + if (af.IsAllowed (ApplicationUri, method, headerKeys)) { foreach (GrantTo gt in policy.GrantedResources) { // is the requested access to the Uri granted under this policy ? if (gt.IsGranted (uri)) @@ -152,9 +158,11 @@ namespace System.Net.Policy { public Headers HttpRequestHeaders { get; private set; } + public bool AllowAnyMethod { get; set; } + public string Scheme { get; internal set; } - public bool IsAllowed (Uri uri, string [] headerKeys) + public bool IsAllowed (Uri uri, string method, string [] headerKeys) { // check headers if (!HttpRequestHeaders.IsAllowed (headerKeys)) @@ -173,6 +181,16 @@ namespace System.Net.Policy { return false; } } + // check methods + if (!AllowAnyMethod) { + // if not all methods are allowed (*) then only GET and POST request are possible + // further restriction exists in the Client http stack + if ((String.Compare (method, "GET", StringComparison.OrdinalIgnoreCase) != 0) && + (String.Compare (method, "POST", StringComparison.OrdinalIgnoreCase) != 0)) { + return false; + } + } + // check domains if (AllowAnyDomain) return true; diff --git a/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicyParser.cs b/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicyParser.cs index 52001176feb..f1cd5edb408 100644 --- a/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicyParser.cs +++ b/mcs/class/System.Net/System.Net.Policy/ClientAccessPolicyParser.cs @@ -5,7 +5,7 @@ // Atsushi Enomoto // Moonlight List (moonlight-list@lists.ximian.com) // -// Copyright (C) 2009 Novell, Inc. http://www.novell.com +// Copyright (C) 2009-2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -97,14 +97,22 @@ namespace System.Net.Policy { for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) { if (reader.NodeType != XmlNodeType.Element) throw new XmlException (String.Format ("Unexpected access-policy content: {0}", reader.NodeType)); - if (reader.IsEmptyElement) { + + if ((reader.LocalName != "cross-domain-access") || reader.IsEmptyElement) { reader.Skip (); continue; } + reader.ReadStartElement ("cross-domain-access", String.Empty); for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) { if (reader.NodeType != XmlNodeType.Element) throw new XmlException (String.Format ("Unexpected access-policy content: {0}", reader.NodeType)); + + if ((reader.Name != "policy") || reader.IsEmptyElement) { + reader.Skip (); + continue; + } + ReadPolicyElement (reader, cap); } reader.ReadEndElement (); @@ -116,22 +124,19 @@ namespace System.Net.Policy { static void ReadPolicyElement (XmlReader reader, ClientAccessPolicy cap) { - if (reader.IsEmptyElement) { + if (reader.HasAttributes || reader.IsEmptyElement) { reader.Skip (); return; } var policy = new AccessPolicy (); - cap.AccessPolicyList.Add (policy); + bool valid = true; reader.ReadStartElement ("policy", String.Empty); for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) { if (reader.NodeType != XmlNodeType.Element) throw new XmlException (String.Format ("Unexpected policy content: {0}", reader.NodeType)); - if (reader.IsEmptyElement || !String.IsNullOrEmpty (reader.NamespaceURI)) { - reader.Skip (); - continue; - } + switch (reader.LocalName) { case "allow-from": ReadAllowFromElement (reader, policy); @@ -140,24 +145,41 @@ namespace System.Net.Policy { ReadGrantToElement (reader, policy); break; default: + valid = false; reader.Skip (); - continue; + break; } } + + if (valid) + cap.AccessPolicyList.Add (policy); reader.ReadEndElement (); } static void ReadAllowFromElement (XmlReader reader, AccessPolicy policy) { - var v = new AllowFrom (); - policy.AllowedServices.Add (v); - if (reader.IsEmptyElement) { reader.Skip (); return; } - v.HttpRequestHeaders.SetHeaders (reader.GetAttribute ("http-request-headers")); + bool valid = true; + string headers = null; + string methods = null; // new in SL3 + if (reader.HasAttributes) { + int n = reader.AttributeCount; + headers = reader.GetAttribute ("http-request-headers"); + if (headers != null) + n--; + methods = reader.GetAttribute ("http-methods"); + if (methods != null) + n--; + valid = (n == 0); + } + + var v = new AllowFrom (); + v.HttpRequestHeaders.SetHeaders (headers); + v.AllowAnyMethod = (methods == "*"); // only legal value defined, otherwise restricted to GET and POST reader.ReadStartElement ("allow-from", String.Empty); for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) { if (reader.NodeType != XmlNodeType.Element) @@ -189,19 +211,41 @@ namespace System.Net.Policy { reader.Skip (); break; default: + valid = false; reader.Skip (); continue; } } + if (valid) + policy.AllowedServices.Add (v); reader.ReadEndElement (); } + // only "path" and "include-subpaths" attributes are allowed - anything else is not considered + static Resource CreateResource (XmlReader reader) + { + int n = reader.AttributeCount; + string path = reader.GetAttribute ("path"); + if (path != null) + n--; + string subpaths = reader.GetAttribute ("include-subpaths"); + if (subpaths != null) + n--; + if ((n != 0) || !reader.IsEmptyElement) + return null; + + return new Resource () { + Path = path, + IncludeSubpaths = subpaths == null ? false : XmlConvert.ToBoolean (subpaths) + }; + } + static void ReadGrantToElement (XmlReader reader, AccessPolicy policy) { var v = new GrantTo (); - policy.GrantedResources.Add (v); + bool valid = true; - if (reader.IsEmptyElement) { + if (reader.HasAttributes || reader.IsEmptyElement) { reader.Skip (); return; } @@ -214,15 +258,14 @@ namespace System.Net.Policy { reader.Skip (); continue; } + switch (reader.LocalName) { case "resource": - var r = new Resource (); - v.Resources.Add (r); - r.Path = reader.GetAttribute ("path"); - if (reader.MoveToAttribute ("include-subpaths")) { - r.IncludeSubpaths = XmlConvert.ToBoolean (reader.Value); - reader.MoveToElement (); - } + var r = CreateResource (reader); + if (r == null) + valid = false; + else + v.Resources.Add (r); break; case "socket-resource": // ignore everything that is not TCP @@ -231,9 +274,14 @@ namespace System.Net.Policy { // we can merge them all together inside a policy policy.PortMask |= ParsePorts (reader.GetAttribute ("port")); break; + default: + valid = false; + break; } reader.Skip (); } + if (valid) + policy.GrantedResources.Add (v); reader.ReadEndElement (); } diff --git a/mcs/class/System.Net/System.Net.Policy/CrossDomainPolicyManager.cs b/mcs/class/System.Net/System.Net.Policy/CrossDomainPolicyManager.cs index 87848f6e71a..87acfea9035 100644 --- a/mcs/class/System.Net/System.Net.Policy/CrossDomainPolicyManager.cs +++ b/mcs/class/System.Net/System.Net.Policy/CrossDomainPolicyManager.cs @@ -95,18 +95,34 @@ namespace System.Net.Policy { private static void AddPolicy (Uri responseUri, ICrossDomainPolicy policy) { string root = GetRoot (responseUri); - try { - policies.Add (root, policy); - } - catch (ArgumentException) { - // it's possible another request already added this root + policies [root] = policy; + } + + // see moon/test/2.0/WebPolicies/Pages.xaml.cs for all test cases + private static bool CheckContentType (string contentType) + { + const string application_xml = "application/xml"; + + // most common case: all text/* are accepted + if (contentType.StartsWith ("text/")) + return true; + + // special case (e.g. used in nbcolympics) + if (contentType.StartsWith (application_xml)) { + if (application_xml.Length == contentType.Length) + return true; // exact match + + // e.g. "application/xml; charset=x" - we do not care what comes after ';' + if (contentType.Length > application_xml.Length) + return contentType [application_xml.Length] == ';'; } + return false; } public static ICrossDomainPolicy BuildSilverlightPolicy (HttpWebResponse response) { // return null if no Silverlight policy was found, since we offer a second chance with a flash policy - if (response.StatusCode != HttpStatusCode.OK) + if ((response.StatusCode != HttpStatusCode.OK) || !CheckContentType (response.ContentType)) return null; ICrossDomainPolicy policy = null; @@ -125,7 +141,7 @@ namespace System.Net.Policy { public static ICrossDomainPolicy BuildFlashPolicy (HttpWebResponse response) { ICrossDomainPolicy policy = null; - if (response.StatusCode == HttpStatusCode.OK) { + if ((response.StatusCode == HttpStatusCode.OK) && CheckContentType (response.ContentType)) { try { policy = FlashCrossDomainPolicy.FromStream (response.GetResponseStream ()); } catch (Exception ex) { @@ -225,9 +241,30 @@ namespace System.Net.Policy { return ms; } - public static ClientAccessPolicy CreateForEndPoint (IPEndPoint endpoint) + static Stream GetPolicyStream (Uri uri) + { + // FIXME + throw new NotSupportedException ("Fetching socket policy from " + uri.ToString () + " is not yet available in moonlight"); + } + + public static ClientAccessPolicy CreateForEndPoint (IPEndPoint endpoint, SocketClientAccessPolicyProtocol protocol) { - Stream s = GetPolicyStream (endpoint); + Stream s = null; + + switch (protocol) { + case SocketClientAccessPolicyProtocol.Tcp: + s = GetPolicyStream (endpoint); + break; + case SocketClientAccessPolicyProtocol.Http: + // It will NOT attempt to download the policy via the custom TCP protocol if the + // policy check fails. + // http://blogs.msdn.com/ncl/archive/2010/04/15/silverlight-4-socket-policy-changes.aspx + string url = String.Format ("http://{0}:80{1}", endpoint.Address.ToString (), + CrossDomainPolicyManager.ClientAccessPolicyFile); + s = GetPolicyStream (new Uri (url)); + break; + } + if (s == null) return null; @@ -243,7 +280,7 @@ namespace System.Net.Policy { return policy; } - static public bool CheckEndPoint (EndPoint endpoint) + static public bool CheckEndPoint (EndPoint endpoint, SocketClientAccessPolicyProtocol protocol) { // if needed transform the DnsEndPoint into a usable IPEndPoint IPEndPoint ip = (endpoint as IPEndPoint); @@ -254,7 +291,7 @@ namespace System.Net.Policy { string address = ip.Address.ToString (); ClientAccessPolicy policy = null; if (!socket_policies.TryGetValue (address, out policy)) { - policy = CreateForEndPoint (ip); + policy = CreateForEndPoint (ip, protocol); socket_policies.Add (address, policy); } diff --git a/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicy.cs b/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicy.cs index ee90aebb058..fd15eeb8ae1 100644 --- a/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicy.cs +++ b/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicy.cs @@ -54,7 +54,12 @@ namespace System.Net.Policy { set { site_control = value; } } - public override bool IsAllowed (Uri uri, string [] headerKeys) + public override bool IsAllowed (WebRequest request) + { + return IsAllowed (request.RequestUri, request.Headers.AllKeys); + } + + public bool IsAllowed (Uri uri, string [] headerKeys) { switch (SiteControl) { case "all": diff --git a/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicyParser.cs b/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicyParser.cs index 22a6f966256..5189455ac8a 100644 --- a/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicyParser.cs +++ b/mcs/class/System.Net/System.Net.Policy/FlashCrossDomainPolicyParser.cs @@ -83,9 +83,9 @@ namespace System.Net.Policy { partial class FlashCrossDomainPolicy { - static bool ReadBooleanAttribute (XmlReader reader, string attribute) + static bool ReadBooleanAttribute (string attribute) { - switch (reader.GetAttribute (attribute)) { + switch (attribute) { case null: case "true": return true; @@ -96,6 +96,55 @@ namespace System.Net.Policy { } } + // only "domain" and "secure" attributes are allowed - anything else is considered invalid + static AllowAccessFrom CreateAllowAccessFrom (XmlReader reader) + { + int n = reader.AttributeCount; + string domain = reader.GetAttribute ("domain"); + if (domain != null) + n--; + string secure = reader.GetAttribute ("secure"); + if (secure != null) + n--; + if (n != 0) + throw new XmlException ("unknown/unsupported attributes"); + + return new AllowAccessFrom () { Domain = domain, Secure = ReadBooleanAttribute (secure) }; + } + + // only "domain", "secure" and "headers" attributes are allowed - anything else is considered invalid + static AllowHttpRequestHeadersFrom CreateAllowHttpRequestHeadersFrom (XmlReader reader) + { + int n = reader.AttributeCount; + string domain = reader.GetAttribute ("domain"); + if (domain != null) + n--; + string secure = reader.GetAttribute ("secure"); + if (secure != null) + n--; + string headers = reader.GetAttribute ("headers"); + if (headers != null) + n--; + if (n != 0) + throw new XmlException ("unknown/unsupported attributes"); + + var h = new AllowHttpRequestHeadersFrom () { Domain = domain, Secure = ReadBooleanAttribute (secure) }; + h.Headers.SetHeaders (headers); + return h; + } + + // only "permitted-cross-domain-policies" attribute is allowed - anything else is considered invalid + static string GetSiteControl (XmlReader reader) + { + int n = reader.AttributeCount; + string site = reader.GetAttribute ("permitted-cross-domain-policies"); + if (site != null) + n--; + if (n != 0) + throw new XmlException ("unknown/unsupported attributes"); + return site; + } + static public ICrossDomainPolicy FromStream (Stream stream) { FlashCrossDomainPolicy cdp = new FlashCrossDomainPolicy (); @@ -110,48 +159,39 @@ namespace System.Net.Policy { using (XmlReader reader = XmlReader.Create (sr, policy_settings)) { reader.MoveToContent (); - if (reader.IsEmptyElement) { + if (reader.HasAttributes || reader.IsEmptyElement) { reader.Skip (); return null; } - reader.ReadStartElement ("cross-domain-policy", String.Empty); - for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) { - if (reader.NodeType != XmlNodeType.Element) - throw new XmlException (String.Format ("Unexpected cross-domain-policy content: {0}", reader.NodeType)); - switch (reader.LocalName) { - case "site-control": - cdp.SiteControl = reader.GetAttribute ("permitted-cross-domain-policies"); - reader.Skip (); - break; - case "allow-access-from": - var a = new AllowAccessFrom () { - Domain = reader.GetAttribute ("domain"), - Secure = ReadBooleanAttribute (reader, "secure") }; -/* Silverlight policies are used for sockets - var p = reader.GetAttribute ("to-ports"); - if (p == "*") - a.AllowAnyPort = true; - else if (p != null) - a.ToPorts = Array.ConvertAll (p.Split (','), s => XmlConvert.ToInt32 (s)); -*/ - cdp.AllowedAccesses.Add (a); - reader.Skip (); - break; - case "allow-http-request-headers-from": - var h = new AllowHttpRequestHeadersFrom () { - Domain = reader.GetAttribute ("domain"), - Secure = ReadBooleanAttribute (reader, "secure") }; - h.Headers.SetHeaders (reader.GetAttribute ("headers")); - cdp.AllowedHttpRequestHeaders.Add (h); - reader.Skip (); - break; - default: - reader.Skip (); - continue; + while (!reader.EOF) { + reader.ReadStartElement ("cross-domain-policy", String.Empty); + for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) { + if (reader.NodeType != XmlNodeType.Element) + throw new XmlException (String.Format ("Unexpected cross-domain-policy content: {0}", reader.NodeType)); + switch (reader.LocalName) { + case "site-control": + cdp.SiteControl = GetSiteControl (reader); + reader.Skip (); + break; + case "allow-access-from": + var a = CreateAllowAccessFrom (reader); + cdp.AllowedAccesses.Add (a); + reader.Skip (); + break; + case "allow-http-request-headers-from": + var h = CreateAllowHttpRequestHeadersFrom (reader); + cdp.AllowedHttpRequestHeaders.Add (h); + reader.Skip (); + break; + default: + reader.Skip (); + return null; + } } + reader.ReadEndElement (); + reader.MoveToContent (); } - reader.ReadEndElement (); } // if none supplied set a default for headers diff --git a/mcs/class/System.Net/System.Net.Sockets/ChangeLog b/mcs/class/System.Net/System.Net.Sockets/ChangeLog index 382f28b43fc..adc52712b6a 100644 --- a/mcs/class/System.Net/System.Net.Sockets/ChangeLog +++ b/mcs/class/System.Net/System.Net.Sockets/ChangeLog @@ -1,3 +1,12 @@ +2010-04-21 Sebastien Pouliot + + * SocketClientAccessPolicyProtocol.cs: New SL4 enum to select TCP + (default) or HTTP (new) to retrieve the socket xdomain policy + +2010-03-19 Sebastien Pouliot + + * SocketException_2_1.cs: Add extra ctor (soon to be used) + 2009-04-28 Sebastien Pouliot * SocketException_2_1.cs: Remove extra ctor and property unused in 2.1 diff --git a/mcs/class/System.Net/System.Net.Sockets/SocketClientAccessPolicyProtocol.cs b/mcs/class/System.Net/System.Net.Sockets/SocketClientAccessPolicyProtocol.cs new file mode 100644 index 00000000000..c34dc4f774b --- /dev/null +++ b/mcs/class/System.Net/System.Net.Sockets/SocketClientAccessPolicyProtocol.cs @@ -0,0 +1,31 @@ +// +// SocketClientAccessPolicyProtocol.cs (Silverlight specific) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace System.Net.Sockets { + + public enum SocketClientAccessPolicyProtocol { + Tcp, + Http + } +} + diff --git a/mcs/class/System.Net/System.Net.Sockets/SocketException_2_1.cs b/mcs/class/System.Net/System.Net.Sockets/SocketException_2_1.cs index 9d040c2c565..133ec798dc2 100644 --- a/mcs/class/System.Net/System.Net.Sockets/SocketException_2_1.cs +++ b/mcs/class/System.Net/System.Net.Sockets/SocketException_2_1.cs @@ -48,6 +48,12 @@ namespace System.Net.Sockets { error_code = error; } + internal SocketException (int error, string message) + : base (message) + { + error_code = error; + } + public int ErrorCode { get { return error_code; } } diff --git a/mcs/class/System.Net/System.Net/ChangeLog b/mcs/class/System.Net/System.Net/ChangeLog index 8dab13acca7..d7066e11f1e 100644 --- a/mcs/class/System.Net/System.Net/ChangeLog +++ b/mcs/class/System.Net/System.Net/ChangeLog @@ -1,3 +1,46 @@ +2010-04-21 Sebastien Pouliot + + * HttpWebResponse_2_1.cs: Method, StatusCode and StatusDescription + property getters are now virtual (instead of abstract) and throw + NIE in SL4 (final) API. + * WebRequest_2_1.cs: Added ContentLength (SL4) property to throw + NIE. Implement (SL4) CreateHttp methods. Rework stack registration + logic. + * WebResponse_2_1.cs: default Headers getter throws NIE + +2010-04-05 Sebastien Pouliot + + * InternalWebResponseStreamWrapper.cs: Move back to + System.Windows.dll + +2010-03-19 Sebastien Pouliot + + * HttpWebRequest_2_1.cs: AllowWriteStreamBuffering getter/setter + throws NIE by default (must be overridden). Revert Accept and + ContentType behavior to SL2 (identical to SL4 but different from + SL3). + * WebClient_2_1.cs: Initialize UseDefaultCredentials to true. Set + the properties when creating a new WebRequest + +2010-03-18 Sebastien Pouliot + + * HttpWebRequest_2_1.cs: Add SL4 RC AllowWriteStreamBuffering and + SupportsCookieContainer properties. + * WebClient_2_1.cs: Add SL4 RC AllowWriteStreamBuffering and + UseDefaultCredentials properties. + * WebHeaderCollection_2_1.cs: Authorization and Proxy-Authorization + are valid (i.e. usable) headers in SL4 (in both stacks) + +2010-03-16 Rolf Bjarne Kvinge + + * WebRequest_2_1.cs: Added UseDefaultCredentials property. + +2010-03-12 Sebastien Pouliot + + * WebClient_2_1.cs: Directly set 'progress' delegate field + * WebRequest_2_1.cs: Avoid using reflection (since it was not + really needed anyway) + 2010-03-03 Andreia Gaita * InternalWebRequestStreamWrapper.cs: don't add a newline to the diff --git a/mcs/class/System.Net/System.Net/HttpWebRequest_2_1.cs b/mcs/class/System.Net/System.Net/HttpWebRequest_2_1.cs index 4f980982895..e2fccc637c4 100644 --- a/mcs/class/System.Net/System.Net/HttpWebRequest_2_1.cs +++ b/mcs/class/System.Net/System.Net/HttpWebRequest_2_1.cs @@ -53,13 +53,7 @@ namespace System.Net { public string Accept { get { return Headers [HttpRequestHeader.Accept]; } // this header cannot be set directly inside the collection (hence the helper) - set { - if (value == null) - throw new ArgumentNullException ("Accept"); - if (value.Length == 0) - throw new ArgumentException ("Accept"); - Headers.SetHeader ("accept", value); - } + set { Headers.SetHeader ("accept", value); } } public virtual bool AllowReadStreamBuffering { @@ -67,16 +61,16 @@ namespace System.Net { set { throw NotImplemented (); } } + // new in SL4 RC + public virtual bool AllowWriteStreamBuffering { + get { throw NotImplemented (); } + set { throw NotImplemented (); } + } + public override string ContentType { get { return Headers [HttpRequestHeader.ContentType]; } // this header cannot be set directly inside the collection (hence the helper) - set { - if (value == null) - throw new ArgumentNullException ("ContentType"); - if (value.Length == 0) - throw new ArgumentException ("ContentType"); - Headers.SetHeader ("content-type", value); - } + set { Headers.SetHeader ("content-type", value); } } public virtual bool HaveResponse { @@ -119,6 +113,10 @@ namespace System.Net { get { throw NotImplemented (); } } + // new in SL4 RC + public virtual bool SupportsCookieContainer { + get { return false; } + } public override void Abort () { diff --git a/mcs/class/System.Net/System.Net/HttpWebResponse_2_1.cs b/mcs/class/System.Net/System.Net/HttpWebResponse_2_1.cs index 53dd52fe813..d26af210250 100644 --- a/mcs/class/System.Net/System.Net/HttpWebResponse_2_1.cs +++ b/mcs/class/System.Net/System.Net/HttpWebResponse_2_1.cs @@ -35,9 +35,17 @@ namespace System.Net { public abstract class HttpWebResponse : WebResponse { - public abstract string Method { get; } - public abstract HttpStatusCode StatusCode { get; } - public abstract string StatusDescription { get; } + public virtual string Method { + get { throw NotImplemented (); } + } + + public virtual HttpStatusCode StatusCode { + get { throw NotImplemented (); } + } + + public virtual string StatusDescription { + get { throw NotImplemented (); } + } public virtual CookieCollection Cookies { get { throw NotImplemented (); } diff --git a/mcs/class/System.Net/System.Net/InternalWebResponseStreamWrapper.cs b/mcs/class/System.Net/System.Net/InternalWebResponseStreamWrapper.cs deleted file mode 100644 index 00d44faa1c8..00000000000 --- a/mcs/class/System.Net/System.Net/InternalWebResponseStreamWrapper.cs +++ /dev/null @@ -1,100 +0,0 @@ -/* - * InternalWebResponseStreamWrapper.cs. - * - * Contact: - * Moonlight List (moonlight-list@lists.ximian.com) - * - * Copyright 2008,2010 Novell, Inc. (http://www.novell.com) - * - * See the LICENSE file included with the distribution for details. - * - */ - -using System.IO; - -namespace System.Net { - - // simply a read-only wrapper around a stream + a no-op Close - internal sealed class InternalWebResponseStreamWrapper : Stream { - - private Stream stream; - - internal InternalWebResponseStreamWrapper (Stream s) - { - stream = s; - } - - public override bool CanRead { - get { - return stream.CanRead; - } - } - - public override bool CanSeek { - get { - return stream.CanSeek; - } - } - - public override bool CanWrite { - get { - return false; - } - } - - public override long Length { - get { - return stream.Length; - } - } - - public override long Position { - get { - return stream.Position; - } - set { - stream.Position = value; - } - } - - public override void Flush () - { - throw new NotSupportedException (); - } - - public override void Close () - { - // We cannot call "stream.Close" on a memory stream since it deletes the data - } - - public override void SetLength (long value) - { - throw new NotSupportedException (); - } - - public override int Read (byte [] buffer, int offset, int count) - { - return stream.Read (buffer, offset, count); - } - - public override void Write (byte [] buffer, int offset, int count) - { - throw new NotSupportedException (); - } - - public override void WriteByte (byte value) - { - throw new NotSupportedException (); - } - - public override long Seek (long offset, SeekOrigin origin) - { - return stream.Seek (offset, origin); - } - - internal Stream InnerStream { - get { return stream; } - } - } -} - diff --git a/mcs/class/System.Net/System.Net/WebClient_2_1.cs b/mcs/class/System.Net/System.Net/WebClient_2_1.cs index 0fc7bf404e6..1487adc40b6 100644 --- a/mcs/class/System.Net/System.Net/WebClient_2_1.cs +++ b/mcs/class/System.Net/System.Net/WebClient_2_1.cs @@ -47,6 +47,7 @@ namespace System.Net { bool is_busy; Encoding encoding = Encoding.UTF8; bool allow_read_buffering = true; + bool allow_write_buffering = true; WebRequest request; object locker; CallbackData callback_data; @@ -59,6 +60,7 @@ namespace System.Net { // but it happens that MS SL2 also has this default .ctor as SSC :-) baseAddress = (AppDomain.CurrentDomain.GetData ("xap_uri") as string); locker = new object (); + UseDefaultCredentials = true; } // Properties @@ -115,6 +117,17 @@ namespace System.Net { set { allow_read_buffering = value; } } + // new in SL4 RC + [MonoTODO ("value is unused, current implementation always works like it's true (default)")] + public bool AllowWriteStreamBuffering { + get { return allow_write_buffering; } + set { allow_write_buffering = value; } + } + + public bool UseDefaultCredentials { + get; set; + } + // Methods void CheckBusy () @@ -536,14 +549,17 @@ namespace System.Net { // if the URI is relative then we use our base address URI to make an absolute one Uri uri = address.IsAbsoluteUri ? address : new Uri (new Uri (baseAddress), address); - WebRequest request = WebRequest.Create (uri); + HttpWebRequest request = (HttpWebRequest) WebRequest.Create (uri); + request.AllowReadStreamBuffering = AllowReadStreamBuffering; + request.AllowWriteStreamBuffering = AllowWriteStreamBuffering; + request.UseDefaultCredentials = UseDefaultCredentials; - request.SetupProgressDelegate (delegate (long read, long length) { + request.progress = delegate (long read, long length) { callback_data.sync_context.Post (delegate (object sender) { OnDownloadProgressChanged (new DownloadProgressChangedEventArgs (read, length, callback_data.user_token)); }, null); - }); + }; return request; } diff --git a/mcs/class/System.Net/System.Net/WebHeaderCollection_2_1.cs b/mcs/class/System.Net/System.Net/WebHeaderCollection_2_1.cs index 61274562a4d..c12528ccdde 100644 --- a/mcs/class/System.Net/System.Net/WebHeaderCollection_2_1.cs +++ b/mcs/class/System.Net/System.Net/WebHeaderCollection_2_1.cs @@ -220,13 +220,11 @@ namespace System.Net { case "accept-charset": case "accept-encoding": case "accept-language": - case "authorization": case "cookie": case "expect": case "host": case "if-modified-since": case "max-forwards": - case "proxy-authorization": case "referer": case "te": case "user-agent": diff --git a/mcs/class/System.Net/System.Net/WebRequest_2_1.cs b/mcs/class/System.Net/System.Net/WebRequest_2_1.cs index 68b18aa63b2..8edf07bc1be 100644 --- a/mcs/class/System.Net/System.Net/WebRequest_2_1.cs +++ b/mcs/class/System.Net/System.Net/WebRequest_2_1.cs @@ -31,23 +31,34 @@ #if NET_2_1 -using System; using System.Collections.Generic; using System.IO; -using System.Reflection; namespace System.Net { public abstract class WebRequest { + const string SystemWindows = "System.Windows, PublicKey=00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB"; + const string BrowserStack = "System.Net.Browser.BrowserHttpWebRequestCreator, " + SystemWindows; + const string ClientStack = "System.Net.Browser.ClientHttpWebRequestCreator, " + SystemWindows; + static IWebRequestCreate default_creator; + static IWebRequestCreate browser_creator; + static IWebRequestCreate client_creator; static Dictionary registred_prefixes; + internal Action progress; + public abstract string ContentType { get; set; } public abstract WebHeaderCollection Headers { get; set; } public abstract string Method { get; set; } public abstract Uri RequestUri { get; } + public virtual long ContentLength { + get { throw NotImplemented (); } + set { throw NotImplemented (); } + } + // custom registered prefixes return null (unless they override this) public virtual IWebRequestCreate CreatorInstance { get { return null; } @@ -58,9 +69,17 @@ namespace System.Net { set { throw NotImplemented (); } } + public virtual bool UseDefaultCredentials { + get { throw NotImplemented (); } + set { throw NotImplemented (); } + } + static WebRequest () { registred_prefixes = new Dictionary (StringComparer.OrdinalIgnoreCase); + browser_creator = (IWebRequestCreate) Activator.CreateInstance (Type.GetType (BrowserStack)); + client_creator = (IWebRequestCreate) Activator.CreateInstance (Type.GetType (ClientStack)); + default_creator = browser_creator; } protected WebRequest () @@ -118,9 +137,26 @@ namespace System.Net { return creator.Create (uri); } - internal static void RegisterDefaultStack (IWebRequestCreate creator) + public static HttpWebRequest CreateHttp (string requestUriString) + { + return CreateHttp (new Uri (requestUriString)); + } + + public static HttpWebRequest CreateHttp (Uri uri) { - default_creator = creator; + if (uri == null) + throw new ArgumentNullException ("uri"); + if (!uri.IsAbsoluteUri) + throw new InvalidOperationException ("Uri is not absolute."); + + // we do not check the registred prefixes from CreateHttp and *always* use the client HTTP stack + switch (uri.Scheme) { + case "http": + case "https": + return (HttpWebRequest) client_creator.Create (uri); + default: + throw new NotSupportedException (string.Format ("Scheme {0} not supported", uri.Scheme)); + } } // We can register for @@ -150,13 +186,6 @@ namespace System.Net { return true; } - internal void SetupProgressDelegate (Action progress) - { - FieldInfo fi = GetType ().GetField ("progress", BindingFlags.Instance | BindingFlags.NonPublic); - if (fi != null) - fi.SetValue (this, progress); - } - static Exception NotImplemented () { // hide the "normal" NotImplementedException from corcompare-like tools diff --git a/mcs/class/System.Net/System.Net/WebResponse_2_1.cs b/mcs/class/System.Net/System.Net/WebResponse_2_1.cs index b1205b11aa1..4431d2e1996 100644 --- a/mcs/class/System.Net/System.Net/WebResponse_2_1.cs +++ b/mcs/class/System.Net/System.Net/WebResponse_2_1.cs @@ -30,7 +30,6 @@ #if NET_2_1 -using System; using System.IO; namespace System.Net { @@ -41,7 +40,14 @@ namespace System.Net { public abstract string ContentType { get; } public abstract Uri ResponseUri { get; } - public virtual WebHeaderCollection Headers { get; internal set; } + public virtual WebHeaderCollection Headers { + get { throw NotImplemented (); } + internal set { ; } + } + + public virtual bool SupportsHeaders { + get { return false; } + } protected WebResponse () { @@ -54,6 +60,12 @@ namespace System.Net { { Close (); } + + static Exception NotImplemented () + { + // hide the "normal" NotImplementedException from corcompare-like tools + return new NotImplementedException (); + } } } diff --git a/mcs/class/System.Net/moonlight_raw_System.Net.dll.sources b/mcs/class/System.Net/moonlight_raw_System.Net.dll.sources new file mode 100644 index 00000000000..5a6bebcba78 --- /dev/null +++ b/mcs/class/System.Net/moonlight_raw_System.Net.dll.sources @@ -0,0 +1,75 @@ +Assembly/AssemblyInfo.cs +System.Net/Dns_2_1.cs +System.Net/HttpWebRequest_2_1.cs +System.Net/HttpWebResponse_2_1.cs +System.Net/InternalWebRequestStreamWrapper.cs +System.Net/WebExceptionStatus_2_1.cs +System.Net/WebHeaderCollection_2_1.cs +System.Net/WebClient_2_1.cs +System.Net/WebRequest_2_1.cs +System.Net/WebResponse_2_1.cs +System.Net/WriteStreamClosedEventArgs_2_1.cs +System.Net/WriteStreamClosedEventHandler_2_1.cs +System.Net.Sockets/AddressFamily_2_1.cs +System.Net.Sockets/ProtocolType_2_1.cs +System.Net.Sockets/SocketClientAccessPolicyProtocol.cs +System.Net.Sockets/SocketAsyncOperation_2_1.cs +System.Net.Sockets/SocketException_2_1.cs +System.Net.Sockets/SocketType_2_1.cs +System.Net.Sockets/UdpAnySourceMulticastClient.cs +System.Net.Sockets/UdpSingleSourceMulticastClient.cs +System.Net.NetworkInformation/NetworkChange_2_1.cs +System.Net.NetworkInformation/NetworkInterface_2_1.cs +System.Net.Policy/BaseDomainPolicy.cs +System.Net.Policy/ClientAccessPolicy.cs +System.Net.Policy/ClientAccessPolicyParser.cs +System.Net.Policy/CrossDomainPolicyManager.cs +System.Net.Policy/FlashCrossDomainPolicy.cs +System.Net.Policy/FlashCrossDomainPolicyParser.cs +System.Net.Policy/ICrossDomainPolicy.cs +System.Net.Policy/NoAccessPolicy.cs +System.Net.Policy/PolicyDownloadPolicy.cs +System.Net.Policy/SiteOfOriginPolicy.cs +../System/System.Net/Cookie.cs +../System/System.Net/CookieCollection.cs +../System/System.Net/CookieContainer.cs +../System/System.Net/CookieException.cs +../System/System.Net/DnsEndPoint.cs +../System/System.Net/EndPoint.cs +../System/System.Net/HttpRequestHeader.cs +../System/System.Net/HttpResponseHeader.cs +../System/System.Net/HttpStatusCode.cs +../System/System.Net/ICredentialLookup.cs +../System/System.Net/IPAddress.cs +../System/System.Net/IPEndPoint.cs +../System/System.Net/IPHostEntry.cs +../System/System.Net/IPv6Address.cs +../System/System.Net/IWebRequestCreate.cs +../System/System.Net/NetworkCredential.cs +../System/System.Net/ProtocolViolationException.cs +../System/System.Net/SocketAddress.cs +../System/System.Net.Sockets/LingerOption.cs +../System/System.Net.Sockets/MulticastOption.cs +../System/System.Net.Sockets/ProtocolFamily.cs +../System/System.Net.Sockets/SelectMode.cs +../System/System.Net.Sockets/Socket_2_1.cs +../System/System.Net.Sockets/SocketError.cs +../System/System.Net.Sockets/SocketFlags.cs +../System/System.Net.Sockets/SocketOptionLevel.cs +../System/System.Net.Sockets/SocketOptionName.cs +../System/System.Net.Sockets/SocketShutdown.cs +../System/System.Net.Sockets/SocketAsyncEventArgs.cs +../System/System.Net/WebException.cs +../System/System.Net/DownloadProgressChangedEventArgs.cs +../System/System.Net/DownloadProgressChangedEventHandler.cs +../System/System.Net/DownloadStringCompletedEventArgs.cs +../System/System.Net/DownloadStringCompletedEventHandler.cs +../System/System.Net/OpenReadCompletedEventArgs.cs +../System/System.Net/OpenReadCompletedEventHandler.cs +../System/System.Net/OpenWriteCompletedEventArgs.cs +../System/System.Net/OpenWriteCompletedEventHandler.cs +../System/System.Net/UploadProgressChangedEventArgs.cs +../System/System.Net/UploadProgressChangedEventHandler.cs +../System/System.Net/UploadStringCompletedEventArgs.cs +../System/System.Net/UploadStringCompletedEventHandler.cs +../System/System.Net.NetworkInformation/NetworkAddressChangedEventHandler.cs diff --git a/mcs/class/System.Net/net_2_1_raw_System.Net.dll.sources b/mcs/class/System.Net/net_2_1_raw_System.Net.dll.sources deleted file mode 100644 index 85566a02931..00000000000 --- a/mcs/class/System.Net/net_2_1_raw_System.Net.dll.sources +++ /dev/null @@ -1,75 +0,0 @@ -Assembly/AssemblyInfo.cs -System.Net/Dns_2_1.cs -System.Net/HttpWebRequest_2_1.cs -System.Net/HttpWebResponse_2_1.cs -System.Net/InternalWebRequestStreamWrapper.cs -System.Net/InternalWebResponseStreamWrapper.cs -System.Net/WebExceptionStatus_2_1.cs -System.Net/WebHeaderCollection_2_1.cs -System.Net/WebClient_2_1.cs -System.Net/WebRequest_2_1.cs -System.Net/WebResponse_2_1.cs -System.Net/WriteStreamClosedEventArgs_2_1.cs -System.Net/WriteStreamClosedEventHandler_2_1.cs -System.Net.Sockets/AddressFamily_2_1.cs -System.Net.Sockets/SocketException_2_1.cs -System.Net.Sockets/ProtocolType_2_1.cs -System.Net.Sockets/SocketAsyncOperation_2_1.cs -System.Net.Sockets/SocketType_2_1.cs -System.Net.Sockets/UdpAnySourceMulticastClient.cs -System.Net.Sockets/UdpSingleSourceMulticastClient.cs -System.Net.NetworkInformation/NetworkChange_2_1.cs -System.Net.NetworkInformation/NetworkInterface_2_1.cs -System.Net.Policy/BaseDomainPolicy.cs -System.Net.Policy/ClientAccessPolicy.cs -System.Net.Policy/ClientAccessPolicyParser.cs -System.Net.Policy/CrossDomainPolicyManager.cs -System.Net.Policy/FlashCrossDomainPolicy.cs -System.Net.Policy/FlashCrossDomainPolicyParser.cs -System.Net.Policy/ICrossDomainPolicy.cs -System.Net.Policy/NoAccessPolicy.cs -System.Net.Policy/PolicyDownloadPolicy.cs -System.Net.Policy/SiteOfOriginPolicy.cs -../System/System.Net/Cookie.cs -../System/System.Net/CookieCollection.cs -../System/System.Net/CookieContainer.cs -../System/System.Net/CookieException.cs -../System/System.Net/DnsEndPoint.cs -../System/System.Net/EndPoint.cs -../System/System.Net/HttpRequestHeader.cs -../System/System.Net/HttpResponseHeader.cs -../System/System.Net/HttpStatusCode.cs -../System/System.Net/ICredentialLookup.cs -../System/System.Net/IPAddress.cs -../System/System.Net/IPEndPoint.cs -../System/System.Net/IPHostEntry.cs -../System/System.Net/IPv6Address.cs -../System/System.Net/IWebRequestCreate.cs -../System/System.Net/NetworkCredential.cs -../System/System.Net/ProtocolViolationException.cs -../System/System.Net/SocketAddress.cs -../System/System.Net.Sockets/LingerOption.cs -../System/System.Net.Sockets/MulticastOption.cs -../System/System.Net.Sockets/ProtocolFamily.cs -../System/System.Net.Sockets/SelectMode.cs -../System/System.Net.Sockets/Socket_2_1.cs -../System/System.Net.Sockets/SocketError.cs -../System/System.Net.Sockets/SocketFlags.cs -../System/System.Net.Sockets/SocketOptionLevel.cs -../System/System.Net.Sockets/SocketOptionName.cs -../System/System.Net.Sockets/SocketShutdown.cs -../System/System.Net.Sockets/SocketAsyncEventArgs.cs -../System/System.Net/WebException.cs -../System/System.Net/DownloadProgressChangedEventArgs.cs -../System/System.Net/DownloadProgressChangedEventHandler.cs -../System/System.Net/DownloadStringCompletedEventArgs.cs -../System/System.Net/DownloadStringCompletedEventHandler.cs -../System/System.Net/OpenReadCompletedEventArgs.cs -../System/System.Net/OpenReadCompletedEventHandler.cs -../System/System.Net/OpenWriteCompletedEventArgs.cs -../System/System.Net/OpenWriteCompletedEventHandler.cs -../System/System.Net/UploadProgressChangedEventArgs.cs -../System/System.Net/UploadProgressChangedEventHandler.cs -../System/System.Net/UploadStringCompletedEventArgs.cs -../System/System.Net/UploadStringCompletedEventHandler.cs -../System/System.Net.NetworkInformation/NetworkAddressChangedEventHandler.cs diff --git a/mcs/class/System.Numerics/System.Numerics/ChangeLog b/mcs/class/System.Numerics/System.Numerics/ChangeLog index 5a833c6403a..01204baf424 100644 --- a/mcs/class/System.Numerics/System.Numerics/ChangeLog +++ b/mcs/class/System.Numerics/System.Numerics/ChangeLog @@ -1,3 +1,7 @@ +2010-04-23 Marek Safar + + * Complex.cs: Add explicit BigInteger operator. + 2010-03-06 Rodrigo Kumpera * BigInteger.cs: Simply Parse/TryParse. diff --git a/mcs/class/System.Numerics/System.Numerics/Complex.cs b/mcs/class/System.Numerics/System.Numerics/Complex.cs index 86090e24978..c5d94e0970e 100644 --- a/mcs/class/System.Numerics/System.Numerics/Complex.cs +++ b/mcs/class/System.Numerics/System.Numerics/Complex.cs @@ -5,7 +5,7 @@ // Miguel de Icaza (miguel@gnome.org) // Marek Safar (marek.safar@gmail.com) // -// Copyright 2009 Novell, Inc. +// Copyright 2009, 2010 Novell, Inc. // // // @@ -179,10 +179,10 @@ namespace System.Numerics { return new Complex ((double) value, 0); } - //public static explicit operator Complex (BigInteger value) - //{ - // return new Complex ((double) value, 0); - //} + public static explicit operator Complex (BigInteger value) + { + return new Complex ((double) value, 0); + } public override string ToString () { diff --git a/mcs/class/System.Runtime.Caching/Assembly/AssemblyInfo.cs b/mcs/class/System.Runtime.Caching/Assembly/AssemblyInfo.cs new file mode 100644 index 00000000000..b5d614faa89 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Assembly/AssemblyInfo.cs @@ -0,0 +1,70 @@ +// +// AssemblyInfo.cs +// +// Author: +// Andreas Nahr (ClassDevelopment@A-SoftTech.com) +// +// (C) 2003 Ximian, Inc. http://www.ximian.com +// (C) 2010 Novell, Inc (http://novell.com/) +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Reflection; +using System.Resources; +using System.Security; +using System.Security.Permissions; +using System.Diagnostics; +using System.Runtime; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +[assembly: AssemblyTitle ("System.Runtime.Caching.dll")] +[assembly: AssemblyDescription ("System.Runtime.Caching.dll")] +[assembly: AssemblyDefaultAlias ("System.Runtime.Caching.dll")] + +[assembly: AssemblyCompany (Consts.MonoCompany)] +[assembly: AssemblyProduct (Consts.MonoProduct)] +[assembly: AssemblyCopyright (Consts.MonoCopyright)] +[assembly: AssemblyVersion (Consts.FxVersion)] +[assembly: SatelliteContractVersion (Consts.FxVersion)] +[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)] +[assembly: AssemblyFileVersion (Consts.FxFileVersion)] + +[assembly: NeutralResourcesLanguage ("en-US")] +[assembly: CLSCompliant (true)] +[assembly: AssemblyDelaySign (true)] + +[assembly: ComVisible (false)] + +[assembly: CompilationRelaxations (CompilationRelaxations.NoStringInterning)] +[assembly: RuntimeCompatibility (WrapNonExceptionThrows = true)] +[assembly: SecurityPermission (SecurityAction.RequestMinimum, SkipVerification = true)] + +[assembly: AssemblyKeyFile ("../msfinal.pub")] + +[assembly: AssemblyTargetedPatchBand ("1.0.21-0")] +[assembly: Debuggable (DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] +[assembly: AllowPartiallyTrustedCallers] +[assembly: SecurityRules (SecurityRuleSet.Level2, SkipVerificationInFullTrust=true)] diff --git a/mcs/class/System.Runtime.Caching/Assembly/ChangeLog b/mcs/class/System.Runtime.Caching/Assembly/ChangeLog new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mcs/class/System.Runtime.Caching/ChangeLog b/mcs/class/System.Runtime.Caching/ChangeLog new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mcs/class/System.Runtime.Caching/Makefile b/mcs/class/System.Runtime.Caching/Makefile new file mode 100644 index 00000000000..e72dfce0e5f --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Makefile @@ -0,0 +1,23 @@ +thisdir = class/System.Runtime.Caching +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Runtime.Caching.dll +LIB_MCS_FLAGS = -r:System.dll \ + -r:System.Data.dll \ + -r:System.Configuration.dll \ + -r:System.Core.dll + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = $(RESOURCE_FILES) + +VALID_PROFILE := $(filter 4.0, $(FRAMEWORK_VERSION)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.Runtime.Caching.dll +NO_INSTALL = yes +NO_SIGN_ASSEMBLY = yes +NO_TEST = yes +endif + +include ../../build/library.make diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/CachingSectionGroup.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/CachingSectionGroup.cs new file mode 100644 index 00000000000..41bf83cd7bb --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/CachingSectionGroup.cs @@ -0,0 +1,44 @@ +// +// CachingSectionGroup.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Configuration; + +namespace System.Runtime.Caching.Configuration +{ + public sealed class CachingSectionGroup : ConfigurationSectionGroup + { + [ConfigurationProperty ("memoryCache")] + public MemoryCacheSection MemoryCaches { + get { return Sections ["memoryCache"] as MemoryCacheSection; } + } + + public CachingSectionGroup () + { + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/ChangeLog b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/ChangeLog new file mode 100644 index 00000000000..408ba9d852b --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/ChangeLog @@ -0,0 +1,5 @@ +2010-04-24 Marek Habersack + + * MemoryCacheSettingsCollection.cs: added and implemented methods + which appeared in .NET 4.0 final. + diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheElement.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheElement.cs new file mode 100644 index 00000000000..f7f3336a1a7 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheElement.cs @@ -0,0 +1,110 @@ +// +// MemoryCacheElement.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.ComponentModel; +using System.Configuration; + +namespace System.Runtime.Caching.Configuration +{ + public sealed class MemoryCacheElement : ConfigurationElement + { + static ConfigurationProperty cacheMemoryLimitMegabytesProp; + static ConfigurationProperty nameProp; + static ConfigurationProperty physicalMemoryLimitPercentageProp; + static ConfigurationProperty pollingIntervalProp; + static ConfigurationPropertyCollection properties; + + [ConfigurationProperty ("cacheMemoryLimitMegabytes", DefaultValue = 0)] + [IntegerValidator (MinValue = 1)] + public int CacheMemoryLimitMegabytes { + get { return (int) base [cacheMemoryLimitMegabytesProp]; } + set { base [cacheMemoryLimitMegabytesProp] = value; } + } + + [ConfigurationProperty ("name", DefaultValue = "", IsRequired = true, IsKey = true)] + [TypeConverter (typeof(WhiteSpaceTrimStringConverter))] + [StringValidator (MinLength = 1)] + public string Name { + get { return (string) base [nameProp]; } + set { base [nameProp] = value; } + } + + [ConfigurationProperty ("physicalMemoryLimitPercentage", DefaultValue = 0)] + [IntegerValidator (MinValue = 1, MaxValue = 100)] + public int PhysicalMemoryLimitPercentage { + get { return (int) base [physicalMemoryLimitPercentageProp]; } + set { base [physicalMemoryLimitPercentageProp] = value; } + } + + [ConfigurationProperty ("pollingInterval", DefaultValue = "00:02:00")] + [TypeConverter (typeof(InfiniteTimeSpanConverter))] + public TimeSpan PollingInterval { + get { return (TimeSpan) base [pollingIntervalProp]; } + set { base [pollingIntervalProp] = value; } + } + + protected override ConfigurationPropertyCollection Properties { + get { return properties; } + } + + static MemoryCacheElement () + { + cacheMemoryLimitMegabytesProp = new ConfigurationProperty ("cacheMemoryLimitMegabytes", typeof (int), 0, + TypeDescriptor.GetConverter (typeof (int)), + new IntegerValidator (1, Int32.MaxValue), + ConfigurationPropertyOptions.None); + nameProp = new ConfigurationProperty ("name", typeof (string), String.Empty, + TypeDescriptor.GetConverter (typeof (string)), + new NullableStringValidator (1), + ConfigurationPropertyOptions.IsKey | ConfigurationPropertyOptions.IsRequired); + physicalMemoryLimitPercentageProp = new ConfigurationProperty ("physicalMemoryLimitPercentage", typeof (int), 0, + TypeDescriptor.GetConverter (typeof (int)), + new IntegerValidator (1, 100), + ConfigurationPropertyOptions.None); + pollingIntervalProp = new ConfigurationProperty ("pollingInterval", typeof (TimeSpan), TimeSpan.FromMinutes (2), + new InfiniteTimeSpanConverter (), + new DefaultValidator (), + ConfigurationPropertyOptions.None); + + properties = new ConfigurationPropertyCollection (); + properties.Add (cacheMemoryLimitMegabytesProp); + properties.Add (nameProp); + properties.Add (physicalMemoryLimitPercentageProp); + properties.Add (pollingIntervalProp); + } + + internal MemoryCacheElement () + { + } + + public MemoryCacheElement (string name) + { + this.Name = name; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheSection.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheSection.cs new file mode 100644 index 00000000000..a84f3a78a83 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheSection.cs @@ -0,0 +1,59 @@ +// +// MemoryCacheSection.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Configuration; + +namespace System.Runtime.Caching.Configuration +{ + public sealed class MemoryCacheSection : ConfigurationSection + { + static ConfigurationProperty namedCachesProp; + static ConfigurationPropertyCollection properties; + + static MemoryCacheSection () + { + namedCachesProp = new ConfigurationProperty ("namedCaches", typeof (MemoryCacheSettingsCollection), null); + + properties = new ConfigurationPropertyCollection (); + properties.Add (namedCachesProp); + } + + public MemoryCacheSection () + { + } + + [ConfigurationProperty ("namedCaches")] + public MemoryCacheSettingsCollection NamedCaches { + get { return base [namedCachesProp] as MemoryCacheSettingsCollection; } + } + + protected override ConfigurationPropertyCollection Properties { + get { return properties; } + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheSettingsCollection.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheSettingsCollection.cs new file mode 100644 index 00000000000..5ef8ad1843e --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Configuration/MemoryCacheSettingsCollection.cs @@ -0,0 +1,124 @@ +// +// MemoryCacheSettingsCollection.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Configuration; + +namespace System.Runtime.Caching.Configuration +{ + [ConfigurationCollection (typeof(MemoryCacheElement), CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)] + public sealed class MemoryCacheSettingsCollection : ConfigurationElementCollection + { + static ConfigurationPropertyCollection properties; + + public override ConfigurationElementCollectionType CollectionType { + get { return ConfigurationElementCollectionType.AddRemoveClearMap; } + } + + public MemoryCacheElement this[int index] { + get { return BaseGet (index) as MemoryCacheElement; } + set { + if (BaseGet (index) != null) + BaseRemoveAt (index); + BaseAdd (index, value); + } + } + + public new MemoryCacheElement this[string key] { + get { + foreach (MemoryCacheElement mce in this) { + if (String.Compare (key, mce.Name, StringComparison.Ordinal) == 0) + return mce; + } + + return null; + } + } + + protected override ConfigurationPropertyCollection Properties { + get { return properties; } + } + + static MemoryCacheSettingsCollection () + { + properties = new ConfigurationPropertyCollection (); + } + + public MemoryCacheSettingsCollection () + { + } + + public void Add (MemoryCacheElement cache) + { + BaseAdd (cache); + } + + public void Clear () + { + BaseClear (); + } + + protected override ConfigurationElement CreateNewElement () + { + return new MemoryCacheElement (); + } + + protected override ConfigurationElement CreateNewElement (string elementName) + { + return new MemoryCacheElement (elementName); + } + + protected override object GetElementKey (ConfigurationElement element) + { + if (element == null) + return null; + + return ((MemoryCacheElement)element).Name; + } + + public int IndexOf (MemoryCacheElement cache) + { + if (cache == null) + return -1; + + return BaseIndexOf (cache); + } + + public void Remove (MemoryCacheElement cache) + { + if (cache == null) + return; + + BaseRemove (GetElementKey (cache)); + } + + public void RemoveAt (int index) + { + BaseRemoveAt (index); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/ChangeLog b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/ChangeLog new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IApplicationIdentifier.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IApplicationIdentifier.cs new file mode 100644 index 00000000000..17b59dde29f --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IApplicationIdentifier.cs @@ -0,0 +1,36 @@ +// +// IApplicationIdentifier.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching.Hosting +{ + public interface IApplicationIdentifier + { + string GetApplicationId (); + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IFileChangeNotificationSystem.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IFileChangeNotificationSystem.cs new file mode 100644 index 00000000000..fa46c2f3088 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IFileChangeNotificationSystem.cs @@ -0,0 +1,37 @@ +// +// IFileChangeNotificationSystem.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching.Hosting +{ + public interface IFileChangeNotificationSystem + { + void StartMonitoring (string filePath, OnChangedCallback onChangedCallback, out object state, out DateTimeOffset lastWriteTime, out long fileSize); + void StopMonitoring (string filePath, object state); + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IMemoryCacheManager.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IMemoryCacheManager.cs new file mode 100644 index 00000000000..1e01b3e790c --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.Hosting/IMemoryCacheManager.cs @@ -0,0 +1,38 @@ +// +// IMemoryCacheManager.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Runtime.Caching; + +namespace System.Runtime.Caching.Hosting +{ + public interface IMemoryCacheManager + { + void ReleaseCache (MemoryCache cache); + void UpdateCacheSize (long size, MemoryCache cache); + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching.dll.sources b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.dll.sources new file mode 100644 index 00000000000..2278e3e3411 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching.dll.sources @@ -0,0 +1,41 @@ +../../build/common/Consts.cs +../../build/common/Locale.cs +../../build/common/MonoTODOAttribute.cs +../System.Web/System.Web.Configuration_2.0/NullableStringValidator.cs + +Assembly/AssemblyInfo.cs +System.Runtime.Caching/CacheEntryChangeMonitor.cs +System.Runtime.Caching/CacheEntryRemovedArguments.cs +System.Runtime.Caching/CacheEntryRemovedCallback.cs +System.Runtime.Caching/CacheEntryRemovedReason.cs +System.Runtime.Caching/CacheEntryUpdateArguments.cs +System.Runtime.Caching/CacheEntryUpdateCallback.cs +System.Runtime.Caching/CacheItem.cs +System.Runtime.Caching/CacheItemPolicy.cs +System.Runtime.Caching/CacheItemPriority.cs +System.Runtime.Caching/ChangeMonitor.cs +System.Runtime.Caching/DefaultCacheCapabilities.cs +System.Runtime.Caching/FileChangeMonitor.cs +System.Runtime.Caching/FileChangeNotificationSystem.cs +System.Runtime.Caching/FileChangeNotificationSystemEntry.cs +System.Runtime.Caching/Helpers.cs +System.Runtime.Caching/HostFileChangeMonitor.cs +System.Runtime.Caching/MemoryCache.cs +System.Runtime.Caching/MemoryCacheContainer.cs +System.Runtime.Caching/MemoryCacheEntry.cs +System.Runtime.Caching/MemoryCacheEntryChangeMonitor.cs +System.Runtime.Caching/MemoryCacheLRU.cs +System.Runtime.Caching/MemoryCachePerformanceCounters.cs +System.Runtime.Caching/MemoryCacheEntryPriorityQueue.cs +System.Runtime.Caching/ObjectCache.cs +System.Runtime.Caching/OnChangedCallback.cs +System.Runtime.Caching/SqlChangeMonitor.cs + +System.Runtime.Caching.Configuration/CachingSectionGroup.cs +System.Runtime.Caching.Configuration/MemoryCacheSection.cs +System.Runtime.Caching.Configuration/MemoryCacheSettingsCollection.cs +System.Runtime.Caching.Configuration/MemoryCacheElement.cs + +System.Runtime.Caching.Hosting/IApplicationIdentifier.cs +System.Runtime.Caching.Hosting/IFileChangeNotificationSystem.cs +System.Runtime.Caching.Hosting/IMemoryCacheManager.cs diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryChangeMonitor.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryChangeMonitor.cs new file mode 100644 index 00000000000..a56c9abe761 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryChangeMonitor.cs @@ -0,0 +1,43 @@ +// +// CacheEntryChangeMonitor.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.ObjectModel; + +namespace System.Runtime.Caching +{ + public abstract class CacheEntryChangeMonitor : ChangeMonitor + { + public abstract ReadOnlyCollection CacheKeys { get; } + public abstract DateTimeOffset LastModified { get; } + public abstract string RegionName { get; } + + protected CacheEntryChangeMonitor () + { + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedArguments.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedArguments.cs new file mode 100644 index 00000000000..ef57ee2dbfe --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedArguments.cs @@ -0,0 +1,51 @@ +// +// CacheEntryRemovedArguments.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public class CacheEntryRemovedArguments + { + public CacheItem CacheItem { get; private set; } + public CacheEntryRemovedReason RemovedReason { get; private set; } + public ObjectCache Source { get; private set; } + + public CacheEntryRemovedArguments (ObjectCache source, CacheEntryRemovedReason reason, CacheItem cacheItem) + { + if (source == null) + throw new ArgumentNullException ("source"); + + if (cacheItem == null) + throw new ArgumentNullException ("cacheItem"); + + this.CacheItem = cacheItem; + this.RemovedReason = reason; + this.Source = source; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedCallback.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedCallback.cs new file mode 100644 index 00000000000..600f406c5e5 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedCallback.cs @@ -0,0 +1,33 @@ +// +// CacheEntryRemovedCallback.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public delegate void CacheEntryRemovedCallback (CacheEntryRemovedArguments arguments); +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedReason.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedReason.cs new file mode 100644 index 00000000000..b04e1e13e1e --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryRemovedReason.cs @@ -0,0 +1,40 @@ +// +// CacheEntryRemoveReason.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public enum CacheEntryRemovedReason + { + Removed, + Expired, + Evicted, + ChangeMonitorChanged, + CacheSpecificEviction + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryUpdateArguments.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryUpdateArguments.cs new file mode 100644 index 00000000000..2fae5282e6a --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryUpdateArguments.cs @@ -0,0 +1,55 @@ +// +// CacheEntryUpdateArguments.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public class CacheEntryUpdateArguments + { + public string Key { get; private set; } + public string RegionName { get; private set; } + public CacheEntryRemovedReason RemovedReason { get; private set; } + public ObjectCache Source { get; private set; } + public CacheItem UpdatedCacheItem { get; set; } + public CacheItemPolicy UpdatedCacheItemPolicy { get; set; } + + public CacheEntryUpdateArguments (ObjectCache source, CacheEntryRemovedReason reason, string key, string regionName) + { + if (source == null) + throw new ArgumentNullException ("source"); + + if (key == null) + throw new ArgumentNullException ("key"); + + this.Key = key; + this.RegionName = regionName; + this.RemovedReason = reason; + this.Source = source; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryUpdateCallback.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryUpdateCallback.cs new file mode 100644 index 00000000000..0de0cc5f393 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheEntryUpdateCallback.cs @@ -0,0 +1,33 @@ +// +// CacheEntryUpdateCallback.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public delegate void CacheEntryUpdateCallback (CacheEntryUpdateArguments arguments); +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItem.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItem.cs new file mode 100644 index 00000000000..42eba2d0b2a --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItem.cs @@ -0,0 +1,53 @@ +// +// CacheItem.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public class CacheItem + { + public string Key { get; set; } + public string RegionName { get; set; } + public object Value { get; set; } + + public CacheItem (string key) : this (key, null, null) + { + } + + public CacheItem (string key, object value) : this (key, value, null) + { + } + + public CacheItem (string key, object value, string regionName) + { + this.Key = key; + this.RegionName = regionName; + this.Value = value; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItemPolicy.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItemPolicy.cs new file mode 100644 index 00000000000..3c0a7fa7147 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItemPolicy.cs @@ -0,0 +1,60 @@ +// +// CacheItemPolicy.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.ObjectModel; + +namespace System.Runtime.Caching +{ + public class CacheItemPolicy + { + Collection changeMonitors; + + public DateTimeOffset AbsoluteExpiration { get; set; } + + public Collection ChangeMonitors { + get { + if (changeMonitors == null) + changeMonitors = new Collection (); + + return changeMonitors; + } + } + + public CacheItemPriority Priority { get; set; } + public CacheEntryRemovedCallback RemovedCallback { get; set; } + public TimeSpan SlidingExpiration { get; set; } + public CacheEntryUpdateCallback UpdateCallback { get; set; } + + public CacheItemPolicy () + { + this.AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration; + this.Priority = CacheItemPriority.Default; + this.SlidingExpiration = ObjectCache.NoSlidingExpiration; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItemPriority.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItemPriority.cs new file mode 100644 index 00000000000..71e5a27a299 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/CacheItemPriority.cs @@ -0,0 +1,37 @@ +// +// CacheItemPriority.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public enum CacheItemPriority + { + Default, + NotRemovable + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ChangeLog b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ChangeLog new file mode 100644 index 00000000000..3e5faffd2c4 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ChangeLog @@ -0,0 +1,43 @@ +2010-04-26 Marek Habersack + + * MemoryCacheLRU.cs: added + + * MemoryCacheContainer.cs: added LRU entry cache. + + * MemoryCache.cs: added option to emulate one CPU on SMP machines + (for testing purposes) - "__MonoEmulateOneCPU" + +2010-04-24 Marek Habersack + + * ObjectCache.cs: implemented all the non-abstract methods. + + * MemoryCacheContainer.cs, MemoryCacheEntry.cs, + MemoryCacheEntryChangeMonitor.cs, + MemoryCacheEntryPriorityQueue.cs, + MemoryCachePerformanceCounters.cs: added + + * MemoryCache.cs: implemented physical memory size detection, item + expiration timer, indexer, reading of configuration values from + config files, cache memory limit calculation, the + AddOrGetExisting, Set, Get, Contains, + CreateCacheEntryChangeMonitor, Dispose, GetCacheItem, GetCount, + GetEnumerator, GetValues, Remove and Trim methods. + Implemented support for per-cpu item containers. + Modified parameters of several methods to match .NET 4.0 release. + + * HostFileChangeMonitor.cs: implemented according to tests. + + * Helpers.cs: added new properties, StringComparer and Is64bit + + * FileChangeNotificationSystemEntry.cs: added + + * FileChangeNotificationSystem.cs: implemented + + * ChangeMonitor.cs: NotifyOnChanged now properly throws an + exception if it was called more than once. + + * CacheEntryRemovedReason.cs: renamed from + CacheEntryRemoveReason.cs + + * CacheEntryChangeMonitor.cs: renamed from CacheEntryMonitor.cs + diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ChangeMonitor.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ChangeMonitor.cs new file mode 100644 index 00000000000..a0f5fcdc3a8 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ChangeMonitor.cs @@ -0,0 +1,128 @@ +// +// ChangeMonitor.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public abstract class ChangeMonitor : IDisposable + { + bool initializationComplete; + bool notifyOnChangedCalled; + OnChangedCallback onChangedCallback; + object onChangedState; + + public bool HasChanged { get; private set; } + public bool IsDisposed { get; private set; } + public abstract string UniqueId { get; } + + protected ChangeMonitor () + { + } + + public void Dispose () + { + if (IsDisposed) + return; + + if (!initializationComplete) + // TODO: check if Dispose (bool) is called in this case + throw new InvalidOperationException ("Initialization is not complete in the derived change-monitor class that called the base Dispose method."); + + try { + try { + InvokeOnChangedCallback (onChangedState); + } catch { + // ignore + // TODO: check what happens if the callback throws an exception - is + // Dispose (true) called then? + } + + Dispose (true); + } finally { + IsDisposed = true; + } + } + + protected abstract void Dispose (bool disposing); + + protected void InitializationComplete () + { + initializationComplete = true; + if (HasChanged) + Dispose (); + } + + void InvokeOnChangedCallback (object state) + { + if (onChangedCallback == null) + return; + + try { + onChangedCallback (state); + } finally { + onChangedCallback = null; + onChangedState = null; + } + } + + public void NotifyOnChanged (OnChangedCallback onChangedCallback) + { + if (onChangedCallback == null) + throw new ArgumentNullException ("onChangedCallback"); + + if (notifyOnChangedCalled) + throw new InvalidOperationException ("The callback method has already been invoked."); + + notifyOnChangedCalled = true; + this.onChangedCallback = onChangedCallback; + if (HasChanged) { + InvokeOnChangedCallback (onChangedState); + return; + } + + } + + protected void OnChanged (object state) + { + HasChanged = true; + try { + if (onChangedCallback == null) + onChangedState = state; + else + InvokeOnChangedCallback (state); + } catch { + // ignore + // TODO: check what happens if callback throws an exception - is + // Dispose below called? + } finally { + if (initializationComplete) + Dispose (); + } + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/DefaultCacheCapabilities.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/DefaultCacheCapabilities.cs new file mode 100644 index 00000000000..2fd90c415bf --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/DefaultCacheCapabilities.cs @@ -0,0 +1,45 @@ +// +// DefaultCacheCapabilities.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + [Flags] + public enum DefaultCacheCapabilities + { + None = 0x00, + InMemoryProvider = 0x01, + OutOfProcessProvider = 0x02, + CacheEntryChangeMonitors = 0x04, + AbsoluteExpirations = 0x08, + SlidingExpirations = 0x10, + CacheEntryUpdateCallback = 0x20, + CacheEntryRemovedCallback = 0x40, + CacheRegions = 0x80 + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeMonitor.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeMonitor.cs new file mode 100644 index 00000000000..a3eb1794157 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeMonitor.cs @@ -0,0 +1,42 @@ +// +// FileChangeMonitor.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.ObjectModel; + +namespace System.Runtime.Caching +{ + public abstract class FileChangeMonitor : ChangeMonitor + { + public abstract ReadOnlyCollection FilePaths { get; } + public abstract DateTimeOffset LastModified { get; } + + protected FileChangeMonitor () + { + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeNotificationSystem.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeNotificationSystem.cs new file mode 100644 index 00000000000..39de267874d --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeNotificationSystem.cs @@ -0,0 +1,155 @@ +// +// FileChangeNotificationSystem.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Caching.Hosting; +using System.Text; + +namespace System.Runtime.Caching +{ + sealed class FileChangeNotificationSystem : IFileChangeNotificationSystem, IDisposable + { + static readonly object watchers_lock = new object (); + + Dictionary watchers; + OnChangedCallback callback; + + Dictionary Watchers { + get { + if (watchers == null) + watchers = new Dictionary (Helpers.StringEqualityComparer); + + return watchers; + } + } + + public void StartMonitoring (string filePath, OnChangedCallback onChangedCallback, out object state, out DateTimeOffset lastWriteTime, out long fileSize) + { + if (String.IsNullOrEmpty (filePath)) + throw new ArgumentNullException ("filePath"); + + callback = onChangedCallback; + + string parentDir; + if (File.Exists (filePath)) { + var fi = new FileInfo (filePath); + lastWriteTime = DateTimeOffset.FromFileTime (fi.LastWriteTimeUtc.Ticks); + fileSize = fi.Length; + parentDir = Path.GetDirectoryName (filePath); + } else if (Directory.Exists (filePath)) { + var di = new DirectoryInfo (filePath); + lastWriteTime = DateTimeOffset.FromFileTime (di.LastWriteTimeUtc.Ticks); + fileSize = -1L; + parentDir = filePath; + } else { + lastWriteTime = DateTimeOffset.MaxValue; + fileSize = -1L; + + if (filePath.LastIndexOf (Path.DirectorySeparatorChar) != -1) + parentDir = Path.GetDirectoryName (filePath); + else + parentDir = filePath; + } + + FileChangeNotificationSystemEntry entry; + lock (watchers_lock) { + Dictionary watchers = Watchers; + + if (!watchers.TryGetValue (parentDir, out entry)) { + entry = new FileChangeNotificationSystemEntry (parentDir, this); + watchers.Add (parentDir, entry); + } + + entry.Add (filePath); + entry.Start (); + } + + state = entry; + } + + public void StopMonitoring (string filePath, object state) + { + if (String.IsNullOrEmpty (filePath)) + return; + + var entry = state as FileChangeNotificationSystemEntry; + if (entry == null) + return; + + lock (watchers_lock) { + entry.Remove (filePath); + if (entry.IsEmpty) { + if (watchers != null && watchers.ContainsKey (filePath)) + watchers.Remove (filePath); + + entry.Stop (); + entry.Dispose (); + } + } + } + + public void OnChanged (WatcherChangeTypes changeType, string filePath, string newFilePath) + { + if (callback == null) + return; + + FileChangeNotificationSystemEntry entry; + + if (watchers == null || !watchers.TryGetValue (filePath, out entry)) + entry = null; + + callback (entry); + } + + public void Dispose () + { + lock (watchers_lock) { + if (watchers == null || watchers.Count == 0) + return; + + FileChangeNotificationSystemEntry entry; + foreach (var de in watchers) { + entry = de.Value; + if (entry == null) + continue; + + entry.Stop (); + entry.Dispose (); + } + + watchers.Clear (); + } + } + + void IDisposable.Dispose () + { + Dispose (); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeNotificationSystemEntry.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeNotificationSystemEntry.cs new file mode 100644 index 00000000000..0445dcb1b8a --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/FileChangeNotificationSystemEntry.cs @@ -0,0 +1,179 @@ +// +// FileChangeNotificationSystemEntry.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.Caching.Hosting; +using System.Text; + +namespace System.Runtime.Caching +{ + // This class is NOT thread-safe - the caller needs to assure access serialization when + // calling Add/Remove + sealed class FileChangeNotificationSystemEntry : IDisposable + { + string watchedDirPath; + FileChangeNotificationSystem owner; + FileSystemWatcher watcher; + SortedDictionary filePaths; + + SortedDictionary FilePaths { + get { + if (filePaths == null) + filePaths = new SortedDictionary (Helpers.StringComparer); + return filePaths; + } + } + + public bool IsEmpty { + get { return (filePaths == null || filePaths.Count == 0); } + } + + public FileChangeNotificationSystemEntry (string dirPath, FileChangeNotificationSystem owner) + { + if (String.IsNullOrEmpty (dirPath)) + throw new ArgumentNullException ("dirPath"); + + if (owner == null) + throw new ArgumentNullException ("owner"); + + watchedDirPath = dirPath; + this.owner = owner; + } + + public void Add (string filePath) + { + if (String.IsNullOrEmpty (filePath)) + return; + + bool start = false; + try { + if (watcher == null) { + watcher = new FileSystemWatcher (watchedDirPath); + watcher.IncludeSubdirectories = false; + watcher.Filter = String.Empty; + watcher.NotifyFilter = NotifyFilters.FileName | + NotifyFilters.DirectoryName | + NotifyFilters.Size | + NotifyFilters.LastWrite | + NotifyFilters.CreationTime; + watcher.Changed += OnChanged; + watcher.Created += OnChanged; + watcher.Deleted += OnChanged; + watcher.Renamed += OnRenamed; + } else if (watcher.EnableRaisingEvents) { + Stop (); + start = true; + } + + SortedDictionary filePaths = FilePaths; + if (filePaths.ContainsKey (filePath)) + return; + + filePaths.Add (filePath, true); + } finally { + if (start) + Start (); + } + } + + public void Remove (string filePath) + { + if (filePath == null) + return; + + bool start = false; + try { + if (watcher != null && watcher.EnableRaisingEvents) { + Stop (); + start = true; + } + + SortedDictionary filePaths = FilePaths; + if (!filePaths.ContainsKey (filePath)) + return; + + filePaths.Remove (filePath); + } finally { + if (start) + Start (); + } + } + + public void Start () + { + if (watcher == null) + return; + + watcher.EnableRaisingEvents = true; + } + + public void Stop () + { + if (watcher == null) + return; + + watcher.EnableRaisingEvents = false; + } + + public void Dispose () + { + if (watcher == null) + return; + + try { + Stop (); + } finally { + watcher.Dispose (); + } + } + + void IDisposable.Dispose () + { + Dispose (); + } + + void OnChanged (object source, FileSystemEventArgs e) + { + string fullPath = e.FullPath; + if (owner == null || filePaths == null || !filePaths.ContainsKey (fullPath)) + return; + + owner.OnChanged (e.ChangeType, fullPath, null); + } + + void OnRenamed (object source, RenamedEventArgs e) + { + string fullPath = e.FullPath; + if (owner == null || filePaths == null || !filePaths.ContainsKey (fullPath)) + return; + + owner.OnChanged (e.ChangeType, e.OldFullPath, e.FullPath); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/Helpers.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/Helpers.cs new file mode 100644 index 00000000000..03852438fe2 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/Helpers.cs @@ -0,0 +1,94 @@ +// +// ObjectCache.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; + +namespace System.Runtime.Caching +{ + static class Helpers + { + public static bool CaseInsensitive { + get; + private set; + } + + public static bool Is64Bit { + get; + private set; + } + + public static IEqualityComparer StringEqualityComparer { + get; private set; + } + + public static IComparer StringComparer { + get; private set; + } + + public static StringComparison StringComparison { + get; private set; + } + + static Helpers () + { + PlatformID pid = Environment.OSVersion.Platform; + bool runningOnWindows = ((int) pid != 128 && pid != PlatformID.Unix && pid != PlatformID.MacOSX); + + Is64Bit = IntPtr.Size == 8; + if (runningOnWindows) + CaseInsensitive = true; + else { + string mono_iomap = Environment.GetEnvironmentVariable ("MONO_IOMAP"); + if (!String.IsNullOrEmpty (mono_iomap)) { + if (mono_iomap == "all") + CaseInsensitive = true; + else { + string[] parts = mono_iomap.Split (':'); + foreach (string p in parts) { + if (p == "all" || p == "case") { + CaseInsensitive = true; + break; + } + } + } + } + } + + if (CaseInsensitive) { + StringEqualityComparer = global::System.StringComparer.OrdinalIgnoreCase; + StringComparer = global::System.StringComparer.OrdinalIgnoreCase; + StringComparison = global::System.StringComparison.OrdinalIgnoreCase; + } else { + StringEqualityComparer = global::System.StringComparer.Ordinal; + StringComparer = global::System.StringComparer.Ordinal; + StringComparison = global::System.StringComparison.Ordinal; + + } + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/HostFileChangeMonitor.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/HostFileChangeMonitor.cs new file mode 100644 index 00000000000..93a8ee7bde2 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/HostFileChangeMonitor.cs @@ -0,0 +1,195 @@ +// +// HostFileChangeMonitor.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Runtime.Caching.Hosting; +using System.Text; + +namespace System.Runtime.Caching +{ + public sealed class HostFileChangeMonitor : FileChangeMonitor + { + const long INVALID_FILE_SIZE = -1L; + static readonly object notificationSystemLock = new object (); + static readonly DateTime missingFileTimeStamp = new DateTime (0x701CE1722770000); + static IFileChangeNotificationSystem notificationSystem; + static bool notificationSystemSetFromHost; + + ReadOnlyCollection filePaths; + DateTime lastModified; + string uniqueId; + bool disposeNotificationSystem; + + Dictionary notificationStates; + + public override ReadOnlyCollection FilePaths { + get { return filePaths;} + } + + public override DateTimeOffset LastModified { + get { return lastModified; } + } + + public override string UniqueId { + get { return uniqueId; } + } + + public HostFileChangeMonitor (IList filePaths) + { + if (filePaths == null) + throw new ArgumentNullException ("filePaths"); + + if (filePaths.Count == 0) + throw new ArgumentException ("filePaths contains zero items."); + + var list = new List (filePaths.Count); + var sb = new StringBuilder (); + lastModified = DateTime.MinValue; + DateTime lastWrite; + long size; + bool ignoreForUniqueId; + + foreach (string p in filePaths) { + if (String.IsNullOrEmpty (p)) + throw new ArgumentException ("A path in the filePaths list is null or an empty string."); + + if (!Path.IsPathRooted (p)) + throw new ArgumentException ("Absolute path information is required."); + + if (list.Contains (p)) + ignoreForUniqueId = true; + else + ignoreForUniqueId = false; + + list.Add (p); + + if (ignoreForUniqueId) + continue; + + if (Directory.Exists (p)) { + var di = new DirectoryInfo (p); + lastWrite = di.LastWriteTimeUtc; + size = INVALID_FILE_SIZE; + } else if (File.Exists (p)) { + var fi = new FileInfo (p); + lastWrite = fi.LastWriteTimeUtc; + size = fi.Length; + } else { + lastWrite = missingFileTimeStamp; + size = INVALID_FILE_SIZE; + } + + if (lastWrite > lastModified) + lastModified = lastWrite; + + sb.AppendFormat ("{0}{1:X}{2:X}", p, lastWrite.Ticks, (ulong)size); + } + + this.filePaths = new ReadOnlyCollection (list); + this.uniqueId = sb.ToString (); + + bool initComplete = false; + try { + InitMonitoring (); + initComplete = true; + } finally { + InitializationComplete (); + if (!initComplete) + Dispose (); + } + } + + void InitMonitoring () + { + IServiceProvider host; + if (!notificationSystemSetFromHost && (host = ObjectCache.Host) != null) { + lock (notificationSystemLock) { + if (!notificationSystemSetFromHost) { + if (host != null) + notificationSystem = host.GetService (typeof (IFileChangeNotificationSystem)) as IFileChangeNotificationSystem; + + if (notificationSystem != null) + notificationSystemSetFromHost = true; + } + } + } + + if (!notificationSystemSetFromHost) { + notificationSystem = new FileChangeNotificationSystem (); + disposeNotificationSystem = true; + } + + object state; + + // TODO: what are these two used for? + DateTimeOffset lastWriteTime; + long fileSize; + + notificationStates = new Dictionary (filePaths.Count, Helpers.StringEqualityComparer); + foreach (string path in filePaths) { + if (notificationStates.ContainsKey (path)) + continue; // silently ignore dupes + + notificationSystem.StartMonitoring (path, OnChanged, out state, out lastWriteTime, out fileSize); + notificationStates.Add (path, state); + } + } + + protected override void Dispose (bool disposing) + { + if (disposing && notificationSystem != null) { + object state; + + foreach (var de in notificationStates) { + state = de.Value; + if (state == null) + continue; + + try { + notificationSystem.StopMonitoring (de.Key, state); + } catch { + // ignore + } + } + + if (disposeNotificationSystem) { + var fcns = notificationSystem as FileChangeNotificationSystem; + if (fcns != null) { + try { + fcns.Dispose (); + } finally { + notificationSystem = null; + } + } + } + } + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCache.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCache.cs new file mode 100644 index 00000000000..272b006050a --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCache.cs @@ -0,0 +1,600 @@ +// +// MemoryCache.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Configuration; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.Caching.Configuration; +using System.Threading; + +namespace System.Runtime.Caching +{ + public class MemoryCache : ObjectCache, IEnumerable, IDisposable + { + const long DEFAULT_TIMER_PERIOD = 20000; // .NET's default, ms + + static long totalPhysicalMemory = 0; + static int numCPUs; + + string name; + MemoryCacheContainer[] containers; + DefaultCacheCapabilities defaultCaps; + MemoryCachePerformanceCounters perfCounters; + bool noPerformanceCounters; + bool emulateOneCPU; + + static ulong TotalPhysicalMemory { + get { + if (totalPhysicalMemory == 0) + DetermineTotalPhysicalMemory (); + + return (ulong)totalPhysicalMemory; + } + } + + internal long TimerPeriod { + get; private set; + } + + public static MemoryCache Default { get; private set; } + + // LAMESPEC: this value is represented in bytes, not megabytes + public long CacheMemoryLimit { get; private set; } + + public override DefaultCacheCapabilities DefaultCacheCapabilities { + get { return defaultCaps; } + } + + public override object this [string key] { + [TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] + get { return FindContainer (key).Get (key); } + set { Set (key, value, ObjectCache.InfiniteAbsoluteExpiration); } + } + + public override string Name { + [TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] + get { return name; } + } + + public long PhysicalMemoryLimit { get; private set; } + public TimeSpan PollingInterval { get; private set; } + + static MemoryCache () + { + numCPUs = Environment.ProcessorCount; + Default = new MemoryCache (); + } + + MemoryCache () + { + name = "Default"; + CommonInit (name); + } + + public MemoryCache (string name, NameValueCollection config = null) + { + if (name == null) + throw new ArgumentNullException ("name"); + + if (name.Length == 0) + throw new ArgumentException ("is an empty string.", "name"); + + if (String.Compare (name, "default", StringComparison.OrdinalIgnoreCase) == 0) + throw new ArgumentException ("'default' is a reserved name.", "name"); + + this.name = name; + CommonInit (name, config); + } + + void CommonInit (string name, NameValueCollection config = null) + { + this.defaultCaps = DefaultCacheCapabilities.InMemoryProvider | + DefaultCacheCapabilities.CacheEntryChangeMonitors | + DefaultCacheCapabilities.AbsoluteExpirations | + DefaultCacheCapabilities.SlidingExpirations | + DefaultCacheCapabilities.CacheEntryRemovedCallback | + DefaultCacheCapabilities.CacheEntryUpdateCallback; + + GetValuesFromConfig (name, config); + containers = new MemoryCacheContainer [numCPUs]; + perfCounters = new MemoryCachePerformanceCounters (name.ToLowerInvariant (), noPerformanceCounters); + } + + static void DetermineTotalPhysicalMemory () + { + var pc = new PerformanceCounter ("Mono Memory", "Total Physical Memory"); + long memBytes = pc.RawValue; + + if (memBytes == 0) + memBytes = 134217728L; // 128MB, the runtime default when it's + // impossible to determine the physical + // memory size + + Interlocked.CompareExchange (ref totalPhysicalMemory, memBytes, 0); + } + + bool ParseBoolConfigValue (string paramName, string name, NameValueCollection config, bool doTrow) + { + string value = config [name]; + if (String.IsNullOrEmpty (value)) + return false; + + try { + return Boolean.Parse (value); + } catch { + return false; + } + } + + bool ParseInt32ConfigValue (string paramName, string name, NameValueCollection config, int maxValue, bool doThrow, out int parsed) + { + parsed = -1; + string value = config [name]; + if (String.IsNullOrEmpty (value)) + return false; + + try { + parsed = (int)UInt32.Parse (value); + } catch (Exception ex) { + if (doThrow) + throw new ArgumentException ( + String.Format ("Invalid configuration: {0}=\"{1}\". The {0} value must be a non-negative 32-bit integer", name, value), + paramName, + ex); + return false; + } + + if (parsed < 0 || (uint)parsed > (uint)maxValue) { + if (doThrow) + throw new ArgumentException ( + String.Format ("Invalid configuration: {0}=\"{1}\". The {0} value cannot be greater than '{2}'.", name, value, maxValue), + paramName); + return false; + } + + return true; + } + + bool ParseTimeSpanConfigValue (string paramName, string name, NameValueCollection config, out TimeSpan parsed) + { + string value = config [name]; + if (String.IsNullOrEmpty (value)) { + parsed = TimeSpan.MinValue; + return false; + } + + try { + parsed = TimeSpan.Parse (value); + return true; + } catch (Exception ex) { + throw new ArgumentException ( + String.Format ("Invalid configuration: {0}=\"{1}\". The {0} value must be a time interval that can be parsed by System.TimeSpan.Parse", name, value), + paramName, + ex); + } + } + + void GetValuesFromConfig (string name, NameValueCollection config) + { + var mcs = ConfigurationManager.GetSection ("system.runtime.caching/memoryCache") as MemoryCacheSection; + MemoryCacheSettingsCollection settings = mcs != null ? mcs.NamedCaches : null; + MemoryCacheElement element = settings != null ? settings [name] : null; + + if (element != null && config == null) { + CacheMemoryLimit = (long)element.CacheMemoryLimitMegabytes * 1048576L; + PhysicalMemoryLimit = (long)element.PhysicalMemoryLimitPercentage; + PollingInterval = element.PollingInterval; + } + + if (config != null) { + int parsed; + + if (ParseInt32ConfigValue ("config", "cacheMemoryLimitMegabytes", config, Int32.MaxValue, true, out parsed)) + CacheMemoryLimit = parsed * 1048576L; + else if (element != null) + CacheMemoryLimit = (long)element.CacheMemoryLimitMegabytes * 1048576L; + + if (ParseInt32ConfigValue ("config", "physicalMemoryLimitPercentage", config, 100, true, out parsed)) + PhysicalMemoryLimit = parsed; + else if (element != null) + PhysicalMemoryLimit = (long)element.PhysicalMemoryLimitPercentage; + + TimeSpan ts; + if (ParseTimeSpanConfigValue ("config", "pollingInterval", config, out ts)) + PollingInterval = ts; + else if (element != null) + PollingInterval = element.PollingInterval; + + // Those are Mono-specific + if (!String.IsNullOrEmpty (config ["__MonoDisablePerformanceCounters"])) + noPerformanceCounters = true; + + if (ParseInt32ConfigValue ("config", "__MonoTimerPeriod", config, Int32.MaxValue, false, out parsed)) + TimerPeriod = (long)(parsed * 1000); + else + TimerPeriod = DEFAULT_TIMER_PERIOD; + + if (ParseBoolConfigValue ("config", "__MonoEmulateOneCPU", config, false)) + emulateOneCPU = true; + } else + TimerPeriod = DEFAULT_TIMER_PERIOD; + + if (CacheMemoryLimit == 0) { + // Calculated using algorithm described in this blog entry: + // + // http://blogs.msdn.com/tmarq/archive/2007/06/25/some-history-on-the-asp-net-cache-memory-limits.aspx + // + ulong physicalRam = TotalPhysicalMemory; + ulong maxCacheSize; + + // Determine the upper bound + if (Helpers.Is64Bit) + maxCacheSize = 0x10000000000UL; // 1TB + else if (physicalRam > 0x80000000UL) // 2GB + maxCacheSize = 0x70800000UL; // 1800MB + else + maxCacheSize = 0x32000000UL; // 800MB + + physicalRam = (physicalRam * 3) / 5; // 60% + CacheMemoryLimit = (long)Math.Min (physicalRam, maxCacheSize); + } + + if (PhysicalMemoryLimit == 0) + PhysicalMemoryLimit = 98; + + if (PollingInterval == TimeSpan.Zero) + PollingInterval = TimeSpan.FromMinutes (2); + } + + public override CacheItem AddOrGetExisting (CacheItem item, CacheItemPolicy policy) + { + if (item == null) + throw new ArgumentNullException ("item"); + + string key = item.Key; + return new CacheItem (key, DoAddOrGetExisting (key, item.Value, policy)); + } + + public override object AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + return DoAddOrGetExisting (key, value, policy, regionName); + } + + public override object AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + var policy = new CacheItemPolicy (); + policy.AbsoluteExpiration = absoluteExpiration; + + return DoAddOrGetExisting (key, value, policy, regionName); + } + + object DoAddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null) + { + if (key == null) + throw new ArgumentNullException ("key"); + + if (value == null) + throw new ArgumentNullException ("value"); + + if (policy != null) { + ValidatePolicy (policy, false); + if (policy.AbsoluteExpiration < DateTimeOffset.Now) + return null; + } + + return FindContainer (key).AddOrGetExisting (key, value, policy); + } + + public override bool Contains (string key, string regionName = null) + { + if (key == null) + throw new ArgumentNullException ("key"); + + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + return FindContainer (key).ContainsKey (key); + } + + public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor (IEnumerable keys, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + if (keys == null) + throw new ArgumentNullException ("keys"); + + int count = 0; + foreach (string key in keys) { + if (key == null) + throw new ArgumentException ("The collection 'keys' contains a null element."); + count++; + } + if (count == 0) + throw new ArgumentException ("The collection 'keys' is empty"); + + return new MemoryCacheEntryChangeMonitor (this, keys); + } + + public void Dispose () + { + foreach (MemoryCacheContainer container in containers) { + if (container == null) + continue; + + container.Dispose (); + } + + perfCounters.Dispose (); + } + + MemoryCacheContainer FindContainer (string key) + { + if (key == null) + throw new ArgumentNullException ("key"); + + if (emulateOneCPU || numCPUs == 1) { + if (containers [0] == null) + containers [0] = new MemoryCacheContainer (this, 0, perfCounters); + + return containers [0]; + } + + int containerIdx = Math.Abs (key.GetHashCode () % numCPUs); + if (containers [containerIdx] == null) + containers [containerIdx] = new MemoryCacheContainer (this, containerIdx, perfCounters); + + return containers [containerIdx]; + } + + [TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] + public override object Get (string key, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + if (key == null) + throw new ArgumentNullException ("key"); + + return FindContainer (key).Get (key); + } + + internal MemoryCacheEntry GetEntry (string key) + { + return FindContainer (key).GetEntry (key); + } + + public override CacheItem GetCacheItem (string key, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + if (key == null) + throw new ArgumentNullException ("key"); + + object value = Get (key); + if (value == null) + return null; + + return new CacheItem (key, value); + } + + public override long GetCount (string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + long ret = 0; + MemoryCacheContainer container; + for (int i = 0; i < numCPUs; i++) { + container = containers [i]; + if (container == null) + continue; + + ret += container.Count; + } + + return ret; + } + + protected override IEnumerator > GetEnumerator () + { + var dict = new Dictionary (); + + CopyEntries (dict); + return dict.GetEnumerator (); + } + + public override IDictionary GetValues (IEnumerable keys, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + if (keys == null) + throw new ArgumentNullException ("keys"); + + MemoryCacheEntry entry; + var ret = new Dictionary (); + foreach (string key in keys) { + if (key == null) + throw new ArgumentException ("The collection 'keys' contains a null element."); + + entry = GetEntry (key); + + // LAMESPEC: MSDN says the number of items in the returned dictionary should be the same as in the + // 'keys' collection - this is not the case. The returned dictionary contains only entries for keys + // that exist in the cache. + if (entry == null) + continue; + + ret.Add (key, entry.Value); + } + + if (ret.Count == 0) + return null; + + return ret; + } + + public override object Remove (string key, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + if (key == null) + throw new ArgumentNullException ("key"); + + return FindContainer (key).Remove (key); + } + + internal void Remove (MemoryCacheEntry entry) + { + if (entry == null) + return; + + string key = entry.Key; + FindContainer (key).Remove (key); + } + + public override void Set (CacheItem item, CacheItemPolicy policy) + { + if (item == null) + throw new ArgumentNullException ("item"); + + Set (item.Key, item.Value, policy); + } + + public override void Set (string key, object value, CacheItemPolicy policy, string regionName = null) + { + if (regionName != null) + throw new NotSupportedException ("The parameter regionName must be null."); + + if (key == null) + throw new ArgumentNullException ("key"); + + if (value == null) + throw new ArgumentNullException ("value"); + + if (policy != null) { + ValidatePolicy (policy, true); + if (policy.AbsoluteExpiration < DateTimeOffset.Now) + return; + } + + FindContainer (key).Set (key, value, policy); + } + + public override void Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) + { + var policy = new CacheItemPolicy (); + policy.AbsoluteExpiration = absoluteExpiration; + + Set (key, value, policy, regionName); + } + + IEnumerator IEnumerable.GetEnumerator () + { + // As weird as it is, this method doesn't call the instance GetEnumerator () + // - tests show it returns a Hashtable enumerator for some reason. + var dict = new Hashtable (); + + CopyEntries (dict); + return dict.GetEnumerator (); + } + + void CopyEntries (IDictionary dict) + { + foreach (MemoryCacheContainer container in containers) { + if (container == null) + continue; + + container.CopyEntries (dict); + } + } + + public long Trim (int percent) + { + long ret = 0; + + // We should probably sort the containers by their least recently used + // items, but that is a performance overkill so we'll just resort to a more + // naive method - each container is trimmed independently of the others. + foreach (MemoryCacheContainer container in containers) { + if (container == null) + continue; + + ret += container.Trim (percent); + } + + return ret; + } + + void ValidatePolicy (CacheItemPolicy policy, bool allowUpdateCallback) + { + CacheEntryUpdateCallback updateCallback = policy.UpdateCallback; + if (!allowUpdateCallback && updateCallback != null) + throw new ArgumentException ("CacheItemPolicy.UpdateCallback must be null.", "policy"); + + if (updateCallback != null && policy.RemovedCallback != null) + throw new ArgumentException ("Only one callback can be specified. Either RemovedCallback or UpdateCallback must be null.", "policy"); + + DateTimeOffset absoluteExpiration = policy.AbsoluteExpiration; + TimeSpan slidingExpiration = policy.SlidingExpiration; + + if (absoluteExpiration != ObjectCache.InfiniteAbsoluteExpiration && + slidingExpiration != TimeSpan.Zero) + throw new ArgumentException ( + "policy", + "'AbsoluteExpiration' must be ObjectCache.InfiniteAbsoluteExpiration or 'SlidingExpiration' must be TimeSpan.Zero" + ); + + long ticks = slidingExpiration.Ticks; + if (ticks < 0 || ticks > 315360000000000) + throw new ArgumentOutOfRangeException ( + "policy", + "SlidingExpiration must be greater than or equal to '00:00:00' and less than or equal to '365.00:00:00'." + ); + + CacheItemPriority priority = policy.Priority; + if (priority < CacheItemPriority.Default || priority > CacheItemPriority.NotRemovable) + throw new ArgumentOutOfRangeException ( + "policy", + "'Priority' must be greater than or equal to 'Default' and less than or equal to 'NotRemovable'" + ); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheContainer.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheContainer.cs new file mode 100644 index 00000000000..43de07dcbb7 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheContainer.cs @@ -0,0 +1,420 @@ +// +// MemoryCacheContainer.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Configuration; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.Caching.Configuration; +using System.Threading; + +namespace System.Runtime.Caching +{ + sealed class MemoryCacheContainer : IDisposable + { + const int DEFAULT_LRU_LOWER_BOUND = 10; + + ReaderWriterLockSlim cache_lock = new ReaderWriterLockSlim (); + + SortedDictionary cache; + MemoryCache owner; + MemoryCachePerformanceCounters perfCounters; + MemoryCacheEntryPriorityQueue timedItems; + MemoryCacheLRU lru; + Timer expirationTimer; + + public int ID { + get; private set; + } + + public long Count { + get { return (long)cache.Count; } + } + + public MemoryCacheContainer (MemoryCache owner, int id, MemoryCachePerformanceCounters perfCounters) + { + if (owner == null) + throw new ArgumentNullException ("owner"); + + this.owner = owner; + this.ID = id; + this.perfCounters = perfCounters; + cache = new SortedDictionary (); + lru = new MemoryCacheLRU (this, DEFAULT_LRU_LOWER_BOUND); + } + + bool ExpireIfNeeded (string key, MemoryCacheEntry entry, bool needsLock = true, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Expired) + { + bool locked = false; + + try { + if (entry.IsExpired) { + if (needsLock) { + cache_lock.EnterWriteLock (); + locked = true; + } + + cache.Remove (key); + perfCounters.Decrement (MemoryCachePerformanceCounters.CACHE_ENTRIES); + entry.Removed (owner, CacheEntryRemovedReason.Expired); + + return true; + } + } finally { + if (locked) + cache_lock.ExitWriteLock (); + } + + return false; + } + + public void Dispose () + { + if (expirationTimer != null) { + expirationTimer.Dispose (); + expirationTimer = null; + } + } + + public void CopyEntries (IDictionary dict) + { + bool locked = false; + try { + cache_lock.EnterWriteLock (); + locked = true; + + MemoryCacheEntry entry; + foreach (var de in cache) { + entry = de.Value; + + if (entry.IsExpired) + continue; + + dict.Add (de.Key, entry.Value); + } + } finally { + if (locked) + cache_lock.ExitWriteLock (); + } + } + + public bool ContainsKey (string key) + { + bool readLocked = false; + try { + cache_lock.EnterUpgradeableReadLock (); + readLocked = true; + + MemoryCacheEntry entry; + if (cache.TryGetValue (key, out entry)) { + if (ExpireIfNeeded (key, entry)) + return false; + + return true; + } + + return false; + } finally { + if (readLocked) + cache_lock.ExitUpgradeableReadLock (); + } + } + + // NOTE: this method _MUST_ be called with the write lock held + void AddToCache (string key, MemoryCacheEntry entry, bool update = false) + { + if (update) + cache [key] = entry; + else + cache.Add (key, entry); + lru.Update (entry); + entry.Added (); + if (!update) + perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_ENTRIES); + + if (entry.IsExpirable) + UpdateExpirable (entry); + } + + // NOTE: this method _MUST_ be called with the write lock held + void UpdateExpirable (MemoryCacheEntry entry) + { + if (timedItems == null) + timedItems = new MemoryCacheEntryPriorityQueue (); + + timedItems.Enqueue (entry); + + if (expirationTimer == null) + expirationTimer = new Timer (RemoveExpiredItems, null, owner.TimerPeriod, owner.TimerPeriod); + } + + void RemoveExpiredItems (object state) + { + DoRemoveExpiredItems (true); + } + + long DoRemoveExpiredItems (bool needLock) + { + long count = 0; + bool locked = false; + try { + if (needLock) { + cache_lock.EnterWriteLock (); + locked = true; + } + + if (timedItems == null) + return 0; + + long now = DateTime.Now.Ticks; + MemoryCacheEntry entry = timedItems.Peek (); + + while (entry != null) { + if (entry.Disabled) { + timedItems.Dequeue (); + entry = timedItems.Peek (); + continue; + } + + if (entry.ExpiresAt > now) + break; + + timedItems.Dequeue (); + count++; + DoRemoveEntry (entry, true, entry.Key, CacheEntryRemovedReason.Expired); + entry = timedItems.Peek (); + } + + if (entry == null) { + timedItems = null; + expirationTimer.Dispose (); + expirationTimer = null; + } + + return count; + } finally { + if (locked) + cache_lock.ExitWriteLock (); + } + } + + public object AddOrGetExisting (string key, object value, CacheItemPolicy policy) + { + bool readLocked = false, writeLocked = false; + try { + cache_lock.EnterUpgradeableReadLock (); + readLocked = true; + + MemoryCacheEntry entry; + if (cache.TryGetValue (key, out entry) && entry != null) { + perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_HITS); + return entry.Value; + } + perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_MISSES); + + cache_lock.EnterWriteLock (); + writeLocked = true; + + if (policy == null) + entry = new MemoryCacheEntry (owner, key, value); + else + entry = new MemoryCacheEntry (owner, key, value, + policy.AbsoluteExpiration, + policy.ChangeMonitors, + policy.Priority, + policy.RemovedCallback, + policy.SlidingExpiration, + policy.UpdateCallback); + + AddToCache (key, entry); + return null; + } finally { + if (writeLocked) + cache_lock.ExitWriteLock (); + if (readLocked) + cache_lock.ExitUpgradeableReadLock (); + } + } + + public MemoryCacheEntry GetEntry (string key) + { + bool locked = false; + try { + cache_lock.EnterReadLock (); + locked = true; + + MemoryCacheEntry entry; + if (cache.TryGetValue (key, out entry)) { + if (ExpireIfNeeded (key, entry)) + return null; + + return entry; + } + + return null; + } finally { + if (locked) + cache_lock.ExitReadLock (); + } + } + + public object Get (string key) + { + bool readLocked = false; + try { + cache_lock.EnterUpgradeableReadLock (); + readLocked = true; + + MemoryCacheEntry entry; + if (cache.TryGetValue (key, out entry)) { + if (ExpireIfNeeded (key, entry)) + return null; + + perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_HITS); + return entry.Value; + } + + perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_MISSES); + return null; + } finally { + if (readLocked) + cache_lock.ExitUpgradeableReadLock (); + } + } + + public object Remove (string key, bool needLock = true, bool updateLRU = true) + { + bool writeLocked = false, readLocked = false; + try { + if (needLock) { + cache_lock.EnterUpgradeableReadLock (); + readLocked = true; + } + + MemoryCacheEntry entry; + if (!cache.TryGetValue (key, out entry)) + return null; + + if (needLock) { + cache_lock.EnterWriteLock (); + writeLocked = true; + } + + object ret = entry.Value; + DoRemoveEntry (entry, updateLRU, key); + return ret; + } finally { + if (writeLocked) + cache_lock.ExitWriteLock (); + if (readLocked) + cache_lock.ExitUpgradeableReadLock (); + } + } + + // NOTE: this must be called with the write lock held + void DoRemoveEntry (MemoryCacheEntry entry, bool updateLRU = true, string key = null, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Removed) + { + if (key == null) + key = entry.Key; + + cache.Remove (key); + if (updateLRU) + lru.Remove (entry); + perfCounters.Decrement (MemoryCachePerformanceCounters.CACHE_ENTRIES); + entry.Removed (owner, reason); + } + + public void Set (string key, object value, CacheItemPolicy policy) + { + bool locked = false; + try { + cache_lock.EnterWriteLock (); + locked = true; + + MemoryCacheEntry mce; + bool update = false; + if (cache.TryGetValue (key, out mce)) { + if (mce != null) { + perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_HITS); + mce.Value = value; + mce.SetPolicy (policy); + if (mce.IsExpirable) + UpdateExpirable (mce); + lru.Update (mce); + return; + } + + update = true; + } + perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_MISSES); + if (policy != null) + mce = new MemoryCacheEntry (owner, key, value, + policy.AbsoluteExpiration, + policy.ChangeMonitors, + policy.Priority, + policy.RemovedCallback, + policy.SlidingExpiration, + policy.UpdateCallback); + else + mce = new MemoryCacheEntry (owner, key, value); + AddToCache (key, mce, update); + } finally { + if (locked) + cache_lock.ExitWriteLock (); + } + } + + public long Trim (int percent) + { + int count = cache.Count; + if (count == 0) + return 0; + + long goal = (long)((count * percent) / 100); + bool locked = false; + long ret = 0; + + try { + cache_lock.EnterWriteLock (); + locked = true; + ret = DoRemoveExpiredItems (false); + + goal -= ret; + if (goal > 0) + ret += lru.Trim (goal); + } finally { + if (locked) + cache_lock.ExitWriteLock (); + } + + return ret; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntry.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntry.cs new file mode 100644 index 00000000000..9bae662b4ab --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntry.cs @@ -0,0 +1,199 @@ +// +// MemoryCacheEntry.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Reflection; +using System.Runtime.InteropServices; + +namespace System.Runtime.Caching +{ + sealed class MemoryCacheEntry + { + object value; + DateTimeOffset absoluteExpiration; + Collection monitors; + CacheItemPriority priority; + CacheEntryRemovedCallback removedCallback; + TimeSpan slidingExpiration; + CacheEntryUpdateCallback updateCallback; + MemoryCache owner; + long expiresAt; + bool disabled; + + public bool Disabled { + get { return disabled; } + set { + if (value) { + this.value = null; + this.Key = null; + this.disabled = true; + } else + this.disabled = false; + } + } + + public bool IsExpired { + get { + if (absoluteExpiration != ObjectCache.InfiniteAbsoluteExpiration && absoluteExpiration.UtcTicks < DateTime.UtcNow.Ticks) + return true; + + if (slidingExpiration != ObjectCache.NoSlidingExpiration && DateTime.UtcNow.Ticks - LastModified.Ticks > slidingExpiration.Ticks) + return true; + + return false; + } + } + + public bool IsRemovable { + get { return priority != CacheItemPriority.NotRemovable; } + } + + public bool IsExpirable { + get { return expiresAt > 0; } + } + + public string Key { + get; private set; + } + + public DateTime LastModified { + get; set; + } + + public long ExpiresAt { + get { return expiresAt; } + } + + public object Value { + get { return value; } + set { + this.value = value; + LastModified = DateTime.UtcNow; + } + } + + public MemoryCacheEntry (MemoryCache owner, string key, object value) + : this (owner, key, value, DateTimeOffset.MaxValue, null, CacheItemPriority.Default, null, TimeSpan.MaxValue, null) + { + } + + public MemoryCacheEntry (MemoryCache owner, string key, object value, DateTimeOffset absoluteExpiration, Collection monitors, + CacheItemPriority priority, CacheEntryRemovedCallback removedCallback, TimeSpan slidingExpiration, + CacheEntryUpdateCallback updateCallback) + { + if (value == null) + throw new ArgumentNullException ("value"); + + if (owner == null) + throw new ArgumentNullException ("owner"); + + this.owner = owner; + this.Key = key; + this.Value = value; + this.absoluteExpiration = absoluteExpiration; + this.monitors = monitors; + this.priority = priority; + this.removedCallback = removedCallback; + this.slidingExpiration = slidingExpiration; + this.updateCallback = updateCallback; + this.LastModified = DateTime.UtcNow; + + if (absoluteExpiration != ObjectCache.InfiniteAbsoluteExpiration) + expiresAt = absoluteExpiration.Ticks; + else if (slidingExpiration != ObjectCache.NoSlidingExpiration) + expiresAt = DateTime.Now.Ticks + slidingExpiration.Ticks; + else + expiresAt = 0; + } + + public void Added () + { + Disabled = false; + if (monitors == null || monitors.Count == 0) + return; + + foreach (ChangeMonitor monitor in monitors) + monitor.NotifyOnChanged (OnMonitorChanged); + } + + public override int GetHashCode () + { + return Key.GetHashCode (); + } + + void OnMonitorChanged (object state) + { + owner.Remove (this); + } + + public void Removed (MemoryCache owner, CacheEntryRemovedReason reason) + { + if (removedCallback == null) { + Disabled = true; + return; + } + + try { + removedCallback (new CacheEntryRemovedArguments (owner, reason, new CacheItem (Key, Value))); + } catch { + // ignore - we don't care about the exceptions thrown inside the + // handler + } finally { + Disabled = true; + } + } + + public void Updated (MemoryCache owner, CacheEntryRemovedReason reason) + { + if (updateCallback == null) + return; + + try { + var args = new CacheEntryUpdateArguments (owner, reason, Key, null); + updateCallback (args); + } catch { + // ignore - we don't care about the exceptions thrown inside the + // handler + } + } + + public void SetPolicy (CacheItemPolicy policy) + { + if (policy == null) + return; + + absoluteExpiration = policy.AbsoluteExpiration; + monitors = policy.ChangeMonitors; + priority = policy.Priority; + removedCallback = policy.RemovedCallback; + slidingExpiration = policy.SlidingExpiration; + updateCallback = policy.UpdateCallback; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntryChangeMonitor.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntryChangeMonitor.cs new file mode 100644 index 00000000000..4faf22168ee --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntryChangeMonitor.cs @@ -0,0 +1,100 @@ +// +// MemoryCacheEntryChangeMonitor.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; + +namespace System.Runtime.Caching +{ + sealed class MemoryCacheEntryChangeMonitor : CacheEntryChangeMonitor + { + ReadOnlyCollection cacheKeys; + DateTimeOffset lastModified; + MemoryCache owner; + string uniqueId; + + public override ReadOnlyCollection CacheKeys { + get { return cacheKeys; } + } + + public override DateTimeOffset LastModified { + get { return lastModified; } + } + + public override string RegionName { + get { return null; } + } + + public override string UniqueId { + get { return uniqueId; } + } + + public MemoryCacheEntryChangeMonitor (MemoryCache owner, IEnumerable keys) + { + this.owner = owner; + this.lastModified = DateTimeOffset.MinValue; + + MemoryCacheEntry mce; + var sb = new StringBuilder (); + var list = new List (); + foreach (string key in keys) { + mce = owner.GetEntry (key); + list.Add (key); +#if true + // LAMESPEC: this is what's happening + DateTimeOffset modtime; + modtime = new DateTimeOffset (mce != null ? mce.LastModified : DateTime.MinValue); + if (this.lastModified < modtime) + this.lastModified = modtime; +#else + // LAMESPEC: this is what is supposed to be happening + if (mce == null) { + OnChanged (null); + sb.Append ("{0}{1:x}", key, DateTime.MinValue.Ticks); + continue; + } + + DateTime modtime = mce.LastModified; + if (this.lastModtime < modtime) + this.lastModtime = new DateTimeOffset (modtime); +#endif + sb.AppendFormat ("{0}{1:X}", key, modtime.Ticks); + } + this.uniqueId = sb.ToString (); + this.cacheKeys = new ReadOnlyCollection (list); + + // TODO: hook up to change events on MemoryCache + } + + protected override void Dispose (bool disposing) + { + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntryPriorityQueue.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntryPriorityQueue.cs new file mode 100644 index 00000000000..dceb63bfc59 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheEntryPriorityQueue.cs @@ -0,0 +1,199 @@ +// +// Author(s): +// Marek Habersack +// +// (C) 2009-2010 Novell, Inc (http://novell.com) +// +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; + +namespace System.Runtime.Caching +{ + sealed partial class MemoryCacheEntryPriorityQueue + { + const int INITIAL_HEAP_SIZE = 32; + const int HEAP_RESIZE_THRESHOLD = 8192; + + MemoryCacheEntry[] heap; + int heapSize = 0; + int heapCount = 0; + ReaderWriterLockSlim queueLock; + + public int Count { + get { return heapCount; } + } + + public int Size { + get { return heapSize; } + } + + public MemoryCacheEntryPriorityQueue () + { + queueLock = new ReaderWriterLockSlim (); + } + + MemoryCacheEntry[] GetHeapWithGrow () + { + if (heap == null) { + heap = new MemoryCacheEntry [INITIAL_HEAP_SIZE]; + heapSize = INITIAL_HEAP_SIZE; + heapCount = 0; + return heap; + } + + if (heapCount >= heapSize) { + heapSize <<= 1; + Array.Resize (ref heap, heapSize); + } + + return heap; + } + + MemoryCacheEntry[] GetHeapWithShrink () + { + if (heap == null) + return null; + + if (heapSize > HEAP_RESIZE_THRESHOLD) { + int halfTheSize = heapSize >> 1; + + if (heapCount < halfTheSize) + Array.Resize (ref heap, halfTheSize + (heapCount / 3)); + } + + return heap; + } + + public void Enqueue (MemoryCacheEntry item) + { + if (item == null) + return; + + bool locked = false; + MemoryCacheEntry[] heap; + + try { + queueLock.EnterWriteLock (); + locked = true; + heap = GetHeapWithGrow (); + heap [heapCount++] = item; + BubbleUp (heap); + } finally { + if (locked) + queueLock.ExitWriteLock (); + } + } + + public MemoryCacheEntry Dequeue () + { + MemoryCacheEntry ret = null; + MemoryCacheEntry[] heap; + bool locked = false; + int index; + + try { + queueLock.EnterWriteLock (); + locked = true; + heap = GetHeapWithShrink (); + if (heap == null || heapCount == 0) + return null; + + ret = heap [0]; + index = --heapCount; + heap [0] = heap [index]; + heap [index] = null; + + if (heapCount > 0) + BubbleDown (heap); + + return ret; + } finally { + if (locked) + queueLock.ExitWriteLock (); + } + } + + public MemoryCacheEntry Peek () + { + bool locked = false; + + try { + queueLock.EnterReadLock (); + locked = true; + if (heap == null || heapCount == 0) + return null; + + return heap [0]; + } finally { + if (locked) + queueLock.ExitReadLock (); + } + } + + void BubbleDown (MemoryCacheEntry[] heap) + { + int index = 0; + int left = 1; + int right = 2; + MemoryCacheEntry item = heap [0]; + int selected = (right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt) ? 2 : 1; + + while (selected < heapCount && heap [selected].ExpiresAt < item.ExpiresAt) { + heap [index] = heap [selected]; + index = selected; + left = (index << 1) + 1; + right = left + 1; + selected = right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt ? right : left; + } + heap [index] = item; + } + + void BubbleUp (MemoryCacheEntry[] heap) + { + int index, parentIndex; + MemoryCacheEntry parent, item; + + if (heapCount <= 1) + return; + + index = heapCount - 1; + parentIndex = (index - 1) >> 1; + + item = heap [index]; + while (index > 0) { + parent = heap [parentIndex]; + if (heap [index].ExpiresAt >= parent.ExpiresAt) + break; + + heap [index] = parent; + index = parentIndex; + parentIndex = (index - 1) >> 1; + } + + heap [index] = item; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheLRU.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheLRU.cs new file mode 100644 index 00000000000..2ad420e776b --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCacheLRU.cs @@ -0,0 +1,109 @@ +// +// MemoryCacheLRU.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; + +namespace System.Runtime.Caching +{ + // NOTE: all the public methods in this assume that the owner's write lock is held + sealed class MemoryCacheLRU + { + int trimLowerBound; + Dictionary > index; + LinkedList lru; + MemoryCacheContainer owner; + + public MemoryCacheLRU (MemoryCacheContainer owner, int trimLowerBound) + { + this.trimLowerBound = trimLowerBound; + index = new Dictionary > (); + lru = new LinkedList (); + this.owner = owner; + } + + public void Update (MemoryCacheEntry entry) + { + if (entry == null) + return; + + int hash = entry.GetHashCode (); + LinkedListNode node; + + if (!index.TryGetValue (hash, out node)) { + node = new LinkedListNode (entry); + index.Add (hash, node); + } else { + lru.Remove (node); + node.Value = entry; + } + + lru.AddLast (node); + } + + public void Remove (MemoryCacheEntry entry) + { + if (entry == null) + return; + + int hash = entry.GetHashCode (); + LinkedListNode node; + + if (index.TryGetValue (hash, out node)) { + lru.Remove (node); + index.Remove (hash); + } + } + + public long Trim (long upTo) + { + int count = index.Count; + if (count <= 10) + return 0; + + // The list is used below to reproduce .NET's behavior which selects the + // entries using the LRU order, but it removes them from the cache in the + // MRU order + var toremove = new List ((int)upTo); + long removed = 0; + MemoryCacheEntry entry; + + while (upTo > removed && count > 10) { + entry = lru.First.Value; + toremove.Insert (0, entry); + Remove (entry); + removed++; + count--; + } + + foreach (MemoryCacheEntry e in toremove) + owner.Remove (e.Key, false); + + return removed; + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCachePerformanceCounters.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCachePerformanceCounters.cs new file mode 100644 index 00000000000..4a947f32a2e --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/MemoryCachePerformanceCounters.cs @@ -0,0 +1,125 @@ +// +// MemoryCache.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; + +// +// Counters in the ".NET Memory Cache 4.0" are not documented on MSDN. They were discovered using +// perfmon there their definition may change without any notice +// +namespace System.Runtime.Caching +{ + sealed class MemoryCachePerformanceCounters : IDisposable + { + const string dotNetCategoryName = ".NET Memory Cache 4.0"; + + public const int CACHE_ENTRIES = 0; + public const int CACHE_HIT_RATIO = 1; + public const int CACHE_HITS = 2; + public const int CACHE_MISSES = 3; + public const int CACHE_TRIMS = 4; + public const int CACHE_TURNOVER_RATE = 5; + const int COUNTERS_LAST = CACHE_TURNOVER_RATE; + + PerformanceCounter[] perfCounters; + + public MemoryCachePerformanceCounters (string instanceName, bool noCounters) + { + var collection = new CounterCreationDataCollection (); + + if (!noCounters) { + if (!PerformanceCounterCategory.Exists (dotNetCategoryName)) { + // TODO: check: + // + // - types of all the counters + // + CreateCounter ("Cache Entries", PerformanceCounterType.NumberOfItems64, collection); + CreateCounter ("Cache Hit Ratio", PerformanceCounterType.RawFraction, collection); + CreateCounter ("Cache Hits", PerformanceCounterType.NumberOfItems64, collection); + CreateCounter ("Cache Misses", PerformanceCounterType.NumberOfItems64, collection); + CreateCounter ("Cache Trims", PerformanceCounterType.NumberOfItems64, collection); + CreateCounter ("Cache Turnover Rate", PerformanceCounterType.RateOfCountsPerSecond64, collection); + + PerformanceCounterCategory.Create (dotNetCategoryName, "System.Runtime.Caching.MemoryCache Performance Counters", + PerformanceCounterCategoryType.MultiInstance, collection); + } + + perfCounters = new PerformanceCounter [COUNTERS_LAST + 1]; + perfCounters [CACHE_ENTRIES] = new PerformanceCounter (dotNetCategoryName, "Cache Entries", instanceName, false); + perfCounters [CACHE_ENTRIES].RawValue = 0; + perfCounters [CACHE_HIT_RATIO] = new PerformanceCounter (dotNetCategoryName, "Cache Hit Ratio", instanceName, false); + perfCounters [CACHE_HIT_RATIO].RawValue = 0; + perfCounters [CACHE_HITS] = new PerformanceCounter (dotNetCategoryName, "Cache Hits", instanceName, false); + perfCounters [CACHE_HITS].RawValue = 0; + perfCounters [CACHE_MISSES] = new PerformanceCounter (dotNetCategoryName, "Cache Misses", instanceName, false); + perfCounters [CACHE_MISSES].RawValue = 0; + perfCounters [CACHE_TRIMS] = new PerformanceCounter (dotNetCategoryName, "Cache Trims", instanceName, false); + perfCounters [CACHE_TRIMS].RawValue = 0; + perfCounters [CACHE_TURNOVER_RATE] = new PerformanceCounter (dotNetCategoryName, "Cache Turnover Rate", instanceName, false); + perfCounters [CACHE_TURNOVER_RATE].RawValue = 0; + } + } + + public void Dispose () + { + foreach (PerformanceCounter counter in perfCounters) { + if (counter == null) + continue; + + counter.Dispose (); + } + } + + public void Decrement (int counteridx) + { + if (perfCounters == null || counteridx < 0 || counteridx > COUNTERS_LAST) + return; + + perfCounters [counteridx].Decrement (); + } + + public void Increment (int counteridx) + { + if (perfCounters == null || counteridx < 0 || counteridx > COUNTERS_LAST) + return; + + perfCounters [counteridx].Increment (); + } + + void CreateCounter (string name, PerformanceCounterType type, CounterCreationDataCollection collection) + { + var ccd = new CounterCreationData (); + + ccd.CounterName = name; + ccd.CounterType = type; + collection.Add (ccd); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ObjectCache.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ObjectCache.cs new file mode 100644 index 00000000000..118273042cf --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/ObjectCache.cs @@ -0,0 +1,115 @@ +// +// ObjectCache.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Runtime; + +namespace System.Runtime.Caching +{ + public abstract class ObjectCache : IEnumerable>, IEnumerable + { + static IServiceProvider host; + + public static readonly DateTimeOffset InfiniteAbsoluteExpiration = DateTimeOffset.MaxValue; + public static readonly TimeSpan NoSlidingExpiration = TimeSpan.Zero; + + public static IServiceProvider Host { + [TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] + get { return host; } + set { + if (value == null) + throw new ArgumentNullException ("value"); + + if (host != null) + throw new InvalidOperationException ("The property has already been set, and can only be set once."); + + host = value; + } + } + + public abstract DefaultCacheCapabilities DefaultCacheCapabilities { get; } + public abstract object this [string key] { get; set; } + public abstract string Name { get; } + + [TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] + protected ObjectCache () + { + } + + public virtual bool Add (CacheItem item, CacheItemPolicy policy) + { + return AddOrGetExisting (item, policy) == null; + } + + public virtual bool Add (string key, object value, CacheItemPolicy policy, string regionName = null) + { + return AddOrGetExisting (key, value, policy, regionName) == null; + } + + public virtual bool Add (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) + { + return AddOrGetExisting (key, value, absoluteExpiration, regionName) == null; + } + + public abstract CacheItem AddOrGetExisting (CacheItem value, CacheItemPolicy policy); + public abstract object AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null); + public abstract object AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null); + public abstract bool Contains (string key, string regionName = null); + public abstract CacheEntryChangeMonitor CreateCacheEntryChangeMonitor (IEnumerable keys, string regionName = null); + public abstract object Get (string key, string regionName = null); + public abstract CacheItem GetCacheItem (string key, string regionName = null); + public abstract long GetCount (string regionName = null); + protected abstract IEnumerator > GetEnumerator (); + public abstract IDictionary GetValues (IEnumerable keys, string regionName = null); + + [TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] + public virtual IDictionary GetValues (string regionName = null, params string[] keys) + { + return GetValues (keys.AsEnumerable (), regionName); + } + + public abstract object Remove (string key, string regionName = null); + public abstract void Set (CacheItem item, CacheItemPolicy policy); + public abstract void Set (string key, object value, CacheItemPolicy policy, string regionName = null); + public abstract void Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null); + + [TargetedPatchingOptOut ("Performance critical to inline this type of method across NGen image boundaries")] + IEnumerator > IEnumerable>.GetEnumerator () + { + return GetEnumerator (); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return GetEnumerator (); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/OnChangedCallback.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/OnChangedCallback.cs new file mode 100644 index 00000000000..bed109c9b07 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/OnChangedCallback.cs @@ -0,0 +1,33 @@ +// +// OnChangedCallback.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; + +namespace System.Runtime.Caching +{ + public delegate void OnChangedCallback (object state); +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching/SqlChangeMonitor.cs b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/SqlChangeMonitor.cs new file mode 100644 index 00000000000..d244426a33d --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching/SqlChangeMonitor.cs @@ -0,0 +1,54 @@ +// +// SqlChangeMonitor.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Data.SqlClient; + +namespace System.Runtime.Caching +{ + public sealed class SqlChangeMonitor : ChangeMonitor + { + string uniqueId; + + public override string UniqueId { + get { return uniqueId; } + } + + public SqlChangeMonitor (SqlDependency dependency) + { + if (dependency == null) + throw new ArgumentNullException ("dependency"); + + throw new NotImplementedException (); + } + + protected override void Dispose (bool disposing) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/System.Runtime.Caching_test.dll.sources b/mcs/class/System.Runtime.Caching/System.Runtime.Caching_test.dll.sources new file mode 100644 index 00000000000..f555a9479e4 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/System.Runtime.Caching_test.dll.sources @@ -0,0 +1,9 @@ +Common/AppDomainTools.cs +Common/AssertExtensions.cs +Common/PokerChangeMonitor.cs +Common/PokerMemoryCache.cs +Common/PokerObjectCache.cs +Common/TestNotificationSystem.cs +System.Runtime.Caching/HostFileChangeMonitorTest.cs +System.Runtime.Caching/MemoryCacheTest.cs +System.Runtime.Caching/ObjectCacheTest.cs \ No newline at end of file diff --git a/mcs/class/System.Runtime.Caching/Test/Common/AppDomainTools.cs b/mcs/class/System.Runtime.Caching/Test/Common/AppDomainTools.cs new file mode 100644 index 00000000000..5bbf8e154ca --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/Common/AppDomainTools.cs @@ -0,0 +1,80 @@ +// +// AppDomainTools.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Security.Policy; +using System.Text; + +using NUnit.Framework; + +namespace MonoTests.Common +{ + class AppDomainTools + { + public static void RunInSeparateDomain (Action handler, string format, params object[] parms) + { + var setup = AppDomain.CurrentDomain.SetupInformation; + setup.ShadowCopyDirectories = null; + setup.ShadowCopyFiles = null; + setup.ApplicationBase = Path.GetDirectoryName (typeof (AppDomainTools).Assembly.Location); + var ad = AppDomain.CreateDomain ("Test", new Evidence (AppDomain.CurrentDomain.Evidence) , setup); + ad.SetData ("testHandler", handler); + string message; + if (parms != null && parms.Length > 0) + message = String.Format (format, parms); + else + message = format; + ad.SetData ("failureMessage", message); + //ad.AssemblyResolve += ResolveAssemblyEventHandler; + ad.DoCallBack (RunTest); + } + + static Assembly ResolveAssemblyEventHandler (object sender, ResolveEventArgs args) + { + string path = Path.Combine (AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "nunit.framework.dll"); + if (File.Exists (path)) + return Assembly.LoadFrom (path); + + return null; + } + + static void RunTest () + { + Action handler = AppDomain.CurrentDomain.GetData ("testHandler") as Action; + if (handler == null) { + string message = AppDomain.CurrentDomain.GetData ("failureMessage") as string; + Assert.Fail (message); + } + + handler (); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/Common/AssertExtensions.cs b/mcs/class/System.Runtime.Caching/Test/Common/AssertExtensions.cs new file mode 100644 index 00000000000..41e340bfd35 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/Common/AssertExtensions.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +using NUnit.Framework; + +namespace MonoTests.Common +{ + delegate void AssertThrowsDelegate(); + + static class AssertExtensions + { + public static void AreEqual (byte[] expected, byte[] data, string message) + { + if (expected == null) { + if (data == null) + return; + Assert.Fail ("{0}{1}Expected: null{1}Got: byte array with {2} elements and of rank {3}{1}", + message, Environment.NewLine, data.Length, data.Rank); + } + + if (data == null) + Assert.Fail ("{0}{1}Expected: byte array with {2} elements and rank {3}{1}Got: null{1}", + message, Environment.NewLine, expected.Length, expected.Rank); + + if (expected.Rank > 1) + Assert.Fail ("Only single-dimensional arrays are supported."); + + if (expected.Rank != data.Rank || expected.Length != data.Length) + Assert.Fail ("{0}{1}Expected: byte array with {2} elements and rank {3}{1}Got: byte array with {4} elements and rank {5}{1}", + message, Environment.NewLine, expected.Length, expected.Rank, data.Length, data.Rank); + + int max = expected.Length; + for (int i = 0; i < max; i++) { + if (expected[i] != data[i]) + Assert.Fail ("{0}{1}Arrays differ at index {2}.{1}Expected 0x{3:X} got 0x{4:X}{1}", + message, Environment.NewLine, i, expected[i], data[i]); + } + } + + public static void Throws (AssertThrowsDelegate code, string message) + { + Throws(typeof(ET), code, message); + } + + public static void Throws(Type exceptionType, AssertThrowsDelegate code, string message) + { + if (code == null) + Assert.Fail("No code provided for the test."); + + Exception exception = null; + try + { + code(); + } + catch (Exception ex) + { + exception = ex; + } + + if (exceptionType == null) + { + if (exception == null) + Assert.Fail("{0}{1}Expected: any exception thrown{1}But was: no exception thrown{1}", + message, Environment.NewLine); + return; + } + + if (exception == null || exception.GetType() != exceptionType) + Assert.Fail("{0}{1}Expected: {2}{1}But was: {3}{1}{4}{1}", + message, + Environment.NewLine, + exceptionType, + exception == null ? "no exception" : exception.GetType().ToString(), + exception == null ? "no exception" : exception.ToString()); + } + + public static void Throws(AssertThrowsDelegate code, string message) + { + Throws(null, code, message); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/Common/ChangeLog b/mcs/class/System.Runtime.Caching/Test/Common/ChangeLog new file mode 100644 index 00000000000..dbeafd60e5a --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/Common/ChangeLog @@ -0,0 +1,6 @@ +2010-04-24 Marek Habersack + + * AppDomainTools.cs, AssertExtensions.cs, PokerChangeMonitor.cs, + PokerMemoryCache.cs, PokerObjectCache.cs, + TestNotificationSystem.cs: added + diff --git a/mcs/class/System.Runtime.Caching/Test/Common/PokerChangeMonitor.cs b/mcs/class/System.Runtime.Caching/Test/Common/PokerChangeMonitor.cs new file mode 100644 index 00000000000..344f724ad96 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/Common/PokerChangeMonitor.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Runtime.Caching; +using System.Text; + +namespace MonoTests.Common +{ + class PokerChangeMonitor : ChangeMonitor + { + List calls; + string uniqueId; + + public List Calls + { + get + { + if (calls == null) + calls = new List (); + + return calls; + } + } + + public override string UniqueId + { + get { return uniqueId; } + } + + public PokerChangeMonitor () + { + uniqueId = "UniqueID"; + InitializationComplete (); + } + + public void SignalChange () + { + OnChanged (null); + } + + protected override void Dispose (bool disposing) + { + Calls.Add ("Dispose (bool disposing)"); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/Common/PokerMemoryCache.cs b/mcs/class/System.Runtime.Caching/Test/Common/PokerMemoryCache.cs new file mode 100644 index 00000000000..d2c0aaa05bf --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/Common/PokerMemoryCache.cs @@ -0,0 +1,158 @@ +// +// PokerMemoryCache.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Runtime.Caching; +using System.Text; + +namespace MonoTests.Common +{ + class PokerMemoryCache : MemoryCache + { + List calls; + + public List Calls + { + get + { + if (calls == null) + calls = new List (); + return calls; + } + } + + public override object this [string key] + { + get + { + Calls.Add ("get_this [string key]"); + return base [key]; + } + set + { + Calls.Add ("set_this [string key]"); + base [key] = value; + } + } + + public PokerMemoryCache (string name, NameValueCollection config = null) + : base (name, config) + { } + + public override CacheItem AddOrGetExisting (CacheItem item, CacheItemPolicy policy) + { + Calls.Add ("AddOrGetExisting (CacheItem item, CacheItemPolicy policy)"); + return base.AddOrGetExisting (item, policy); + } + + public override object AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null) + { + Calls.Add ("AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)"); + return base.AddOrGetExisting (key, value, policy, regionName); + } + + public override object AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) + { + Calls.Add ("AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)"); + return base.AddOrGetExisting (key, value, absoluteExpiration, regionName); + } + + public override object Get (string key, string regionName = null) + { + Calls.Add ("Get (string key, string regionName = null)"); + return base.Get (key, regionName); + } + + public override CacheItem GetCacheItem (string key, string regionName = null) + { + Calls.Add ("GetCacheItem (string key, string regionName = null)"); + return base.GetCacheItem (key, regionName); + } + + public override long GetCount (string regionName = null) + { + Calls.Add ("GetCount (string regionName = null)"); + return base.GetCount (regionName); + } + + public override bool Contains (string key, string regionName = null) + { + Calls.Add ("Contains (string key, string regionName = null)"); + return base.Contains (key, regionName); + } + + public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor (IEnumerable keys, string regionName = null) + { + Calls.Add ("CreateCacheEntryChangeMonitor (IEnumerable keys, string regionName = null)"); + return base.CreateCacheEntryChangeMonitor (keys, regionName); + } + + protected override IEnumerator> GetEnumerator () + { + Calls.Add ("IEnumerator> GetEnumerator ()"); + return base.GetEnumerator (); + } + + public IEnumerator> DoGetEnumerator () + { + return GetEnumerator (); + } + + public override IDictionary GetValues (IEnumerable keys, string regionName = null) + { + Calls.Add ("IDictionary GetValues (IEnumerable keys, string regionName = null)"); + return base.GetValues (keys, regionName); + } + + public override IDictionary GetValues (string regionName, params string [] keys) + { + Calls.Add ("IDictionary GetValues (string regionName, params string [] keys)"); + return base.GetValues (regionName, keys); + } + + public override void Set (CacheItem item, CacheItemPolicy policy) + { + Calls.Add ("Set (CacheItem item, CacheItemPolicy policy)"); + base.Set (item, policy); + } + + public override void Set (string key, object value, CacheItemPolicy policy, string regionName = null) + { + Calls.Add ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)"); + base.Set (key, value, policy, regionName); + } + + public override void Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) + { + Calls.Add ("Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)"); + base.Set (key, value, absoluteExpiration, regionName); + } + + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/Common/PokerObjectCache.cs b/mcs/class/System.Runtime.Caching/Test/Common/PokerObjectCache.cs new file mode 100644 index 00000000000..1bef81e5cf6 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/Common/PokerObjectCache.cs @@ -0,0 +1,186 @@ +// +// PokerObjectCache.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.Caching; + +namespace MonoTests.Common +{ + class PokerObjectCache : ObjectCache + { + Dictionary cache; + + Dictionary Cache { + get + { + if (cache == null) + cache = new Dictionary (); + return cache; + } + } + + public string MethodCalled { get; private set; } + + public override object AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null) + { + MethodCalled = "AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)"; + if (String.IsNullOrEmpty (key) || value == null) + return null; + + object item; + if (Cache.TryGetValue (key, out item)) + return item; + + Cache.Add (key, value); + return null; + } + + public override CacheItem AddOrGetExisting (CacheItem value, CacheItemPolicy policy) + { + MethodCalled = "AddOrGetExisting (CacheItem value, CacheItemPolicy policy)"; + if (value == null) + return null; + + object item; + if (Cache.TryGetValue (value.Key, out item)) + return item as CacheItem; + + Cache.Add (value.Key, value); + return null; + } + + public override object AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) + { + MethodCalled = "AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)"; + if (String.IsNullOrEmpty (key) || value == null) + return null; + + object item; + if (Cache.TryGetValue (key, out item)) + return item; + + Cache.Add (key, value); + return null; + } + + public override bool Contains (string key, string regionName = null) + { + throw new NotImplementedException (); + } + + public override CacheEntryChangeMonitor CreateCacheEntryChangeMonitor (IEnumerable keys, string regionName = null) + { + throw new NotImplementedException (); + } + + public override DefaultCacheCapabilities DefaultCacheCapabilities + { + get { throw new NotImplementedException (); } + } + + public override object Get (string key, string regionName = null) + { + throw new NotImplementedException (); + } + + public override CacheItem GetCacheItem (string key, string regionName = null) + { + throw new NotImplementedException (); + } + + public override long GetCount (string regionName = null) + { + throw new NotImplementedException (); + } + + protected override IEnumerator> GetEnumerator () + { + throw new NotImplementedException (); + } + + public override IDictionary GetValues (IEnumerable keys, string regionName = null) + { + MethodCalled = "IDictionary GetValues (IEnumerable keys, string regionName = null)"; + var ret = new Dictionary (); + if (keys == null) + return ret; + + Dictionary cache = Cache; + if (cache.Count == 0) + return ret; + + object value; + foreach (string key in keys) { + if (!cache.TryGetValue (key, out value)) + continue; + + ret.Add (key, value); + } + + return ret; + } + + public override string Name + { + get { throw new NotImplementedException (); } + } + + public override object Remove (string key, string regionName = null) + { + throw new NotImplementedException (); + } + + public override void Set (string key, object value, CacheItemPolicy policy, string regionName = null) + { + throw new NotImplementedException (); + } + + public override void Set (CacheItem item, CacheItemPolicy policy) + { + throw new NotImplementedException (); + } + + public override void Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) + { + throw new NotImplementedException (); + } + + public override object this [string key] + { + get + { + throw new NotImplementedException (); + } + set + { + throw new NotImplementedException (); + } + } + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/Common/TestNotificationSystem.cs b/mcs/class/System.Runtime.Caching/Test/Common/TestNotificationSystem.cs new file mode 100644 index 00000000000..dbd8cbb7345 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/Common/TestNotificationSystem.cs @@ -0,0 +1,91 @@ +// +// TestNotificationSystem.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Runtime.Caching; +using System.Runtime.Caching.Hosting; + +namespace MonoTests.Common +{ + class TestNotificationSystem : IServiceProvider, IFileChangeNotificationSystem + { + OnChangedCallback callback; + + public bool StartMonitoringCalled { get; private set; } + public uint StartMonitoringCallCount { get; private set; } + public bool StopMonitoringCalled { get; private set; } + public uint StopMonitoringCallCount { get; private set; } + public bool UseNullState { get; set; } + + public object GetService (Type serviceType) + { + return this; + } + + object IServiceProvider.GetService (Type serviceType) + { + return GetService (serviceType); + } + + public void FakeChanged (string filePath) + { + if (callback == null) + return; + + callback (null); + } + + public void StartMonitoring (string filePath, OnChangedCallback onChangedCallback, out object state, out DateTimeOffset lastWriteTime, out long fileSize) + { + if (UseNullState) + state = null; + else + state = filePath; + lastWriteTime = DateTimeOffset.FromFileTime (DateTime.Now.Ticks); + callback = onChangedCallback; + fileSize = 10; + StartMonitoringCalled = true; + StartMonitoringCallCount++; + } + + public void StopMonitoring (string filePath, object state) + { + StopMonitoringCalled = true; + StopMonitoringCallCount++; + } + + void IFileChangeNotificationSystem.StartMonitoring (string filePath, OnChangedCallback onChangedCallback, out object state, out DateTimeOffset lastWriteTime, out long fileSize) + { + StartMonitoring (filePath, onChangedCallback, out state, out lastWriteTime, out fileSize); + } + + void IFileChangeNotificationSystem.StopMonitoring (string filePath, object state) + { + StopMonitoring (filePath, state); + } + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/ChangeLog b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/ChangeLog new file mode 100644 index 00000000000..657cc7b34f3 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/ChangeLog @@ -0,0 +1,10 @@ +2010-04-26 Marek Habersack + + * MemoryCacheTest.cs: added tests for LRU removal of entries. + +2010-04-24 Marek Habersack + + * MemoryCacheTest.cs, ObjectCacheTest.cs: added + + * HostFileChangeMonitorTest.cs: added more tests. + diff --git a/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/HostFileChangeMonitorTest.cs b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/HostFileChangeMonitorTest.cs new file mode 100644 index 00000000000..a52480b56a7 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/HostFileChangeMonitorTest.cs @@ -0,0 +1,305 @@ +// +// HostFileChangeMonitorTest.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Runtime.Caching; +using System.Runtime.Caching.Hosting; +using System.Text; + +using NUnit.Framework; +using MonoTests.Common; + +namespace MonoTests.System.Runtime.Caching +{ + [TestFixture] + public class HostFileChangeMonitorTest + { + [Test] + public void Constructor_Exceptions () + { + HostFileChangeMonitor monitor; + string relPath = Path.Combine ("relative", "file", "path"); + var paths = new List { + relPath + }; + + AssertExtensions.Throws (() => { + monitor = new HostFileChangeMonitor (paths); + }, "#A1"); + + paths.Clear (); + paths.Add (null); + AssertExtensions.Throws (() => { + monitor = new HostFileChangeMonitor (paths); + }, "#A2"); + + paths.Clear (); + paths.Add (String.Empty); + AssertExtensions.Throws (() => { + monitor = new HostFileChangeMonitor (paths); + }, "#A3"); + + AssertExtensions.Throws (() => { + monitor = new HostFileChangeMonitor (null); + }, "#A4"); + + paths.Clear (); + AssertExtensions.Throws (() => { + monitor = new HostFileChangeMonitor (paths); + }, "#A5"); + } + + [Test] + public void Constructor_MissingFiles () + { + AppDomainTools.RunInSeparateDomain (Constructor_MissingFiles_Handler, "Constructor_MissingFiles"); + } + + static void Constructor_MissingFiles_Handler () + { + HostFileChangeMonitor monitor; + PlatformID pid = Environment.OSVersion.Platform; + bool runningOnWindows = ((int) pid != 128 && pid != PlatformID.Unix && pid != PlatformID.MacOSX); + string missingFile = Path.Combine ("missing", "file", "path"); + + if (runningOnWindows) + missingFile = "c:\\" + missingFile; + else + missingFile = "/" + missingFile; + + var paths = new List { + missingFile + }; + + // Actually thrown by FileSystemWatcher constructor - note that the exception message suggests the file's + // parent directory is being watched, not the file itself: + // + // MonoTests.System.Runtime.Caching.HostFileChangeMonitorTest.Constructor_MissingFiles: + // System.ArgumentException : The directory name c:\missing\file is invalid. + // at System.IO.FileSystemWatcher..ctor(String path, String filter) + // at System.IO.FileSystemWatcher..ctor(String path) + // at System.Runtime.Caching.FileChangeNotificationSystem.System.Runtime.Caching.Hosting.IFileChangeNotificationSystem.StartMonitoring(String filePath, OnChangedCallback onChangedCallback, Object& state, DateTimeOffset& lastWriteTime, Int64& fileSize) + // at System.Runtime.Caching.HostFileChangeMonitor.InitDisposableMembers() + // at System.Runtime.Caching.HostFileChangeMonitor..ctor(IList`1 filePaths) + // at MonoTests.System.Runtime.Caching.HostFileChangeMonitorTest.Constructor_MissingFiles() in c:\users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\System.Runtime.Caching\HostFileChangeMonitorTest.cs:line 68 + AssertExtensions.Throws (() => { + monitor = new HostFileChangeMonitor (paths); + }, "#A1"); + + if (runningOnWindows) + missingFile = "c:\\file.txt"; + else + missingFile = "/file.txt"; + + paths.Clear (); + paths.Add (missingFile); + monitor = new HostFileChangeMonitor (paths); + Assert.AreEqual (1, monitor.FilePaths.Count, "#A2-1"); + Assert.AreEqual (missingFile, monitor.FilePaths [0], "#A2-2"); + Assert.AreEqual (missingFile + "701CE1722770000FFFFFFFFFFFFFFFF", monitor.UniqueId, "#A2-4"); + + paths.Add (missingFile); + monitor = new HostFileChangeMonitor (paths); + Assert.AreEqual (2, monitor.FilePaths.Count, "#A3-1"); + Assert.AreEqual (missingFile, monitor.FilePaths [0], "#A3-2"); + Assert.AreEqual (missingFile, monitor.FilePaths [1], "#A3-3"); + Assert.AreEqual (missingFile + "701CE1722770000FFFFFFFFFFFFFFFF", monitor.UniqueId, "#A3-4"); + } + + [Test] + public void Constructor_Duplicates () + { + HostFileChangeMonitor monitor; + PlatformID pid = Environment.OSVersion.Platform; + bool runningOnWindows = ((int) pid != 128 && pid != PlatformID.Unix && pid != PlatformID.MacOSX); + string missingFile = Path.Combine ("missing", "file", "path"); + + if (runningOnWindows) + missingFile = "c:\\file.txt"; + else + missingFile = "/file.txt"; + + var paths = new List { + missingFile, + missingFile + }; + + // Just checks if it doesn't throw any exception for dupes + monitor = new HostFileChangeMonitor (paths); + } + + static Tuple > SetupMonitoring () + { + string testPath = Path.Combine (Path.GetTempPath (), "Dispose_Calls_StopMonitoring"); + if (!Directory.Exists (testPath)) + Directory.CreateDirectory (testPath); + + string firstFile = Path.Combine (testPath, "FirstFile.txt"); + string secondFile = Path.Combine (testPath, "SecondFile.txt"); + + File.WriteAllText (firstFile, "I am the first file."); + File.WriteAllText (secondFile, "I am the second file."); + + var paths = new List { + firstFile, + secondFile + }; + + return new Tuple> (testPath, firstFile, secondFile, paths); + } + + static void CleanupMonitoring (Tuple> setup) + { + string testPath = setup != null ? setup.Item1 : null; + if (String.IsNullOrEmpty (testPath) || !Directory.Exists (testPath)) + return; + + foreach (string f in Directory.EnumerateFiles(testPath)) { + try { + File.Delete (f); + } catch { + // ignore + } + } + } + + [Test] + public void Constructor_Calls_StartMonitoring () + { + AppDomainTools.RunInSeparateDomain (Constructor_Calls_StartMonitoring_Handler, "Constructor_Calls_StartMonitoring_Handler"); + } + + static void Constructor_Calls_StartMonitoring_Handler () + { + Tuple> setup = null; + try { + var tns = new TestNotificationSystem (); + ObjectCache.Host = tns; + setup = SetupMonitoring (); + var monitor = new HostFileChangeMonitor (setup.Item4); + + Assert.IsTrue (tns.StartMonitoringCalled, "#A1-1"); + Assert.AreEqual (2, tns.StartMonitoringCallCount, "#A1-2"); + } finally { + CleanupMonitoring (setup); + } + } + + [Test] + public void Dispose_Calls_StopMonitoring () + { + AppDomainTools.RunInSeparateDomain (Dispose_Calls_StopMonitoring_Handler, "Dispose_Calls_StopMonitoring_Handler"); + } + + static void Dispose_Calls_StopMonitoring_Handler () + { + Tuple> setup = null; + try { + var tns = new TestNotificationSystem (); + ObjectCache.Host = tns; + setup = SetupMonitoring (); + var monitor = new HostFileChangeMonitor (setup.Item4); + tns.FakeChanged (setup.Item2); + + Assert.IsTrue (tns.StopMonitoringCalled, "#A1-1"); + Assert.AreEqual (2, tns.StopMonitoringCallCount, "#A1-2"); + } finally { + CleanupMonitoring (setup); + } + } + + [Test] + public void Dispose_NullState_NoStopMonitoring () + { + AppDomainTools.RunInSeparateDomain (Dispose_NullState_NoStopMonitoring_Handler, "Dispose_NullState_NoStopMonitoring_Handler"); + } + + static void Dispose_NullState_NoStopMonitoring_Handler () + { + Tuple> setup = null; + try { + var tns = new TestNotificationSystem (); + tns.UseNullState = true; + ObjectCache.Host = tns; + setup = SetupMonitoring (); + var monitor = new HostFileChangeMonitor (setup.Item4); + tns.FakeChanged (setup.Item2); + + Assert.IsFalse (tns.StopMonitoringCalled, "#A1-1"); + Assert.AreEqual (0, tns.StopMonitoringCallCount, "#A1-2"); + } finally { + CleanupMonitoring (setup); + } + } + + [Test] + public void UniqueId () + { + Tuple> setup = null; + try { + setup = SetupMonitoring (); + FileInfo fi; + var monitor = new HostFileChangeMonitor (setup.Item4); + var sb = new StringBuilder (); + + fi = new FileInfo (setup.Item2); + sb.AppendFormat ("{0}{1:X}{2:X}", + setup.Item2, + fi.LastWriteTimeUtc.Ticks, + fi.Length); + + fi = new FileInfo (setup.Item3); + sb.AppendFormat ("{0}{1:X}{2:X}", + setup.Item3, + fi.LastWriteTimeUtc.Ticks, + fi.Length); + + Assert.AreEqual (sb.ToString (), monitor.UniqueId, "#A1"); + + var list = new List (setup.Item4); + list.Add (setup.Item1); + + monitor = new HostFileChangeMonitor (list); + var di = new DirectoryInfo (setup.Item1); + sb.AppendFormat ("{0}{1:X}{2:X}", + setup.Item1, + di.LastWriteTimeUtc.Ticks, + -1L); + Assert.AreEqual (sb.ToString (), monitor.UniqueId, "#A2"); + + list.Add (setup.Item1); + monitor = new HostFileChangeMonitor (list); + Assert.AreEqual (sb.ToString (), monitor.UniqueId, "#A3"); + } finally { + CleanupMonitoring (setup); + } + } + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/MemoryCacheTest.cs b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/MemoryCacheTest.cs new file mode 100644 index 00000000000..0039af68b2a --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/MemoryCacheTest.cs @@ -0,0 +1,1240 @@ +// +// MemoryCacheTest.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.Runtime.Caching; +using System.Threading; + +using NUnit.Framework; +using MonoTests.Common; + +namespace MonoTests.System.Runtime.Caching +{ + [TestFixture] + public class MemoryCacheTest + { + [Test] + public void ConstructorParameters () + { + MemoryCache mc; + AssertExtensions.Throws (() => { + mc = new MemoryCache (null); + }, "#A1"); + + AssertExtensions.Throws (() => { + mc = new MemoryCache (String.Empty); + }, "#A2"); + + AssertExtensions.Throws (() => { + mc = new MemoryCache ("default"); + }, "#A3"); + + var config = new NameValueCollection (); + config.Add ("CacheMemoryLimitMegabytes", "invalid"); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-1"); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", "invalid"); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-2"); + + config.Clear (); + config.Add ("PollingInterval", "invalid"); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-3"); + + config.Clear (); + config.Add ("CacheMemoryLimitMegabytes", "-1"); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-4"); + + config.Clear (); + config.Add ("CacheMemoryLimitMegabytes", UInt64.MaxValue.ToString ()); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-5"); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", "-1"); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-6"); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", UInt64.MaxValue.ToString ()); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-7"); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", UInt32.MaxValue.ToString ()); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-8"); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", "-10"); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-9"); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", "0"); + // Just make sure it doesn't throw any exception + mc = new MemoryCache ("MyCache", config); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", "101"); + AssertExtensions.Throws (() => { + mc = new MemoryCache ("MyCache", config); + }, "#A4-10"); + + // Just make sure it doesn't throw any exception + config.Clear (); + config.Add ("UnsupportedSetting", "123"); + mc = new MemoryCache ("MyCache", config); + } + + [Test] + public void Defaults () + { + var mc = new MemoryCache ("MyCache"); + Assert.AreEqual ("MyCache", mc.Name, "#A1"); + Assert.AreEqual (98, mc.PhysicalMemoryLimit, "#A2"); + // Value of this property is different from system to system + //Assert.AreEqual (0, mc.CacheMemoryLimit, "#A3"); + Assert.AreEqual (TimeSpan.FromMinutes (2), mc.PollingInterval, "#A4"); + Assert.AreEqual ( + DefaultCacheCapabilities.InMemoryProvider | + DefaultCacheCapabilities.CacheEntryChangeMonitors | + DefaultCacheCapabilities.AbsoluteExpirations | + DefaultCacheCapabilities.SlidingExpirations | + DefaultCacheCapabilities.CacheEntryRemovedCallback | + DefaultCacheCapabilities.CacheEntryUpdateCallback, + mc.DefaultCacheCapabilities, "#A1"); + } + + [Test] + public void DefaultInstanceDefaults () + { + var mc = MemoryCache.Default; + Assert.AreEqual ("Default", mc.Name, "#A1"); + Assert.AreEqual (98, mc.PhysicalMemoryLimit, "#A2"); + // Value of this property is different from system to system + //Assert.AreEqual (0, mc.CacheMemoryLimit, "#A3"); + Assert.AreEqual (TimeSpan.FromMinutes (2), mc.PollingInterval, "#A4"); + Assert.AreEqual ( + DefaultCacheCapabilities.InMemoryProvider | + DefaultCacheCapabilities.CacheEntryChangeMonitors | + DefaultCacheCapabilities.AbsoluteExpirations | + DefaultCacheCapabilities.SlidingExpirations | + DefaultCacheCapabilities.CacheEntryRemovedCallback | + DefaultCacheCapabilities.CacheEntryUpdateCallback, + mc.DefaultCacheCapabilities, "#A1"); + } + + [Test] + public void ConstructorValues () + { + var config = new NameValueCollection (); + config.Add ("PhysicalMemoryLimitPercentage", "0"); + config.Add ("CacheMemoryLimitMegabytes", "1"); + config.Add ("pollingInterval", "00:10:00"); + + var mc = new MemoryCache ("MyCache", config); + Assert.AreEqual (98, mc.PhysicalMemoryLimit, "#A1"); + Assert.AreEqual (1048576, mc.CacheMemoryLimit, "#A2"); + Assert.AreEqual (TimeSpan.FromMinutes (10), mc.PollingInterval, "#A3"); + + config.Clear (); + config.Add ("PhysicalMemoryLimitPercentage", "10"); + config.Add ("CacheMemoryLimitMegabytes", "5"); + config.Add ("PollingInterval", "01:10:00"); + + mc = new MemoryCache ("MyCache", config); + Assert.AreEqual (10, mc.PhysicalMemoryLimit, "#B1"); + Assert.AreEqual (5242880, mc.CacheMemoryLimit, "#B2"); + Assert.AreEqual (TimeSpan.FromMinutes (70), mc.PollingInterval, "#B3"); + } + + [Test] + public void Indexer () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc [null] = "value"; + }, "#A1-1"); + + AssertExtensions.Throws (() => { + object v = mc [null]; + }, "#A1-2"); + + AssertExtensions.Throws (() => { + mc ["key"] = null; + }, "#A1-3"); + + mc.Calls.Clear (); + mc ["key"] = "value"; + Assert.AreEqual (3, mc.Calls.Count, "#A2-1"); + Assert.AreEqual ("set_this [string key]", mc.Calls [0], "#A2-2"); + Assert.AreEqual ("Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [1], "#A2-3"); + Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [2], "#A2-4"); + Assert.IsTrue (mc.Contains ("key"), "#A2-5"); + + mc.Calls.Clear (); + object value = mc ["key"]; + Assert.AreEqual (1, mc.Calls.Count, "#A3-1"); + Assert.AreEqual ("get_this [string key]", mc.Calls [0], "#A3-2"); + Assert.AreEqual ("value", value, "#A3-3"); + } + + [Test] + public void Contains () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.Contains (null); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.Contains ("key", "region"); + }, "#A1-2"); + + mc.Set ("key", "value", ObjectCache.InfiniteAbsoluteExpiration); + Assert.IsTrue (mc.Contains ("key"), "#A2"); + + var cip = new CacheItemPolicy (); + cip.Priority = CacheItemPriority.NotRemovable; + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (500); + mc.Set ("key", "value", cip); + Assert.IsTrue (mc.Contains ("key"), "#B1-1"); + Thread.Sleep (1000); + // The call below removes the expired entry and returns false + Assert.IsFalse (mc.Contains ("key"), "#B1-2"); + } + + [Test] + public void CreateCacheEntryChangeMonitor () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.CreateCacheEntryChangeMonitor (new string [] { "key" }, "region"); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.CreateCacheEntryChangeMonitor (null); + }, "#A1-2"); + + AssertExtensions.Throws (() => { + mc.CreateCacheEntryChangeMonitor (new string [] {}); + }, "#A1-3"); + + AssertExtensions.Throws (() => { + mc.CreateCacheEntryChangeMonitor (new string [] { "key", null }); + }, "#A1-4"); + + mc.Set ("key1", "value1", ObjectCache.InfiniteAbsoluteExpiration); + mc.Set ("key2", "value2", ObjectCache.InfiniteAbsoluteExpiration); + mc.Set ("key3", "value3", ObjectCache.InfiniteAbsoluteExpiration); + + CacheEntryChangeMonitor monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "key2" }); + Assert.IsNotNull (monitor, "#A2-1"); + Assert.AreEqual ("System.Runtime.Caching.MemoryCacheEntryChangeMonitor", monitor.GetType ().ToString (), "#A2-2"); + Assert.AreEqual (2, monitor.CacheKeys.Count, "#A2-3"); + Assert.AreEqual ("key1", monitor.CacheKeys [0], "#A2-3-1"); + Assert.AreEqual ("key2", monitor.CacheKeys [1], "#A2-3-2"); + Assert.IsNull (monitor.RegionName, "#A2-4"); + // Since this comparison can fail from time to time, leaving it commented out + //Assert.AreEqual (DateTimeOffset.UtcNow.ToString (), monitor.LastModified.ToString (), "#A2-5"); + Assert.IsFalse (monitor.HasChanged, "#A2-5"); + + // The actual unique id is constructed from key names followed by the hex value of ticks of their last modifed time + Assert.IsFalse (String.IsNullOrEmpty (monitor.UniqueId), "#A2-6"); + + // There seems to be a bug in .NET 4.0 regarding the code below. MSDN says that non-existing keys will cause the + // returned monitor instance to be marked as changed, but instead this exception is thrown: + // + // MonoTests.System.Runtime.Caching.MemoryCacheTest.CreateCacheEntryChangeMonitor: + // System.ArgumentOutOfRangeException : The UTC time represented when the offset is applied must be between year 0 and 10,000. + // Parameter name: offset + // + // at System.DateTimeOffset.ValidateDate(DateTime dateTime, TimeSpan offset) + // at System.DateTimeOffset..ctor(DateTime dateTime) + // at System.Runtime.Caching.MemoryCacheEntryChangeMonitor.InitDisposableMembers(MemoryCache cache) + // at System.Runtime.Caching.MemoryCache.CreateCacheEntryChangeMonitor(IEnumerable`1 keys, String regionName) + // at MonoTests.Common.PokerMemoryCache.CreateCacheEntryChangeMonitor(IEnumerable`1 keys, String regionName) in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\Common\PokerMemoryCache.cs:line 113 + // at MonoTests.System.Runtime.Caching.MemoryCacheTest.CreateCacheEntryChangeMonitor() in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\System.Runtime.Caching\MemoryCacheTest.cs:line 275 + // + // It's probably caused by the code passing a DateTime.MinValue to DateTimeOffset constructor for non-existing entries. + // Until this (apparent) bug is fixed, Mono is going to implement the buggy behavior. + // +#if true + AssertExtensions.Throws (() => { + monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "doesnotexist" }); + }, "#A3"); +#else + monitor = mc.CreateCacheEntryChangeMonitor (new string [] { "key1", "doesnotexist" }); + Assert.IsNotNull (monitor, "#A3-1"); + Assert.AreEqual ("System.Runtime.Caching.MemoryCacheEntryChangeMonitor", monitor.GetType ().ToString (), "#A3-2"); + Assert.AreEqual (1, monitor.CacheKeys.Count, "#A3-3"); + Assert.AreEqual ("key1", monitor.CacheKeys [0], "#A3-3-1"); + Assert.IsNull (monitor.RegionName, "#A3-4"); + Assert.IsTrue (monitor.HasChanged, "#A3-5"); +#endif + } + + [Test] + public void AddOrGetExisting_String_Object_DateTimeOffset_String () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.AddOrGetExisting (null, "value", DateTimeOffset.Now); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key", null, DateTimeOffset.Now); + }, "#A1-2"); + + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key", "value", DateTimeOffset.Now, "region"); + }, "#A1-3"); + + object value = mc.AddOrGetExisting ("key3_A2-1", "value", DateTimeOffset.Now.AddMinutes (1)); + Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A2-1"); + Assert.IsNull (value, "#A2-2"); + + mc.Calls.Clear (); + value = mc.AddOrGetExisting ("key3_A2-1", "value2", DateTimeOffset.Now.AddMinutes (1)); + Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A3-1"); + Assert.IsNotNull (value, "#A3-2"); + Assert.AreEqual ("value", value, "#A3-3"); + Assert.AreEqual (2, mc.Calls.Count, "#A3-4"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [0], "#A3-5"); + + value = mc.AddOrGetExisting ("key_expired", "value", DateTimeOffset.MinValue); + Assert.IsFalse (mc.Contains ("key_expired"), "#A4-1"); + Assert.IsNull (value, "#A4-1"); + } + + [Test] + public void AddOrGetExisting_String_Object_CacheItemPolicy_String () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.AddOrGetExisting (null, "value", null); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key", null, null); + }, "#A1-2"); + + var cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTime.Now.AddMinutes (1); + cip.SlidingExpiration = TimeSpan.FromMinutes (1); + + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key", "value", cip); + }, "#A1-3"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.MinValue; + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key3", "value", cip); + }, "#A1-4"); + + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key", "value", null, "region"); + }, "#A1-5"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (500); + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key3", "value", cip); + }, "#A1-6"); + + cip = new CacheItemPolicy (); + cip.Priority = (CacheItemPriority) 20; + AssertExtensions.Throws (() => { + mc.AddOrGetExisting ("key3", "value", cip); + }, "#A1-7"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromTicks (0L); + mc.AddOrGetExisting ("key3_A2-1", "value", cip); + Assert.IsTrue (mc.Contains ("key3_A2-1"), "#A2-1"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (365); + mc.AddOrGetExisting ("key3_A2-2", "value", cip); + Assert.IsTrue (mc.Contains ("key3_A2-2"), "#A2-2"); + + cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { }; + object value = mc.AddOrGetExisting ("key3_A2-3", "value", cip); + Assert.IsTrue (mc.Contains ("key3_A2-3"), "#A2-3"); + Assert.IsNull (value, "#A2-4"); + + mc.Calls.Clear (); + value = mc.AddOrGetExisting ("key3_A2-3", "value2", null); + Assert.IsTrue (mc.Contains ("key3_A2-3"), "#A3-1"); + Assert.IsNotNull (value, "#A3-2"); + Assert.AreEqual ("value", value, "#A3-3"); + Assert.AreEqual (2, mc.Calls.Count, "#A3-4"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [0], "#A3-5"); + + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.MinValue; + value = mc.AddOrGetExisting ("key_expired", "value", cip); + Assert.IsFalse (mc.Contains ("key_expired"), "#A4-1"); + Assert.IsNull (value, "#A4-1"); + } + + [Test] + public void AddOrGetExisting_CacheItem_CacheItemPolicy () + { + var mc = new PokerMemoryCache ("MyCache"); + CacheItem ci, ci2; + + AssertExtensions.Throws (() => { + ci = mc.AddOrGetExisting (null, new CacheItemPolicy ()); + }, "#A1"); + + ci = new CacheItem ("key", "value"); + ci2 = mc.AddOrGetExisting (ci, null); + + // LAMESPEC: MSDN says it should return null if the entry does not exist yet. + // + Assert.IsNotNull (ci2, "#A2-1"); + Assert.AreNotEqual (ci, ci2, "#A2-2"); + Assert.IsNull (ci2.Value, "#A2-3"); + Assert.IsTrue (mc.Contains (ci.Key), "#A2-4"); + Assert.AreEqual (ci.Key, ci2.Key, "#A2-5"); + + ci = new CacheItem ("key", "value"); + ci2 = mc.AddOrGetExisting (ci, null); + Assert.IsNotNull (ci2, "#A3-1"); + Assert.AreNotEqual (ci, ci2, "#A3-2"); + Assert.IsNotNull (ci2.Value, "#A3-3"); + Assert.AreEqual (ci.Value, ci2.Value, "#A3-4"); + Assert.AreEqual (ci.Key, ci2.Key, "#A3-5"); + + AssertExtensions.Throws (() => { + ci = new CacheItem (null, "value"); + ci2 = mc.AddOrGetExisting (ci, null); + }, "#A4"); + + ci = new CacheItem (String.Empty, "value"); + ci2 = mc.AddOrGetExisting (ci, null); + Assert.IsNotNull (ci2, "#A5-1"); + Assert.AreNotEqual (ci, ci2, "#A5-2"); + Assert.IsNull (ci2.Value, "#A5-3"); + Assert.IsTrue (mc.Contains (ci.Key), "#A5-4"); + Assert.AreEqual (ci.Key, ci2.Key, "#A5-5"); + + ci = new CacheItem ("key2", null); + + // Thrown from: + // at System.Runtime.Caching.MemoryCacheEntry..ctor(String key, Object value, DateTimeOffset absExp, TimeSpan slidingExp, CacheItemPriority priority, Collection`1 dependencies, CacheEntryRemovedCallback removedCallback, MemoryCache cache) + // at System.Runtime.Caching.MemoryCache.AddOrGetExistingInternal(String key, Object value, CacheItemPolicy policy) + // at System.Runtime.Caching.MemoryCache.AddOrGetExisting(CacheItem item, CacheItemPolicy policy) + // at MonoTests.System.Runtime.Caching.MemoryCacheTest.AddOrGetExisting_CacheItem_CacheItemPolicy() in C:\Users\grendel\documents\visual studio 2010\Projects\System.Runtime.Caching.Test\System.Runtime.Caching.Test\System.Runtime.Caching\MemoryCacheTest.cs:line 211 + AssertExtensions.Throws (() => { + ci2 = mc.AddOrGetExisting (ci, null); + }, "#B1"); + + ci = new CacheItem ("key3", "value"); + var cip = new CacheItemPolicy (); + cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { }; + AssertExtensions.Throws (() => { + ci2 = mc.AddOrGetExisting (ci, cip); + }, "#B2"); + + ci = new CacheItem ("key3", "value"); + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.Now; + cip.SlidingExpiration = TimeSpan.FromTicks (DateTime.Now.Ticks); + AssertExtensions.Throws (() => { + mc.AddOrGetExisting (ci, cip); + }, "#B3"); + + ci = new CacheItem ("key3", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.MinValue; + AssertExtensions.Throws (() => { + mc.AddOrGetExisting (ci, cip); + }, "#B4-1"); + + ci = new CacheItem ("key4_#B4-2", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromTicks (0L); + mc.AddOrGetExisting (ci, cip); + Assert.IsTrue (mc.Contains ("key4_#B4-2"), "#B4-2"); + + ci = new CacheItem ("key3", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (500); + AssertExtensions.Throws (() => { + mc.AddOrGetExisting (ci, cip); + }, "#B5-1"); + + ci = new CacheItem ("key5_#B5-2", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (365); + mc.AddOrGetExisting (ci, cip); + Assert.IsTrue (mc.Contains ("key5_#B5-2"), "#B5-2"); + + ci = new CacheItem ("key3", "value"); + cip = new CacheItemPolicy (); + cip.Priority = (CacheItemPriority)20; + AssertExtensions.Throws (() => { + mc.AddOrGetExisting (ci, cip); + }, "#B6"); + + ci = new CacheItem ("key3_B7", "value"); + cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { }; + ci2 = mc.AddOrGetExisting (ci, cip); + Assert.IsTrue (mc.Contains ("key3_B7"), "#B7"); + + // LAMESPEC: MSDN says it should return null if the entry does not exist yet. + // + Assert.IsNotNull (ci2, "#C1-1"); + Assert.AreNotEqual (ci, ci2, "#C1-2"); + Assert.IsNull (ci2.Value, "#C1-3"); + Assert.IsTrue (mc.Contains (ci.Key), "#C1-4"); + Assert.AreEqual (ci.Key, ci2.Key, "#C1-5"); + + // The entry is never inserted as its expiration date is before now + ci = new CacheItem ("key_D1", "value_D1"); + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.MinValue; + ci2 = mc.AddOrGetExisting (ci, cip); + Assert.IsFalse (mc.Contains ("key_D1"), "#D1-1"); + Assert.IsNotNull (ci2, "#D1-2"); + Assert.IsNull (ci2.Value, "#D1-3"); + Assert.AreEqual ("key_D1", ci2.Key, "#D1-4"); + + mc.Calls.Clear (); + ci = new CacheItem ("key_D2", "value_D2"); + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.MaxValue; + mc.AddOrGetExisting (ci, cip); + Assert.IsTrue (mc.Contains ("key_D2"), "#D2-1"); + Assert.AreEqual (2, mc.Calls.Count, "#D2-2"); + Assert.AreEqual ("AddOrGetExisting (CacheItem item, CacheItemPolicy policy)", mc.Calls [0], "#D2-3"); + } + + [Test] + public void Set_String_Object_CacheItemPolicy_String () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.Set ("key", "value", new CacheItemPolicy (), "region"); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.Set (null, "value", new CacheItemPolicy ()); + }, "#A1-2"); + + AssertExtensions.Throws (() => { + mc.Set ("key", null, new CacheItemPolicy ()); + }, "#A1-3"); + + var cip = new CacheItemPolicy (); + cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { }; + cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { }; + AssertExtensions.Throws (() => { + mc.Set ("key", "value", cip); + }, "#A1-4"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.MinValue; + AssertExtensions.Throws (() => { + mc.Set ("key", "value", cip); + }, "#A1-5"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromTicks (0L); + mc.Set ("key_A1-6", "value", cip); + Assert.IsTrue (mc.Contains ("key_A1-6"), "#A1-6"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (500); + AssertExtensions.Throws (() => { + mc.Set ("key", "value", cip); + }, "#A1-7"); + + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (365); + mc.Set ("key_A1-8", "value", cip); + Assert.IsTrue (mc.Contains ("key_A1-8"), "#A1-8"); + + cip = new CacheItemPolicy (); + cip.Priority = (CacheItemPriority) 20; + AssertExtensions.Throws (() => { + mc.Set ("key", "value", cip); + }, "#A1-9"); + + cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { }; + mc.Set ("key_A2", "value_A2", cip); + Assert.IsTrue (mc.Contains ("key_A2"), "#A2"); + + mc.Set ("key_A3", "value_A3", new CacheItemPolicy ()); + Assert.IsTrue (mc.Contains ("key_A3"), "#A3-1"); + Assert.AreEqual ("value_A3", mc.Get ("key_A3"), "#A3-2"); + + // The entry is never inserted as its expiration date is before now + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.MinValue; + mc.Set ("key_A4", "value_A4", cip); + Assert.IsFalse (mc.Contains ("key_A4"), "#A4"); + + mc.Calls.Clear (); + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.MaxValue; + mc.Set ("key_A5", "value_A5", cip); + Assert.IsTrue (mc.Contains ("key_A5"), "#A5-1"); + Assert.AreEqual (2, mc.Calls.Count, "#A5-2"); + Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [0], "#A5-3"); + } + + [Test] + public void Set_String_Object_DateTimeOffset_String () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.Set ("key", "value", DateTimeOffset.MaxValue, "region"); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.Set (null, "value", DateTimeOffset.MaxValue); + }, "#A1-2"); + + AssertExtensions.Throws (() => { + mc.Set ("key", null, DateTimeOffset.MaxValue); + }, "#A1-3"); + + // The entry is never inserted as its expiration date is before now + mc.Set ("key_A2", "value_A2", DateTimeOffset.MinValue); + Assert.IsFalse (mc.Contains ("key_A2"), "#A2"); + + mc.Calls.Clear (); + mc.Set ("key", "value", DateTimeOffset.MaxValue); + + Assert.AreEqual (2, mc.Calls.Count, "#A2-1"); + Assert.AreEqual ("Set (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", mc.Calls [0], "#A2-2"); + Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [1], "#A2-3"); + } + + [Test] + public void Set_CacheItem_CacheItemPolicy () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.Set (null, new CacheItemPolicy ()); + }, "#A1-1"); + + // Actually thrown from the Set (string, object, CacheItemPolicy, string) overload + var ci = new CacheItem (null, "value"); + AssertExtensions.Throws (() => { + mc.Set (ci, new CacheItemPolicy ()); + }, "#A1-2"); + + ci = new CacheItem ("key", null); + AssertExtensions.Throws (() => { + mc.Set (ci, new CacheItemPolicy ()); + }, "#A1-3"); + + ci = new CacheItem ("key", "value"); + var cip = new CacheItemPolicy (); + cip.UpdateCallback = (CacheEntryUpdateArguments arguments) => { }; + cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { }; + AssertExtensions.Throws (() => { + mc.Set (ci, cip); + }, "#A1-4"); + + ci = new CacheItem ("key", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.MinValue; + AssertExtensions.Throws (() => { + mc.Set (ci, cip); + }, "#A1-5"); + + ci = new CacheItem ("key_A1-6", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromTicks (0L); + mc.Set (ci, cip); + Assert.IsTrue (mc.Contains ("key_A1-6"), "#A1-6"); + + ci = new CacheItem ("key", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (500); + AssertExtensions.Throws (() => { + mc.Set (ci, cip); + }, "#A1-7"); + + ci = new CacheItem ("key_A1-8", "value"); + cip = new CacheItemPolicy (); + cip.SlidingExpiration = TimeSpan.FromDays (365); + mc.Set (ci, cip); + Assert.IsTrue (mc.Contains ("key_A1-8"), "#A1-8"); + + ci = new CacheItem ("key", "value"); + cip = new CacheItemPolicy (); + cip.Priority = (CacheItemPriority) 20; + AssertExtensions.Throws (() => { + mc.Set (ci, cip); + }, "#A1-9"); + + ci = new CacheItem ("key_A2", "value_A2"); + cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments arguments) => { }; + mc.Set (ci, cip); + Assert.IsTrue (mc.Contains ("key_A2"), "#A2"); + + ci = new CacheItem ("key_A3", "value_A3"); + mc.Set (ci, new CacheItemPolicy ()); + Assert.IsTrue (mc.Contains ("key_A3"), "#A3-1"); + Assert.AreEqual ("value_A3", mc.Get ("key_A3"), "#A3-2"); + + // The entry is never inserted as its expiration date is before now + ci = new CacheItem ("key_A4", "value"); + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.MinValue; + mc.Set (ci, cip); + Assert.IsFalse (mc.Contains ("key_A4"), "#A4"); + + ci = new CacheItem ("key_A5", "value"); + mc.Calls.Clear (); + mc.Set (ci, new CacheItemPolicy ()); + + Assert.AreEqual (2, mc.Calls.Count, "#A5-1"); + Assert.AreEqual ("Set (CacheItem item, CacheItemPolicy policy)", mc.Calls [0], "#A5-2"); + Assert.AreEqual ("Set (string key, object value, CacheItemPolicy policy, string regionName = null)", mc.Calls [1], "#A5-3"); + } + + [Test] + public void Remove () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.Remove ("key", "region"); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.Remove (null); + }, "#A1-2"); + + bool callbackInvoked; + CacheEntryRemovedReason reason = (CacheEntryRemovedReason) 1000; + var cip = new CacheItemPolicy (); + cip.Priority = CacheItemPriority.NotRemovable; + mc.Set ("key2", "value1", cip); + object value = mc.Remove ("key2"); + + Assert.IsNotNull (value, "#B1-1"); + Assert.IsFalse (mc.Contains ("key2"), "#B1-2"); + + cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + }; + + mc.Set ("key", "value", cip); + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.Remove ("key"); + Assert.IsNotNull (value, "#C1-1"); + Assert.IsTrue (callbackInvoked, "#C1-2"); + Assert.AreEqual (CacheEntryRemovedReason.Removed, reason, "#C1-3"); + + cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + throw new ApplicationException ("test"); + }; + + mc.Set ("key", "value", cip); + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.Remove ("key"); + Assert.IsNotNull (value, "#C2-1"); + Assert.IsTrue (callbackInvoked, "#C2-2"); + Assert.AreEqual (CacheEntryRemovedReason.Removed, reason, "#C2-3"); + + // LAMESPEC: UpdateCallback is not called on remove + cip = new CacheItemPolicy (); + cip.UpdateCallback = (CacheEntryUpdateArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + }; + + mc.Set ("key", "value", cip); + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.Remove ("key"); + Assert.IsNotNull (value, "#D1-1"); + Assert.IsFalse (callbackInvoked, "#D1-2"); + + cip = new CacheItemPolicy (); + cip.UpdateCallback = (CacheEntryUpdateArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + throw new ApplicationException ("test"); + }; + + mc.Set ("key", "value", cip); + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.Remove ("key"); + Assert.IsNotNull (value, "#D2-1"); + Assert.IsFalse (callbackInvoked, "#D2-2"); + } + + [Test] + public void TimedExpiration () + { + bool expired = false; + CacheEntryRemovedReason reason = CacheEntryRemovedReason.CacheSpecificEviction; + NameValueCollection config; + int sleepPeriod; +#if !DOTNET + config = new NameValueCollection (); + config.Add ("__MonoTimerPeriod", "1"); + sleepPeriod = 1100; +#else + config = null; + sleepPeriod = 20100; // 20s is the .NET period - discovered by experimentation +#endif + var mc = new PokerMemoryCache ("MyCache", config); + var cip = new CacheItemPolicy (); + + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + expired = true; + reason = args.RemovedReason; + }; + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50); + mc.Set ("key", "value", cip); + Thread.Sleep (100); + + Assert.IsFalse (expired, "#A1"); + object value = mc.Get ("key"); + + Assert.IsNull (value, "#A2-1"); + Assert.IsTrue (expired, "#A2-2"); + Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "A2-3"); + + expired = false; + cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + expired = true; + reason = args.RemovedReason; + }; + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50); + mc.Set ("key", "value", cip); + Thread.Sleep (sleepPeriod); + + Assert.IsTrue (expired, "#A3-1"); + Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#A3-2"); + + int expiredCount = 0; + object expiredCountLock = new object (); + CacheEntryRemovedCallback removedCb = (CacheEntryRemovedArguments args) => { + lock (expiredCountLock) { + expiredCount++; + } + }; + + cip = new CacheItemPolicy (); + cip.RemovedCallback = removedCb; + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (20); + mc.Set ("key1", "value1", cip); + + cip = new CacheItemPolicy (); + cip.RemovedCallback = removedCb; + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (200); + mc.Set ("key2", "value2", cip); + + cip = new CacheItemPolicy (); + cip.RemovedCallback = removedCb; + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (600); + mc.Set ("key3", "value3", cip); + + cip = new CacheItemPolicy (); + cip.RemovedCallback = removedCb; + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (sleepPeriod + 100); + mc.Set ("key4", "value4", cip); + + Thread.Sleep (sleepPeriod); + Assert.AreEqual (3, expiredCount, "#A4"); + } + + [Test] + public void GetEnumerator () + { + var mc = new PokerMemoryCache ("MyCache"); + + // This one is a Hashtable enumerator + IEnumerator enumerator = ((IEnumerable) mc).GetEnumerator (); + + // This one is a Dictionary enumerator + IEnumerator enumerator2 = mc.DoGetEnumerator (); + + Assert.IsNotNull (enumerator, "#A1-1"); + Assert.IsNotNull (enumerator2, "#A1-2"); + Assert.IsTrue (enumerator.GetType () != enumerator2.GetType (), "#A1-3"); + + mc.Set ("key1", "value1", null); + mc.Set ("key2", "value2", null); + mc.Set ("key3", "value3", null); + + bool expired = false; + var cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTime.Now.AddMilliseconds (50); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + expired = true; + }; + + mc.Set ("key4", "value4", cip); + Thread.Sleep (100); + + enumerator = ((IEnumerable) mc).GetEnumerator (); + int count = 0; + while (enumerator.MoveNext ()) { + count++; + } + + Assert.IsFalse (expired, "#A2-1"); + Assert.AreEqual (3, count, "#A2-2"); + + expired = false; + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTime.Now.AddMilliseconds (50); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + expired = true; + }; + + mc.Set ("key5", "value5", cip); + Thread.Sleep (100); + + enumerator2 = mc.DoGetEnumerator (); + count = 0; + while (enumerator2.MoveNext ()) { + count++; + } + + Assert.IsFalse (expired, "#A3-1"); + Assert.AreEqual (3, count, "#A3-2"); + } + + [Test] + public void GetValues () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.GetValues (null); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.GetValues (new string[] {}, "region"); + }, "#A1-2"); + + AssertExtensions.Throws (() => { + mc.GetValues (new string [] { "key", null }); + }, "#A1-3"); + + IDictionary value = mc.GetValues (new string[] {}); + Assert.IsNull (value, "#A2"); + + mc.Set ("key1", "value1", null); + mc.Set ("key2", "value2", null); + mc.Set ("key3", "value3", null); + + Assert.IsTrue (mc.Contains ("key1"), "#A3-1"); + Assert.IsTrue (mc.Contains ("key2"), "#A3-2"); + Assert.IsTrue (mc.Contains ("key3"), "#A3-2"); + + value = mc.GetValues (new string [] { "key1", "key3" }); + Assert.IsNotNull (value, "#A4-1"); + Assert.AreEqual (2, value.Count, "#A4-2"); + Assert.AreEqual ("value1", value ["key1"], "#A4-3"); + Assert.AreEqual ("value3", value ["key3"], "#A4-4"); + Assert.AreEqual (typeof (Dictionary), value.GetType (), "#A4-5"); + + // LAMESPEC: MSDN says the number of items in the returned dictionary should be the same as in the + // 'keys' collection - this is not the case. The returned dictionary contains only entries for keys + // that exist in the cache. + value = mc.GetValues (new string [] { "key1", "key3", "nosuchkey" }); + Assert.IsNotNull (value, "#A5-1"); + Assert.AreEqual (2, value.Count, "#A5-2"); + Assert.AreEqual ("value1", value ["key1"], "#A5-3"); + Assert.AreEqual ("value3", value ["key3"], "#A5-4"); + Assert.IsFalse (value.ContainsKey ("Key1"), "#A5-5"); + } + + [Test] + public void Get () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.Get ("key", "region"); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.Get (null); + }, "#A1-2"); + + object value; + mc.Set ("key", "value", null); + value = mc.Get ("key"); + Assert.IsNotNull (value, "#A2-1"); + Assert.AreEqual ("value", value, "#A2-2"); + + value = mc.Get ("nosuchkey"); + Assert.IsNull (value, "#A3"); + + var cip = new CacheItemPolicy (); + bool callbackInvoked; + CacheEntryRemovedReason reason = (CacheEntryRemovedReason)1000; + + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + }; + mc.Set ("key", "value", cip); + Thread.Sleep (500); + + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.Get ("key"); + Assert.IsNull (value, "#B1-1"); + Assert.IsTrue (callbackInvoked, "#B1-2"); + Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B1-3"); + + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + throw new ApplicationException ("test"); + }; + + mc.Set ("key", "value", cip); + Thread.Sleep (500); + + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.Get ("key"); + Assert.IsNull (value, "#B2-1"); + Assert.IsTrue (callbackInvoked, "#B2-2"); + Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B2-3"); + } + + [Test] + public void GetCacheItem () + { + var mc = new PokerMemoryCache ("MyCache"); + + AssertExtensions.Throws (() => { + mc.GetCacheItem ("key", "region"); + }, "#A1-1"); + + AssertExtensions.Throws (() => { + mc.GetCacheItem (null); + }, "#A1-2"); + + CacheItem value; + mc.Set ("key", "value", null); + value = mc.GetCacheItem ("key"); + Assert.IsNotNull (value, "#A2-1"); + Assert.AreEqual ("value", value.Value, "#A2-2"); + Assert.AreEqual ("key", value.Key, "#A2-3"); + + value = mc.GetCacheItem ("doesnotexist"); + Assert.IsNull (value, "#A3"); + + var cip = new CacheItemPolicy (); + bool callbackInvoked; + CacheEntryRemovedReason reason = (CacheEntryRemovedReason) 1000; + + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + }; + mc.Set ("key", "value", cip); + Thread.Sleep (500); + + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.GetCacheItem ("key"); + Assert.IsNull (value, "#B1-1"); + Assert.IsTrue (callbackInvoked, "#B1-2"); + Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B1-3"); + + cip = new CacheItemPolicy (); + cip.AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds (50); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + callbackInvoked = true; + reason = args.RemovedReason; + throw new ApplicationException ("test"); + }; + + mc.Set ("key", "value", cip); + Thread.Sleep (500); + + callbackInvoked = false; + reason = (CacheEntryRemovedReason) 1000; + value = mc.GetCacheItem ("key"); + Assert.IsNull (value, "#B2-1"); + Assert.IsTrue (callbackInvoked, "#B2-2"); + Assert.AreEqual (CacheEntryRemovedReason.Expired, reason, "#B2-3"); + } + + [Test] + public void ChangeMonitors () + { + bool removed = false; + var mc = new PokerMemoryCache ("MyCache"); + var cip = new CacheItemPolicy (); + var monitor = new PokerChangeMonitor (); + cip.ChangeMonitors.Add (monitor); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + removed = true; + }; + + mc.Set ("key", "value", cip); + Assert.AreEqual (0, monitor.Calls.Count, "#A1"); + + monitor.SignalChange (); + Assert.IsTrue (removed, "#A2"); + + bool onChangedCalled = false; + monitor = new PokerChangeMonitor (); + monitor.NotifyOnChanged ((object state) => { + onChangedCalled = true; + }); + + cip = new CacheItemPolicy (); + cip.ChangeMonitors.Add (monitor); + + // Thrown by ChangeMonitor.NotifyOnChanged + AssertExtensions.Throws (() => { + mc.Set ("key1", "value1", cip); + }, "#A3"); + } + + // NOTE: on Windows with 2 or more CPUs this test will most probably fail. + [Test] + public void Trim () + { + var config = new NameValueCollection (); + config ["__MonoEmulateOneCPU"] = "true"; + var mc = new MemoryCache ("MyCache", config); + + for (int i = 0; i < 10; i++) + mc.Set ("key" + i.ToString (), "value" + i.ToString (), null); + + // .NET doesn't touch the freshest 10 entries + Assert.AreEqual (10, mc.GetCount (), "#A1-1"); + long trimmed = mc.Trim (50); + Assert.AreEqual (0, trimmed, "#A1-2"); + Assert.AreEqual (10, mc.GetCount (), "#A1-3"); + + mc = new MemoryCache ("MyCache", config); + // Only entries 11- are considered for removal + for (int i = 0; i < 11; i++) + mc.Set ("key" + i.ToString (), "value" + i.ToString (), null); + + Assert.AreEqual (11, mc.GetCount (), "#A2-1"); + trimmed = mc.Trim (50); + Assert.AreEqual (1, trimmed, "#A2-2"); + Assert.AreEqual (10, mc.GetCount (), "#A2-3"); + + mc = new MemoryCache ("MyCache", config); + // Only entries 11- are considered for removal + for (int i = 0; i < 125; i++) + mc.Set ("key" + i.ToString (), "value" + i.ToString (), null); + + Assert.AreEqual (125, mc.GetCount (), "#A3-1"); + trimmed = mc.Trim (50); + Assert.AreEqual (62, trimmed, "#A3-2"); + Assert.AreEqual (63, mc.GetCount (), "#A3-3"); + + // Testing the removal order + mc = new MemoryCache ("MyCache", config); + var removed = new List (); + var cip = new CacheItemPolicy (); + cip.RemovedCallback = (CacheEntryRemovedArguments args) => { + removed.Add (args.CacheItem.Key); + }; + + for (int i = 0; i < 50; i++) + mc.Set ("key" + i.ToString (), "value" + i.ToString (), cip); + + object value; + for (int i = 0; i < 50; i++) + value = mc.Get ("key" + i.ToString ()); + + trimmed = mc.Trim (50); + Assert.AreEqual (25, mc.GetCount (), "#A4-1"); + Assert.AreEqual (25, trimmed, "#A4-2"); + Assert.AreEqual (25, removed.Count, "#A4-3"); + + // OK, this is odd... The list is correct in terms of entries removed but the entries + // are removed in the _MOST_ frequently used order, within the group selected for removal. + for (int i = 24; i >= 0; i--) { + int idx = 24 - i; + Assert.AreEqual ("key" + i.ToString (), removed [idx], "#A5-" + idx.ToString ()); + } + } + } +} diff --git a/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/ObjectCacheTest.cs b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/ObjectCacheTest.cs new file mode 100644 index 00000000000..e5eefb72970 --- /dev/null +++ b/mcs/class/System.Runtime.Caching/Test/System.Runtime.Caching/ObjectCacheTest.cs @@ -0,0 +1,159 @@ +// +// ObjectCacheTest.cs +// +// Authors: +// Marek Habersack +// +// Copyright (C) 2010 Novell, Inc. (http://novell.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Runtime.Caching; + +using NUnit.Framework; +using MonoTests.Common; + +namespace MonoTests.System.Runtime.Caching +{ + [TestFixture] + public class ObjectCacheTest + { + [Test] + public void Host () + { + Assert.IsTrue (ObjectCache.Host == null, "#A1"); + + AppDomainTools.RunInSeparateDomain (Host_SetToNull, "Host_SetToNull"); + AppDomainTools.RunInSeparateDomain (Host_SetToProvider, "Host_SetToProvider"); + } + + static void Host_SetToNull () + { + AssertExtensions.Throws (() => { + ObjectCache.Host = null; + }, "#A2"); + } + + static void Host_SetToProvider () + { + var tns1 = new TestNotificationSystem (); + var tns2 = new TestNotificationSystem (); + ObjectCache.Host = tns1; + Assert.IsNotNull (ObjectCache.Host, "#A3-1"); + Assert.AreEqual (tns1, ObjectCache.Host, "#A3-2"); + + AssertExtensions.Throws (() => { + ObjectCache.Host = tns2; + }, "#A4"); + } + + [Test] + public void Add_CacheItem_CacheItemPolicy () + { + var poker = new PokerObjectCache (); + bool ret; + + ret = poker.Add (null, null); + Assert.IsTrue (ret, "#A1-1"); + Assert.AreEqual ("AddOrGetExisting (CacheItem value, CacheItemPolicy policy)", poker.MethodCalled, "#A1-2"); + + var item = new CacheItem ("key", 1234); + ret = poker.Add (item, null); + Assert.IsTrue (ret, "#A2-1"); + Assert.AreEqual ("AddOrGetExisting (CacheItem value, CacheItemPolicy policy)", poker.MethodCalled, "#A2-2"); + + ret = poker.Add (item, null); + Assert.IsFalse (ret, "#A3-1"); + Assert.AreEqual ("AddOrGetExisting (CacheItem value, CacheItemPolicy policy)", poker.MethodCalled, "#A3-2"); + } + + [Test] + public void Add_String_Object_CacheItemPolicy_String () + { + var poker = new PokerObjectCache (); + bool ret; + + ret = poker.Add (null, null, null, null); + Assert.IsTrue (ret, "#A1-1"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)", poker.MethodCalled, "#A1-2"); + + ret = poker.Add ("key", 1234, null, null); + Assert.IsTrue (ret, "#A2-1"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)", poker.MethodCalled, "#A2-2"); + + ret = poker.Add ("key", 1234, null, null); + Assert.IsFalse (ret, "#A2-1"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, CacheItemPolicy policy, string regionName = null)", poker.MethodCalled, "#A2-2"); + } + + [Test] + public void Add_String_Object_DateTimeOffset_String () + { + var poker = new PokerObjectCache (); + bool ret; + + ret = poker.Add (null, null, DateTimeOffset.Now, null); + Assert.IsTrue (ret, "#A1-1"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", poker.MethodCalled, "#A1-2"); + + ret = poker.Add ("key", 1234, DateTimeOffset.Now, null); + Assert.IsTrue (ret, "#A2-1"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", poker.MethodCalled, "#A2-2"); + + ret = poker.Add ("key", 1234, DateTimeOffset.Now, null); + Assert.IsFalse (ret, "#A2-1"); + Assert.AreEqual ("AddOrGetExisting (string key, object value, DateTimeOffset absoluteExpiration, string regionName = null)", poker.MethodCalled, "#A2-2"); + } + + [Test] + public void GetValues () + { + var poker = new PokerObjectCache (); + + IDictionary values = poker.GetValues (null, (string []) null); + Assert.IsNotNull (values, "#A1-1"); + Assert.AreEqual (0, values.Count, "#A1-2"); + Assert.AreEqual ("IDictionary GetValues (IEnumerable keys, string regionName = null)", poker.MethodCalled, "#A1-3"); + + poker.Add ("key1", 1, null); + poker.Add ("key2", 2, null); + poker.Add ("key3", 3, null); + + values = poker.GetValues (new string [] { "key1", "key2", "key3" }); + Assert.IsNotNull (values, "#A2-1"); + Assert.AreEqual (3, values.Count, "#A2-2"); + Assert.AreEqual ("IDictionary GetValues (IEnumerable keys, string regionName = null)", poker.MethodCalled, "#A2-3"); + + values = poker.GetValues (new string [] { "key1", "key22", "key3" }); + Assert.IsNotNull (values, "#A3-1"); + Assert.AreEqual (2, values.Count, "#A3-2"); + Assert.AreEqual ("IDictionary GetValues (IEnumerable keys, string regionName = null)", poker.MethodCalled, "#A3-3"); + } + + [Test] + public void Defaults () + { + Assert.AreEqual (DateTimeOffset.MaxValue, ObjectCache.InfiniteAbsoluteExpiration, "#A1"); + Assert.AreEqual (TimeSpan.Zero, ObjectCache.NoSlidingExpiration, "#A2"); + } + } +} diff --git a/mcs/class/System.Runtime.Serialization/ChangeLog b/mcs/class/System.Runtime.Serialization/ChangeLog index 701f3bbfe19..06bfd0b1de3 100644 --- a/mcs/class/System.Runtime.Serialization/ChangeLog +++ b/mcs/class/System.Runtime.Serialization/ChangeLog @@ -1,3 +1,7 @@ +2010-03-16 Jb Evain + + * net_2_1_*.dll.sources: rename to moonlight_*.dll.sources. + 2010-03-03 Atsushi Enomoto * System.Runtime.Serialization.dll.sources: diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/ChangeLog b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/ChangeLog index 497a7fb3b9d..7f4f2d8e3a0 100755 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/ChangeLog +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/ChangeLog @@ -1,3 +1,23 @@ +2010-04-05 Atsushi Enomoto + + * DataContractExporter-new.cs : do not expect contract attribute on + dictionary map. Non-contract type also uses this. + +2010-04-05 Atsushi Enomoto + + * SerializationMap.XsdExporter.cs, DataContractExporter-new.cs : + handle schema export for SharedTypeMap. + +2010-04-05 Atsushi Enomoto + + * KnownTypeCollection.cs, SerializationMap.cs : split SharedTypeMap + .ctor() and initialization. Fixed infinite loop for some + [Serializable] types (such as Assembly). + +2010-04-02 Atsushi Enomoto + + * DataContractSerializer : implement IsStartObject(). + 2010-03-12 Atsushi Enomoto * KnownTypeCollection.cs, SerializationMap.cs : diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs index aa34575839f..44ab29d1859 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/DataContractSerializer.cs @@ -237,10 +237,12 @@ namespace System.Runtime.Serialization get { return preserve_refs; } } - [MonoTODO] public override bool IsStartObject (XmlDictionaryReader reader) { - throw new NotImplementedException (); + if (reader == null) + throw new ArgumentNullException ("reader"); + reader.MoveToContent (); + return reader.IsStartElement (root_name, root_ns); } // SP1 diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs index 037615f7e6e..62ace1948be 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/KnownTypeCollection.cs @@ -722,9 +722,9 @@ namespace System.Runtime.Serialization if (FindUserMap (qname) != null) throw new InvalidOperationException (String.Format ("There is already a registered type for XML name {0}", qname)); - SharedTypeMap ret = - new SharedTypeMap (type, qname, this); + SharedTypeMap ret = new SharedTypeMap (type, qname, this); contracts.Add (ret); + ret.Initialize (); return ret; } diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.XsdExporter.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.XsdExporter.cs index 4d7988d21d2..ce950f0b1e0 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.XsdExporter.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.XsdExporter.cs @@ -62,7 +62,7 @@ namespace System.Runtime.Serialization { public override void ExportSchemaType (XsdDataContractExporter exporter) { - exporter.ExportStandardComplexType (RuntimeType.GetCustomAttribute (false), RuntimeType); + exporter.ExportStandardComplexType (RuntimeType.GetCustomAttribute (false), RuntimeType, Members); } } @@ -70,7 +70,7 @@ namespace System.Runtime.Serialization { public override void ExportSchemaType (XsdDataContractExporter exporter) { - exporter.ExportStandardComplexType (null, RuntimeType); + exporter.ExportStandardComplexType (null, RuntimeType, Members); } } @@ -102,7 +102,7 @@ namespace System.Runtime.Serialization { public override void ExportSchemaType (XsdDataContractExporter exporter) { - throw new NotImplementedException (); + exporter.ExportStandardComplexType (null, RuntimeType, Members); } } diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs index c04a26d7833..992b1286841 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/SerializationMap.cs @@ -968,7 +968,11 @@ namespace System.Runtime.Serialization Type type, QName qname, KnownTypeCollection knownTypes) : base (type, qname, knownTypes) { - Members = GetMembers (type, XmlName, false); + } + + public void Initialize () + { + Members = GetMembers (RuntimeType, XmlName, false); } List GetMembers (Type type, QName qname, bool declared_only) diff --git a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter-new.cs b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter-new.cs index 9cce840b166..27bde112d64 100644 --- a/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter-new.cs +++ b/mcs/class/System.Runtime.Serialization/System.Runtime.Serialization/XsdDataContractExporter-new.cs @@ -219,67 +219,12 @@ namespace System.Runtime.Serialization if (imported_types.FirstOrDefault (i => i.ClrType == type) != null) return false; -#if true known_types.TryRegister (type); var map = known_types.FindUserMap (type); if (map == null) return false; map.ExportSchemaType (this); return true; -#else - var cdca = type.GetCustomAttribute (true); - var dicType = GetIDictionaryInterfaceType (type); - if (dicType != null) { - ExportDictionaryContractType (cdca, type, dicType); - return true; - } - // not sure if contract is required - if (type.IsArray && type != typeof (byte [])) { - ExportListContractType (cdca, type); - return true; - } - if (cdca != null) { - ExportListContractType (cdca, type); - return true; - } - - var dca = type.GetCustomAttribute (true); - if (type.IsEnum) { // regardless of DCA existence. - ExportEnumContractType (dca, type); - return true; - } - if (dca != null) { - ExportStandardComplexType (dca, type); - return true; - } - - // FIXME: support [Serializable] - - if (rejectNonContract) - throw new InvalidDataContractException ("DataContractAttribute is missing"); - - return false; -#endif - } - - // copied from KnownTypeCollection, removing IDictionary - static Type GetIDictionaryInterfaceType (Type type) - { - foreach (var iface in type.GetInterfaces ()) - if (iface == typeof (IDictionary) || (iface.IsGenericType && iface.GetGenericTypeDefinition () == typeof (IDictionary<,>))) - return iface; - - return null; - } - - // copied from KnownTypeCollection, removing IDictionary - static Type GetCollectionInterfaceType (Type type) - { - foreach (var iface in type.GetInterfaces ()) - if (iface == typeof (IList) || (iface.IsGenericType && iface.GetGenericTypeDefinition () == typeof (ICollection<>))) - return iface; - - return null; } internal void ExportDictionaryContractType (CollectionDataContractAttribute attr, Type type, Type dicType) @@ -292,8 +237,12 @@ namespace System.Runtime.Serialization ExportCore (keyType, false); ExportCore (valueType, false); - var keyName = attr.KeyName ?? "Key"; - var valueName = attr.ValueName ?? "Value"; + string keyName = "Key", valueName = "Value"; + if (attr != null) { + keyName = attr.KeyName ?? keyName; + valueName = attr.ValueName ?? valueName; + } + string itemName = attr != null && attr.ItemName != null ? attr.ItemName : "KeyValueOf" + keyName + valueName; var ct = CreateComplexType (qname, type); var appInfo = new XmlSchemaAppInfo (); @@ -305,7 +254,7 @@ namespace System.Runtime.Serialization var seq = new XmlSchemaSequence (); ct.Particle = seq; - var el = new XmlSchemaElement () { Name = attr.ItemName ?? "KeyValueOf" + keyName + valueName, MinOccurs = 0, MaxOccursString = "unbounded" }; + var el = new XmlSchemaElement () { Name = itemName, MinOccurs = 0, MaxOccursString = "unbounded" }; seq.Items.Add (el); var dictType = new XmlSchemaComplexType (); @@ -378,7 +327,7 @@ namespace System.Runtime.Serialization return r; } - internal void ExportStandardComplexType (DataContractAttribute attr, Type type) + internal void ExportStandardComplexType (DataContractAttribute attr, Type type, List members) { var qname = attr != null && attr.Name != null ? new QName (attr.Name, attr.Namespace ?? GetXmlNamespace (type)) : GetSchemaTypeName (type); var ct = CreateComplexType (qname, type); @@ -390,10 +339,10 @@ namespace System.Runtime.Serialization var xcce = new XmlSchemaComplexContentExtension (); xcc.Content = xcce; xcce.BaseTypeName = GetSchemaTypeName (type.BaseType); - xcce.Particle = CreateMembersSequence (type, attr != null); + xcce.Particle = CreateMembersSequence (type, members, attr != null); } else - ct.Particle = CreateMembersSequence (type, attr != null); + ct.Particle = CreateMembersSequence (type, members, attr != null); } XmlSchemaSimpleType CreateSimpleType (QName qname, Type type) @@ -431,7 +380,8 @@ namespace System.Runtime.Serialization return a1.Order == a2.Order ? String.CompareOrdinal (a1.Name ?? m1.Name, a2.Name ?? m2.Name) : a1.Order - a2.Order; } - XmlSchemaSequence CreateMembersSequence (Type type, bool expectContract) + // FIXME: use members parameter to determine which members are to be exported. + XmlSchemaSequence CreateMembersSequence (Type type, List dataMembers, bool expectContract) { var seq = new XmlSchemaSequence (); var members = new List (); @@ -446,7 +396,8 @@ namespace System.Runtime.Serialization if ((!expectContract || mi.GetCustomAttribute (false) != null) && mi.GetIndexParameters ().Length == 0) members.Add (mi); - members.Sort (CompareMembers); + if (expectContract) + members.Sort (CompareMembers); foreach (var mi in members) { var dma = mi.GetCustomAttribute (false); diff --git a/mcs/class/System.Runtime.Serialization/monotouch_System.Runtime.Serialization.dll.sources b/mcs/class/System.Runtime.Serialization/monotouch_System.Runtime.Serialization.dll.sources index 602d0d07a69..7885b804a7c 100644 --- a/mcs/class/System.Runtime.Serialization/monotouch_System.Runtime.Serialization.dll.sources +++ b/mcs/class/System.Runtime.Serialization/monotouch_System.Runtime.Serialization.dll.sources @@ -1,2 +1,2 @@ -#include net_2_1_raw_System.Runtime.Serialization.dll.sources +#include moonlight_raw_System.Runtime.Serialization.dll.sources System.Xml/OnXmlDictionaryReaderClose.cs diff --git a/mcs/class/System.Runtime.Serialization/moonlight_raw_System.Runtime.Serialization.dll.sources b/mcs/class/System.Runtime.Serialization/moonlight_raw_System.Runtime.Serialization.dll.sources new file mode 100644 index 00000000000..59cd659ac4d --- /dev/null +++ b/mcs/class/System.Runtime.Serialization/moonlight_raw_System.Runtime.Serialization.dll.sources @@ -0,0 +1,46 @@ +Assembly/AssemblyInfo.cs +System.Runtime.Serialization/CollectionDataContractAttribute.cs +System.Runtime.Serialization/ContractNamespaceAttribute.cs +System.Runtime.Serialization/DataContractAttribute.cs +System.Runtime.Serialization/DataContractSerializer.cs +System.Runtime.Serialization/DataMemberAttribute.cs +System.Runtime.Serialization/EnumMemberAttribute.cs +System.Runtime.Serialization/ExportOptions.cs +System.Runtime.Serialization/ExtensionDataObject.cs +System.Runtime.Serialization/IDataContractSurrogate.cs +System.Runtime.Serialization/IExtensibleDataObject.cs +System.Runtime.Serialization/IgnoreDataMemberAttribute.cs +System.Runtime.Serialization/InvalidDataContractException.cs +System.Runtime.Serialization/KnownTypeAttribute.cs +System.Runtime.Serialization/KnownTypeCollection.cs +System.Runtime.Serialization/NetDataContractSerializer.cs +System.Runtime.Serialization/SerializationMap.cs +System.Runtime.Serialization/XmlFormatterDeserializer.cs +System.Runtime.Serialization/XmlFormatterSerializer.cs +System.Runtime.Serialization/XmlObjectSerializer.cs +System.Xml/IStreamProvider.cs +System.Xml/IXmlBinaryReaderInitializer.cs +System.Xml/IXmlBinaryWriterInitializer.cs +System.Xml/IXmlDictionary.cs +System.Xml/IXmlMtomReaderInitializer.cs +System.Xml/IXmlMtomWriterInitializer.cs +System.Xml/IXmlUTF8ReaderInitializer.cs +System.Xml/IXmlUTF8WriterInitializer.cs +System.Xml/OnXmlDictionaryReaderClose.cs +System.Xml/UniqueId.cs +System.Xml/XmlBinaryDictionaryReader.cs +System.Xml/XmlBinaryDictionaryWriter.cs +System.Xml/XmlBinaryFormat.cs +System.Xml/XmlBinaryReaderSession.cs +System.Xml/XmlBinaryWriterSession.cs +System.Xml/XmlC14NWriter.cs +System.Xml/XmlCanonicalWriter.cs +System.Xml/XmlDictionary.cs +System.Xml/XmlDictionaryReader.cs +System.Xml/XmlDictionaryReaderAutoGen.cs +System.Xml/XmlDictionaryReaderQuotas.cs +System.Xml/XmlDictionaryString.cs +System.Xml/XmlDictionaryWriter.cs +System.Xml/XmlDictionaryWriterAutoGen.cs +System.Xml/XmlSimpleDictionaryReader.cs +System.Xml/XmlSimpleDictionaryWriter.cs diff --git a/mcs/class/System.Runtime.Serialization/net_2_1_raw_System.Runtime.Serialization.dll.sources b/mcs/class/System.Runtime.Serialization/net_2_1_raw_System.Runtime.Serialization.dll.sources deleted file mode 100644 index 59cd659ac4d..00000000000 --- a/mcs/class/System.Runtime.Serialization/net_2_1_raw_System.Runtime.Serialization.dll.sources +++ /dev/null @@ -1,46 +0,0 @@ -Assembly/AssemblyInfo.cs -System.Runtime.Serialization/CollectionDataContractAttribute.cs -System.Runtime.Serialization/ContractNamespaceAttribute.cs -System.Runtime.Serialization/DataContractAttribute.cs -System.Runtime.Serialization/DataContractSerializer.cs -System.Runtime.Serialization/DataMemberAttribute.cs -System.Runtime.Serialization/EnumMemberAttribute.cs -System.Runtime.Serialization/ExportOptions.cs -System.Runtime.Serialization/ExtensionDataObject.cs -System.Runtime.Serialization/IDataContractSurrogate.cs -System.Runtime.Serialization/IExtensibleDataObject.cs -System.Runtime.Serialization/IgnoreDataMemberAttribute.cs -System.Runtime.Serialization/InvalidDataContractException.cs -System.Runtime.Serialization/KnownTypeAttribute.cs -System.Runtime.Serialization/KnownTypeCollection.cs -System.Runtime.Serialization/NetDataContractSerializer.cs -System.Runtime.Serialization/SerializationMap.cs -System.Runtime.Serialization/XmlFormatterDeserializer.cs -System.Runtime.Serialization/XmlFormatterSerializer.cs -System.Runtime.Serialization/XmlObjectSerializer.cs -System.Xml/IStreamProvider.cs -System.Xml/IXmlBinaryReaderInitializer.cs -System.Xml/IXmlBinaryWriterInitializer.cs -System.Xml/IXmlDictionary.cs -System.Xml/IXmlMtomReaderInitializer.cs -System.Xml/IXmlMtomWriterInitializer.cs -System.Xml/IXmlUTF8ReaderInitializer.cs -System.Xml/IXmlUTF8WriterInitializer.cs -System.Xml/OnXmlDictionaryReaderClose.cs -System.Xml/UniqueId.cs -System.Xml/XmlBinaryDictionaryReader.cs -System.Xml/XmlBinaryDictionaryWriter.cs -System.Xml/XmlBinaryFormat.cs -System.Xml/XmlBinaryReaderSession.cs -System.Xml/XmlBinaryWriterSession.cs -System.Xml/XmlC14NWriter.cs -System.Xml/XmlCanonicalWriter.cs -System.Xml/XmlDictionary.cs -System.Xml/XmlDictionaryReader.cs -System.Xml/XmlDictionaryReaderAutoGen.cs -System.Xml/XmlDictionaryReaderQuotas.cs -System.Xml/XmlDictionaryString.cs -System.Xml/XmlDictionaryWriter.cs -System.Xml/XmlDictionaryWriterAutoGen.cs -System.Xml/XmlSimpleDictionaryReader.cs -System.Xml/XmlSimpleDictionaryWriter.cs diff --git a/mcs/class/System.Security/ChangeLog b/mcs/class/System.Security/ChangeLog index 770ffc3a8a1..82455b4257c 100644 --- a/mcs/class/System.Security/ChangeLog +++ b/mcs/class/System.Security/ChangeLog @@ -1,3 +1,7 @@ +2010-03-16 Jb Evain + + * Makefile: rename the net_2_1 profile to moonlight. + 2009-06-05 Marek Safar * Makefile: Fixed NET_2_0 conditional to actually handle Mono.Security diff --git a/mcs/class/System.Security/Makefile b/mcs/class/System.Security/Makefile index 3d55d17cf2b..bf261067d24 100644 --- a/mcs/class/System.Security/Makefile +++ b/mcs/class/System.Security/Makefile @@ -13,7 +13,7 @@ LIB_MCS_FLAGS += -r:Mono.Security.dll -nowarn:414 TEST_MCS_FLAGS += -nowarn:168,183,414 endif -VALID_PROFILE := $(filter net_1_1 net_2_0 net_2_1_raw net_4_0, $(PROFILE)) +VALID_PROFILE := $(filter net_1_1 net_2_0 moonlight_raw net_4_0, $(PROFILE)) ifndef VALID_PROFILE # @echo "** Warning: System.Security.dll built without parts that depend on: Mono.Security.dll " else diff --git a/mcs/class/System.ServiceModel.Discovery/Assembly/AssemblyInfo.cs b/mcs/class/System.ServiceModel.Discovery/Assembly/AssemblyInfo.cs new file mode 100644 index 00000000000..fb5235979da --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/Assembly/AssemblyInfo.cs @@ -0,0 +1,61 @@ +// +// AssemblyInfo.cs +// +// Author: +// Joel W. Reed (joelwreed@gmail.com) +// + +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Reflection; +using System.Resources; +using System.Security; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about the System.ServiceModel assembly + +[assembly: AssemblyVersion (Consts.FxVersion)] +[assembly: SatelliteContractVersion (Consts.FxVersion)] + +[assembly: AssemblyTitle ("System.ServiceModel.Discovery.dll")] +[assembly: AssemblyDescription ("System.ServiceModel.Discovery.dll")] +[assembly: AssemblyConfiguration ("Development version")] +[assembly: AssemblyCompany ("MONO development team")] +[assembly: AssemblyProduct ("MONO CLI")] +[assembly: AssemblyCopyright ("(c) 2003 Various Authors")] +[assembly: AssemblyTrademark ("")] + +[assembly: CLSCompliant (true)] +[assembly: AssemblyDefaultAlias ("System.ServiceModel.Discovery.dll")] +[assembly: AssemblyInformationalVersion ("3.5.594.0")] +[assembly: NeutralResourcesLanguage ("en-US")] + +[assembly: ComVisible (false)] + +[assembly: AssemblyDelaySign (true)] +#if NET_2_1 +[assembly: AssemblyKeyFile ("../silverlight.pub")] +#else +[assembly: AssemblyKeyFile("../winfx.pub")] +#endif diff --git a/mcs/class/System.ServiceModel.Discovery/Assembly/ChangeLog b/mcs/class/System.ServiceModel.Discovery/Assembly/ChangeLog new file mode 100755 index 00000000000..ce289a8a77d --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/Assembly/ChangeLog @@ -0,0 +1,4 @@ +2010-03-19 Atsushi Enomoto + + * : initial checkin (mostly stubs). + diff --git a/mcs/class/System.ServiceModel.Discovery/ChangeLog b/mcs/class/System.ServiceModel.Discovery/ChangeLog new file mode 100644 index 00000000000..ce289a8a77d --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/ChangeLog @@ -0,0 +1,4 @@ +2010-03-19 Atsushi Enomoto + + * : initial checkin (mostly stubs). + diff --git a/mcs/class/System.ServiceModel.Discovery/Makefile b/mcs/class/System.ServiceModel.Discovery/Makefile new file mode 100644 index 00000000000..de570d08739 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/Makefile @@ -0,0 +1,24 @@ +thisdir = class/System.ServiceModel.Discovery +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.ServiceModel.Discovery.dll +LIB_MCS_FLAGS = -r:System.dll -r:System.Xml.dll -r:System.Runtime.Serialization.dll -r:System.ServiceModel.dll -r:System.Core.dll -r:System.Xml.Linq.dll + +ifneq (2.1, $(FRAMEWORK_VERSION)) +LIB_MCS_FLAGS += -d:NET_3_5 -d:NET_3_0 \ + -r:System.Configuration.dll +endif + +TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) + +EXTRA_DISTFILES = $(RESOURCE_FILES) + +VALID_PROFILE := $(filter 2.0 2.1 4.0, $(FRAMEWORK_VERSION)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.ServiceModel.Discovery.dll +NO_INSTALL = yes +NO_SIGN_ASSEMBLY = yes +endif + +include ../../build/library.make diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/ChangeLog b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/ChangeLog new file mode 100755 index 00000000000..ce289a8a77d --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/ChangeLog @@ -0,0 +1,4 @@ +2010-03-19 Atsushi Enomoto + + * : initial checkin (mostly stubs). + diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/DiscoveryMessageSequenceApril2005.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/DiscoveryMessageSequenceApril2005.cs new file mode 100755 index 00000000000..ea4791f12f4 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/DiscoveryMessageSequenceApril2005.cs @@ -0,0 +1,75 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionApril2005 +{ + public class DiscoveryMessageSequenceApril2005 : IXmlSerializable + { + public static DiscoveryMessageSequenceApril2005 FromDiscoveryMessageSequence (DiscoveryMessageSequence discoveryMessageSequence) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + internal DiscoveryMessageSequenceApril2005 () + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public DiscoveryMessageSequence ToDiscoveryMessageSequence () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/EndpointDiscoveryMetadataApril2005.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/EndpointDiscoveryMetadataApril2005.cs new file mode 100755 index 00000000000..526de2e9806 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/EndpointDiscoveryMetadataApril2005.cs @@ -0,0 +1,70 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionApril2005 +{ + public class EndpointDiscoveryMetadataApril2005 : IXmlSerializable + { + public static EndpointDiscoveryMetadataApril2005 FromEndpointDiscoveryMetadata (EndpointDiscoveryMetadata endpointDiscoveryMetadata) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public EndpointDiscoveryMetadata ToEndpointDiscoveryMetadata () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/FindCriteriaApril2005.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/FindCriteriaApril2005.cs new file mode 100755 index 00000000000..a7603ae6efd --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/FindCriteriaApril2005.cs @@ -0,0 +1,70 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionApril2005 +{ + public class FindCriteriaApril2005 : IXmlSerializable + { + public static FindCriteriaApril2005 FromFindCriteria (FindCriteria findCriteria) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public FindCriteria ToFindCriteria () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/ResolveCriteriaApril2005.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/ResolveCriteriaApril2005.cs new file mode 100755 index 00000000000..0a6567344db --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionApril2005/ResolveCriteriaApril2005.cs @@ -0,0 +1,70 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionApril2005 +{ + public class ResolveCriteriaApril2005 : IXmlSerializable + { + public static ResolveCriteriaApril2005 FromResolveCriteria (ResolveCriteria resolveCriteria) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public ResolveCriteria ToResolveCriteria () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/ChangeLog b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/ChangeLog new file mode 100755 index 00000000000..ce289a8a77d --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/ChangeLog @@ -0,0 +1,4 @@ +2010-03-19 Atsushi Enomoto + + * : initial checkin (mostly stubs). + diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/DiscoveryMessageSequence11.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/DiscoveryMessageSequence11.cs new file mode 100755 index 00000000000..1b88d4d3d71 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/DiscoveryMessageSequence11.cs @@ -0,0 +1,75 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionCD1 +{ + public class DiscoveryMessageSequence11 : IXmlSerializable + { + public static DiscoveryMessageSequence11 FromDiscoveryMessageSequence (DiscoveryMessageSequence discoveryMessageSequence) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + internal DiscoveryMessageSequence11 () + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public DiscoveryMessageSequence ToDiscoveryMessageSequence () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/EndpointDiscoveryMetadata11.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/EndpointDiscoveryMetadata11.cs new file mode 100755 index 00000000000..4d2260bc57c --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/EndpointDiscoveryMetadata11.cs @@ -0,0 +1,70 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionCD1 +{ + public class EndpointDiscoveryMetadata11 : IXmlSerializable + { + public static EndpointDiscoveryMetadata11 FromEndpointDiscoveryMetadata (EndpointDiscoveryMetadata endpointDiscoveryMetadata) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public EndpointDiscoveryMetadata ToEndpointDiscoveryMetadata () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/FindCriteria11.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/FindCriteria11.cs new file mode 100755 index 00000000000..a82174bbd05 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/FindCriteria11.cs @@ -0,0 +1,70 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionCD1 +{ + public class FindCriteria11 : IXmlSerializable + { + public static FindCriteria11 FromFindCriteria (FindCriteria findCriteria) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public FindCriteria ToFindCriteria () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/ResolveCriteria11.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/ResolveCriteria11.cs new file mode 100755 index 00000000000..33670619146 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.VersionCD1/ResolveCriteria11.cs @@ -0,0 +1,70 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Schema; +using System.Xml.Serialization; + +namespace System.ServiceModel.Discovery.VersionCD1 +{ + public class ResolveCriteria11 : IXmlSerializable + { + public static ResolveCriteria11 FromResolveCriteria (ResolveCriteria resolveCriteria) + { + throw new NotImplementedException (); + } + + public static XmlQualifiedName GetSchema (XmlSchemaSet schemaSet) + { + throw new NotImplementedException (); + } + + public XmlSchema GetSchema () + { + throw new NotImplementedException (); + } + + public void ReadXml (XmlReader reader) + { + throw new NotImplementedException (); + } + + public ResolveCriteria ToResolveCriteria () + { + throw new NotImplementedException (); + } + + public void WriteXml (XmlWriter writer) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.dll.sources b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.dll.sources new file mode 100644 index 00000000000..480500485d2 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery.dll.sources @@ -0,0 +1,43 @@ +../../build/common/Consts.cs +../../build/common/Locale.cs +../../build/common/MonoTODOAttribute.cs +Assembly/AssemblyInfo.cs +System.ServiceModel.Discovery.VersionApril2005/DiscoveryMessageSequenceApril2005.cs +System.ServiceModel.Discovery.VersionApril2005/EndpointDiscoveryMetadataApril2005.cs +System.ServiceModel.Discovery.VersionApril2005/FindCriteriaApril2005.cs +System.ServiceModel.Discovery.VersionApril2005/ResolveCriteriaApril2005.cs +System.ServiceModel.Discovery.VersionCD1/DiscoveryMessageSequence11.cs +System.ServiceModel.Discovery.VersionCD1/EndpointDiscoveryMetadata11.cs +System.ServiceModel.Discovery.VersionCD1/FindCriteria11.cs +System.ServiceModel.Discovery.VersionCD1/ResolveCriteria11.cs +System.ServiceModel.Discovery/AnnouncementClient.cs +System.ServiceModel.Discovery/AnnouncementEndpoint.cs +System.ServiceModel.Discovery/AnnouncementEventArgs.cs +System.ServiceModel.Discovery/AnnouncementService.cs +System.ServiceModel.Discovery/DiscoveryClient.cs +System.ServiceModel.Discovery/DiscoveryClientBindingElement.cs +System.ServiceModel.Discovery/DiscoveryEndpoint.cs +System.ServiceModel.Discovery/DiscoveryEndpointProvider.cs +System.ServiceModel.Discovery/DiscoveryMessageSequence.cs +System.ServiceModel.Discovery/DiscoveryMessageSequenceGenerator.cs +System.ServiceModel.Discovery/DiscoveryOperationContextExtension.cs +System.ServiceModel.Discovery/DiscoveryProxy.cs +System.ServiceModel.Discovery/DiscoveryService.cs +System.ServiceModel.Discovery/DiscoveryServiceExtension.cs +System.ServiceModel.Discovery/DiscoveryVersion.cs +System.ServiceModel.Discovery/DynamicEndpoint.cs +System.ServiceModel.Discovery/EndpointDiscoveryBehavior.cs +System.ServiceModel.Discovery/EndpointDiscoveryMetadata.cs +System.ServiceModel.Discovery/FindCompletedEventArgs.cs +System.ServiceModel.Discovery/FindCriteria.cs +System.ServiceModel.Discovery/FindProgressChangedEventArgs.cs +System.ServiceModel.Discovery/FindRequestContext.cs +System.ServiceModel.Discovery/FindResponse.cs +System.ServiceModel.Discovery/ResolveCompletedEventArgs.cs +System.ServiceModel.Discovery/ResolveCriteria.cs +System.ServiceModel.Discovery/ResolveResponse.cs +System.ServiceModel.Discovery/ServiceDiscoveryBehavior.cs +System.ServiceModel.Discovery/ServiceDiscoveryMode.cs +System.ServiceModel.Discovery/UdpAnnouncementEndpoint.cs +System.ServiceModel.Discovery/UdpDiscoveryEndpoint.cs +System.ServiceModel.Discovery/UdpTransportSettings.cs diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementClient.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementClient.cs new file mode 100755 index 00000000000..380e5ede216 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementClient.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public sealed class AnnouncementClient : ICommunicationObject, IDisposable + { + public AnnouncementClient () + { + } + + public AnnouncementClient (AnnouncementEndpoint announcementEndpoint) + { + } + + public AnnouncementClient (string endpointConfigurationName) + { + } + + public ChannelFactory ChannelFactory { get; private set; } + public ClientCredentials ClientCredentials { get; private set; } + public ServiceEndpoint Endpoint { get; private set; } + public IClientChannel InnerChannel { get; private set; } + public DiscoveryMessageSequenceGenerator MessageSequenceGenerator { get; set; } + + CommunicationState ICommunicationObject.State { + get { return InnerChannel.State; } + } + + public event EventHandler AnnounceOfflineCompleted; + public event EventHandler AnnounceOnlineCompleted; + + event EventHandler ICommunicationObject.Closed { + add { InnerChannel.Closed += value; } + remove { InnerChannel.Closed -= value; } + } + event EventHandler ICommunicationObject.Closing { + add { InnerChannel.Closing += value; } + remove { InnerChannel.Closing -= value; } + } + event EventHandler ICommunicationObject.Faulted { + add { InnerChannel.Faulted += value; } + remove { InnerChannel.Faulted -= value; } + } + event EventHandler ICommunicationObject.Opened { + add { InnerChannel.Opened += value; } + remove { InnerChannel.Opened -= value; } + } + event EventHandler ICommunicationObject.Opening { + add { InnerChannel.Opening += value; } + remove { InnerChannel.Opening -= value; } + } + + public void AnnounceOffline (EndpointDiscoveryMetadata discoveryMetadata) + { + throw new NotImplementedException (); + } + + public void AnnounceOfflineAsync (EndpointDiscoveryMetadata discoveryMetadata) + { + throw new NotImplementedException (); + } + + public void AnnounceOfflineAsync (EndpointDiscoveryMetadata discoveryMetadata, object userState) + { + throw new NotImplementedException (); + } + + public void AnnounceOnline (EndpointDiscoveryMetadata discoveryMetadata) + { + throw new NotImplementedException (); + } + + public void AnnounceOnlineAsync (EndpointDiscoveryMetadata discoveryMetadata) + { + throw new NotImplementedException (); + } + + public void AnnounceOnlineAsync (EndpointDiscoveryMetadata discoveryMetadata, object userState) + { + throw new NotImplementedException (); + } + + public IAsyncResult BeginAnnounceOffline (EndpointDiscoveryMetadata discoveryMetadata, AsyncCallback callback, object state) + { + throw new NotImplementedException (); + } + + public IAsyncResult BeginAnnounceOnline (EndpointDiscoveryMetadata discoveryMetadata, AsyncCallback callback, object state) + { + throw new NotImplementedException (); + } + + public void EndAnnounceOffline (IAsyncResult result) + { + throw new NotImplementedException (); + } + + public void EndAnnounceOnline (IAsyncResult result) + { + throw new NotImplementedException (); + } + + public void Close () + { + throw new NotImplementedException (); + } + + public void Open () + { + throw new NotImplementedException (); + } + + // explicit interface impl. + + void ICommunicationObject.Open () + { + InnerChannel.Open (); + } + + void ICommunicationObject.Open (TimeSpan timeout) + { + InnerChannel.Open (timeout); + } + + void ICommunicationObject.Close () + { + InnerChannel.Close (); + } + + void ICommunicationObject.Close (TimeSpan timeout) + { + InnerChannel.Close (timeout); + } + + IAsyncResult ICommunicationObject.BeginOpen (AsyncCallback callback, object state) + { + return InnerChannel.BeginOpen (callback, state); + } + + IAsyncResult ICommunicationObject.BeginOpen (TimeSpan timeout, AsyncCallback callback, object state) + { + return InnerChannel.BeginOpen (timeout, callback, state); + } + + IAsyncResult ICommunicationObject.BeginClose (AsyncCallback callback, object state) + { + return InnerChannel.BeginClose (callback, state); + } + + IAsyncResult ICommunicationObject.BeginClose (TimeSpan timeout, AsyncCallback callback, object state) + { + return InnerChannel.BeginClose (timeout, callback, state); + } + + void ICommunicationObject.EndOpen (IAsyncResult result) + { + InnerChannel.EndOpen (result); + } + + void ICommunicationObject.EndClose (IAsyncResult result) + { + InnerChannel.EndClose (result); + } + + void ICommunicationObject.Abort () + { + InnerChannel.Abort (); + } + + void IDisposable.Dispose () + { + InnerChannel.Dispose (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementEndpoint.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementEndpoint.cs new file mode 100755 index 00000000000..0de05476270 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementEndpoint.cs @@ -0,0 +1,69 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class AnnouncementEndpoint : ServiceEndpoint + { + public AnnouncementEndpoint () + : this (DiscoveryVersion.WSDiscovery11) + { + } + + public AnnouncementEndpoint (DiscoveryVersion discoveryVersion) + : this (discoveryVersion, null, null) + { + if (discoveryVersion == null) + throw new ArgumentNullException ("discoveryVersion"); + DiscoveryVersion = discoveryVersion; + } + + public AnnouncementEndpoint (Binding binding, EndpointAddress address) + : this (DiscoveryVersion.WSDiscoveryApril2005, binding, address) + { + } + + [MonoTODO] + public AnnouncementEndpoint (DiscoveryVersion discoveryVersion, Binding binding, EndpointAddress address) + : base (null, binding, address) + { + if (discoveryVersion == null) + throw new ArgumentNullException ("discoveryVersion"); + DiscoveryVersion = discoveryVersion; + } + + public DiscoveryVersion DiscoveryVersion { get; private set; } + + [MonoTODO] + public TimeSpan MaxAnnouncementDelay { get; set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementEventArgs.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementEventArgs.cs new file mode 100755 index 00000000000..e929544da13 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementEventArgs.cs @@ -0,0 +1,46 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class AnnouncementEventArgs : EventArgs + { + internal AnnouncementEventArgs (EndpointDiscoveryMetadata metadata, DiscoveryMessageSequence queue) + { + EndpointDiscoveryMetadata = metadata; + MessageSequence = queue; + } + + public EndpointDiscoveryMetadata EndpointDiscoveryMetadata { get; private set; } + public DiscoveryMessageSequence MessageSequence { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementService.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementService.cs new file mode 100755 index 00000000000..69f42d977a6 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/AnnouncementService.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] + public class AnnouncementService + { + public AnnouncementService () + { + } + + public AnnouncementService (int duplicateMessageHistoryLength) + { + } + + public event EventHandler OfflineAnnouncementReceived; + public event EventHandler OnlineAnnouncementReceived; + + protected virtual IAsyncResult OnBeginOfflineAnnouncement (DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, object state) + { + throw new NotImplementedException (); + } + + protected virtual IAsyncResult OnBeginOnlineAnnouncement (DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, object state) + { + throw new NotImplementedException (); + } + + protected virtual void OnEndOfflineAnnouncement (IAsyncResult result) + { + throw new NotImplementedException (); + } + + protected virtual void OnEndOnlineAnnouncement (IAsyncResult result) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ChangeLog b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ChangeLog new file mode 100755 index 00000000000..ce289a8a77d --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ChangeLog @@ -0,0 +1,4 @@ +2010-03-19 Atsushi Enomoto + + * : initial checkin (mostly stubs). + diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryClient.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryClient.cs new file mode 100755 index 00000000000..b454c530f79 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryClient.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public sealed class DiscoveryClient : ICommunicationObject, IDisposable + { + public DiscoveryClient () + { + } + + public DiscoveryClient (DiscoveryEndpoint discoveryEndpoint) + { + } + + public DiscoveryClient (string endpointConfigurationName) + { + } + + public ChannelFactory ChannelFactory { get; private set; } + public ClientCredentials ClientCredentials { get; private set; } + public ServiceEndpoint Endpoint { get; private set; } + public IClientChannel InnerChannel { get; private set; } + + CommunicationState ICommunicationObject.State { + get { return InnerChannel.State; } + } + + public event EventHandler FindCompleted; + public event EventHandler FindProgressChanged; + public event EventHandler ProxyAvailable; + public event EventHandler ResolveCompleted; + + event EventHandler ICommunicationObject.Closed { + add { InnerChannel.Closed += value; } + remove { InnerChannel.Closed -= value; } + } + event EventHandler ICommunicationObject.Closing { + add { InnerChannel.Closing += value; } + remove { InnerChannel.Closing -= value; } + } + event EventHandler ICommunicationObject.Faulted { + add { InnerChannel.Faulted += value; } + remove { InnerChannel.Faulted -= value; } + } + event EventHandler ICommunicationObject.Opened { + add { InnerChannel.Opened += value; } + remove { InnerChannel.Opened -= value; } + } + event EventHandler ICommunicationObject.Opening { + add { InnerChannel.Opening += value; } + remove { InnerChannel.Opening -= value; } + } + + public void CancelAsync (object userState) + { + throw new NotImplementedException (); + } + + public void Close () + { + throw new NotImplementedException (); + } + + public FindResponse Find (FindCriteria criteria) + { + throw new NotImplementedException (); + } + + public void FindAsync (FindCriteria criteria) + { + throw new NotImplementedException (); + } + + public void FindAsync (FindCriteria criteria, object userState) + { + throw new NotImplementedException (); + } + + public void Open () + { + throw new NotImplementedException (); + } + + public ResolveResponse Resolve (ResolveCriteria criteria) + { + throw new NotImplementedException (); + } + + public void ResolveAsync (ResolveCriteria criteria) + { + throw new NotImplementedException (); + } + + public void ResolveAsync (ResolveCriteria criteria, object userState) + { + throw new NotImplementedException (); + } + + // explicit interface impl. + + void ICommunicationObject.Open () + { + InnerChannel.Open (); + } + + void ICommunicationObject.Open (TimeSpan timeout) + { + InnerChannel.Open (timeout); + } + + void ICommunicationObject.Close () + { + InnerChannel.Close (); + } + + void ICommunicationObject.Close (TimeSpan timeout) + { + InnerChannel.Close (timeout); + } + + IAsyncResult ICommunicationObject.BeginOpen (AsyncCallback callback, object state) + { + return InnerChannel.BeginOpen (callback, state); + } + + IAsyncResult ICommunicationObject.BeginOpen (TimeSpan timeout, AsyncCallback callback, object state) + { + return InnerChannel.BeginOpen (timeout, callback, state); + } + + IAsyncResult ICommunicationObject.BeginClose (AsyncCallback callback, object state) + { + return InnerChannel.BeginClose (callback, state); + } + + IAsyncResult ICommunicationObject.BeginClose (TimeSpan timeout, AsyncCallback callback, object state) + { + return InnerChannel.BeginClose (timeout, callback, state); + } + + void ICommunicationObject.EndOpen (IAsyncResult result) + { + InnerChannel.EndOpen (result); + } + + void ICommunicationObject.EndClose (IAsyncResult result) + { + InnerChannel.EndClose (result); + } + + void ICommunicationObject.Abort () + { + InnerChannel.Abort (); + } + + void IDisposable.Dispose () + { + InnerChannel.Dispose (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryClientBindingElement.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryClientBindingElement.cs new file mode 100755 index 00000000000..c3b2d2a66c9 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryClientBindingElement.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public sealed class DiscoveryClientBindingElement : BindingElement + { + [MonoTODO] + public static readonly EndpointAddress DiscoveryEndpointAddress = null; + + public DiscoveryClientBindingElement () + { + } + + public DiscoveryClientBindingElement (DiscoveryEndpointProvider discoveryEndpointProvider, FindCriteria findCriteria) + { + DiscoveryEndpointProvider = discoveryEndpointProvider; + FindCriteria = findCriteria; + } + + public DiscoveryEndpointProvider DiscoveryEndpointProvider { get; set; } + public FindCriteria FindCriteria { get; set; } + + public override IChannelFactory BuildChannelFactory (BindingContext context) + { + throw new NotImplementedException (); + } + + public override IChannelListener BuildChannelListener (BindingContext context) + { + throw new NotImplementedException (); + } + + public override bool CanBuildChannelFactory (BindingContext context) + { + throw new NotImplementedException (); + } + + public override bool CanBuildChannelListener (BindingContext context) + { + throw new NotImplementedException (); + } + + public override BindingElement Clone () + { + throw new NotImplementedException (); + } + + public override T GetProperty (BindingContext context) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryEndpoint.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryEndpoint.cs new file mode 100755 index 00000000000..5b3d8b852cd --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryEndpoint.cs @@ -0,0 +1,66 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class DiscoveryEndpoint : ServiceEndpoint + { + public DiscoveryEndpoint () + : this (null, null) + { + } + + public DiscoveryEndpoint (Binding binding, EndpointAddress endpointAddress) + : this (DiscoveryVersion.WSDiscoveryApril2005, ServiceDiscoveryMode.Managed, binding, endpointAddress) + { + } + + public DiscoveryEndpoint (DiscoveryVersion discoveryVersion, ServiceDiscoveryMode discoveryMode) + : this (discoveryVersion, discoveryMode, null, null) + { + } + + public DiscoveryEndpoint (DiscoveryVersion discoveryVersion, ServiceDiscoveryMode discoveryMode, Binding binding, EndpointAddress endpointAddress) + : base (null, binding, endpointAddress) + { + if (discoveryVersion == null) + throw new ArgumentNullException ("discoveryVersion"); + DiscoveryVersion = discoveryVersion; + DiscoveryMode = discoveryMode; + } + + public ServiceDiscoveryMode DiscoveryMode { get; private set; } + public DiscoveryVersion DiscoveryVersion { get; private set; } + [MonoTODO] + public TimeSpan MaxResponseDelay { get; set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryEndpointProvider.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryEndpointProvider.cs new file mode 100755 index 00000000000..46cff0d2f5e --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryEndpointProvider.cs @@ -0,0 +1,39 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public abstract class DiscoveryEndpointProvider + { + public abstract DiscoveryEndpoint GetDiscoveryEndpoint (); + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryMessageSequence.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryMessageSequence.cs new file mode 100755 index 00000000000..7590eb1f177 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryMessageSequence.cs @@ -0,0 +1,99 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class DiscoveryMessageSequence : IComparable, IEquatable + { + internal DiscoveryMessageSequence (long instanceId, Uri sequenceId, long messageNumber) + { + InstanceId = instanceId; + SequenceId = sequenceId; + MessageNumber = messageNumber; + } + + public long InstanceId { get; private set; } + public long MessageNumber { get; private set; } + public Uri SequenceId { get; private set; } + + [MonoTODO] + public bool CanCompareTo (DiscoveryMessageSequence other) + { + if (other == null) + return false; + return InstanceId == other.InstanceId && SequenceId.Equals (other.SequenceId); + } + + [MonoTODO] + public int CompareTo (DiscoveryMessageSequence other) + { + throw new NotImplementedException (); + } + + public bool Equals (DiscoveryMessageSequence other) + { + if (other == null) + return false; + return InstanceId == other.InstanceId && + SequenceId.Equals (other.SequenceId) && + MessageNumber == other.MessageNumber; + } + + public override bool Equals (object obj) + { + var s = obj as DiscoveryMessageSequence; + return s != null && Equals (s); + } + + [MonoTODO] + public override int GetHashCode () + { + throw new NotImplementedException (); + } + + [MonoTODO] + public override string ToString () + { + throw new NotImplementedException (); + } + + public static bool operator == (DiscoveryMessageSequence messageSequence1, DiscoveryMessageSequence messageSequence2) + { + return messageSequence1 != null ? messageSequence1.Equals (messageSequence2) : messageSequence2 == null; + } + + public static bool operator != (DiscoveryMessageSequence messageSequence1, DiscoveryMessageSequence messageSequence2) + { + return messageSequence1 == null ? messageSequence2 != null : !messageSequence1.Equals (messageSequence2); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryMessageSequenceGenerator.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryMessageSequenceGenerator.cs new file mode 100755 index 00000000000..f960a4a7b0a --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryMessageSequenceGenerator.cs @@ -0,0 +1,57 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class DiscoveryMessageSequenceGenerator + { + [MonoTODO ("default values?")] + public DiscoveryMessageSequenceGenerator () + { + } + + public DiscoveryMessageSequenceGenerator (long instanceId, Uri sequenceId) + { + instance_id = instanceId; + sequence_id = sequenceId; + } + + long instance_id, message_count; + Uri sequence_id; + + [MonoTODO ("default number?")] + public DiscoveryMessageSequence Next () + { + return new DiscoveryMessageSequence (instance_id, sequence_id, message_count++); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryOperationContextExtension.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryOperationContextExtension.cs new file mode 100755 index 00000000000..ccc64892c12 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryOperationContextExtension.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public class DiscoveryOperationContextExtension : IExtension + { + internal DiscoveryOperationContextExtension () + { + } + + void IExtension.Attach (OperationContext owner) + { + } + + void IExtension.Detach (OperationContext owner) + { + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryProxy.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryProxy.cs new file mode 100755 index 00000000000..33a3ffb5e01 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryProxy.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public abstract class DiscoveryProxy + { + protected DiscoveryProxy () + { + } + + protected DiscoveryProxy (DiscoveryMessageSequenceGenerator messageSequenceGenerator) + { + } + + protected DiscoveryProxy (DiscoveryMessageSequenceGenerator messageSequenceGenerator, int duplicateMessageHistoryLength) + { + } + + protected virtual IAsyncResult BeginShouldRedirectFind (FindCriteria resolveCriteria, AsyncCallback callback, Object state) + { + throw new NotImplementedException (); + } + + protected virtual IAsyncResult BeginShouldRedirectResolve (ResolveCriteria findCriteria, AsyncCallback callback, Object state) + { + throw new NotImplementedException (); + } + + protected virtual bool EndShouldRedirectFind (IAsyncResult result, out Collection redirectionEndpoints) + { + throw new NotImplementedException (); + } + + protected virtual bool EndShouldRedirectResolve (IAsyncResult result, out Collection redirectionEndpoints) + { + throw new NotImplementedException (); + } + + protected abstract IAsyncResult OnBeginFind (FindRequestContext findRequestContext, AsyncCallback callback, Object state); + protected abstract IAsyncResult OnBeginOfflineAnnouncement (DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, Object state); + protected abstract IAsyncResult OnBeginOnlineAnnouncement (DiscoveryMessageSequence messageSequence, EndpointDiscoveryMetadata endpointDiscoveryMetadata, AsyncCallback callback, Object state); + protected abstract IAsyncResult OnBeginResolve (ResolveCriteria resolveCriteria, AsyncCallback callback, Object state); + protected abstract void OnEndFind (IAsyncResult result); + protected abstract void OnEndOfflineAnnouncement (IAsyncResult result); + protected abstract void OnEndOnlineAnnouncement (IAsyncResult result); + protected abstract EndpointDiscoveryMetadata OnEndResolve (IAsyncResult result); + + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryService.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryService.cs new file mode 100755 index 00000000000..1bd1c9a6378 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryService.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public abstract class DiscoveryService + { + protected DiscoveryService () + { + } + + protected DiscoveryService (DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator) + { + } + + protected DiscoveryService (DiscoveryMessageSequenceGenerator discoveryMessageSequenceGenerator, int duplicateMessageHistoryLength) + { + } + + protected abstract IAsyncResult OnBeginFind (FindRequestContext findRequestContext, AsyncCallback callback, Object state); + + protected abstract IAsyncResult OnBeginResolve (ResolveCriteria resolveCriteria, AsyncCallback callback, Object state); + + protected abstract void OnEndFind (IAsyncResult result); + + protected abstract EndpointDiscoveryMetadata OnEndResolve (IAsyncResult result); + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryServiceExtension.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryServiceExtension.cs new file mode 100755 index 00000000000..a55f1450c13 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryServiceExtension.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public abstract class DiscoveryServiceExtension : IExtension + { + protected abstract DiscoveryService GetDiscoveryService (); + + void IExtension.Attach (ServiceHostBase owner) + { + } + + void IExtension.Detach (ServiceHostBase owner) + { + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryVersion.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryVersion.cs new file mode 100755 index 00000000000..ac106cc2ab3 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DiscoveryVersion.cs @@ -0,0 +1,89 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public sealed class DiscoveryVersion + { + static DiscoveryVersion () + { + v11 = new DiscoveryVersion ("WSDiscovery11"); + april2005 = new DiscoveryVersion ("WSDiscoveryApril2005"); + cd1 = new DiscoveryVersion ("WSDiscoveryCD1"); + } + + static readonly DiscoveryVersion v11, april2005, cd1; + + public static DiscoveryVersion WSDiscovery11 { + get { return v11; } + } + + public static DiscoveryVersion WSDiscoveryApril2005 { + get { return april2005; } + } + + public static DiscoveryVersion WSDiscoveryCD1 { + get { return cd1; } + } + + public static DiscoveryVersion FromName (string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + switch (name) { + case "WSDiscovery11": + return v11; + case "WSDiscoveryApril2005": + return april2005; + case "WSDiscoveryCD1": + return cd1; + default: + throw new ArgumentNullException (String.Format ("Invalid version name: {0}", name)); + } + } + + internal DiscoveryVersion (string name) + { + this.Name = name; + } + + public Uri AdhocAddress { get; private set; } + public MessageVersion MessageVersion { get; private set; } + public string Name { get; private set; } + public string Namespace { get; private set; } + + public override string ToString () + { + return Name; + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DynamicEndpoint.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DynamicEndpoint.cs new file mode 100755 index 00000000000..80f1d81edd7 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/DynamicEndpoint.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public class DynamicEndpoint : ServiceEndpoint + { + public DynamicEndpoint (ContractDescription contract, Binding binding) + : base (contract, binding, null) + { + } + + public DiscoveryEndpointProvider DiscoveryEndpointProvider { get; set; } + public FindCriteria FindCriteria { get; set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/EndpointDiscoveryBehavior.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/EndpointDiscoveryBehavior.cs new file mode 100755 index 00000000000..334c944de4a --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/EndpointDiscoveryBehavior.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public class EndpointDiscoveryBehavior : IEndpointBehavior + { + void IEndpointBehavior.AddBindingParameters (ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) + { + } + + void IEndpointBehavior.ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime) + { + } + + void IEndpointBehavior.ApplyDispatchBehavior (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) + { + } + + void IEndpointBehavior.Validate (ServiceEndpoint endpoint) + { + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/EndpointDiscoveryMetadata.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/EndpointDiscoveryMetadata.cs new file mode 100755 index 00000000000..a905159c140 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/EndpointDiscoveryMetadata.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Linq; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public class EndpointDiscoveryMetadata + { + public static EndpointDiscoveryMetadata FromServiceEndpoint (ServiceEndpoint endpoint) + { + throw new NotImplementedException (); + } + + public static EndpointDiscoveryMetadata FromServiceEndpoint (ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) + { + throw new NotImplementedException (); + } + + public EndpointAddress Address { get; set; } + public Collection ContractTypeNames { get; private set; } + public Collection Extensions { get; private set; } + public Collection ListenUris { get; private set; } + public Collection Scopes { get; private set; } + public int Version { get; set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindCompletedEventArgs.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindCompletedEventArgs.cs new file mode 100755 index 00000000000..7abcfb4694c --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindCompletedEventArgs.cs @@ -0,0 +1,46 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class FindCompletedEventArgs : AsyncCompletedEventArgs + { + internal FindCompletedEventArgs (FindResponse result, Exception error, bool cancelled, object userState) + : base (error, cancelled, userState) + { + this.Result = result; + } + + public FindResponse Result { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindCriteria.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindCriteria.cs new file mode 100755 index 00000000000..12c79fd2158 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindCriteria.cs @@ -0,0 +1,91 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml; +using System.Xml.Linq; + +namespace System.ServiceModel.Discovery +{ + public class FindCriteria + { + public static readonly Uri ScopeMatchByExact = new Uri ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/strcmp0"); + public static readonly Uri ScopeMatchByLdap = new Uri ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/ldap"); + public static readonly Uri ScopeMatchByNone = new Uri ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/none"); + public static readonly Uri ScopeMatchByPrefix = new Uri ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/rfc3986"); + public static readonly Uri ScopeMatchByUuid = new Uri ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/uuid"); + + public static FindCriteria CreateMetadataExchangeEndpointCriteria () + { + return CreateMetadataExchangeEndpointCriteria (typeof (IMetadataExchange)); + } + + public static FindCriteria CreateMetadataExchangeEndpointCriteria (IEnumerable contractTypeNames) + { + var fc = new FindCriteria (); + foreach (var type in contractTypeNames) + fc.ContractTypeNames.Add (type); + return fc; + } + + public static FindCriteria CreateMetadataExchangeEndpointCriteria (Type contractType) + { + return new FindCriteria (contractType); + } + + public FindCriteria () + { + ContractTypeNames = new Collection (); + Extensions = new Collection (); + Scopes = new Collection (); + } + + [MonoTODO] + public FindCriteria (Type contractType) + : this () + { + throw new NotImplementedException (); + } + + public Collection ContractTypeNames { get; private set; } + public TimeSpan Duration { get; set; } + public Collection Extensions { get; private set; } + [MonoTODO] + public int MaxResults { get; set; } + public Uri ScopeMatchBy { get; set; } + public Collection Scopes { get; private set; } + + [MonoTODO] + public bool IsMatch (EndpointDiscoveryMetadata endpointDiscoveryMetadata) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindProgressChangedEventArgs.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindProgressChangedEventArgs.cs new file mode 100755 index 00000000000..d01affdc084 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindProgressChangedEventArgs.cs @@ -0,0 +1,48 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class FindProgressChangedEventArgs : ProgressChangedEventArgs + { + internal FindProgressChangedEventArgs (EndpointDiscoveryMetadata metadata, DiscoveryMessageSequence sequence, int progressPercentage, object userState) + : base (progressPercentage, userState) + { + EndpointDiscoveryMetadata = metadata; + MessageSequence = sequence; + } + + public EndpointDiscoveryMetadata EndpointDiscoveryMetadata { get;private set; } + public DiscoveryMessageSequence MessageSequence { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindRequestContext.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindRequestContext.cs new file mode 100755 index 00000000000..06ab140d2d0 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindRequestContext.cs @@ -0,0 +1,58 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class FindRequestContext + { + protected FindRequestContext (FindCriteria criteria) + { + if (criteria == null) + throw new ArgumentNullException ("criteria"); + Criteria = criteria; + } + + public FindCriteria Criteria { get; private set; } + + [MonoTODO] + public void AddMatchingEndpoint (EndpointDiscoveryMetadata matchingEndpoint) + { + OnAddMatchingEndpoint (matchingEndpoint); + } + + [MonoTODO] + protected virtual void OnAddMatchingEndpoint (EndpointDiscoveryMetadata matchingEndpoint) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindResponse.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindResponse.cs new file mode 100755 index 00000000000..451d3d2f6c1 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/FindResponse.cs @@ -0,0 +1,50 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class FindResponse + { + internal FindResponse () + { + Endpoints = new Collection (); + } + + public Collection Endpoints { get; private set; } + + [MonoTODO] + public DiscoveryMessageSequence GetMessageSequence (EndpointDiscoveryMetadata endpointDiscoveryMetadata) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveCompletedEventArgs.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveCompletedEventArgs.cs new file mode 100755 index 00000000000..220fb963a3a --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveCompletedEventArgs.cs @@ -0,0 +1,46 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class ResolveCompletedEventArgs : AsyncCompletedEventArgs + { + internal ResolveCompletedEventArgs (ResolveResponse result, Exception error, bool cancelled, object userState) + : base (error, cancelled, userState) + { + this.Result = result; + } + + public ResolveResponse Result { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveCriteria.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveCriteria.cs new file mode 100755 index 00000000000..11731efb31c --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveCriteria.cs @@ -0,0 +1,54 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; +using System.Xml.Linq; + +namespace System.ServiceModel.Discovery +{ + public class ResolveCriteria + { + public ResolveCriteria () + { + Extensions = new Collection (); + } + + public ResolveCriteria (EndpointAddress address) + : this () + { + Address = address; + } + + public EndpointAddress Address { get; set; } + [MonoTODO] + public TimeSpan Duration { get; set; } + public Collection Extensions { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveResponse.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveResponse.cs new file mode 100755 index 00000000000..6a1b4f1fb38 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ResolveResponse.cs @@ -0,0 +1,46 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class ResolveResponse + { + internal ResolveResponse (EndpointDiscoveryMetadata metadata, DiscoveryMessageSequence sequence) + { + EndpointDiscoveryMetadata = metadata; + MessageSequence = sequence; + } + + public EndpointDiscoveryMetadata EndpointDiscoveryMetadata { get; private set; } + public DiscoveryMessageSequence MessageSequence { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ServiceDiscoveryBehavior.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ServiceDiscoveryBehavior.cs new file mode 100755 index 00000000000..22599e37721 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ServiceDiscoveryBehavior.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + [MonoTODO] + public class ServiceDiscoveryBehavior : IServiceBehavior + { + void IServiceBehavior.AddBindingParameters (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) + { + } + + void IServiceBehavior.ApplyDispatchBehavior (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + } + + void IServiceBehavior.Validate (ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) + { + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ServiceDiscoveryMode.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ServiceDiscoveryMode.cs new file mode 100755 index 00000000000..3b65b64e78c --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/ServiceDiscoveryMode.cs @@ -0,0 +1,32 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +namespace System.ServiceModel.Discovery +{ + public enum ServiceDiscoveryMode + { + Adhoc, + Managed + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpAnnouncementEndpoint.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpAnnouncementEndpoint.cs new file mode 100755 index 00000000000..95823a6b5e8 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpAnnouncementEndpoint.cs @@ -0,0 +1,83 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class UdpAnnouncementEndpoint : AnnouncementEndpoint + { + [MonoTODO] + public static readonly Uri DefaultIPv4MulticastAddress; + [MonoTODO] + public static readonly Uri DefaultIPv6MulticastAddress; + + // (1)->(2) + public UdpAnnouncementEndpoint () + : this (DiscoveryVersion.WSDiscovery11) + { + } + + // (2), everything falls to here. + public UdpAnnouncementEndpoint (DiscoveryVersion discoveryVersion) + : base (discoveryVersion) + { + TransportSettings = new UdpTransportSettings (); + } + + // (3)->(4) + public UdpAnnouncementEndpoint (string multicastAddress) + : this (new Uri (multicastAddress)) + { + } + + // (4)->(5) + public UdpAnnouncementEndpoint (Uri multicastAddress) + : this (DiscoveryVersion.WSDiscovery11, multicastAddress) + { + } + + // (5)->(6) + public UdpAnnouncementEndpoint (DiscoveryVersion discoveryVersion, string multicastAddress) + : this (discoveryVersion, new Uri (multicastAddress)) + { + } + + // (6)->(2) + public UdpAnnouncementEndpoint (DiscoveryVersion discoveryVersion, Uri multicastAddress) + : this (discoveryVersion) + { + MulticastAddress = multicastAddress; + } + + public Uri MulticastAddress { get; set; } + public UdpTransportSettings TransportSettings { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpDiscoveryEndpoint.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpDiscoveryEndpoint.cs new file mode 100755 index 00000000000..72c57b7edd4 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpDiscoveryEndpoint.cs @@ -0,0 +1,83 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class UdpDiscoveryEndpoint : DiscoveryEndpoint + { + [MonoTODO] + public static readonly Uri DefaultIPv4MulticastAddress; + [MonoTODO] + public static readonly Uri DefaultIPv6MulticastAddress; + + // (1)->(2) + public UdpDiscoveryEndpoint () + : this (DiscoveryVersion.WSDiscovery11) + { + } + + // (2), everything falls to here. + public UdpDiscoveryEndpoint (DiscoveryVersion discoveryVersion) + : base (discoveryVersion, ServiceDiscoveryMode.Adhoc) + { + TransportSettings = new UdpTransportSettings (); + } + + // (3)->(4) + public UdpDiscoveryEndpoint (string multicastAddress) + : this (new Uri (multicastAddress)) + { + } + + // (4)->(5) + public UdpDiscoveryEndpoint (Uri multicastAddress) + : this (DiscoveryVersion.WSDiscovery11, multicastAddress) + { + } + + // (5)->(6) + public UdpDiscoveryEndpoint (DiscoveryVersion discoveryVersion, string multicastAddress) + : this (discoveryVersion, new Uri (multicastAddress)) + { + } + + // (6)->(2) + public UdpDiscoveryEndpoint (DiscoveryVersion discoveryVersion, Uri multicastAddress) + : this (discoveryVersion) + { + MulticastAddress = multicastAddress; + } + + public Uri MulticastAddress { get; set; } + public UdpTransportSettings TransportSettings { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpTransportSettings.cs b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpTransportSettings.cs new file mode 100755 index 00000000000..e0f2171fed2 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery/UdpTransportSettings.cs @@ -0,0 +1,51 @@ +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace System.ServiceModel.Discovery +{ + public class UdpTransportSettings + { + internal UdpTransportSettings () + { + } + + public int DuplicateMessageHistoryLength { get; set; } + public long MaxBufferPoolSize { get; set; } + public int MaxMulticastRetransmitCount { get; set; } + public int MaxPendingMessageCount { get; set; } + public long MaxReceivedMessageSize { get; set; } + public int MaxUnicastRetransmitCount { get; set; } + public string MulticastInterfaceId { get; set; } + public int SocketReceiveBufferSize { get; set; } + public int TimeToLive { get; set; } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery_test.dll.sources b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery_test.dll.sources new file mode 100644 index 00000000000..ffd63d37c59 --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/System.ServiceModel.Discovery_test.dll.sources @@ -0,0 +1,2 @@ +System.ServiceModel.Discovery/DiscoveryVersionTest.cs +System.ServiceModel.Discovery/FindCriteriaTest.cs diff --git a/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/ChangeLog b/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/ChangeLog new file mode 100755 index 00000000000..ce289a8a77d --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/ChangeLog @@ -0,0 +1,4 @@ +2010-03-19 Atsushi Enomoto + + * : initial checkin (mostly stubs). + diff --git a/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/DiscoveryVersionTest.cs b/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/DiscoveryVersionTest.cs new file mode 100755 index 00000000000..3e73e0b28ae --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/DiscoveryVersionTest.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Discovery; +using System.ServiceModel.Dispatcher; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.Discovery +{ + [TestFixture] + public class DiscoveryVersionTest + { + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void NullName () + { + DiscoveryVersion.FromName (null); + } + + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void EmptyName () + { + DiscoveryVersion.FromName (String.Empty); + } + + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void InvalidName () + { + DiscoveryVersion.FromName ("foobar"); + } + + [Test] + public void ValidName () + { + DiscoveryVersion.FromName ("WSDiscovery11"); + DiscoveryVersion.FromName ("WSDiscoveryApril2005"); + DiscoveryVersion.FromName ("WSDiscoveryCD1"); + } + } +} diff --git a/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/FindCriteriaTest.cs b/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/FindCriteriaTest.cs new file mode 100755 index 00000000000..53bf01bf75e --- /dev/null +++ b/mcs/class/System.ServiceModel.Discovery/Test/System.ServiceModel.Discovery/FindCriteriaTest.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Discovery; +using System.ServiceModel.Dispatcher; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.Discovery +{ + [TestFixture] + public class FindCriteriaTest + { + [Test] + [Ignore ("huh? should they really return Uri like 'http://schemas.microsoft.com/ws/2008/06/discovery/strcmp0' ?")] + public void StaticUris () + { + Assert.AreEqual ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/strcmp0", FindCriteria.ScopeMatchByExact.ToString (), "#1"); + Assert.AreEqual ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/none", FindCriteria.ScopeMatchByLdap.ToString (), "#2"); + Assert.AreEqual ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/none", FindCriteria.ScopeMatchByNone.ToString (), "#3"); + Assert.AreEqual ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/rfc3986", FindCriteria.ScopeMatchByPrefix.ToString (), "#4"); + Assert.AreEqual ("http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/uuid", FindCriteria.ScopeMatchByUuid.ToString (), "#5"); + } + } +} diff --git a/mcs/class/System.ServiceModel.Web/ChangeLog b/mcs/class/System.ServiceModel.Web/ChangeLog index bfa93fd472e..d0c60882654 100644 --- a/mcs/class/System.ServiceModel.Web/ChangeLog +++ b/mcs/class/System.ServiceModel.Web/ChangeLog @@ -1,3 +1,9 @@ +2010-03-12 Atsushi Enomoto + + * net_2_0_System.ServiceModel.Web.dll.sources, + common_System.ServiceModel.Web.dll.sources : UriTemplates are + moved to Sys.SM.dll in 4.0 profile. + 2010-03-12 Atsushi Enomoto * monotouch_System.ServiceModel.Web.dll.sources : diff --git a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog index ef28ea94c9f..4c38b06db2d 100644 --- a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog +++ b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/ChangeLog @@ -1,3 +1,18 @@ +2010-04-24 Atsushi Enomoto + + * JsonSerializationReader.cs : use List if the contract member + type is interface. + +2010-03-16 Jb Evain + + * DataContractJsonSerializer.cs: use MOONLIGHT symbol to + disambiguate MonoTouch and Moonlight code. + +2010-03-13 Kornél Pál + + * JavaScriptReader.cs: Deserialize "false" correctly. + Fixed bug #586712. + 2010-03-10 Atsushi Enomoto * JavaScriptReader.cs : moved from Sys.Json/JsonReader.cs. diff --git a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs index d5ea4db36a6..355ea31dadb 100644 --- a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs +++ b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs @@ -91,7 +91,7 @@ namespace System.Runtime.Serialization.Json always_emit_type = alwaysEmitTypeInformation; } -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT public DataContractJsonSerializer (Type type, IEnumerable knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation) : this (type, default_root_name, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, alwaysEmitTypeInformation) { @@ -117,7 +117,7 @@ namespace System.Runtime.Serialization.Json int max_items; bool ignore_extension; bool always_emit_type; -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT IDataContractSurrogate surrogate; [MonoTODO] diff --git a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JavaScriptReader.cs b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JavaScriptReader.cs index b3be29ae8d9..746030825a7 100644 --- a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JavaScriptReader.cs +++ b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JavaScriptReader.cs @@ -86,7 +86,7 @@ namespace System.Runtime.Serialization.Json return true; case 'f': Expect ("false"); - return true; + return false; case 'n': Expect ("null"); // FIXME: what should we return? diff --git a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs index f57d2068b8c..87cb0dc1e26 100644 --- a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs +++ b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs @@ -259,6 +259,8 @@ namespace System.Runtime.Serialization.Json { reader.ReadStartElement (); object ret; + if (collectionType.IsInterface) + collectionType = typeof (List<>).MakeGenericType (elementType); if (typeof (IList).IsAssignableFrom (collectionType)) { #if NET_2_1 Type listType = collectionType.IsArray ? typeof (List<>).MakeGenericType (elementType) : null; diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/ChangeLog b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/ChangeLog index 2cf709207df..cea57d02506 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/ChangeLog +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/ChangeLog @@ -1,3 +1,13 @@ +2010-03-19 Atsushi Enomoto + + * WebHttpBehavior.cs : set FilterPriority to make it in higher + priority than conflicting endpoints (such as mex endpoint). + +2010-03-16 Jb Evain + + * WebHttpBehavior.cs: use MOONLIGHT symbol to + disambiguate MonoTouch and Moonlight code. + 2009-10-23 Atsushi Enomoto * WebHttpBehavior.cs : add experimental monotouch build. diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/WebHttpBehavior.cs b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/WebHttpBehavior.cs index cc4609ac620..c17c78899c9 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/WebHttpBehavior.cs +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Description/WebHttpBehavior.cs @@ -102,7 +102,7 @@ namespace System.ServiceModel.Description public virtual void ApplyClientBehavior (ServiceEndpoint endpoint, ClientRuntime clientRuntime) { AddClientErrorInspector (endpoint, clientRuntime); -#if NET_2_1 && !MONOTOUCH +#if MOONLIGHT throw new NotSupportedException ("Due to the lack of ClientRuntime.Operations, Silverlight cannot support this binding."); #else foreach (ClientOperation oper in clientRuntime.Operations) { @@ -118,6 +118,7 @@ namespace System.ServiceModel.Description { endpointDispatcher.DispatchRuntime.OperationSelector = GetOperationSelector (endpoint); // FIXME: get HostNameComparisonMode from WebHttpBinding by some means. + endpointDispatcher.FilterPriority = 1; // It is to take higher priority than that of ServiceMetadataExtension (whose URL likely conflicts with this one). endpointDispatcher.AddressFilter = new PrefixEndpointAddressMessageFilter (endpoint.Address); endpointDispatcher.ContractFilter = new MatchAllMessageFilter (); AddServerErrorHandlers (endpoint, endpointDispatcher); diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog index 8c770f141e1..e99209a6f13 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/ChangeLog @@ -1,3 +1,8 @@ +2010-03-16 Jb Evain + + * WebMessageFormatter.cs: use MOONLIGHT symbol to + disambiguate MonoTouch and Moonlight code. + 2009-10-23 Atsushi Enomoto * JsonQueryStringConverter.cs diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs index 0eefabf073d..ba802e34c03 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Dispatcher/WebMessageFormatter.cs @@ -158,7 +158,7 @@ namespace System.ServiceModel.Description break; case WebContentFormat.Json: // FIXME: after name argument they are hack -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT if (IsResponseBodyWrapped) return GetSerializer (ref json_serializer, p => new DataContractJsonSerializer (p.Type, BodyName ?? p.Name, null, 0x100000, false, null, true)); else diff --git a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog index 72b72095aab..0b7aa1e74fd 100644 --- a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog +++ b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/ChangeLog @@ -1,3 +1,8 @@ +2010-04-05 Atsushi Enomoto + + * DataContractJsonSerializerTest.cs : don't use ToUniversalTime() + which makes test results timezone dependent. + 2010-03-10 Atsushi Enomoto * DataContractJsonSerializerTest.cs : oops, the test was careless. diff --git a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs index e6ba1c108c2..a6e09f9d159 100644 --- a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs +++ b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs @@ -1349,11 +1349,11 @@ namespace MonoTests.System.Runtime.Serialization.Json var ms = new MemoryStream (); DataContractJsonSerializer serializer = new DataContractJsonSerializer (typeof (Query)); Query query = new Query () { - StartDate = new DateTime (2010, 3, 4, 5, 6, 7).ToUniversalTime (), - EndDate = new DateTime (2010, 4, 5, 6, 7, 8).ToUniversalTime () + StartDate = new DateTime (2010, 3, 4, 5, 6, 7), + EndDate = new DateTime (2010, 4, 5, 6, 7, 8) }; serializer.WriteObject (ms, query); - Assert.AreEqual ("{\"StartDate\":\"\\/Date(1267646767000)\\/\",\"EndDate\":\"\\/Date(1270415228000)\\/\"}", Encoding.UTF8.GetString (ms.ToArray ()), "#1"); + Assert.AreEqual ("{\"StartDate\":\"\\/Date(1267679167000)\\/\",\"EndDate\":\"\\/Date(1270447628000)\\/\"}", Encoding.UTF8.GetString (ms.ToArray ()), "#1"); ms.Position = 0; Console.WriteLine (new StreamReader (ms).ReadToEnd ()); ms.Position = 0; diff --git a/mcs/class/System.ServiceModel.Web/common_System.ServiceModel.Web.dll.sources b/mcs/class/System.ServiceModel.Web/common_System.ServiceModel.Web.dll.sources index ae726bc6b95..04dbe4f9bd7 100644 --- a/mcs/class/System.ServiceModel.Web/common_System.ServiceModel.Web.dll.sources +++ b/mcs/class/System.ServiceModel.Web/common_System.ServiceModel.Web.dll.sources @@ -37,8 +37,3 @@ System.ServiceModel.Web/WebServiceHost.cs System.ServiceModel/WebHttpBinding.cs System.ServiceModel/WebHttpSecurity.cs System.ServiceModel/WebHttpSecurityMode.cs -System/UriTemplate.cs -System/UriTemplateEquivalenceComparer.cs -System/UriTemplateMatch.cs -System/UriTemplateMatchException.cs -System/UriTemplateTable.cs diff --git a/mcs/class/System.ServiceModel.Web/moonlight_raw_System.ServiceModel.Web.dll.sources b/mcs/class/System.ServiceModel.Web/moonlight_raw_System.ServiceModel.Web.dll.sources new file mode 100644 index 00000000000..07c6038f68e --- /dev/null +++ b/mcs/class/System.ServiceModel.Web/moonlight_raw_System.ServiceModel.Web.dll.sources @@ -0,0 +1,12 @@ +Assembly/AssemblyInfo.cs +System.Runtime.Serialization.Json/DataContractJsonSerializer_2_1.cs +System.Runtime.Serialization.Json/IXmlJsonReaderInitializer.cs +System.Runtime.Serialization.Json/IXmlJsonWriterInitializer.cs +System.Runtime.Serialization.Json/JavaScriptObjectDeserializer.cs +System.Runtime.Serialization.Json/JavaScriptReader.cs +System.Runtime.Serialization.Json/JsonReader.cs +System.Runtime.Serialization.Json/JsonReaderWriterFactory.cs +System.Runtime.Serialization.Json/JsonSerializationReader.cs +System.Runtime.Serialization.Json/JsonSerializationWriter.cs +System.Runtime.Serialization.Json/JsonWriter.cs +System.Runtime.Serialization.Json/TypeMap.cs diff --git a/mcs/class/System.ServiceModel.Web/net_2_0_System.ServiceModel.Web.dll.sources b/mcs/class/System.ServiceModel.Web/net_2_0_System.ServiceModel.Web.dll.sources index 27493ec8201..effcff77237 100644 --- a/mcs/class/System.ServiceModel.Web/net_2_0_System.ServiceModel.Web.dll.sources +++ b/mcs/class/System.ServiceModel.Web/net_2_0_System.ServiceModel.Web.dll.sources @@ -46,3 +46,8 @@ System.ServiceModel.Syndication/TextSyndicationContentKind.cs System.ServiceModel.Syndication/UrlSyndicationContent.cs System.ServiceModel.Syndication/Workspace.cs System.ServiceModel.Syndication/XmlSyndicationContent.cs +System/UriTemplate.cs +System/UriTemplateEquivalenceComparer.cs +System/UriTemplateMatch.cs +System/UriTemplateMatchException.cs +System/UriTemplateTable.cs diff --git a/mcs/class/System.ServiceModel.Web/net_2_1_raw_System.ServiceModel.Web.dll.sources b/mcs/class/System.ServiceModel.Web/net_2_1_raw_System.ServiceModel.Web.dll.sources deleted file mode 100644 index 07c6038f68e..00000000000 --- a/mcs/class/System.ServiceModel.Web/net_2_1_raw_System.ServiceModel.Web.dll.sources +++ /dev/null @@ -1,12 +0,0 @@ -Assembly/AssemblyInfo.cs -System.Runtime.Serialization.Json/DataContractJsonSerializer_2_1.cs -System.Runtime.Serialization.Json/IXmlJsonReaderInitializer.cs -System.Runtime.Serialization.Json/IXmlJsonWriterInitializer.cs -System.Runtime.Serialization.Json/JavaScriptObjectDeserializer.cs -System.Runtime.Serialization.Json/JavaScriptReader.cs -System.Runtime.Serialization.Json/JsonReader.cs -System.Runtime.Serialization.Json/JsonReaderWriterFactory.cs -System.Runtime.Serialization.Json/JsonSerializationReader.cs -System.Runtime.Serialization.Json/JsonSerializationWriter.cs -System.Runtime.Serialization.Json/JsonWriter.cs -System.Runtime.Serialization.Json/TypeMap.cs diff --git a/mcs/class/System.ServiceModel/ChangeLog b/mcs/class/System.ServiceModel/ChangeLog index d2293ebdb7c..0bb3d5ac1c3 100755 --- a/mcs/class/System.ServiceModel/ChangeLog +++ b/mcs/class/System.ServiceModel/ChangeLog @@ -1,3 +1,63 @@ +2010-04-23 Astushi Enomoto + + * Http_listener_notes.txt: update comment, as I have fixed one issue + with lengthy explanation. + +2010-04-21 Astushi Enomoto + + * Http_listener_notes.txt: more comment. + +2010-04-20 Astushi Enomoto + + * Http_listener_notes.txt: added explanation on *why* it is SO hard + to solve. + +2010-04-05 Astushi Enomoto + + * System.ServiceModel.dll.sources : add some new config types and + ChannelTerminatedException.cs. + +2010-04-02 Astushi Enomoto + + * System.ServiceModel_test.dll.sources : add some new fault tests. + +2010-03-24 Astushi Enomoto + + * System.ServiceModel.dll.sources : move back all the Features tests + that were once disabled (now we can handle mannerless tests). + +2010-03-19 Astushi Enomoto + + * System.ServiceModel.dll.sources : remove unused class. + * HTTP_listener_notes.txt : add some more comments. + +2010-03-18 Astushi Enomoto + + * System.ServiceModel_test.dll.sources : + Add Constants.cs and XPathMessageContextTest.cs. + +2010-03-18 Astushi Enomoto + + * System.ServiceModel.dll.sources : added some missing types. + +2010-03-17 Astushi Enomoto + + * System.ServiceModel_test.dll.sources : + add MetadataExchangeBindingsTest.cs. + +2010-03-16 Jb Evain + + * net_2_1_*.dll.sources: rename to moonlight_*.dll.sources. + +2010-03-15 Astushi Enomoto + + * net_4_0_System.ServiceModel.dll.sources: + more types from Sys.SM.Web.dll in 4.0 profile here. + +2010-03-15 Astushi Enomoto + + * Dummy_2_1.cs : added cosmetic silverlight sdk compatibility stuff. + 2010-03-11 Astushi Enomoto * System.ServiceModel.dll.sources, diff --git a/mcs/class/System.ServiceModel/Dummy_2_1.cs b/mcs/class/System.ServiceModel/Dummy_2_1.cs index a3aa98d78e4..4c90120ed87 100644 --- a/mcs/class/System.ServiceModel/Dummy_2_1.cs +++ b/mcs/class/System.ServiceModel/Dummy_2_1.cs @@ -1,3 +1,4 @@ +using System.Reflection; using System.Runtime.Serialization; namespace System.ServiceModel @@ -7,6 +8,19 @@ namespace System.ServiceModel { public InstanceContext (object dummy) {} } + // introduced for silverlight sdk compatibility + internal class OperationFormatStyleHelper + { + public static bool IsDefined (OperationFormatStyle style) + { + switch (style) { + case OperationFormatStyle.Document: + case OperationFormatStyle.Rpc: + return true; + } + return false; + } + } } namespace System.ServiceModel.Channels { @@ -23,6 +37,41 @@ namespace System.ServiceModel.Description public interface IWsdlExportExtension {} public interface IWsdlImportExtension {} public interface IContractBehavior {} + + // introduced for silverlight sdk compatibility + internal class ServiceReflector + { + public static T GetSingleAttribute (ICustomAttributeProvider p, Type [] types) + { + T ret = default (T); + foreach (Type t in types) { + foreach (object att in p.GetCustomAttributes (t, false)) { + if (att is T) { + if (ret != null) + throw new InvalidOperationException (String.Format ("More than one {0} attributes are found in the argument types", typeof (T))); + ret = (T) att; + } + } + } + return ret; + } + } +} +namespace System.ServiceModel.DiagnosticUtility +{ + // introduced for silverlight sdk compatibility + internal class ExceptionUtility + { + public static Exception ThrowHelperError (Exception error) + { + return error; + } + + public static Exception ThrowHelperArgumentNull (string arg) + { + return new ArgumentNullException (arg); + } + } } namespace System.ServiceModel.Dispatcher { diff --git a/mcs/class/System.ServiceModel/HTTP_listener_notes.txt b/mcs/class/System.ServiceModel/HTTP_listener_notes.txt index 0a04e518873..54374d7a5de 100644 --- a/mcs/class/System.ServiceModel/HTTP_listener_notes.txt +++ b/mcs/class/System.ServiceModel/HTTP_listener_notes.txt @@ -11,10 +11,11 @@ This mostly explains what our WCF does, and does not explain what I think it rea -- IChannelListener only has methods for receiving requests that must be explicitly invoked for each request (i.e. to repeatedly process requests it must invoke receiver methods every time, unlike ServiceHost.Open() method). - Inside the service loop, IChannelListener invokes [Begin]AcceptChannel() to get a channel such as HttpSimpleReplyChannel`1 or AspNetReplyChannel`1. Channels can be created as much as the service throttle limitation (ServiceThrottle) allows. - Then the loop manager invokes the channel's [Begin]TryReceiveRequest(). -- When WSDLs are enabled, ServiceMetadataExtension populates another ChannelDispatcher that serves HTTP requests to WSDLs. --- It is important to understand that during this process it populates HTTP channel listener onto the same port and even possibly onto the same target URL, differentiating only by the request parameter (e.g. "?wsdl"). This causes a lot of confusion on both IHttpHandler (for ASP.NET) and HttpListener (for non-ASP.NET). +- When WSDLs are enabled, ServiceMetadataExtension populates another ChannelDispatcher (yes, not just an EndpointDispatcher) that serves HTTP requests to WSDLs. +-- It is important to understand that during this process it populates HTTP channel listener onto the *same* port and even possibly onto the same target URL, differentiating only by the request parameter (e.g. "?wsdl"). This causes a lot of confusion on both IHttpHandler (for ASP.NET) and HttpListener (for non-ASP.NET). - Inside (abstract) HttpChannelListener`1, it internally has (abstract) HttpListenerManager which manages the actual HTTP listeners. -- This intermediate stuff is required to manage HTTP listeners across the actual HttpChannelListeners because more than one channel listeners might use the identical HTTP listener; only one HttpListener can listen to a specific URI prefix, while (as explained above) WSDL support dispatcher may listen to the same URI only differentiating the query parameter. +- While building ChannelDispatcher inside ServiceHostBase, we have a tricky code that sets ChannelDispatcher to HttpChannelListener. It is to make sure to apply ServiceMetadataExtension to the listener internals. Without that info, it is not possible to handle wsdl requests precisely (or if you have any simpler idea to achieve this safely, we would glad to hear it). ** non-ASP.NET-specific process flow @@ -47,10 +48,22 @@ This mostly explains what our WCF does, and does not explain what I think it rea locking: TBD +** Some notes + +- WebHttpBinding creates HTTP channel listeners that share an identical endpoint URI, which could also be mapped by ServiceMetadataExtension. It brings problem on dispatching HTTP request to correct listener. FilterPriority is used to resolve the issue (possibly to some extent) that requests to wsdl/mex are treated in lower priority. +- While multiple channel dispatchers' endpoints could indicate an identical HTTP URI, it is not allowed to use the same HTTP URI across more than one ServiceHostBase and attempt to create such endpoints will result in InvalidOperationException for conflict with existing listeners. +- Actually, .NET seems to reject duplicate listen URI at HttpChannelListener level (precisely to say, equivalent to that of mono, ones from HttpTransportBindingElement.BuildChannelListener()). We don't reject that (bug). + + ** Bugs There is not a few bugs on service implementations and there often are reasons: -- TCP duplex channels used to fail to serve requests when the throttle is 1. It was due to failure in managing closed channels (while it is duplex and hence it has to maintain channels until it is explicitly closed, clients often, or mostly, disconnects without any notice. So it had to be changed to explicitly check if the connection is available at any beginning of the request processing). --- When there is more than one endpoint definition in web.config, it somehow fails to build appropriate HttpHandler chain (bug #573795). +-- If there are more than one endpoint with the identical listen URI, it will fail to dispatch requests to correct listener even if the endpoints have appropriately configured FilterPriority. part of bug #573795. - ASP.NET listener ends up to dump ThreadAbort during its shutdown. It's mostly harmless though. + +** Required changes + +- HttpChannelListeners (Simple-, AspNet-) need an owner ChannelDispatcher. It has to be set probably at ICommunicationObject.Opening event. +- After having ChannelDispatcher to manage a HttpChannelListener for each endpoint URI (create new or reuse), the listener has to differentiate HTTP requests to an appropriate channel, by EndpointDispatcher.FilterPriority. diff --git a/mcs/class/System.ServiceModel/Makefile b/mcs/class/System.ServiceModel/Makefile index a090d8cc0da..6bb0e3c915b 100755 --- a/mcs/class/System.ServiceModel/Makefile +++ b/mcs/class/System.ServiceModel/Makefile @@ -31,7 +31,7 @@ LIB_MCS_FLAGS += /d:NET_3_0 \ /r:Mono.Security.dll endif -ifeq (net_2_1_raw, $(PROFILE)) +ifeq (moonlight_raw, $(PROFILE)) LIB_MCS_FLAGS += /r:System.Net endif diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AddressingVersion.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AddressingVersion.cs index 6b45f5d4ced..1983e3a91e2 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AddressingVersion.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AddressingVersion.cs @@ -34,24 +34,29 @@ namespace System.ServiceModel.Channels { string name; string address; + string fault_ns; - AddressingVersion (string name, string address) + AddressingVersion (string name, string address, string faultNS) { this.name = name; this.address = address; + this.fault_ns = faultNS; } static AddressingVersion addressing200408 = new AddressingVersion ( "Addressing200408", - "http://schemas.xmlsoap.org/ws/2004/08/addressing"); + "http://schemas.xmlsoap.org/ws/2004/08/addressing", + "http://schemas.xmlsoap.org/ws/2004/08/addressing/fault"); static AddressingVersion addressing1_0 = new AddressingVersion ( "Addressing10", - "http://www.w3.org/2005/08/addressing"); + "http://www.w3.org/2005/08/addressing", + "http://www.w3.org/2005/08/addressing/fault"); static AddressingVersion none = new AddressingVersion ( "AddressingNone", - "http://schemas.microsoft.com/ws/2005/05/addressing/none"); + "http://schemas.microsoft.com/ws/2005/05/addressing/none", + null); public static AddressingVersion WSAddressing10 { get { return addressing1_0; } @@ -69,6 +74,10 @@ namespace System.ServiceModel.Channels get { return address; } } + internal string FaultNamespace { + get { return fault_ns; } + } + internal string ActionNotSupported { get { return "ActionNotSupported"; } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetReplyChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetReplyChannel.cs index 75cf52ce010..8b083f5e984 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetReplyChannel.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetReplyChannel.cs @@ -54,7 +54,7 @@ namespace System.ServiceModel.Channels if (http_context == null) return; try { - listener.HttpHandler.EndRequest (listener, http_context); + ((AspNetListenerManager) listener.ListenerManager).HttpHandler.EndRequest (listener, http_context); } finally { http_context = null; } @@ -65,7 +65,7 @@ namespace System.ServiceModel.Channels lock (waiting) foreach (HttpContext ctx in waiting) try { - listener.HttpHandler.EndRequest (listener, ctx); + ((AspNetListenerManager) listener.ListenerManager).HttpHandler.EndRequest (listener, ctx); } catch { } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetRequestContext.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetRequestContext.cs index 9cbb4bf3c58..59bf2bbcbca 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetRequestContext.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/AspNetRequestContext.cs @@ -74,6 +74,8 @@ namespace System.ServiceModel.Channels { if (hp.SuppressEntityBody) suppressEntityBody = true; } + if (msg.IsFault) + ctx.Response.StatusCode = 500; if (!suppressEntityBody) { ctx.Response.AddHeader ("Content-Length", ms.Length.ToString (CultureInfo.InvariantCulture)); ctx.Response.OutputStream.Write (ms.GetBuffer (), 0, (int) ms.Length); diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BindingContext.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BindingContext.cs index 1dac543ba51..8a051867f59 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BindingContext.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BindingContext.cs @@ -155,7 +155,10 @@ namespace System.ServiceModel.Channels { bool restore = PrepareElements (); try { - return DequeueBindingElement ().BuildChannelListener (this); + var be = DequeueBindingElement (false); + if (be == null) + throw new InvalidOperationException ("There is likely no TransportBindingElement that can build a channel listener in this binding context"); + return be.BuildChannelListener (this); } finally { if (restore) elements = empty_collection; @@ -181,8 +184,10 @@ namespace System.ServiceModel.Channels { bool restore = PrepareElements (); try { - return elements.Count > 0 && - DequeueBindingElement ().CanBuildChannelListener (this); + var be = DequeueBindingElement (false); + if (be == null) + throw new InvalidOperationException ("There is likely no TransportBindingElement that can build a channel listener in this binding context"); + return be.CanBuildChannelListener (this); } finally { if (restore) elements = empty_collection; diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BodyWriter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BodyWriter.cs index 7fbcdcebc54..1f9cf98f7b4 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BodyWriter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BodyWriter.cs @@ -57,7 +57,6 @@ namespace System.ServiceModel.Channels OnWriteBodyContents (writer); } - [MonoTODO ("use maxBufferSize somewhere")] protected virtual BodyWriter OnCreateBufferedCopy ( int maxBufferSize) { @@ -67,10 +66,33 @@ namespace System.ServiceModel.Channels StringWriter sw = new StringWriter (); using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw, s))) WriteBodyContents (w); - return new XmlReaderBodyWriter (sw.ToString ()); + var xml = sw.ToString (); + if (xml.Length > 0) + return new XmlReaderBodyWriter (xml, maxBufferSize, null); + else + return new EmptyBodyWriter (); } protected abstract void OnWriteBodyContents ( XmlDictionaryWriter writer); + + class EmptyBodyWriter : BodyWriter + { + public EmptyBodyWriter () + : base (true) + { + } + + protected override BodyWriter OnCreateBufferedCopy ( + int maxBufferSize) + { + return new EmptyBodyWriter (); + } + + protected override void OnWriteBodyContents (XmlDictionaryWriter writer) + { + // nothing to do + } + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs index 9078b9d1cdd..ae295d08b0a 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/BufferManager.cs @@ -1,9 +1,38 @@ // -// BufferManager.cs +// BufferManager.cs: +// This class suffers from an engineering problem in its +// design: when this API is used to limit the total pool +// size it will throw, but no user code is designed to +// cope with that. // -// Author: Atsushi Enomoto (atsushi@ximian.com) +// Instead of the Microsoft strategy, we allow allocation +// to go as far as it wants to go and merely allow this +// to be a pool that can be used recycle buffers. // -// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// This still gives us the main benefit of this class, while +// avoiding the potential crashing scenarios and simplifies +// the implementation significantly from what has been +// document in the blogosphere. +// +// There are a few problems: for example, if we do not find +// a buffer of the proper size in the expected slot, say +// a 31k buffer in the slot for [32k-64k] values, we will +// allocate a new buffer, even if there might have been a +// buffer for 128k. +// +// A few considerations: +// +// The size of an empty array is either 16 on 32 bit systems +// and 32 bytes in 64 bit systems. +// +// We take this information into account for the minimum allocation +// pools. +// +// Authors: +// Atsushi Enomoto (atsushi@ximian.com) +// Miguel de Icaza (miguel@gnome.org) +// +// Copyright (C) 2005, 2010 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -25,6 +54,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; +using System.Collections.Generic; using System.IO; using System.Collections.ObjectModel; using System.ServiceModel; @@ -39,26 +69,71 @@ namespace System.ServiceModel.Channels public abstract void Clear (); - [MonoTODO] public static BufferManager CreateBufferManager ( long maxBufferPoolSize, int maxBufferSize) { - return new DefaultBufferManager (maxBufferPoolSize, - maxBufferSize); + return new DefaultBufferManager (maxBufferPoolSize, maxBufferSize); } public abstract void ReturnBuffer (byte[] buffer); public abstract byte[] TakeBuffer (int bufferSize); +#if DEBUG_BUFFER + internal abstract void DumpStats (); +#endif + class DefaultBufferManager : BufferManager { + const int log_min = 5; // Anything smaller than 1 << log_cut goes into the first bucket long max_pool_size; int max_size; - byte [] buffer; + List [] buffers = new List [32-log_min]; - public DefaultBufferManager (long maxBufferPoolSize, - int maxBufferSize) +#if DEBUG_BUFFER + internal override void DumpStats () + { + Console.WriteLine ("- hit={0} miss={1}-", hits, miss); + for (int i = 0; i < buffers.Length; i++){ + if (buffers [i] == null) + continue; + + Console.Write ("Slot {0} - {1} [", i, buffers [i].Count); + byte [][] arr = buffers [i].ToArray (); + + for (int j = 0; j < Math.Min (3, arr.Length); j++) + Console.Write ("{0} ", arr [j].Length); + Console.WriteLine ("]"); + } + } +#endif + + static int log2 (uint n) + { + int pos = 0; + if (n >= 1<<16) { + n >>= 16; + pos += 16; + } + if (n >= 1<< 8) { + n >>= 8; + pos += 8; + } + if (n >= 1<< 4) { + n >>= 4; + pos += 4; + } + if (n >= 1<< 2) { + n >>= 2; + pos += 2; + } + if (n >= 1<< 1) + pos += 1; + + return ((n == 0) ? (-1) : pos); + } + + public DefaultBufferManager (long maxBufferPoolSize, int maxBufferSize) { this.max_pool_size = maxBufferPoolSize; this.max_size = maxBufferSize; @@ -66,28 +141,85 @@ namespace System.ServiceModel.Channels public override void Clear () { - if (buffer != null) - Array.Clear (buffer, 0, buffer.Length); + foreach (var stack in buffers){ + if (stack == null) + continue; + stack.Clear (); + } + Array.Clear (buffers, 0, buffers.Length); } public override void ReturnBuffer (byte [] buffer) { - // is this correct? - - if (this.buffer == null) + if (buffer == null) return; - Array.Copy (this.buffer, buffer, this.buffer.Length); + + uint size = (uint) buffer.Length; + int l2 = log2 (size); + if (l2 > log_min) + l2 -= log_min; + + List returned = buffers [l2]; + if (returned == null) + returned = buffers [l2] = new List (); + + returned.Add (buffer); } + int hits, miss; + public override byte [] TakeBuffer (int bufferSize) { - if (bufferSize > max_size) + if (bufferSize < 0 || (max_size >= 0 && bufferSize > max_size)) throw new ArgumentOutOfRangeException (); - if (buffer == null || buffer.Length < bufferSize) - buffer = new byte [bufferSize]; - return buffer; + int l2 = log2 ((uint) bufferSize); + if (l2 > log_min) + l2 -= log_min; + + List returned = buffers [l2]; + if (returned == null || returned.Count == 0) + return new byte [bufferSize]; + + foreach (var e in returned){ + if (e.Length >= bufferSize){ + hits++; + returned.Remove (e); + return e; + } + } + return new byte [bufferSize]; + } + } + } + +#if DEBUG_BUFFER + class Foo { + static void Main () + { + var a = BufferManager.CreateBufferManager (1024*1024, 1024*1024); + var rand = new Random (0); + + var buffs = new List (); + for (int i = 0; i < 4096; i++){ + a.DumpStats (); + var request = rand.Next (1,1024*1024); + if ((i % 2) == 0) + request = rand.Next (1024, 4096); + + var x = a.TakeBuffer (request); + if (x.Length < request) + throw new Exception (); + Console.WriteLine ("Delta={2} Requested {0} got={1} bytes ", request, x.Length, x.Length-request); + if ((i % 3) == 0){ + Console.WriteLine ("Return: {0}", x.Length); + a.ReturnBuffer (x); + } + else + buffs.Add (x); } + a.DumpStats (); } } -} +#endif +} \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog index 863e71e8d38..db7b6625f18 100755 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog @@ -1,3 +1,223 @@ +2010-04-23 Atsushi Enomoto + + * HttpListenerManager.cs : fixed the issue that mex_info is never + retrieved from the latest channel listener (which could be other + listener than the one which was set mex info). + +2010-04-23 Atsushi Enomoto + + * HttpChannelListener.cs, HttpListenerManager.cs : + actually it should be ChannelDispatcher-to-HttpChannelListener, + to identify which dispatcher to send reqs. + +2010-04-23 Atsushi Enomoto + + * HttpReplyChannel.cs : remove old Http Keep-Alive workaround. + +2010-04-23 Atsushi Enomoto + + * HttpTransportBindingElement.cs, + HttpChannelListener.cs, + HttpListenerManager.cs : add host-to-http-listener mapping so that + they can be managed per host. + +2010-04-21 Atsushi Enomoto + + * BindingContext.cs : require a TransportBindingElement when + building a channel listener. + +2010-04-19 Atsushi Enomoto + + * HttpReplyChannel.cs : use local var to hold wait handle to avoid + possible NRE on field. Based on the patch by Matt Dargavel. + +2010-04-07 Miguel de Icaza + + * BufferManager.cs: Implement the BufferManager. + +2010-04-07 Atsushi Enomoto + + * WSSecurityMessageHeader.cs : add FIXME comment. + +2010-04-06 Atsushi Enomoto + + * HttpRequestChannel.cs : add commented note. + +2010-04-06 Atsushi Enomoto + + * HttpReplyChannel.cs : fill To header only if it does not exist. + +2010-04-06 Atsushi Enomoto + + * SecureMessageGenerator.cs : set ReplyTo and To, do not add. + +2010-04-06 Atsushi Enomoto + + * MessageHeaders.cs : use matching addressing version. + Remove header item if the same ones already exist. + +2010-04-06 Gonzalo Paniagua Javier + + * HttpRequestChannel.cs: don't create the wait handle unless it is + really needed. + +2010-04-02 Atsushi Enomoto + + * HttpRequestChannel.cs : use correct max buffer size. + +2010-04-02 Atsushi Enomoto + + * MessageFault.cs : check null serializer and detail. + Make sure to consume s12:Reason EndElement. + +2010-04-02 Atsushi Enomoto + + * MessageFault.cs : when created from XmlReader, it should not + deserialize fault details immediately. This class itself should + not do that. Strongly typed FaultContractInfo may want to use the + reader (GetReaderAtDetailContents()) for its own deserialization. + +2010-04-01 Atsushi Enomoto + + * ConnectionOrientedTransportBindingElement.cs, + TcpTransportBindingElement.cs : implement GetProperty(). + +2010-04-01 Atsushi Enomoto + + * HttpTransportBindingElement.cs, HttpsTransportBindingElement.cs: + implement HttpsTransportBindingElement.GetProperty(). Extend the + properties type from HTTP. + +2010-04-01 Atsushi Enomoto + + * FaultConverter.cs : use addressing version from the message. + +2010-03-30 Atsushi Enomoto + + * FaultConverter.cs : check envelope version, not addressing version. + +2010-03-29 Atsushi Enomoto + + * FaultConverter.cs : implemented TryCreateException(). + +2010-03-29 Atsushi Enomoto + + * MessageFault.cs : cosmetic method name clarification. + +2010-03-29 Atsushi Enomoto + + * XmlReaderBodyWriter.cs, Message.cs, MessageImpl.cs, BodyWriter.cs: + fix BodyWriter buffering that dropped in-scope namespaces and thus + caused problem on resolving QNames. + +2010-03-26 Atsushi Enomoto + + * FaultConverter.cs : do implement OnTryCreateFaultMessage() to work + with certain Exception types. + +2010-03-26 Atsushi Enomoto + + * Message.cs : fix explanation on CreateMessage() overloads. + +2010-03-26 Atsushi Enomoto + + * MessageFault.cs : Write Subcode element correctly and fix wrong + Code/Value/Subcode element relationship. Give better error message. + +2010-03-26 Atsushi Enomoto + + * HttpRequestChannel.cs : ok, no need for conditional code path. + +2010-03-26 Atsushi Enomoto + + * AddressingVersion.cs : add fault action namespace. + +2010-03-26 Sebastien Pouliot + + * HttpRequestChannel.cs: There is no WebHeaderCollection.Add + method in SL API + +2010-03-26 Atsushi Enomoto + + * MessageImpl.cs : pass IsFault argument in OnCreateBufferedCopy(). + +2010-03-26 Atsushi Enomoto + + * HttpRequestContext.cs, AspNetRequestContext.cs : return HTTP 500 + for fault message. + +2010-03-26 Atsushi Enomoto + + * HttpRequestChannel.cs : create HttpResponseMessageProperty. + +2010-03-25 Atsushi Enomoto + + * HttpRequestContext.cs : removed HTTP status rewriting for + commented reason. + +2010-03-25 Atsushi Enomoto + + * HttpRequestChannel.cs : handle only 4xx errors as to not process + content stream. + +2010-03-25 Atsushi Enomoto + + * MessageFault.cs : do not use SOAP11 namespace for fault contents. + +2010-03-24 Atsushi Enomoto + + * ReplyChannelBase.cs, HttpReplyChannel.cs : add some locking. + Patch by Matt Dargavel. + +2010-03-24 Atsushi Enomoto + + * HttpListenerManager.cs : use lock object which is subject to + change. Fix by Matt Dargavel. + +2010-03-24 Atsushi Enomoto + + * HttpListenerManager.cs : remove consumed HttpListenerContext from + the pending queue. Compare "wsdl" request in case insensitive + manner. Patch by Matt Dargavel. + +2010-03-24 Atsushi Enomoto + + * HttpRequestContext.cs : apply the patch by Matt Dargavel, which is + supposed to provide detailed 400 error message. + +2010-03-24 Atsushi Enomoto + + * TransactionFlowBindingElement.cs: revamp the previous change to + not regress regarding service metadata. + +2010-03-24 Atsushi Enomoto + + * ChannelListenerBase.cs, TransactionFlowBindingElement.cs: fix + GetProperty() bug that fails to retrieve properties. (This may + be rewritten later if an ongoing change proposal is to take place.) + +2010-03-18 Atsushi Enomoto + + * ReliableSessionBindingElement.cs, + PrivacyNoticeBindingElement.cs, + RemoteEndpointMessageProperty.cs : added some missing types. + +2010-03-17 Atsushi Enomoto + + * MessageHeaders.cs : + why does it filter out most of the headers? kill it. + +2010-03-17 Atsushi Enomoto + + * SvcHttpHandler.cs, AspNetReplyChannel.cs, HttpChannelListener.cs, + HttpListenerManager.cs : refactoring on acquiring SvcHttpHandler + to not raise "not found" error (see bug #573795). + +2010-03-16 Jb Evain + + * HttpRequestChannel.cs, HttpTransportBindingElement.cs: use + MOONLIGHT symbol to disambiguate MonoTouch and Moonlight code. + 2010-03-09 Atsushi Enomoto * HttpListenerManager.cs : For ASP.NET, use correct GenericIdentity diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChannelListenerBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChannelListenerBase.cs index 1d3042b49ed..a932f68bf34 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChannelListenerBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChannelListenerBase.cs @@ -84,7 +84,7 @@ namespace System.ServiceModel.Channels get { return timeouts.SendTimeout; } } - internal KeyedByTypeCollection Properties { + internal virtual KeyedByTypeCollection Properties { get { if (properties == null) properties = new KeyedByTypeCollection (); diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs index 5d6024b705f..8aa13507d13 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ConnectionOrientedTransportBindingElement.cs @@ -128,5 +128,13 @@ namespace System.ServiceModel.Channels } return false; } + + public override T GetProperty (BindingContext context) + { + // since this class cannot be derived (internal .ctor + // only), we cannot examine what this should do. + // So, handle all properties in the derived types. + return base.GetProperty (context); + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/FaultConverter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/FaultConverter.cs index ef383290328..d77e34153d7 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/FaultConverter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/FaultConverter.cs @@ -62,57 +62,93 @@ namespace System.ServiceModel.Channels { return OnTryCreateFaultMessage (error, out message); } + } - Message CreateSimpleFaultMessage (Exception error, MessageVersion version) + class SimpleFaultConverter : FaultConverter + { + static readonly Dictionary map; + + static SimpleFaultConverter () { - OperationContext ctx = OperationContext.Current; - // FIXME: support more fault code depending on the exception type. - FaultCode fc = null; - if (error is EndpointNotFoundException) - fc = new FaultCode ( - "DestinationUnreachable", - version.Addressing.Namespace); + map = new Dictionary (); + map [typeof (EndpointNotFoundException)] = "DestinationUnreachable"; + map [typeof (ActionNotSupportedException)] = "ActionNotSupported"; + } + + MessageVersion version; + + public SimpleFaultConverter (MessageVersion version) + { + this.version = version; + } + + protected override bool OnTryCreateException ( + Message message, MessageFault fault, out Exception error) + { + if (message == null) + throw new ArgumentNullException ("message"); + if (fault == null) + throw new ArgumentNullException ("fault"); + + error = null; + + FaultCode fc; + if (version.Envelope.Equals (EnvelopeVersion.Soap11)) + fc = fault.Code; else - fc = new FaultCode ( - "FIXME_InternalError", - version.Addressing.Namespace); + fc = fault.Code.SubCode; -#if !NET_2_1 - // FIXME: set correct fault reason. - if (ctx.EndpointDispatcher.ChannelDispatcher.IncludeExceptionDetailInFaults) { - ExceptionDetail detail = new ExceptionDetail (error); - return Message.CreateMessage (version, fc, - "error occured", detail, ctx.IncomingMessageHeaders != null ? ctx.IncomingMessageHeaders.Action : null); + if (fc == null) + return false; + + string msg = fault.Reason.GetMatchingTranslation ().Text; + if (fc.Namespace == message.Version.Addressing.Namespace) { + switch (fc.Name) { + case "ActionNotSupported": + error = new ActionNotSupportedException (msg); + return true; + case "DestinationUnreachable": + error = new EndpointNotFoundException (msg); + return true; + } } -#endif - return Message.CreateMessage (version, fc, "error occured", ctx.IncomingMessageHeaders.Action); + + return false; } - class SimpleFaultConverter : FaultConverter + protected override bool OnTryCreateFaultMessage (Exception error, out Message message) { - MessageVersion version; - public SimpleFaultConverter (MessageVersion version) - { - this.version = version; + if (version.Envelope.Equals (EnvelopeVersion.None)) { + message = null; + return false; } - protected override bool OnTryCreateException ( - Message message, MessageFault fault, out Exception error) - { - error = null; + string action; + if (!map.TryGetValue (error.GetType (), out action)) { + message = null; return false; } - protected override bool OnTryCreateFaultMessage ( - Exception error, out Message message) - { - message = null; - if (OperationContext.Current == null) - return false; + FaultCode fc; + if (version.Envelope.Equals (EnvelopeVersion.Soap12)) + fc = new FaultCode ("Sender", version.Envelope.Namespace, new FaultCode (action, version.Addressing.Namespace)); + else + fc = new FaultCode (action, version.Addressing.Namespace); - message = CreateSimpleFaultMessage (error, version); - return true; + OperationContext ctx = OperationContext.Current; + // FIXME: support more fault code depending on the exception type. +#if !NET_2_1 + // FIXME: set correct fault reason. + if (ctx != null && ctx.EndpointDispatcher.ChannelDispatcher.IncludeExceptionDetailInFaults) { + ExceptionDetail detail = new ExceptionDetail (error); + message = Message.CreateMessage (version, fc, + error.Message, detail, version.Addressing.FaultNamespace); } + else +#endif + message = Message.CreateMessage (version, fc, error.Message, version.Addressing.FaultNamespace); + + return true; } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpChannelListener.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpChannelListener.cs index bb268417eac..988d431c508 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpChannelListener.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpChannelListener.cs @@ -33,6 +33,7 @@ using System.Net; using System.Net.Security; using System.ServiceModel; using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; using System.ServiceModel.Security; using System.Text; @@ -66,7 +67,7 @@ namespace System.ServiceModel.Channels protected override HttpListenerManager CreateListenerManager () { - return new HttpSimpleListenerManager (this, Source, SecurityTokenManager); + return new HttpSimpleListenerManager (this, Source, SecurityTokenManager, ChannelDispatcher); } } @@ -79,10 +80,6 @@ namespace System.ServiceModel.Channels { } - internal SvcHttpHandler HttpHandler { - get { return ((AspNetListenerManager) ListenerManager).Source; } - } - protected override TChannel CreateChannel (TimeSpan timeout) { if (typeof (TChannel) == typeof (IReplyChannel)) @@ -93,7 +90,7 @@ namespace System.ServiceModel.Channels protected override HttpListenerManager CreateListenerManager () { - return new AspNetListenerManager (this, Source, SecurityTokenManager); + return new AspNetListenerManager (this, Source, SecurityTokenManager, ChannelDispatcher); } } @@ -104,10 +101,15 @@ namespace System.ServiceModel.Channels MessageEncoder encoder; HttpListenerManager httpChannelManager; + internal static HttpChannelListenerBaseCurrentHttpChannelListener; + public HttpChannelListenerBase (HttpTransportBindingElement source, BindingContext context) : base (context) { + if (ServiceHostBase.CurrentServiceHostHack != null) + DispatcherBuilder.ChannelDispatcherSetter = delegate (ChannelDispatcher cd) { this.ChannelDispatcher = cd; }; + this.Source = source; // The null Uri check looks weird, but it seems the listener can be built without it. // See HttpTransportBindingElementTest.BuildChannelListenerWithoutListenUri(). @@ -128,6 +130,8 @@ namespace System.ServiceModel.Channels SecurityTokenManager = new ServiceCredentialsSecurityTokenManager ((ServiceCredentials) context.BindingParameters [typeof (ServiceCredentials)]); } + internal ChannelDispatcher ChannelDispatcher { get; set; } + public HttpTransportBindingElement Source { get; private set; } public HttpListenerManager ListenerManager { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpListenerManager.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpListenerManager.cs index 51b1272bef9..927ed06c85e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpListenerManager.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpListenerManager.cs @@ -33,6 +33,7 @@ using System.Collections.Specialized; using System.IdentityModel.Selectors; using System.IdentityModel.Tokens; using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; using System.ServiceModel.Security; using System.Security.Principal; using System.Text; @@ -140,17 +141,19 @@ namespace System.ServiceModel.Channels internal class HttpSimpleListenerManager : HttpListenerManager { - static Dictionary opened_listeners; - HttpListener http_listener; + static Dictionary> http_listeners_table = new Dictionary> (); - static HttpSimpleListenerManager () - { - opened_listeners = new Dictionary (); - } + Dictionary opened_listeners; + HttpListener http_listener; - public HttpSimpleListenerManager (IChannelListener channelListener, HttpTransportBindingElement source, ServiceCredentialsSecurityTokenManager securityTokenManager) - : base (channelListener, source, securityTokenManager) + public HttpSimpleListenerManager (IChannelListener channelListener, HttpTransportBindingElement source, ServiceCredentialsSecurityTokenManager securityTokenManager, ChannelDispatcher dispatcher) + : base (channelListener, source, securityTokenManager, dispatcher) { + object key = dispatcher != null ? dispatcher.Host : new object (); // so that HttpChannelListener without ServiceHost is always assigned a new table. + if (!http_listeners_table.TryGetValue (key, out opened_listeners)) { + opened_listeners = new Dictionary (); + http_listeners_table [key] = opened_listeners; + } } protected override void OnRegister (IChannelListener channelListener, TimeSpan timeout) @@ -209,15 +212,13 @@ namespace System.ServiceModel.Channels { SvcHttpHandler http_handler; - public AspNetListenerManager (IChannelListener channelListener, HttpTransportBindingElement source, ServiceCredentialsSecurityTokenManager securityTokenManager) - : base (channelListener, source, securityTokenManager) + public AspNetListenerManager (IChannelListener channelListener, HttpTransportBindingElement source, ServiceCredentialsSecurityTokenManager securityTokenManager, ChannelDispatcher dispatcher) + : base (channelListener, source, securityTokenManager, dispatcher) { - http_handler = SvcHttpHandlerFactory.GetHandlerForListener (channelListener); + http_handler = SvcHttpHandler.Current; } - public SvcHttpHandler Source { - get { return http_handler; } - } + internal SvcHttpHandler HttpHandler { get { return http_handler; } } protected override void OnRegister (IChannelListener channelListener, TimeSpan timeout) { @@ -253,6 +254,7 @@ namespace System.ServiceModel.Channels public MetadataPublishingInfo MexInfo { get { return mex_info; } } public HttpTransportBindingElement Source { get; private set; } + public ChannelDispatcher Dispatcher { get; private set; } SecurityTokenAuthenticator security_token_authenticator; SecurityTokenResolver security_token_resolver; @@ -262,11 +264,11 @@ namespace System.ServiceModel.Channels registered_channels = new Dictionary> (); } - protected HttpListenerManager (IChannelListener channelListener, HttpTransportBindingElement source, ServiceCredentialsSecurityTokenManager securityTokenManager) + protected HttpListenerManager (IChannelListener channelListener, HttpTransportBindingElement source, ServiceCredentialsSecurityTokenManager securityTokenManager, ChannelDispatcher dispatcher) { + this.Dispatcher = dispatcher; this.channel_listener = channelListener; - // FIXME: this cast should not be required, but current JIT somehow causes an internal error. - mex_info = ((IChannelListener) channelListener).GetProperty (); + mex_info = Dispatcher.Listener.GetProperty (); wsdl_instance = mex_info != null ? mex_info.Instance : null; Source = source; @@ -334,6 +336,7 @@ namespace System.ServiceModel.Channels lock (pending) { foreach (var pctx in pending) { if (FilterHttpContext (pctx)) { + pending.Remove (pctx); callback (pctx); return; } @@ -382,7 +385,7 @@ namespace System.ServiceModel.Channels } } - lock (registered_channels) { + lock (pending) { pending.Add (ctx); // FIXME: this should not be required, but it somehow saves some failures wrt concurrent calls. Thread.Sleep (100); @@ -406,7 +409,7 @@ namespace System.ServiceModel.Channels if (wsdl_instance.WsdlUrl != null && Uri.Compare (ctx.RequestUrl, wsdl_instance.WsdlUrl, cmpflag, fmtflag, StringComparison.Ordinal) == 0) { if (mex_info == null) return false; // Do not handle this at normal dispatcher. - if (ctx.QueryString [null] == "wsdl") + if (String.Compare (ctx.QueryString [null], "wsdl", StringComparison.OrdinalIgnoreCase) == 0) return mex_info.SupportsMex; // wsdl dispatcher should handle this. if (!wsdl_instance.HelpUrl.Equals (wsdl_instance.WsdlUrl)) return true; // in case help URL is not equivalent to WSDL URL, it anyways returns WSDL regardless of ?wsdl existence. diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpReplyChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpReplyChannel.cs index 28a6fc73292..3cf3ec29891 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpReplyChannel.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpReplyChannel.cs @@ -121,11 +121,6 @@ namespace System.ServiceModel.Channels Message msg = null; - // FIXME: our HttpConnection (under HttpListener) - // somehow breaks when the underlying connection is - // reused. Remove it when it gets fixed. - ctx.Response.KeepAlive = false; - if (ctx.Request.HttpMethod == "POST") { if (!Encoder.IsContentTypeSupported (ctx.Request.ContentType)) { ctx.Response.StatusCode = (int) HttpStatusCode.UnsupportedMediaType; @@ -151,16 +146,14 @@ namespace System.ServiceModel.Channels } else if (ctx.Request.HttpMethod == "GET") { msg = Message.CreateMessage (MessageVersion, null); } - msg.Headers.To = ctx.Request.Url; + if (msg.Headers.To == null) + msg.Headers.To = ctx.Request.Url; msg.Properties.Add ("Via", LocalAddress.Uri); msg.Properties.Add (HttpRequestMessageProperty.Name, CreateRequestProperty (ctx.Request.HttpMethod, ctx.Request.Url.Query, ctx.Request.Headers)); /* MessageBuffer buf = msg.CreateBufferedCopy (0x10000); msg = buf.CreateMessage (); -System.Xml.XmlTextWriter w = new System.Xml.XmlTextWriter (Console.Out); -w.Formatting = System.Xml.Formatting.Indented; -buf.CreateMessage ().WriteMessage (w); -w.Close (); +Console.WriteLine (buf.CreateMessage ()); */ context = new HttpRequestContext (this, msg, ctx); reqctx = context; @@ -174,11 +167,10 @@ w.Close (); if (wait != null) throw new InvalidOperationException ("Another wait operation is in progress"); try { - wait = new AutoResetEvent (false); + var wait_ = new AutoResetEvent (false); + wait = wait_; // wait can be set to null if HttpContextAcquired runs to completion before we do WaitOne source.ListenerManager.GetHttpContextAsync (timeout, HttpContextAcquired); - if (wait != null) // in case callback is done before WaitOne() here. - return wait.WaitOne (timeout, false); - return waiting.Count > 0; + return wait_.WaitOne (timeout, false) && waiting.Count > 0; } catch (HttpListenerException e) { // FIXME: does this make sense? I doubt. if ((uint) e.ErrorCode == 0x80004005) // invalid handle. Happens during shutdown. @@ -197,7 +189,8 @@ w.Close (); throw new InvalidOperationException ("WaitForRequest operation has not started"); var sctx = (HttpListenerContextInfo) ctx; if (State == CommunicationState.Opened && ctx != null) - waiting.Add (sctx.Source); + lock (waiting) + waiting.Add (sctx.Source); SignalAsyncWait (); } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs index 8e700f3c0c3..4bae6026237 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestChannel.cs @@ -43,9 +43,6 @@ namespace System.ServiceModel.Channels WebRequest web_request; - // FIXME: supply maxSizeOfHeaders. - int max_headers = 0x10000; - // Constructor public HttpRequestChannel (HttpChannelFactory factory, @@ -55,10 +52,6 @@ namespace System.ServiceModel.Channels this.source = factory; } - public int MaxSizeOfHeaders { - get { return max_headers; } - } - public MessageEncoder Encoder { get { return source.MessageEncoder; } } @@ -93,7 +86,7 @@ namespace System.ServiceModel.Channels ((HttpWebRequest) web_request).CookieContainer = cmgr.CookieContainer; #endif -#if !NET_2_1 || MONOTOUCH // until we support NetworkCredential like SL4 will do. +#if !MOONLIGHT // until we support NetworkCredential like SL4 will do. // client authentication (while SL3 has NetworkCredential class, it is not implemented yet. So, it is non-SL only.) var httpbe = (HttpTransportBindingElement) source.Transport; string authType = null; @@ -153,6 +146,13 @@ namespace System.ServiceModel.Channels } #endif +/* +// FIXME: this causes invalid message security. +var mb = message.CreateBufferedCopy (0x10000); +message = mb.CreateMessage (); +Console.WriteLine (mb.CreateMessage ()); +*/ + if (!suppressEntityBody && String.Compare (web_request.Method, "GET", StringComparison.OrdinalIgnoreCase) != 0) { MemoryStream buffer = new MemoryStream (); Encoder.WriteMessage (message, buffer); @@ -205,7 +205,7 @@ namespace System.ServiceModel.Channels } var hrr = (HttpWebResponse) res; - if ((int) hrr.StatusCode >= 400) { + if ((int) hrr.StatusCode >= 400 && (int) hrr.StatusCode < 500) { channelResult.Complete (new WebException (String.Format ("There was an error on processing web request: Status code {0}({1}): {2}", (int) hrr.StatusCode, hrr.StatusCode, hrr.StatusDescription))); } @@ -223,9 +223,12 @@ namespace System.ServiceModel.Channels } ms.Seek (0, SeekOrigin.Begin); - channelResult.Response = Encoder.ReadMessage ( - //responseStream, MaxSizeOfHeaders); - ms, MaxSizeOfHeaders, res.ContentType); + Message ret = Encoder.ReadMessage ( + ms, (int) source.Transport.MaxReceivedMessageSize, res.ContentType); + var rp = new HttpResponseMessageProperty () { StatusCode = hrr.StatusCode, StatusDescription = hrr.StatusDescription }; + foreach (var key in hrr.Headers.AllKeys) + rp.Headers [key] = hrr.Headers [key]; + ret.Properties.Add (HttpResponseMessageProperty.Name, rp); /* MessageBuffer buf = ret.CreateBufferedCopy (0x10000); ret = buf.CreateMessage (); @@ -234,6 +237,7 @@ w.Formatting = System.Xml.Formatting.Indented; buf.CreateMessage ().WriteMessage (w); w.Close (); */ + channelResult.Response = ret; channelResult.Complete (); } } catch (Exception ex) { @@ -320,16 +324,15 @@ w.Close (); AsyncCallback callback; ManualResetEvent wait; Exception error; + object locker = new object (); + bool is_completed; public HttpChannelRequestAsyncResult (Message message, TimeSpan timeout, AsyncCallback callback, object state) { - CompletedSynchronously = true; Message = message; Timeout = timeout; this.callback = callback; AsyncState = state; - - wait = new ManualResetEvent (false); } public Message Response { @@ -337,7 +340,13 @@ w.Close (); } public WaitHandle AsyncWaitHandle { - get { return wait; } + get { + lock (locker) { + if (wait == null) + wait = new ManualResetEvent (is_completed); + } + return wait; + } } public object AsyncState { @@ -358,7 +367,6 @@ w.Close (); error = error ?? ex; IsCompleted = true; - wait.Set (); if (callback != null) callback (this); } @@ -368,7 +376,14 @@ w.Close (); } public bool IsCompleted { - get; private set; + get { return is_completed; } + set { + is_completed = value; + lock (locker) { + if (is_completed && wait != null) + wait.Set (); + } + } } public void WaitEnd () @@ -377,11 +392,11 @@ w.Close (); // FIXME: Do we need to use the timeout? If so, what happens when the timeout is reached. // Is the current request cancelled and an exception thrown? If so we need to pass the // exception to the Complete () method and allow the result to complete 'normally'. -#if NET_2_1 || MONOTOUCH +#if NET_2_1 // neither Moonlight nor MonoTouch supports contexts (WaitOne default to false) - bool result = wait.WaitOne (Timeout); + bool result = AsyncWaitHandle.WaitOne (Timeout); #else - bool result = wait.WaitOne (Timeout, true); + bool result = AsyncWaitHandle.WaitOne (Timeout, true); #endif if (!result) throw new TimeoutException (); diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestContext.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestContext.cs index 2919454e8be..4f3c424ecf3 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestContext.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpRequestContext.cs @@ -56,18 +56,12 @@ namespace System.ServiceModel.Channels if (msg == null) throw new ArgumentNullException ("msg"); - // Handle DestinationUnreacheable as 400 (it is what .NET does). - if (msg.IsFault) { - // FIXME: isn't there any better way? - var mb = msg.CreateBufferedCopy (0x10000); - var fault = MessageFault.CreateFault (mb.CreateMessage (), 0x10000); - if (fault.Code.Name == "DestinationUnreachable") { - ctx.Response.StatusCode = 400; - return; - } - else - msg = mb.CreateMessage (); - } + // FIXME: probably in WebHttpBinding land, there should + // be some additional code (probably IErrorHandler) that + // treats DestinationUnreachable (and possibly any other) + // errors as HTTP 400 or something appropriate. + // I originally rewrote the HTTP status here, but it + // was wrong. // FIXME: should this be done here? if (channel.MessageVersion.Addressing.Equals (AddressingVersion.None)) @@ -91,6 +85,8 @@ namespace System.ServiceModel.Channels if (hp.SuppressEntityBody) suppressEntityBody = true; } + if (msg.IsFault) + ctx.Response.StatusCode = 500; if (!suppressEntityBody) { ctx.Response.ContentLength64 = ms.Length; ctx.Response.OutputStream.Write (ms.GetBuffer (), 0, (int) ms.Length); diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpTransportBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpTransportBindingElement.cs index 977243d1430..f364d618c5b 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpTransportBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpTransportBindingElement.cs @@ -47,7 +47,7 @@ namespace System.ServiceModel.Channels string realm = String.Empty; TransferMode transfer_mode; IDefaultCommunicationTimeouts timeouts; -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT AuthenticationSchemes auth_scheme = AuthenticationSchemes.Anonymous; AuthenticationSchemes proxy_auth_scheme = @@ -75,13 +75,13 @@ namespace System.ServiceModel.Channels transfer_mode = other.transfer_mode; // FIXME: it does not look safe timeouts = other.timeouts; -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT auth_scheme = other.auth_scheme; proxy_auth_scheme = other.proxy_auth_scheme; #endif } -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT public AuthenticationSchemes AuthenticationScheme { get { return auth_scheme; } set { auth_scheme = value; } @@ -170,6 +170,8 @@ namespace System.ServiceModel.Channels } #if !NET_2_1 + internal static object ListenerBuildLock = new object (); + public override IChannelListener BuildChannelListener ( BindingContext context) { @@ -223,61 +225,63 @@ namespace System.ServiceModel.Channels { throw new NotImplementedException (); } +#endif + } - class HttpBindingProperties : ISecurityCapabilities, IBindingDeliveryCapabilities - { - HttpTransportBindingElement source; +#if !NET_2_1 + class HttpBindingProperties : ISecurityCapabilities, IBindingDeliveryCapabilities + { + HttpTransportBindingElement source; - public HttpBindingProperties (HttpTransportBindingElement source) - { - this.source = source; - } + public HttpBindingProperties (HttpTransportBindingElement source) + { + this.source = source; + } - public bool AssuresOrderedDelivery { - get { return false; } - } + public bool AssuresOrderedDelivery { + get { return false; } + } - public bool QueuedDelivery { - get { return false; } - } + public bool QueuedDelivery { + get { return false; } + } - public ProtectionLevel SupportedRequestProtectionLevel { - get { return ProtectionLevel.None; } - } + public virtual ProtectionLevel SupportedRequestProtectionLevel { + get { return ProtectionLevel.None; } + } - public ProtectionLevel SupportedResponseProtectionLevel { - get { return ProtectionLevel.None; } - } + public virtual ProtectionLevel SupportedResponseProtectionLevel { + get { return ProtectionLevel.None; } + } - public bool SupportsClientAuthentication { - get { return source.AuthenticationScheme != AuthenticationSchemes.Anonymous; } - } + public virtual bool SupportsClientAuthentication { + get { return source.AuthenticationScheme != AuthenticationSchemes.Anonymous; } + } - public bool SupportsServerAuthentication { - get { - switch (source.AuthenticationScheme) { - case AuthenticationSchemes.Negotiate: - return true; - default: - return false; - } + public virtual bool SupportsServerAuthentication { + get { + switch (source.AuthenticationScheme) { + case AuthenticationSchemes.Negotiate: + return true; + default: + return false; } } + } - public bool SupportsClientWindowsIdentity { - get { - switch (source.AuthenticationScheme) { - case AuthenticationSchemes.Basic: - case AuthenticationSchemes.Digest: // hmm... why? but they return true on .NET - case AuthenticationSchemes.Negotiate: - case AuthenticationSchemes.Ntlm: - return true; - default: - return false; - } + public virtual bool SupportsClientWindowsIdentity { + get { + switch (source.AuthenticationScheme) { + case AuthenticationSchemes.Basic: + case AuthenticationSchemes.Digest: // hmm... why? but they return true on .NET + case AuthenticationSchemes.Negotiate: + case AuthenticationSchemes.Ntlm: + return true; + default: + return false; } } } -#endif } +#endif } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpsTransportBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpsTransportBindingElement.cs index 396a4276574..ad0c83047ef 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpsTransportBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpsTransportBindingElement.cs @@ -89,6 +89,47 @@ namespace System.ServiceModel.Channels { throw new NotImplementedException (); } + + // overriden only in full profile + public override T GetProperty (BindingContext context) + { + if (typeof (T) == typeof (ISecurityCapabilities)) + return (T) (object) new HttpsBindingProperties (this); + return base.GetProperty (context); + } #endif } + +#if !NET_2_1 + class HttpsBindingProperties : HttpBindingProperties + { + HttpsTransportBindingElement source; + + public HttpsBindingProperties (HttpsTransportBindingElement source) + : base (source) + { + this.source = source; + } + + public override ProtectionLevel SupportedRequestProtectionLevel { + get { return ProtectionLevel.EncryptAndSign; } + } + + public override ProtectionLevel SupportedResponseProtectionLevel { + get { return ProtectionLevel.EncryptAndSign; } + } + + public override bool SupportsClientAuthentication { + get { return source.RequireClientCertificate || base.SupportsClientAuthentication; } + } + + public override bool SupportsServerAuthentication { + get { return true; } + } + + public override bool SupportsClientWindowsIdentity { + get { return source.RequireClientCertificate || base.SupportsClientWindowsIdentity; } + } + } +#endif } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/Message.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/Message.cs index 963d1f1499d..f31b1d8595c 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/Message.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/Message.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2005-2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2005-2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -212,7 +212,6 @@ namespace System.ServiceModel.Channels { } - [MonoTODO ("use maxBufferSize")] protected virtual MessageBuffer OnCreateBufferedCopy ( int maxBufferSize) { @@ -224,7 +223,7 @@ namespace System.ServiceModel.Channels WriteBodyContents (w); var headers = new MessageHeaders (Headers); var props = new MessageProperties (Properties); - return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (sw.ToString ()), false); + return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (sw.ToString (), maxBufferSize, null), false); } protected virtual string OnGetBodyAttribute ( @@ -300,26 +299,19 @@ namespace System.ServiceModel.Channels #region factory methods - // 1) fault -> 4 - // 2) action -> 5 - // 3) fault, action -> 10 - // 4) version, fault -> 10 - // 5) version, action -> EmptyMessage - // 6) action, body -> 12 - // 7) action, xmlReader -> 8 - // 8) action, reader -> 16 - // 10) version, fault, action -> 20 - // 11) version, action, body -> 14 - // 12) action, body, formatter -> 14 - // 13) version, action, body -> 14 - // 14) version, action, body, formatter -> 20 - // 15) version, action, xmlReader -> 16 - // 16) version, action, reader -> 20 - // 17) xmlReader, maxSizeOfHeaders, version -> 18 - // 18) reader, maxSizeOfHeaders, version -> ForwardingMessage - // 19) action, bodyWriter -> 20 - // 20) version, action, bodyWriter -> SimpleMessage - + // 1) version, code, reason, action -> 3 + // 2) version, code, reason, detail, action -> 3 + // 3) version, fault, action -> SimpleMessage + // 4) version, action, body -> 10 or 5 + // 5) version, action, body, formatter -> 10 or 9 + // 6) version, action, xmlReader -> 7 + // 7) version, action, reader -> 9 + // 8) xmlReader, maxSizeOfHeaders, version -> 11 + // 9) version, action, body -> SimpleMessage + // 10) version, action -> EmptyMessage + // 11) reader, maxSizeOfHeaders, version -> XmlReaderMessage + + // 1) public static Message CreateMessage (MessageVersion version, FaultCode code, string reason, string action) { @@ -327,6 +319,7 @@ namespace System.ServiceModel.Channels return CreateMessage (version, fault, action); } + // 2) public static Message CreateMessage (MessageVersion version, FaultCode code, string reason, object detail, string action) @@ -336,6 +329,7 @@ namespace System.ServiceModel.Channels return CreateMessage (version, fault, action); } + // 3) public static Message CreateMessage (MessageVersion version, MessageFault fault, string action) { @@ -343,6 +337,7 @@ namespace System.ServiceModel.Channels new MessageFaultBodyWriter (fault, version), true); } + // 4) public static Message CreateMessage (MessageVersion version, string action, object body) { @@ -351,6 +346,7 @@ namespace System.ServiceModel.Channels CreateMessage (version, action, body, new DataContractSerializer (body.GetType ())); } + // 5) public static Message CreateMessage (MessageVersion version, string action, object body, XmlObjectSerializer xmlFormatter) { @@ -361,6 +357,7 @@ namespace System.ServiceModel.Channels new XmlObjectSerializerBodyWriter (body, xmlFormatter)); } + // 6) public static Message CreateMessage (MessageVersion version, string action, XmlReader body) { @@ -368,6 +365,7 @@ namespace System.ServiceModel.Channels XmlDictionaryReader.CreateDictionaryReader (body)); } + // 7) public static Message CreateMessage (MessageVersion version, string action, XmlDictionaryReader body) { @@ -375,6 +373,7 @@ namespace System.ServiceModel.Channels new XmlReaderBodyWriter (body)); } + // 8) public static Message CreateMessage (XmlReader envelopeReader, int maxSizeOfHeaders, MessageVersion version) { @@ -386,6 +385,7 @@ namespace System.ServiceModel.Channels // Core implementations of CreateMessage. + // 9) public static Message CreateMessage (MessageVersion version, string action, BodyWriter body) { @@ -396,6 +396,7 @@ namespace System.ServiceModel.Channels return new SimpleMessage (version, action, body, false); } + // 10) public static Message CreateMessage (MessageVersion version, string action) { @@ -404,6 +405,7 @@ namespace System.ServiceModel.Channels return new EmptyMessage (version, action); } + // 11) public static Message CreateMessage ( XmlDictionaryReader envelopeReader, int maxSizeOfHeaders, diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs index 727667df90c..79168b1c564 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageFault.cs @@ -43,7 +43,7 @@ namespace System.ServiceModel.Channels if (message.Version.Envelope == EnvelopeVersion.Soap11) return CreateFault11 (message, maxBufferSize); else // common to None and SOAP12 - return CreateFault (message, maxBufferSize, message.Version.Envelope.Namespace); + return CreateFault12 (message, maxBufferSize); } catch (XmlException ex) { throw new CommunicationException ("Received an invalid SOAP Fault message", ex); } @@ -68,12 +68,7 @@ namespace System.ServiceModel.Channels fr = new FaultReason (r.ReadElementContentAsString()); break; case "detail": - //BUGBUG: Handle children of type other than ExceptionDetail, in order to comply with - // FaultContractAttribute. - r.ReadStartElement (); - r.MoveToContent(); - details = new DataContractSerializer (typeof (ExceptionDetail)).ReadObject (r); - break; + return new XmlReaderDetailMessageFault (message, r, fc, fr, null, null); case "faultactor": default: throw new NotImplementedException (); @@ -90,26 +85,40 @@ namespace System.ServiceModel.Channels return CreateFault (fc, fr, details); } - static MessageFault CreateFault (Message message, int maxBufferSize, string ns) + static MessageFault CreateFault12 (Message message, int maxBufferSize) { FaultCode fc = null; FaultReason fr = null; + string node = null; XmlDictionaryReader r = message.GetReaderAtBodyContents (); - r.ReadStartElement ("Fault", ns); - r.MoveToContent (); + r.ReadStartElement ("Fault", message.Version.Envelope.Namespace); - while (r.NodeType != XmlNodeType.EndElement) { + for (r.MoveToContent (); r.NodeType != XmlNodeType.EndElement; r.MoveToContent ()) { + if (r.NamespaceURI != message.Version.Envelope.Namespace) { + r.Skip (); + continue; + } switch (r.LocalName) { case "Code": - fc = ReadFaultCode (r, ns); + fc = ReadFaultCode12 (r, message.Version.Envelope.Namespace); break; case "Reason": - fr = ReadFaultReason (r, ns); + fr = ReadFaultReason12 (r, message.Version.Envelope.Namespace); + break; + case "Node": + node = r.ReadElementContentAsString (); + break; + case "Role": + r.Skip (); // no corresponding member to store. + break; + case "Detail": + if (!r.IsEmptyElement) + return new XmlReaderDetailMessageFault (message, r, fc, fr, null, node); + r.Read (); break; default: throw new XmlException (String.Format ("Unexpected node {0} name {1}", r.NodeType, r.Name)); } - r.MoveToContent (); } if (fr == null) @@ -117,7 +126,7 @@ namespace System.ServiceModel.Channels r.ReadEndElement (); - return CreateFault (fc, fr); + return CreateFault (fc, fr, null, null, null, node); } static FaultCode ReadFaultCode11 (XmlDictionaryReader r) @@ -142,7 +151,7 @@ namespace System.ServiceModel.Channels return new FaultCode (value.Name, value.Namespace, subcode); } - static FaultCode ReadFaultCode (XmlDictionaryReader r, string ns) + static FaultCode ReadFaultCode12 (XmlDictionaryReader r, string ns) { FaultCode subcode = null; XmlQualifiedName value = XmlQualifiedName.Empty; @@ -155,13 +164,13 @@ namespace System.ServiceModel.Channels while (r.NodeType != XmlNodeType.EndElement) { switch (r.LocalName) { case "Subcode": - subcode = ReadFaultCode (r, ns); + subcode = ReadFaultCode12 (r, ns); break; case "Value": value = (XmlQualifiedName) r.ReadElementContentAs (typeof (XmlQualifiedName), r as IXmlNamespaceResolver, "Value", ns); break; default: - throw new ArgumentException (); + throw new ArgumentException (String.Format ("Unexpected Fault Code subelement: '{0}'", r.LocalName)); } r.MoveToContent (); } @@ -170,7 +179,7 @@ namespace System.ServiceModel.Channels return new FaultCode (value.Name, value.Namespace, subcode); } - static FaultReason ReadFaultReason (XmlDictionaryReader r, string ns) + static FaultReason ReadFaultReason12 (XmlDictionaryReader r, string ns) { List l = new List (); if (r.IsEmptyElement) @@ -185,6 +194,8 @@ namespace System.ServiceModel.Channels throw new XmlException ("xml:lang is mandatory on fault reason Text"); l.Add (new FaultReasonText (r.ReadElementContentAsString ("Text", ns), lang)); } + r.ReadEndElement (); + return new FaultReason (l); } @@ -233,12 +244,40 @@ namespace System.ServiceModel.Channels } // pretty simple implementation class - internal class SimpleMessageFault : MessageFault + internal abstract class BaseMessageFault : MessageFault { - bool has_detail; string actor, node; FaultCode code; FaultReason reason; + + protected BaseMessageFault (FaultCode code, FaultReason reason, string actor, string node) + { + this.code = code; + this.reason = reason; + this.actor = actor; + this.node = node; + } + + public override string Actor { + get { return actor; } + } + + public override FaultCode Code { + get { return code; } + } + + public override string Node { + get { return node; } + } + + public override FaultReason Reason { + get { return reason; } + } + } + + internal class SimpleMessageFault : BaseMessageFault + { + bool has_detail; object detail; XmlObjectSerializer formatter; @@ -255,26 +294,15 @@ namespace System.ServiceModel.Channels FaultReason reason, object detail, XmlObjectSerializer formatter, string actor, string node) + : base (code, reason, actor, node) { if (code == null) throw new ArgumentNullException ("code"); if (reason == null) throw new ArgumentNullException ("reason"); - this.code = code; - this.reason = reason; this.detail = detail; this.formatter = formatter; - this.actor = actor; - this.node = node; - } - - public override string Actor { - get { return actor; } - } - - public override FaultCode Code { - get { return code; } } public override bool HasDetail { @@ -283,27 +311,58 @@ namespace System.ServiceModel.Channels get { return has_detail; } } - public override string Node { - get { return node; } + protected override void OnWriteDetailContents (XmlDictionaryWriter writer) + { + if (formatter == null && detail != null) + formatter = new DataContractSerializer (detail.GetType ()); + if (formatter != null) + formatter.WriteObject (writer, detail); + else + throw new InvalidOperationException ("There is no fault detail to write"); } - public override FaultReason Reason { - get { return reason; } + public object Detail { + get { return detail; } } + } - protected override XmlDictionaryReader OnGetReaderAtDetailContents () + class XmlReaderDetailMessageFault : BaseMessageFault + { + XmlDictionaryReader reader; + bool consumed; + + public XmlReaderDetailMessageFault (Message message, XmlDictionaryReader reader, FaultCode code, FaultReason reason, string actor, string node) + : base (code, reason, actor, node) { - // FIXME: use XmlObjectSerializer - return base.OnGetReaderAtDetailContents (); + this.reader = reader; } - protected override void OnWriteDetailContents (XmlDictionaryWriter writer) + void Consume () { - formatter.WriteObject (writer, detail); + if (consumed) + throw new InvalidOperationException ("The fault detail content is already consumed"); + consumed = true; + reader.ReadStartElement (); // consume the wrapper + reader.MoveToContent (); } - public object Detail { - get { return detail; } + public override bool HasDetail { + get { return true; } + } + + protected override XmlDictionaryReader OnGetReaderAtDetailContents () + { + Consume (); + return reader; + } + + protected override void OnWriteDetailContents (XmlDictionaryWriter writer) + { + if (!HasDetail) + throw new InvalidOperationException ("There is no fault detail to write"); + Consume (); + while (reader.NodeType != XmlNodeType.EndElement) + writer.WriteNode (reader, false); } } @@ -351,7 +410,7 @@ namespace System.ServiceModel.Channels EnvelopeVersion version) { writer.WriteStartElement ("Fault", version.Namespace); - WriteFaultCode (writer, version, Code); + WriteFaultCode (writer, version, Code, false); WriteReason (writer, version); if (HasDetail) OnWriteDetail (writer, version); @@ -359,23 +418,23 @@ namespace System.ServiceModel.Channels } private void WriteFaultCode (XmlDictionaryWriter writer, - EnvelopeVersion version, FaultCode code) + EnvelopeVersion version, FaultCode code, bool sub) { if (version == EnvelopeVersion.Soap11) { - writer.WriteStartElement ("", "faultcode", version.Namespace); - if (code.Namespace.Length > 0) + writer.WriteStartElement ("", "faultcode", String.Empty); + if (code.Namespace.Length > 0 && String.IsNullOrEmpty (writer.LookupPrefix (code.Namespace))) writer.WriteXmlnsAttribute ("a", code.Namespace); writer.WriteQualifiedName (code.Name, code.Namespace); writer.WriteEndElement (); } else { // Soap12 - writer.WriteStartElement ("Code", version.Namespace); + writer.WriteStartElement (sub ? "Subcode" : "Code", version.Namespace); writer.WriteStartElement ("Value", version.Namespace); - if (code.Namespace.Length > 0) + if (code.Namespace.Length > 0 && String.IsNullOrEmpty (writer.LookupPrefix (code.Namespace))) writer.WriteXmlnsAttribute ("a", code.Namespace); writer.WriteQualifiedName (code.Name, code.Namespace); - if (code.SubCode != null) - WriteFaultCode (writer, version, code.SubCode); writer.WriteEndElement (); + if (code.SubCode != null) + WriteFaultCode (writer, version, code.SubCode, true); writer.WriteEndElement (); } } @@ -385,7 +444,7 @@ namespace System.ServiceModel.Channels { if (version == EnvelopeVersion.Soap11) { foreach (FaultReasonText t in Reason.Translations) { - writer.WriteStartElement ("", "faultstring", version.Namespace); + writer.WriteStartElement ("", "faultstring", String.Empty); if (t.XmlLang != null) writer.WriteAttributeString ("xml", "lang", null, t.XmlLang); writer.WriteString (t.Text); @@ -412,6 +471,8 @@ namespace System.ServiceModel.Channels protected virtual XmlDictionaryReader OnGetReaderAtDetailContents () { + if (!HasDetail) + throw new InvalidOperationException ("There is no fault detail to read"); MemoryStream ms = new MemoryStream (); using (XmlDictionaryWriter dw = XmlDictionaryWriter.CreateDictionaryWriter ( diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeaders.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeaders.cs index 8b9016b622a..90e88911250 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeaders.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageHeaders.cs @@ -267,15 +267,6 @@ namespace System.ServiceModel.Channels { if (version.Envelope == EnvelopeVersion.None) return; - - // For AddressingVersion.None, don't output the item. - // - // FIXME: It should even ignore Action, but for now - // service dispatcher won't work without it. - if (version.Addressing == AddressingVersion.None && - l [index].Name != "Action") - return; - WriteStartHeader (index, writer); WriteHeaderContents (index, writer); writer.WriteEndElement (); @@ -349,10 +340,14 @@ namespace System.ServiceModel.Channels public EndpointAddress FaultTo { get { - int idx = FindHeader ("FaultTo", Constants.WsaNamespace); + int idx = FindHeader ("FaultTo", version.Addressing.Namespace); return idx < 0 ? null : GetHeader (idx); } - set { AddEndpointAddressHeader ("FaultTo", Constants.WsaNamespace, value); } + set { + RemoveAll ("FaultTo", version.Addressing.Namespace); + if (value != null) + AddEndpointAddressHeader ("FaultTo", version.Addressing.Namespace, value); + } } public EndpointAddress From { @@ -360,7 +355,11 @@ namespace System.ServiceModel.Channels int idx = FindHeader ("From", version.Addressing.Namespace); return idx < 0 ? null : GetHeader (idx); } - set { AddEndpointAddressHeader ("From", Constants.WsaNamespace, value); } + set { + RemoveAll ("From", version.Addressing.Namespace); + if (value != null) + AddEndpointAddressHeader ("From", version.Addressing.Namespace, value); + } } public MessageHeaderInfo this [int index] { @@ -369,16 +368,16 @@ namespace System.ServiceModel.Channels public UniqueId MessageId { get { - int idx = FindHeader ("MessageID", Constants.WsaNamespace); + int idx = FindHeader ("MessageID", version.Addressing.Namespace); return idx < 0 ? null : new UniqueId (GetHeader (idx)); } set { if (version.Addressing == AddressingVersion.None && value != null) throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None"); - RemoveAll ("MessageID", Constants.WsaNamespace); + RemoveAll ("MessageID", version.Addressing.Namespace); if (value != null) - Add (MessageHeader.CreateHeader ("MessageID", Constants.WsaNamespace, value)); + Add (MessageHeader.CreateHeader ("MessageID", version.Addressing.Namespace, value)); } } @@ -386,26 +385,30 @@ namespace System.ServiceModel.Channels public UniqueId RelatesTo { get { - int idx = FindHeader ("RelatesTo", Constants.WsaNamespace); + int idx = FindHeader ("RelatesTo", version.Addressing.Namespace); return idx < 0 ? null : new UniqueId (GetHeader (idx)); } set { if (version.Addressing == AddressingVersion.None && value != null) throw new InvalidOperationException ("WS-Addressing header is not allowed for AddressingVersion.None"); - RemoveAll ("MessageID", Constants.WsaNamespace); + RemoveAll ("MessageID", version.Addressing.Namespace); if (value != null) - Add (MessageHeader.CreateHeader ("RelatesTo", Constants.WsaNamespace, value)); + Add (MessageHeader.CreateHeader ("RelatesTo", version.Addressing.Namespace, value)); } } public EndpointAddress ReplyTo { get { - int idx = FindHeader ("ReplyTo", Constants.WsaNamespace); + int idx = FindHeader ("ReplyTo", version.Addressing.Namespace); return idx < 0 ? null : GetHeader (idx); } - set { AddEndpointAddressHeader ("ReplyTo", Constants.WsaNamespace, value); } + set { + RemoveAll ("ReplyTo", version.Addressing.Namespace); + if (value != null) + AddEndpointAddressHeader ("ReplyTo", version.Addressing.Namespace, value); + } } public Uri To { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageImpl.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageImpl.cs index b3ca10f3491..b4c341d0297 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageImpl.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/MessageImpl.cs @@ -60,16 +60,14 @@ namespace System.ServiceModel.Channels public override bool IsEmpty { get { - if (!body_started) - ReadBodyStart (); + ReadBodyStart (); return is_empty; } } public override bool IsFault { get { - if (!body_started) - ReadBodyStart (); + ReadBodyStart (); return is_fault; } } @@ -82,6 +80,15 @@ namespace System.ServiceModel.Channels get { return version; } } + protected override MessageBuffer OnCreateBufferedCopy ( + int maxBufferSize) + { + ReadBodyStart (); + var headers = new MessageHeaders (Headers); + var props = new MessageProperties (Properties); + return new DefaultMessageBuffer (maxBufferSize, headers, props, new XmlReaderBodyWriter (reader), IsFault); + } + protected override string OnGetBodyAttribute ( string localName, string ns) { @@ -96,8 +103,7 @@ namespace System.ServiceModel.Channels return reader; // silly, but that's what our test expects. if (body_consumed) throw new InvalidOperationException ("The message body XmlReader is already consumed."); - if (!body_started) - ReadBodyStart (); + ReadBodyStart (); if (is_empty) throw new InvalidOperationException ("The message body is empty."); body_consumed = true; @@ -156,6 +162,9 @@ namespace System.ServiceModel.Channels void ReadBodyStart () { + if (body_started) + return; + // read headers in advance. if (headers == null) ReadHeaders (); @@ -261,7 +270,7 @@ namespace System.ServiceModel.Channels { var headers = new MessageHeaders (Headers); var props = new MessageProperties (Properties); - return new DefaultMessageBuffer (maxBufferSize, headers, props, body.CreateBufferedCopy (maxBufferSize), false); + return new DefaultMessageBuffer (maxBufferSize, headers, props, body.CreateBufferedCopy (maxBufferSize), IsFault); } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/PrivacyNoticeBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/PrivacyNoticeBindingElement.cs new file mode 100644 index 00000000000..d1e1e5bd331 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/PrivacyNoticeBindingElement.cs @@ -0,0 +1,67 @@ +// +// PrivacyNoticeBindingElement.cs +// +// Author: Atsushi Enomoto (atsushi@ximian.com) +// +// Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.ServiceModel; +using System.ServiceModel.Description; + +namespace System.ServiceModel.Channels +{ + public sealed class PrivacyNoticeBindingElement : BindingElement, IPolicyExportExtension + { + public PrivacyNoticeBindingElement () + { + // FIXME: apply configuration + } + + public PrivacyNoticeBindingElement (PrivacyNoticeBindingElement elementToBeCloned) + { + var e = elementToBeCloned; + Url = e.Url; + Version = e.Version; + } + + [MonoTODO] + public Uri Url { get; set; } + [MonoTODO] + public int Version { get; set; } + + public override BindingElement Clone () + { + return new PrivacyNoticeBindingElement (this); + } + + public override T GetProperty (BindingContext context) + { + return context.GetInnerProperty (); + } + + void IPolicyExportExtension.ExportPolicy (MetadataExporter exporter, PolicyConversionContext context) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReliableSessionBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReliableSessionBindingElement.cs new file mode 100644 index 00000000000..2a45cbdd547 --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReliableSessionBindingElement.cs @@ -0,0 +1,102 @@ +// +// ReliableSessionBindingElement.cs +// +// Author: Atsushi Enomoto (atsushi@ximian.com) +// +// Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.ServiceModel; +using System.ServiceModel.Description; + +namespace System.ServiceModel.Channels +{ + public sealed class ReliableSessionBindingElement : BindingElement, IPolicyExportExtension + { + public ReliableSessionBindingElement () + { + // FIXME: apply configuration + } + + public ReliableSessionBindingElement (bool ordered) + : this () + { + Ordered = ordered; + } + + [MonoTODO] + public TimeSpan AcknowledgementInterval { get; set; } + [MonoTODO] + public bool FlowControlEnabled { get; set; } + [MonoTODO] + public TimeSpan InactivityTimeout { get; set; } + [MonoTODO] + public int MaxPendingChannels { get; set; } + [MonoTODO] + public int MaxRetryCount { get; set; } + [MonoTODO] + public int MaxTransferWindowSize { get; set; } + [MonoTODO] + public bool Ordered { get; set; } + [MonoTODO] + public ReliableMessagingVersion ReliableMessagingVersion { get; set; } + + [MonoTODO] + public override IChannelFactory BuildChannelFactory (BindingContext context) + { + throw new NotImplementedException (); + } + + [MonoTODO] + public override IChannelListener BuildChannelListener (BindingContext context) + { + throw new NotImplementedException (); + } + + [MonoTODO] + public override bool CanBuildChannelFactory (BindingContext context) + { + throw new NotImplementedException (); + } + + [MonoTODO] + public override bool CanBuildChannelListener (BindingContext context) + { + throw new NotImplementedException (); + } + + public override BindingElement Clone () + { + return (ReliableSessionBindingElement) MemberwiseClone (); + } + + public override T GetProperty (BindingContext context) + { + throw new NotImplementedException (); + } + + void IPolicyExportExtension.ExportPolicy (MetadataExporter exporter, PolicyConversionContext context) + { + throw new NotImplementedException (); + } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/RemoteEndpointMessageProperty.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/RemoteEndpointMessageProperty.cs new file mode 100644 index 00000000000..df95178641a --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/RemoteEndpointMessageProperty.cs @@ -0,0 +1,48 @@ +// +// RemoteEndpointMessageProperty.cs +// +// Author: Atsushi Enomoto (atsushi@ximian.com) +// +// Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.ServiceModel; +using System.ServiceModel.Description; + +namespace System.ServiceModel.Channels +{ + public sealed class RemoteEndpointMessageProperty + { + public static string Name { + get { return "System.ServiceModel.Channels.RemoteEndpointMessageProperty"; } + } + + public RemoteEndpointMessageProperty (string address, int port) + { + Address = address; + Port = port; + } + + public string Address { get; private set; } + public int Port { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReplyChannelBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReplyChannelBase.cs index 580545f703f..9bef1913b1a 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReplyChannelBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/ReplyChannelBase.cs @@ -106,6 +106,7 @@ namespace System.ServiceModel.Channels delegate bool TryReceiveDelegate (TimeSpan timeout, out RequestContext context); TryReceiveDelegate try_recv_delegate; + object async_result_lock = new object (); protected Thread CurrentAsyncThread { get; private set; } protected IAsyncResult CurrentAsyncResult { get; private set; } @@ -115,18 +116,26 @@ namespace System.ServiceModel.Channels throw new InvalidOperationException ("Another async TryReceiveRequest operation is in progress"); if (try_recv_delegate == null) try_recv_delegate = new TryReceiveDelegate (delegate (TimeSpan tout, out RequestContext ctx) { - if (CurrentAsyncResult != null) - CurrentAsyncThread = Thread.CurrentThread; + lock (async_result_lock) { + if (CurrentAsyncResult != null) + CurrentAsyncThread = Thread.CurrentThread; + } try { return TryReceiveRequest (tout, out ctx); } finally { - CurrentAsyncResult = null; - CurrentAsyncThread = null; + lock (async_result_lock) { + CurrentAsyncResult = null; + CurrentAsyncThread = null; + } } }); RequestContext dummy; - CurrentAsyncResult = try_recv_delegate.BeginInvoke (timeout, out dummy, callback, state); - return CurrentAsyncResult; + IAsyncResult result; + lock (async_result_lock) { + result = CurrentAsyncResult = try_recv_delegate.BeginInvoke (timeout, out dummy, callback, state); + } + // Note that at this point CurrentAsyncResult can be null here if delegate has run to completion + return result; } public virtual bool EndTryReceiveRequest (IAsyncResult result) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs index 23e6043de2a..487f0f0c8df 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SecureMessageGenerator.cs @@ -278,10 +278,10 @@ if (!ShouldOutputEncryptedKey) // FIXME: get correct ReplyTo value if (Direction == MessageDirection.Input) - msg.Headers.Add (MessageHeader.CreateHeader ("ReplyTo", msg.Version.Addressing.Namespace, EndpointAddress10.FromEndpointAddress (new EndpointAddress (Constants.WsaAnonymousUri)))); + msg.Headers.ReplyTo = new EndpointAddress (Constants.WsaAnonymousUri); if (MessageTo != null) - msg.Headers.Add (MessageHeader.CreateHeader ("To", msg.Version.Addressing.Namespace, MessageTo.Uri.AbsoluteUri, true)); + msg.Headers.To = MessageTo.Uri; // wss:Security WSSecurityMessageHeader header = diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SvcHttpHandler.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SvcHttpHandler.cs index 413650ba3eb..161b3f476b4 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SvcHttpHandler.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/SvcHttpHandler.cs @@ -63,6 +63,8 @@ namespace System.ServiceModel.Channels { internal class SvcHttpHandler : IHttpHandler { + internal static SvcHttpHandler Current; + static object type_lock = new object (); Type type; @@ -135,7 +137,9 @@ namespace System.ServiceModel.Channels { if (best == null) best = l; } - return best; + if (best != null) + return best; + throw new InvalidOperationException (String.Format ("The argument HTTP context did not match any of the registered listener manager (could be mismatch in URL, method etc.) {0}", ctx.Request.Url)); /* var actx = new AspNetHttpContextInfo (ctx); foreach (var i in listeners) @@ -194,7 +198,17 @@ namespace System.ServiceModel.Channels { void EnsureServiceHost () { lock (type_lock) { + Current = this; + try { + EnsureServiceHostCore (); + } finally { + Current = null; + } + } + } + void EnsureServiceHostCore () + { if (host != null) return; @@ -211,8 +225,6 @@ namespace System.ServiceModel.Channels { // Not precise, but it needs some wait time to have all channels start requesting. And it is somehow required. Thread.Sleep (500); - - } } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs index 07a9d8ff3f7..4549bdb43d5 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TcpTransportBindingElement.cs @@ -35,7 +35,6 @@ using System.ServiceModel.Description; namespace System.ServiceModel.Channels { - [MonoTODO] public class TcpTransportBindingElement : ConnectionOrientedTransportBindingElement { @@ -83,7 +82,6 @@ namespace System.ServiceModel.Channels set { teredo_enabled = value; } } - [MonoTODO] public override IChannelFactory BuildChannelFactory ( BindingContext context) { @@ -106,11 +104,29 @@ namespace System.ServiceModel.Channels return new TcpTransportBindingElement (this); } - [MonoTODO] public override T GetProperty (BindingContext context) { - // FIXME: ... or return ISecurityCapabilities? - return context.GetInnerProperty (); + if (typeof (T) == typeof (IBindingDeliveryCapabilities)) + return (T) (object) new TcpBindingProperties (this); + return base.GetProperty (context); + } + } + + class TcpBindingProperties : IBindingDeliveryCapabilities + { + TcpTransportBindingElement source; + + public TcpBindingProperties (TcpTransportBindingElement source) + { + this.source = source; + } + + public bool AssuresOrderedDelivery { + get { return true; } + } + + public bool QueuedDelivery { + get { return false; } } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransactionFlowBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransactionFlowBindingElement.cs index 9324471fa94..d753c885f3e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransactionFlowBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransactionFlowBindingElement.cs @@ -161,6 +161,11 @@ namespace System.ServiceModel.Channels this.protocol = protocol; } + public override T GetProperty () + { + return inner_listener.GetProperty () ?? base.GetProperty (); + } + public override Uri Uri { get { return inner_listener.Uri; } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WSSecurityMessageHeader.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WSSecurityMessageHeader.cs index fc02db81f6b..b99bf133702 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WSSecurityMessageHeader.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/WSSecurityMessageHeader.cs @@ -408,6 +408,8 @@ doc.PreserveWhitespace = true; protected override void OnWriteHeaderContents (XmlDictionaryWriter writer, MessageVersion version) { + // FIXME: it should use XmlDictionaryWriter that CanCanonicalize the output (which is not possible in any built-in writer types, so we'll have to hack it). + foreach (object obj in Contents) { if (obj is WsuTimestamp) { WsuTimestamp ts = (WsuTimestamp) obj; diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/XmlReaderBodyWriter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/XmlReaderBodyWriter.cs index b2220d1b485..1cca9653e1c 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/XmlReaderBodyWriter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Channels/XmlReaderBodyWriter.cs @@ -36,12 +36,22 @@ namespace System.ServiceModel.Channels internal class XmlReaderBodyWriter : BodyWriter { XmlDictionaryReader reader; - string xml; + string xml_bak; + XmlParserContext parser_context; + bool consumed; - public XmlReaderBodyWriter (string xml) + public XmlReaderBodyWriter (string xml, int maxBufferSize, XmlParserContext ctx) : base (true) { - this.xml = xml; + var settings = new XmlReaderSettings () { + // FIXME: enable this line (once MaxCharactersInDocument is implemented) + // MaxCharactersInDocument = maxBufferSize, + ConformanceLevel = ConformanceLevel.Fragment + }; + reader = XmlDictionaryReader.CreateDictionaryReader (XmlReader.Create (new StringReader (xml), settings, ctx)); + reader.MoveToContent (); + xml_bak = xml; + parser_context = ctx; } public XmlReaderBodyWriter (XmlDictionaryReader reader) @@ -54,21 +64,60 @@ namespace System.ServiceModel.Channels protected override BodyWriter OnCreateBufferedCopy ( int maxBufferSize) { - if (xml == null) { - xml = reader.ReadOuterXml (); +#if true + if (xml_bak == null) { + if (consumed) + throw new InvalidOperationException ("Body xml reader is already consumed"); + var sw = new StringWriter (); + var xw = XmlDictionaryWriter.CreateDictionaryWriter (XmlWriter.Create (sw)); + xw.WriteStartElement (reader.Prefix, reader.LocalName, reader.NamespaceURI); + xw.WriteAttributes (reader, false); + + var nsmgr = new XmlNamespaceManager (reader.NameTable); + var inr = reader as IXmlNamespaceResolver; + if (inr != null) + foreach (var p in inr.GetNamespacesInScope (XmlNamespaceScope.ExcludeXml)) + if (xw.LookupPrefix (p.Value) != p.Key) + xw.WriteXmlnsAttribute (p.Key, p.Value); + if (!reader.IsEmptyElement) { + reader.Read (); + while (reader.NodeType != XmlNodeType.EndElement) + xw.WriteNode (reader, false); + } + xw.WriteEndElement (); + + xw.Close (); + xml_bak = sw.ToString (); reader = null; } - return new XmlReaderBodyWriter (xml); +#else // FIXME: this should be better, but somehow doesn't work. + if (xml_bak == null) { + if (consumed) + throw new InvalidOperationException ("Body xml reader is already consumed"); + var nss = new XmlNamespaceManager (reader.NameTable); + var nsr = reader as IXmlNamespaceResolver; + if (nsr != null) + foreach (var p in nsr.GetNamespacesInScope (XmlNamespaceScope.ExcludeXml)) + nss.AddNamespace (p.Key, p.Value); + parser_context = new XmlParserContext (nss.NameTable, nss, reader.XmlLang, reader.XmlSpace); + xml_bak = reader.ReadOuterXml (); + } +#endif + return new XmlReaderBodyWriter (xml_bak, maxBufferSize, parser_context); } protected override void OnWriteBodyContents ( XmlDictionaryWriter writer) { - if (reader == null && String.IsNullOrEmpty (xml)) + if (consumed) + throw new InvalidOperationException ("Body xml reader is already consumed"); + if (reader == null && String.IsNullOrEmpty (xml_bak)) return; - XmlReader r = reader ?? XmlReader.Create (new StringReader (xml)); + XmlReader r = xml_bak != null ? XmlReader.Create (new StringReader (xml_bak), null, parser_context) : reader; r.MoveToContent (); writer.WriteNode (r, false); + if (xml_bak == null) + consumed = true; } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressElementCollection.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressElementCollection.cs index af37d8e4f92..e2ed5603217 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressElementCollection.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressElementCollection.cs @@ -65,6 +65,15 @@ namespace System.ServiceModel.Configuration protected override object GetElementKey (ConfigurationElement element) { return ((BaseAddressElement) element).BaseAddress; } + + protected override ConfigurationElement CreateNewElement () + { + return new BaseAddressElement (); + } + + protected override bool ThrowOnDuplicate { + get { return false; } + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressPrefixFilterElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressPrefixFilterElement.cs new file mode 100644 index 00000000000..5bf6098f09f --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressPrefixFilterElement.cs @@ -0,0 +1,102 @@ +// +// BaseAddressPrefixFilterElement.cs +// +// Author: +// Atsushi Enomoto +// +// Copyright (C) 2010 Novell, Inc. http://www.novell.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Configuration; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.IdentityModel.Claims; +using System.IdentityModel.Policy; +using System.IdentityModel.Tokens; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Diagnostics; +using System.ServiceModel.Dispatcher; +using System.ServiceModel.MsmqIntegration; +using System.ServiceModel.PeerResolvers; +using System.ServiceModel.Security; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.ServiceModel.Configuration +{ + public sealed class BaseAddressPrefixFilterElement + : ConfigurationElement + { + // Static Fields + static ConfigurationPropertyCollection properties; + static ConfigurationProperty prefix; + + static BaseAddressPrefixFilterElement () + { + properties = new ConfigurationPropertyCollection (); + prefix = new ConfigurationProperty ("prefix", + typeof (Uri), null, new UriTypeConverter (), new StringValidator (1, int.MaxValue, null), + ConfigurationPropertyOptions.IsRequired| ConfigurationPropertyOptions.IsKey); + + properties.Add (prefix); + } + + public BaseAddressPrefixFilterElement () + { + } + + public BaseAddressPrefixFilterElement (Uri prefix) + { + Prefix = prefix; + } + + + // Properties + + [ConfigurationProperty ("prefix", + Options = ConfigurationPropertyOptions.IsRequired | ConfigurationPropertyOptions.IsKey, + IsRequired = true, + IsKey = true)] + public Uri Prefix { + get { return (Uri) base [prefix]; } + set { base [prefix] = value; } + } + + protected override ConfigurationPropertyCollection Properties { + get { return properties; } + } + + + } + +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressPrefixFilterElementCollection.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressPrefixFilterElementCollection.cs new file mode 100644 index 00000000000..06d293dbe4c --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BaseAddressPrefixFilterElementCollection.cs @@ -0,0 +1,79 @@ +// +// BaseAddressPrefixFilterElementCollection.cs +// +// Author: +// Atsushi Enomoto +// +// Copyright (C) 2010 Novell, Inc. http://www.novell.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Configuration; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Security.Principal; +using System.IdentityModel.Claims; +using System.IdentityModel.Policy; +using System.IdentityModel.Tokens; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Diagnostics; +using System.ServiceModel.Dispatcher; +using System.ServiceModel.MsmqIntegration; +using System.ServiceModel.PeerResolvers; +using System.ServiceModel.Security; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.ServiceModel.Configuration +{ + [ConfigurationCollection (typeof (BaseAddressPrefixFilterElement), + AddItemName = "add", + RemoveItemName = "remove", + ClearItemsName = "clear", + CollectionType = ConfigurationElementCollectionType.BasicMap)] + public sealed class BaseAddressPrefixFilterElementCollection + : ServiceModelConfigurationElementCollection, ICollection, IEnumerable + { + protected override object GetElementKey (ConfigurationElement element) { + return ((BaseAddressPrefixFilterElement) element).Prefix; + } + + protected override ConfigurationElement CreateNewElement () + { + return new BaseAddressPrefixFilterElement (); + } + + protected override bool ThrowOnDuplicate { + get { return false; } + } + } + +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs index 7db15e6c54c..fe1c268edb5 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BasicHttpBindingElement.cs @@ -224,6 +224,29 @@ namespace System.ServiceModel.Configuration basicHttpBinding.TransferMode = TransferMode; basicHttpBinding.UseDefaultWebProxy = UseDefaultWebProxy; } + + protected internal override void InitializeFrom (Binding binding) + { + BasicHttpBinding b = (BasicHttpBinding) binding; + + base.InitializeFrom (binding); + AllowCookies = b.AllowCookies; + BypassProxyOnLocal = b.BypassProxyOnLocal; + HostNameComparisonMode = b.HostNameComparisonMode; + MaxBufferPoolSize = b.MaxBufferPoolSize; + MaxBufferSize = b.MaxBufferSize; + MaxReceivedMessageSize = b.MaxReceivedMessageSize; + MessageEncoding = b.MessageEncoding; + ProxyAddress = b.ProxyAddress; + + ReaderQuotas.ApplyConfiguration (b.ReaderQuotas); + + Security.Mode = b.Security.Mode; + Security.Transport.ApplyConfiguration (b.Security.Transport); + TextEncoding = b.TextEncoding; + TransferMode = b.TransferMode; + UseDefaultWebProxy = b.UseDefaultWebProxy; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BinaryMessageEncodingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BinaryMessageEncodingElement.cs index ddfecf26304..a83fffc8b2e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BinaryMessageEncodingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BinaryMessageEncodingElement.cs @@ -106,11 +106,40 @@ namespace System.ServiceModel.Configuration get { return (XmlDictionaryReaderQuotasElement) base ["readerQuotas"]; } } - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + protected internal override BindingElement CreateBindingElement () + { + return new BinaryMessageEncodingBindingElement (); } + public override void ApplyConfiguration (BindingElement element) + { + var b = (BinaryMessageEncodingBindingElement) element; + b.MaxReadPoolSize = MaxReadPoolSize; + b.MaxSessionSize = MaxSessionSize; + b.MaxWritePoolSize = MaxWritePoolSize; + + ReaderQuotas.ApplyConfiguration (b.ReaderQuotas); + } + + public override void CopyFrom (ServiceModelExtensionElement element) + { + var b = (BinaryMessageEncodingElement) element; + MaxReadPoolSize = b.MaxReadPoolSize; + MaxSessionSize = b.MaxSessionSize; + MaxWritePoolSize = b.MaxWritePoolSize; + + ReaderQuotas.CopyFrom (b.ReaderQuotas); + } + + protected internal override void InitializeFrom (BindingElement element) + { + var b = (BinaryMessageEncodingBindingElement) element; + MaxReadPoolSize = b.MaxReadPoolSize; + MaxSessionSize = b.MaxSessionSize; + MaxWritePoolSize = b.MaxWritePoolSize; + + ReaderQuotas.InitializeFrom (b.ReaderQuotas); + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingElementExtensionElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingElementExtensionElement.cs index 6f2e4a7a2c7..a5708f2b921 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingElementExtensionElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/BindingElementExtensionElement.cs @@ -63,16 +63,12 @@ namespace System.ServiceModel.Configuration // Properties public abstract Type BindingElementType { get; } - [MonoTODO] public virtual void ApplyConfiguration (BindingElement bindingElement) { - throw new NotImplementedException (); } protected internal abstract BindingElement CreateBindingElement (); - [MonoTODO] protected internal virtual void InitializeFrom (BindingElement bindingElement) { - throw new NotImplementedException (); } internal override string GetConfigurationElementName () { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ChangeLog index 756dae16d18..39440be8b65 100755 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ChangeLog +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ChangeLog @@ -1,3 +1,59 @@ +2010-04-05 Atsushi Enomoto + + * BaseAddressPrefixFilterElementCollection.cs + BaseAddressPrefixFilterElement.cs : new classes. + * ReliableSessionElement.cs + XmlDictionaryReaderQuotasElement.cs + TextMessageEncodingElement.cs + HostTimeoutsElement.cs + BaseAddressElementCollection.cs + BasicHttpBindingElement.cs + BindingElementExtensionElement.cs + StandardBindingElement.cs + BinaryMessageEncodingElement.cs : added couple of missing stuff. + +2010-03-23 Atsushi Enomoto + + * ConnectionOrientedTransportElement.cs, StandardBindingElement.cs, + LocalClientSecuritySettingsElement.cs, CustomBindingElement.cs: + add couple of missing methods and TypeConverterAttributes. + +2010-03-17 Atsushi Enomoto + + * ServiceMetadataPublishingElement.cs : use IsNullOrEmpty(), names + could be "" which is equivalent to null here. + +2010-03-17 Atsushi Enomoto + + * ConfigUtil.cs, StandardBindingCollectionElement.cs, + MexHttpsBindingCollectionElement.cs, + MexHttpBindingCollectionElement.cs : use GetDefault() in + BindingCollectionElement to create a Binding, instead of activator + immediately. And for mex bindings, use MetadataExchangeBindings. + +2010-03-16 Atsushi Enomoto + + * TcpTransportElement.cs + MsmqIntegrationElement.cs + MsmqElementBase.cs + NamedPipeTransportElement.cs + HttpsTransportElement.cs + TransportElement.cs + MsmqTransportElement.cs + HttpTransportElement.cs : implement missing methods. + +2010-03-16 Atsushi Enomoto + + * IssuedTokenClientElement.cs, MsmqBindingElementBase.cs, + NamedPipeConnectionPoolSettingsElement.cs, + TcpConnectionPoolSettingsElement.cs, + StandardBindingReliableSessionElement.cs, + LocalServiceSecuritySettingsElement.cs : use TimeSpanConverter. + +2010-03-15 Atsushi Enomoto + + * ServiceDebugElement.cs : binding names could rather be empty. + 2010-03-09 Atsushi Enomoto * XmlDictionaryReaderQuotasElement.cs : add ApplyConfiguration(). diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConfigUtil.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConfigUtil.cs index 360fe8cf05f..ba23d85f08e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConfigUtil.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConfigUtil.cs @@ -74,7 +74,7 @@ namespace System.ServiceModel.Configuration if (section == null) throw new ArgumentException (String.Format ("binding section for {0} was not found.", binding)); - Binding b = (Binding) Activator.CreateInstance (section.BindingType, new object [0]); + Binding b = section.GetDefault (); foreach (IBindingConfigurationElement el in section.ConfiguredBindings) if (el.Name == bindingConfiguration) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConnectionOrientedTransportElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConnectionOrientedTransportElement.cs index 59c9bb259f0..5ec8e8dde05 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConnectionOrientedTransportElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ConnectionOrientedTransportElement.cs @@ -59,7 +59,8 @@ namespace System.ServiceModel.Configuration { ConfigurationPropertyCollection _properties; - protected ConnectionOrientedTransportElement () { + internal ConnectionOrientedTransportElement () + { } // Properties @@ -67,6 +68,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("channelInitializationTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:00:05")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan ChannelInitializationTimeout { get { return (TimeSpan) base ["channelInitializationTimeout"]; } set { base ["channelInitializationTimeout"] = value; } @@ -105,6 +107,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("maxOutputDelay", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:00:00.2")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan MaxOutputDelay { get { return (TimeSpan) base ["maxOutputDelay"]; } set { base ["maxOutputDelay"] = value; } @@ -157,7 +160,44 @@ namespace System.ServiceModel.Configuration set { base ["transferMode"] = value; } } + public override void ApplyConfiguration (BindingElement bindingElement) + { + var e = (ConnectionOrientedTransportBindingElement) bindingElement; + e.ChannelInitializationTimeout = ChannelInitializationTimeout; + e.ConnectionBufferSize = ConnectionBufferSize; + e.HostNameComparisonMode = HostNameComparisonMode; + e.MaxBufferSize = MaxBufferSize; + e.MaxOutputDelay = MaxOutputDelay; + e.MaxPendingAccepts = MaxPendingAccepts; + e.MaxPendingConnections = MaxPendingConnections; + e.TransferMode = TransferMode; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (ConnectionOrientedTransportElement) from; + ChannelInitializationTimeout = e.ChannelInitializationTimeout; + ConnectionBufferSize = e.ConnectionBufferSize; + HostNameComparisonMode = e.HostNameComparisonMode; + MaxBufferSize = e.MaxBufferSize; + MaxOutputDelay = e.MaxOutputDelay; + MaxPendingAccepts = e.MaxPendingAccepts; + MaxPendingConnections = e.MaxPendingConnections; + TransferMode = e.TransferMode; + } + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var e = (ConnectionOrientedTransportBindingElement) bindingElement; + ChannelInitializationTimeout = e.ChannelInitializationTimeout; + ConnectionBufferSize = e.ConnectionBufferSize; + HostNameComparisonMode = e.HostNameComparisonMode; + MaxBufferSize = e.MaxBufferSize; + MaxOutputDelay = e.MaxOutputDelay; + MaxPendingAccepts = e.MaxPendingAccepts; + MaxPendingConnections = e.MaxPendingConnections; + TransferMode = e.TransferMode; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/CustomBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/CustomBindingElement.cs index afa1dd0c09e..ccf763505ed 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/CustomBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/CustomBindingElement.cs @@ -72,6 +72,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("closeTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan CloseTimeout { get { return (TimeSpan) base ["closeTimeout"]; } set { base ["closeTimeout"] = value; } @@ -80,6 +81,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("openTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan OpenTimeout { get { return (TimeSpan) base ["openTimeout"]; } set { base ["openTimeout"] = value; } @@ -101,6 +103,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("receiveTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:10:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan ReceiveTimeout { get { return (TimeSpan) base ["receiveTimeout"]; } set { base ["receiveTimeout"] = value; } @@ -109,14 +112,27 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("sendTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan SendTimeout { get { return (TimeSpan) base ["sendTimeout"]; } set { base ["sendTimeout"] = value; } } - [MonoTODO] - public void ApplyConfiguration (Binding binding) { - throw new NotImplementedException (); + [MonoTODO ("what to reject?")] + public override void Add (BindingElementExtensionElement element) + { + base.Add (element); + } + + [MonoTODO ("what to reject?")] + public override bool CanAdd (BindingElementExtensionElement element) + { + return true; + } + + public void ApplyConfiguration (Binding binding) + { + OnApplyConfiguration (binding); } [MonoTODO ("implement using EvaluationContext")] @@ -133,6 +149,19 @@ namespace System.ServiceModel.Configuration return element; } + protected void OnApplyConfiguration (Binding binding) + { + if (binding == null) + throw new ArgumentNullException ("binding"); + var b = (CustomBinding) binding; + b.CloseTimeout = CloseTimeout; + b.OpenTimeout = OpenTimeout; + b.ReceiveTimeout = ReceiveTimeout; + b.SendTimeout = SendTimeout; + + foreach (var be in this) + b.Elements.Add (be.CreateBindingElement ()); + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HostTimeoutsElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HostTimeoutsElement.cs index 9b1e34f4c2c..e987942b86d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HostTimeoutsElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HostTimeoutsElement.cs @@ -62,6 +62,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("closeTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:00:10")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan CloseTimeout { get { return (TimeSpan) base ["closeTimeout"]; } set { base ["closeTimeout"] = value; } @@ -70,6 +71,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("openTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan OpenTimeout { get { return (TimeSpan) base ["openTimeout"]; } set { base ["openTimeout"] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpTransportElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpTransportElement.cs index 2412b52d9bc..1933d25a0e8 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpTransportElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpTransportElement.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -192,12 +192,64 @@ namespace System.ServiceModel.Configuration set { base ["useDefaultWebProxy"] = value; } } - - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (HttpTransportBindingElement) bindingElement; + base.ApplyConfiguration (b); + b.AllowCookies = AllowCookies; + b.AuthenticationScheme = AuthenticationScheme; + b.BypassProxyOnLocal = BypassProxyOnLocal; + b.HostNameComparisonMode = HostNameComparisonMode; + b.KeepAliveEnabled = KeepAliveEnabled; + b.MaxBufferSize = MaxBufferSize; + b.ProxyAddress = ProxyAddress; + b.ProxyAuthenticationScheme = ProxyAuthenticationScheme; + b.Realm = Realm; + b.TransferMode = TransferMode; + b.UnsafeConnectionNtlmAuthentication = UnsafeConnectionNtlmAuthentication; + b.UseDefaultWebProxy = UseDefaultWebProxy; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (HttpTransportElement) from; + base.CopyFrom (from); + AllowCookies = e.AllowCookies; + AuthenticationScheme = e.AuthenticationScheme; + BypassProxyOnLocal = e.BypassProxyOnLocal; + HostNameComparisonMode = e.HostNameComparisonMode; + KeepAliveEnabled = e.KeepAliveEnabled; + MaxBufferSize = e.MaxBufferSize; + ProxyAddress = e.ProxyAddress; + ProxyAuthenticationScheme = e.ProxyAuthenticationScheme; + Realm = e.Realm; + TransferMode = e.TransferMode; + UnsafeConnectionNtlmAuthentication = e.UnsafeConnectionNtlmAuthentication; + UseDefaultWebProxy = e.UseDefaultWebProxy; + } + + protected override TransportBindingElement CreateDefaultBindingElement () + { + return new HttpTransportBindingElement (); + } + + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (HttpTransportBindingElement) bindingElement; + base.InitializeFrom (b); + AllowCookies = b.AllowCookies; + AuthenticationScheme = b.AuthenticationScheme; + BypassProxyOnLocal = b.BypassProxyOnLocal; + HostNameComparisonMode = b.HostNameComparisonMode; + KeepAliveEnabled = b.KeepAliveEnabled; + MaxBufferSize = b.MaxBufferSize; + ProxyAddress = b.ProxyAddress; + ProxyAuthenticationScheme = b.ProxyAuthenticationScheme; + Realm = b.Realm; + TransferMode = b.TransferMode; + UnsafeConnectionNtlmAuthentication = b.UnsafeConnectionNtlmAuthentication; + UseDefaultWebProxy = b.UseDefaultWebProxy; } - } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpsTransportElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpsTransportElement.cs index c844e56dc94..a2de9b75550 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpsTransportElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/HttpsTransportElement.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -87,7 +87,31 @@ namespace System.ServiceModel.Configuration set { base ["requireClientCertificate"] = value; } } + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (HttpsTransportBindingElement) bindingElement; + base.ApplyConfiguration (b); + b.RequireClientCertificate = RequireClientCertificate; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (HttpsTransportElement) from; + base.CopyFrom (from); + RequireClientCertificate = e.RequireClientCertificate; + } + protected override TransportBindingElement CreateDefaultBindingElement () + { + return new HttpsTransportBindingElement (); + } + + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (HttpsTransportBindingElement) bindingElement; + base.InitializeFrom (b); + RequireClientCertificate = b.RequireClientCertificate; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/IssuedTokenClientElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/IssuedTokenClientElement.cs index 064d26ceb16..a6d8f55d8c3 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/IssuedTokenClientElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/IssuedTokenClientElement.cs @@ -96,7 +96,7 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); max_issued_token_caching_time = new ConfigurationProperty ("maxIssuedTokenCachingTime", - typeof (TimeSpan), "10675199.02:48:05.4775807", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "10675199.02:48:05.4775807", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); properties.Add (cache_issued_tokens); @@ -168,6 +168,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("maxIssuedTokenCachingTime", Options = ConfigurationPropertyOptions.None, DefaultValue = "10675199.02:48:05.4775807")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan MaxIssuedTokenCachingTime { get { return (TimeSpan) base [max_issued_token_caching_time]; } set { base [max_issued_token_caching_time] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalClientSecuritySettingsElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalClientSecuritySettingsElement.cs index c0dce430f19..9055f054906 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalClientSecuritySettingsElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalClientSecuritySettingsElement.cs @@ -94,6 +94,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("maxClockSkew", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan MaxClockSkew { get { return (TimeSpan) base ["maxClockSkew"]; } set { base ["maxClockSkew"] = value; } @@ -102,6 +103,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("maxCookieCachingTime", Options = ConfigurationPropertyOptions.None, DefaultValue = "10675199.02:48:05.4775807")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan MaxCookieCachingTime { get { return (TimeSpan) base ["maxCookieCachingTime"]; } set { base ["maxCookieCachingTime"] = value; } @@ -133,6 +135,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("replayWindow", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan ReplayWindow { get { return (TimeSpan) base ["replayWindow"]; } set { base ["replayWindow"] = value; } @@ -141,6 +144,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("sessionKeyRenewalInterval", Options = ConfigurationPropertyOptions.None, DefaultValue = "10:00:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan SessionKeyRenewalInterval { get { return (TimeSpan) base ["sessionKeyRenewalInterval"]; } set { base ["sessionKeyRenewalInterval"] = value; } @@ -157,6 +161,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("timestampValidityDuration", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan TimestampValidityDuration { get { return (TimeSpan) base ["timestampValidityDuration"]; } set { base ["timestampValidityDuration"] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalServiceSecuritySettingsElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalServiceSecuritySettingsElement.cs index 99d7649518e..cf4bc33dc38 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalServiceSecuritySettingsElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/LocalServiceSecuritySettingsElement.cs @@ -83,11 +83,11 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); inactivity_timeout = new ConfigurationProperty ("inactivityTimeout", - typeof (TimeSpan), "00:02:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:02:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); issued_cookie_lifetime = new ConfigurationProperty ("issuedCookieLifetime", - typeof (TimeSpan), "10:00:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "10:00:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); max_cached_cookies = new ConfigurationProperty ("maxCachedCookies", @@ -95,7 +95,7 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); max_clock_skew = new ConfigurationProperty ("maxClockSkew", - typeof (TimeSpan), "00:05:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:05:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); max_pending_sessions = new ConfigurationProperty ("maxPendingSessions", @@ -107,7 +107,7 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); negotiation_timeout = new ConfigurationProperty ("negotiationTimeout", - typeof (TimeSpan), "00:01:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:01:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); reconnect_transport_on_failure = new ConfigurationProperty ("reconnectTransportOnFailure", @@ -119,19 +119,19 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); replay_window = new ConfigurationProperty ("replayWindow", - typeof (TimeSpan), "00:05:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:05:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); session_key_renewal_interval = new ConfigurationProperty ("sessionKeyRenewalInterval", - typeof (TimeSpan), "15:00:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "15:00:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); session_key_rollover_interval = new ConfigurationProperty ("sessionKeyRolloverInterval", - typeof (TimeSpan), "00:05:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:05:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); timestamp_validity_duration = new ConfigurationProperty ("timestampValidityDuration", - typeof (TimeSpan), "00:05:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:05:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); properties.Add (detect_replays); @@ -168,6 +168,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("inactivityTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:02:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan InactivityTimeout { get { return (TimeSpan) base [inactivity_timeout]; } set { base [inactivity_timeout] = value; } @@ -176,6 +177,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("issuedCookieLifetime", Options = ConfigurationPropertyOptions.None, DefaultValue = "10:00:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan IssuedCookieLifetime { get { return (TimeSpan) base [issued_cookie_lifetime]; } set { base [issued_cookie_lifetime] = value; } @@ -195,6 +197,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("maxClockSkew", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan MaxClockSkew { get { return (TimeSpan) base [max_clock_skew]; } set { base [max_clock_skew] = value; } @@ -225,6 +228,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("negotiationTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan NegotiationTimeout { get { return (TimeSpan) base [negotiation_timeout]; } set { base [negotiation_timeout] = value; } @@ -256,6 +260,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("replayWindow", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan ReplayWindow { get { return (TimeSpan) base [replay_window]; } set { base [replay_window] = value; } @@ -264,6 +269,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("sessionKeyRenewalInterval", Options = ConfigurationPropertyOptions.None, DefaultValue = "15:00:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan SessionKeyRenewalInterval { get { return (TimeSpan) base [session_key_renewal_interval]; } set { base [session_key_renewal_interval] = value; } @@ -272,6 +278,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("sessionKeyRolloverInterval", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan SessionKeyRolloverInterval { get { return (TimeSpan) base [session_key_rollover_interval]; } set { base [session_key_rollover_interval] = value; } @@ -280,6 +287,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("timestampValidityDuration", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan TimestampValidityDuration { get { return (TimeSpan) base [timestamp_validity_duration]; } set { base [timestamp_validity_duration] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpBindingCollectionElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpBindingCollectionElement.cs index d9d252e2829..c97a174c2b8 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpBindingCollectionElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpBindingCollectionElement.cs @@ -54,7 +54,6 @@ using System.Xml; namespace System.ServiceModel.Configuration { - [MonoTODO] public partial class MexHttpBindingCollectionElement : MexBindingBindingCollectionElement { @@ -70,10 +69,10 @@ namespace System.ServiceModel.Configuration { } - - // Properties - - + protected internal override Binding GetDefault () + { + return MetadataExchangeBindings.CreateMexHttpBinding (); + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpsBindingCollectionElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpsBindingCollectionElement.cs index 09eaf398e30..d7288f40f11 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpsBindingCollectionElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MexHttpsBindingCollectionElement.cs @@ -54,7 +54,6 @@ using System.Xml; namespace System.ServiceModel.Configuration { - [MonoTODO] public partial class MexHttpsBindingCollectionElement : MexBindingBindingCollectionElement { @@ -70,10 +69,10 @@ namespace System.ServiceModel.Configuration { } - - // Properties - - + protected internal override Binding GetDefault () + { + return MetadataExchangeBindings.CreateMexHttpsBinding (); + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqBindingElementBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqBindingElementBase.cs index d4f5d86d72b..a88ce844e65 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqBindingElementBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqBindingElementBase.cs @@ -109,11 +109,11 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); retry_cycle_delay = new ConfigurationProperty ("retryCycleDelay", - typeof (TimeSpan), "00:30:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:30:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); time_to_live = new ConfigurationProperty ("timeToLive", - typeof (TimeSpan), "1.00:00:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "1.00:00:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); use_msmq_tracing = new ConfigurationProperty ("useMsmqTracing", @@ -225,6 +225,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("retryCycleDelay", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:30:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan RetryCycleDelay { get { return (TimeSpan) base [retry_cycle_delay]; } set { base [retry_cycle_delay] = value; } @@ -233,6 +234,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("timeToLive", Options = ConfigurationPropertyOptions.None, DefaultValue = "1.00:00:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan TimeToLive { get { return (TimeSpan) base [time_to_live]; } set { base [time_to_live] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqElementBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqElementBase.cs index 81d05957c9f..1ad2b2a1f3f 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqElementBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqElementBase.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -186,7 +186,77 @@ namespace System.ServiceModel.Configuration set { base ["useSourceJournal"] = value; } } + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (System.ServiceModel.Channels.MsmqBindingElementBase) bindingElement; + base.ApplyConfiguration (b); + b.CustomDeadLetterQueue = CustomDeadLetterQueue; + b.DeadLetterQueue = DeadLetterQueue; + b.Durable = Durable; + b.ExactlyOnce = ExactlyOnce; + b.MaxRetryCycles = MaxRetryCycles; + b.ReceiveErrorHandling = ReceiveErrorHandling; + b.ReceiveRetryCount = ReceiveRetryCount; + b.RetryCycleDelay = RetryCycleDelay; + b.TimeToLive = TimeToLive; + b.UseMsmqTracing = UseMsmqTracing; + b.UseSourceJournal = UseSourceJournal; + var bs = b.MsmqTransportSecurity; + var cs = MsmqTransportSecurity; + bs.MsmqAuthenticationMode = cs.MsmqAuthenticationMode; + bs.MsmqEncryptionAlgorithm = cs.MsmqEncryptionAlgorithm; + bs.MsmqProtectionLevel = cs.MsmqProtectionLevel; + bs.MsmqSecureHashAlgorithm = cs.MsmqSecureHashAlgorithm; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (MsmqElementBase) from; + base.CopyFrom (from); + CustomDeadLetterQueue = e.CustomDeadLetterQueue; + DeadLetterQueue = e.DeadLetterQueue; + Durable = e.Durable; + ExactlyOnce = e.ExactlyOnce; + MaxRetryCycles = e.MaxRetryCycles; + ReceiveErrorHandling = e.ReceiveErrorHandling; + ReceiveRetryCount = e.ReceiveRetryCount; + RetryCycleDelay = e.RetryCycleDelay; + TimeToLive = e.TimeToLive; + UseMsmqTracing = e.UseMsmqTracing; + UseSourceJournal = e.UseSourceJournal; + + var es = e.MsmqTransportSecurity; + var cs = MsmqTransportSecurity; + cs.MsmqAuthenticationMode = es.MsmqAuthenticationMode; + cs.MsmqEncryptionAlgorithm = es.MsmqEncryptionAlgorithm; + cs.MsmqProtectionLevel = es.MsmqProtectionLevel; + cs.MsmqSecureHashAlgorithm = es.MsmqSecureHashAlgorithm; + } + + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (System.ServiceModel.Channels.MsmqBindingElementBase) bindingElement; + base.InitializeFrom (b); + CustomDeadLetterQueue = b.CustomDeadLetterQueue; + DeadLetterQueue = b.DeadLetterQueue; + Durable = b.Durable; + ExactlyOnce = b.ExactlyOnce; + MaxRetryCycles = b.MaxRetryCycles; + ReceiveErrorHandling = b.ReceiveErrorHandling; + ReceiveRetryCount = b.ReceiveRetryCount; + RetryCycleDelay = b.RetryCycleDelay; + TimeToLive = b.TimeToLive; + UseMsmqTracing = b.UseMsmqTracing; + UseSourceJournal = b.UseSourceJournal; + + var bs = b.MsmqTransportSecurity; + var cs = MsmqTransportSecurity; + cs.MsmqAuthenticationMode = bs.MsmqAuthenticationMode; + cs.MsmqEncryptionAlgorithm = bs.MsmqEncryptionAlgorithm; + cs.MsmqProtectionLevel = bs.MsmqProtectionLevel; + cs.MsmqSecureHashAlgorithm = bs.MsmqSecureHashAlgorithm; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqIntegrationElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqIntegrationElement.cs index 06876fdac3d..f1acfbd36df 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqIntegrationElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqIntegrationElement.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -86,12 +86,31 @@ namespace System.ServiceModel.Configuration set { base ["serializationFormat"] = value; } } + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (System.ServiceModel.MsmqIntegration.MsmqIntegrationBindingElement) bindingElement; + base.ApplyConfiguration (b); + b.SerializationFormat = SerializationFormat; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (MsmqIntegrationElement) from; + base.CopyFrom (from); + SerializationFormat = e.SerializationFormat; + } - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + protected override TransportBindingElement CreateDefaultBindingElement () + { + return new System.ServiceModel.MsmqIntegration.MsmqIntegrationBindingElement (); } + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (System.ServiceModel.MsmqIntegration.MsmqIntegrationBindingElement) bindingElement; + base.InitializeFrom (b); + SerializationFormat = b.SerializationFormat; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqTransportElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqTransportElement.cs index 59bb88b8139..f4235e85cf5 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqTransportElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/MsmqTransportElement.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -108,11 +108,37 @@ namespace System.ServiceModel.Configuration set { base ["useActiveDirectory"] = value; } } - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (MsmqTransportBindingElement) bindingElement; + base.ApplyConfiguration (b); + b.MaxPoolSize = MaxPoolSize; + b.QueueTransferProtocol = QueueTransferProtocol; + b.UseActiveDirectory = UseActiveDirectory; } + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (MsmqTransportElement) from; + base.CopyFrom (from); + MaxPoolSize = e.MaxPoolSize; + QueueTransferProtocol = e.QueueTransferProtocol; + UseActiveDirectory = e.UseActiveDirectory; + } + + protected override TransportBindingElement CreateDefaultBindingElement () + { + return new MsmqTransportBindingElement (); + } + + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (MsmqTransportBindingElement) bindingElement; + base.InitializeFrom (b); + MaxPoolSize = b.MaxPoolSize; + QueueTransferProtocol = b.QueueTransferProtocol; + UseActiveDirectory = b.UseActiveDirectory; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeConnectionPoolSettingsElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeConnectionPoolSettingsElement.cs index e66eee7836a..7d29fdf1fab 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeConnectionPoolSettingsElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeConnectionPoolSettingsElement.cs @@ -72,7 +72,7 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); idle_timeout = new ConfigurationProperty ("idleTimeout", - typeof (TimeSpan), "00:02:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:02:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); max_outbound_connections_per_endpoint = new ConfigurationProperty ("maxOutboundConnectionsPerEndpoint", @@ -105,6 +105,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("idleTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:02:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan IdleTimeout { get { return (TimeSpan) base [idle_timeout]; } set { base [idle_timeout] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeTransportElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeTransportElement.cs index d8ba18ec6b5..82f25055d41 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeTransportElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/NamedPipeTransportElement.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -54,7 +54,6 @@ using System.Xml; namespace System.ServiceModel.Configuration { - [MonoTODO] public sealed partial class NamedPipeTransportElement : ConnectionOrientedTransportElement { @@ -87,11 +86,46 @@ namespace System.ServiceModel.Configuration } } - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (NamedPipeTransportBindingElement) bindingElement; + base.ApplyConfiguration (b); + + var bs = b.ConnectionPoolSettings; + var cs = ConnectionPoolSettings; + bs.GroupName = cs.GroupName; + bs.IdleTimeout = cs.IdleTimeout; + bs.MaxOutboundConnectionsPerEndpoint = cs.MaxOutboundConnectionsPerEndpoint; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (NamedPipeTransportElement) from; + base.CopyFrom (from); + + var es = e.ConnectionPoolSettings; + var cs = ConnectionPoolSettings; + cs.GroupName = es.GroupName; + cs.IdleTimeout = es.IdleTimeout; + cs.MaxOutboundConnectionsPerEndpoint = es.MaxOutboundConnectionsPerEndpoint; } + protected override TransportBindingElement CreateDefaultBindingElement () + { + return new NamedPipeTransportBindingElement (); + } + + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (NamedPipeTransportBindingElement) bindingElement; + base.InitializeFrom (b); + + var bs = b.ConnectionPoolSettings; + var cs = ConnectionPoolSettings; + cs.GroupName = bs.GroupName; + cs.IdleTimeout = bs.IdleTimeout; + cs.MaxOutboundConnectionsPerEndpoint = bs.MaxOutboundConnectionsPerEndpoint; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ReliableSessionElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ReliableSessionElement.cs index dc241fe31e6..41220685f8a 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ReliableSessionElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ReliableSessionElement.cs @@ -65,6 +65,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("acknowledgementInterval", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:00:00.2")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan AcknowledgementInterval { get { return (TimeSpan) base ["acknowledgementInterval"]; } set { base ["acknowledgementInterval"] = value; } @@ -85,6 +86,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("inactivityTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:10:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan InactivityTimeout { get { return (TimeSpan) base ["inactivityTimeout"]; } set { base ["inactivityTimeout"] = value; } @@ -143,9 +145,48 @@ namespace System.ServiceModel.Configuration get { return base.Properties; } } - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + protected internal override BindingElement CreateBindingElement () + { + return new ReliableSessionBindingElement (); + } + + public override void ApplyConfiguration (BindingElement element) + { + var b = (ReliableSessionBindingElement) element; + b.AcknowledgementInterval = AcknowledgementInterval; + b.FlowControlEnabled = FlowControlEnabled; + b.InactivityTimeout = InactivityTimeout; + b.MaxPendingChannels = MaxPendingChannels; + b.MaxRetryCount = MaxRetryCount; + b.MaxTransferWindowSize = MaxTransferWindowSize; + b.Ordered = Ordered; + b.ReliableMessagingVersion = ReliableMessagingVersion; + } + + public override void CopyFrom (ServiceModelExtensionElement element) + { + var b = (ReliableSessionElement) element; + AcknowledgementInterval = b.AcknowledgementInterval; + FlowControlEnabled = b.FlowControlEnabled; + InactivityTimeout = b.InactivityTimeout; + MaxPendingChannels = b.MaxPendingChannels; + MaxRetryCount = b.MaxRetryCount; + MaxTransferWindowSize = b.MaxTransferWindowSize; + Ordered = b.Ordered; + ReliableMessagingVersion = b.ReliableMessagingVersion; + } + + protected internal override void InitializeFrom (BindingElement element) + { + var b = (ReliableSessionBindingElement) element; + AcknowledgementInterval = b.AcknowledgementInterval; + FlowControlEnabled = b.FlowControlEnabled; + InactivityTimeout = b.InactivityTimeout; + MaxPendingChannels = b.MaxPendingChannels; + MaxRetryCount = b.MaxRetryCount; + MaxTransferWindowSize = b.MaxTransferWindowSize; + Ordered = b.Ordered; + ReliableMessagingVersion = b.ReliableMessagingVersion; } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceDebugElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceDebugElement.cs index b211ad9b580..41c8682689e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceDebugElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceDebugElement.cs @@ -146,9 +146,9 @@ namespace System.ServiceModel.Configuration HttpsHelpPageUrl = HttpsHelpPageUrl, IncludeExceptionDetailInFaults = IncludeExceptionDetailInFaults, }; - if (HttpHelpPageBinding != null) + if (!String.IsNullOrEmpty (HttpHelpPageBinding)) ret.HttpHelpPageBinding = ConfigUtil.CreateBinding (HttpHelpPageBinding, HttpHelpPageBindingConfiguration); - if (HttpsHelpPageBinding != null) + if (!String.IsNullOrEmpty (HttpsHelpPageBinding)) ret.HttpsHelpPageBinding = ConfigUtil.CreateBinding (HttpsHelpPageBinding, HttpsHelpPageBindingConfiguration); return ret; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceMetadataPublishingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceMetadataPublishingElement.cs index fcd314e24d8..351deef520d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceMetadataPublishingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/ServiceMetadataPublishingElement.cs @@ -137,9 +137,9 @@ namespace System.ServiceModel.Configuration b.HttpsGetEnabled = HttpsGetEnabled; b.HttpGetUrl = HttpGetUrl; b.HttpsGetUrl = HttpsGetUrl; - if (HttpGetBinding != null) + if (!String.IsNullOrEmpty (HttpGetBinding)) b.HttpGetBinding = ConfigUtil.CreateBinding (HttpGetBinding, HttpGetBindingConfiguration); - if (HttpsGetBinding != null) + if (!String.IsNullOrEmpty (HttpsGetBinding)) b.HttpsGetBinding = ConfigUtil.CreateBinding (HttpsGetBinding, HttpsGetBindingConfiguration); return b; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingCollectionElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingCollectionElement.cs index fd75d55dc7d..5e432e1616b 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingCollectionElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingCollectionElement.cs @@ -99,8 +99,9 @@ namespace System.ServiceModel.Configuration throw new NotImplementedException (); } - protected internal override Binding GetDefault () { - throw new NotImplementedException (); + protected internal override Binding GetDefault () + { + return (Binding) Activator.CreateInstance (BindingType, new object [0]); } protected internal override bool TryAdd (string name, Binding binding, System.Configuration.Configuration config) { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingElement.cs index d3bf240bbe0..1e2e59d91df 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingElement.cs @@ -74,6 +74,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("closeTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan CloseTimeout { get { return (TimeSpan) this ["closeTimeout"]; } set { this ["closeTimeout"] = value; } @@ -94,6 +95,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("openTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan OpenTimeout { get { return (TimeSpan) this ["openTimeout"]; } set { this ["openTimeout"] = value; } @@ -116,6 +118,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("receiveTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:10:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan ReceiveTimeout { get { return (TimeSpan) this ["receiveTimeout"]; } set { this ["receiveTimeout"] = value; } @@ -124,6 +127,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("sendTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:01:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan SendTimeout { get { return (TimeSpan) this ["sendTimeout"]; } set { this ["sendTimeout"] = value; } @@ -138,6 +142,14 @@ namespace System.ServiceModel.Configuration binding.SendTimeout = SendTimeout; OnApplyConfiguration (binding); } + + protected internal virtual void InitializeFrom (Binding binding) + { + CloseTimeout = binding.CloseTimeout; + OpenTimeout = binding.OpenTimeout; + ReceiveTimeout = binding.ReceiveTimeout; + SendTimeout = binding.SendTimeout; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingReliableSessionElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingReliableSessionElement.cs index ce9d811ae68..f6e42409f29 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingReliableSessionElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/StandardBindingReliableSessionElement.cs @@ -74,7 +74,7 @@ namespace System.ServiceModel.Configuration { properties = new ConfigurationPropertyCollection (); inactivity_timeout = new ConfigurationProperty ("inactivityTimeout", - typeof (TimeSpan), "00:10:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:10:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); ordered = new ConfigurationProperty ("ordered", @@ -95,6 +95,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("inactivityTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:10:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan InactivityTimeout { get { return (TimeSpan) base [inactivity_timeout]; } set { base [inactivity_timeout] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpConnectionPoolSettingsElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpConnectionPoolSettingsElement.cs index c5509bbb1c2..ac48e04ca54 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpConnectionPoolSettingsElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpConnectionPoolSettingsElement.cs @@ -73,11 +73,11 @@ namespace System.ServiceModel.Configuration ConfigurationPropertyOptions.None); idle_timeout = new ConfigurationProperty ("idleTimeout", - typeof (TimeSpan), "00:02:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:02:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); lease_timeout = new ConfigurationProperty ("leaseTimeout", - typeof (TimeSpan), "00:05:00", null/* FIXME: get converter for TimeSpan*/, null, + typeof (TimeSpan), "00:05:00", new TimeSpanConverter (), null, ConfigurationPropertyOptions.None); max_outbound_connections_per_endpoint = new ConfigurationProperty ("maxOutboundConnectionsPerEndpoint", @@ -111,6 +111,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("idleTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:02:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan IdleTimeout { get { return (TimeSpan) base [idle_timeout]; } set { base [idle_timeout] = value; } @@ -119,6 +120,7 @@ namespace System.ServiceModel.Configuration [ConfigurationProperty ("leaseTimeout", Options = ConfigurationPropertyOptions.None, DefaultValue = "00:05:00")] + [TypeConverter (typeof (TimeSpanConverter))] public TimeSpan LeaseTimeout { get { return (TimeSpan) base [lease_timeout]; } set { base [lease_timeout] = value; } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpTransportElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpTransportElement.cs index c75adfb8e1a..e11ebbebf8b 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpTransportElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TcpTransportElement.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -116,12 +116,37 @@ namespace System.ServiceModel.Configuration set { base ["teredoEnabled"] = value; } } + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (TcpTransportBindingElement) bindingElement; + base.ApplyConfiguration (b); + b.ListenBacklog = ListenBacklog; + b.PortSharingEnabled = PortSharingEnabled; + b.TeredoEnabled = TeredoEnabled; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (TcpTransportElement) from; + base.CopyFrom (from); + ListenBacklog = e.ListenBacklog; + PortSharingEnabled = e.PortSharingEnabled; + TeredoEnabled = e.TeredoEnabled; + } - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + protected override TransportBindingElement CreateDefaultBindingElement () + { + return new TcpTransportBindingElement (); } + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (TcpTransportBindingElement) bindingElement; + base.InitializeFrom (b); + ListenBacklog = b.ListenBacklog; + PortSharingEnabled = b.PortSharingEnabled; + TeredoEnabled = b.TeredoEnabled; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TextMessageEncodingElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TextMessageEncodingElement.cs index 06a3473ca4b..56cfdc76f56 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TextMessageEncodingElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TextMessageEncodingElement.cs @@ -118,11 +118,44 @@ namespace System.ServiceModel.Configuration } - [MonoTODO] - protected internal override BindingElement CreateBindingElement () { - throw new NotImplementedException (); + protected internal override BindingElement CreateBindingElement () + { + return new TextMessageEncodingBindingElement (); } + + public override void ApplyConfiguration (BindingElement element) + { + var b = (TextMessageEncodingBindingElement) element; + b.MaxReadPoolSize = MaxReadPoolSize; + b.MaxWritePoolSize = MaxWritePoolSize; + b.MessageVersion = MessageVersion; + b.WriteEncoding = WriteEncoding; + + ReaderQuotas.ApplyConfiguration (b.ReaderQuotas); + } + + public override void CopyFrom (ServiceModelExtensionElement element) + { + var b = (TextMessageEncodingElement) element; + MaxReadPoolSize = b.MaxReadPoolSize; + MaxWritePoolSize = b.MaxWritePoolSize; + MessageVersion = b.MessageVersion; + WriteEncoding = b.WriteEncoding; + + ReaderQuotas.CopyFrom (b.ReaderQuotas); + } + + protected internal override void InitializeFrom (BindingElement element) + { + var b = (TextMessageEncodingBindingElement) element; + MaxReadPoolSize = b.MaxReadPoolSize; + MaxWritePoolSize = b.MaxWritePoolSize; + MessageVersion = b.MessageVersion; + WriteEncoding = b.WriteEncoding; + + ReaderQuotas.InitializeFrom (b.ReaderQuotas); + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TransportElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TransportElement.cs index 081e2b137e3..0ac73504b83 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TransportElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/TransportElement.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2006 Novell, Inc. http://www.novell.com +// Copyright (C) 2006,2010 Novell, Inc. http://www.novell.com // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -108,7 +108,41 @@ namespace System.ServiceModel.Configuration } } + public override void ApplyConfiguration (BindingElement bindingElement) + { + var b = (TransportBindingElement) bindingElement; + base.ApplyConfiguration (b); + b.ManualAddressing = ManualAddressing; + b.MaxBufferPoolSize = MaxBufferPoolSize; + b.MaxReceivedMessageSize = MaxReceivedMessageSize; + } + + public override void CopyFrom (ServiceModelExtensionElement from) + { + var e = (TransportElement) from; + base.CopyFrom (from); + ManualAddressing = e.ManualAddressing; + MaxBufferPoolSize = e.MaxBufferPoolSize; + MaxReceivedMessageSize = e.MaxReceivedMessageSize; + } + protected internal override BindingElement CreateBindingElement () + { + var b = CreateDefaultBindingElement (); + ApplyConfiguration (b); + return b; + } + + protected abstract TransportBindingElement CreateDefaultBindingElement (); + + protected internal override void InitializeFrom (BindingElement bindingElement) + { + var b = (TransportBindingElement) bindingElement; + base.InitializeFrom (b); + ManualAddressing = b.ManualAddressing; + MaxBufferPoolSize = b.MaxBufferPoolSize; + MaxReceivedMessageSize = b.MaxReceivedMessageSize; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/XmlDictionaryReaderQuotasElement.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/XmlDictionaryReaderQuotasElement.cs index 88adca5ed77..cf92fdf1c67 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/XmlDictionaryReaderQuotasElement.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Configuration/XmlDictionaryReaderQuotasElement.cs @@ -181,6 +181,48 @@ namespace System.ServiceModel.Configuration if (MaxStringContentLength > 0) q.MaxStringContentLength = MaxStringContentLength; } + + internal void ApplyConfiguration (XmlDictionaryReaderQuotasElement q) + { + if (MaxArrayLength > 0) + q.MaxArrayLength = MaxArrayLength; + if (MaxBytesPerRead > 0) + q.MaxBytesPerRead = MaxBytesPerRead; + if (MaxDepth > 0) + q.MaxDepth = MaxDepth; + if (MaxNameTableCharCount > 0) + q.MaxNameTableCharCount = MaxNameTableCharCount; + if (MaxStringContentLength > 0) + q.MaxStringContentLength = MaxStringContentLength; + } + + internal void InitializeFrom (XmlDictionaryReaderQuotas q) + { + if (q.MaxArrayLength > 0) + MaxArrayLength = q.MaxArrayLength; + if (q.MaxBytesPerRead > 0) + MaxBytesPerRead = q.MaxBytesPerRead; + if (q.MaxDepth > 0) + MaxDepth = q.MaxDepth; + if (q.MaxNameTableCharCount > 0) + MaxNameTableCharCount = q.MaxNameTableCharCount; + if (q.MaxStringContentLength > 0) + MaxStringContentLength = q.MaxStringContentLength; + } + + internal void CopyFrom (XmlDictionaryReaderQuotasElement q) + { + if (q.MaxArrayLength > 0) + MaxArrayLength = q.MaxArrayLength; + if (q.MaxBytesPerRead > 0) + MaxBytesPerRead = q.MaxBytesPerRead; + if (q.MaxDepth > 0) + MaxDepth = q.MaxDepth; + if (q.MaxNameTableCharCount > 0) + MaxNameTableCharCount = q.MaxNameTableCharCount; + if (q.MaxStringContentLength > 0) + MaxStringContentLength = q.MaxStringContentLength; + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog index 13309137d54..4a6055fbf60 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ChangeLog @@ -1,3 +1,64 @@ +2010-04-23 Atsushi Enomoto + + * ServiceMetadataExtension.cs : raise an error if it failed to set + mex info. (Make it safer.) + +2010-04-23 Atsushi Enomoto + + * ServiceMetadataExtension.cs : reflect DispatcherBuilder change. + +2010-04-02 Atsushi Enomoto + + * ContractDescriptionGenerator.cs : fill FaultDescription action, + name and namespace as expected. + +2010-04-02 Atsushi Enomoto + + * ContractDescription.cs : fill FaultContractInfos in ClientOperation. + +2010-04-02 Atsushi Enomoto + + * FaultDescription.cs : fill Action. + * ContractDescriptionGenerator.cs : do not fill Faults from service + impl. method. Do this from contract method instead. + * OperationDescription.cs : remove extra TODOs. + +2010-03-24 Atsushi Enomoto + + * ServiceMetadataExtension.cs : compare "wsdl" parameter in case- + insensitive manner. + +2010-03-19 Atsushi Enomoto + + * HostedBindingBehavior.cs : remove unused class. + +2010-03-17 Atsushi Enomoto + + * WsdlExporter.cs : allow identical contract while exporting a set + of endpoints, while reject identical ones when calling + ExportEndpoint() individually. + +2010-03-17 Atsushi Enomoto + + * MetadataExchangeBindings.cs : use WSHttpBinding (it works if other + parts gets fixed). + +2010-03-17 Atsushi Enomoto + + * ServiceMetadataExtension.cs, WsdlExporter.cs : + implement ExportEndpoints() and use it. + +2010-03-16 Jb Evain + + * ClientCredentials.cs, ContractDescription.cs, + IEndpointBehavior.cs: use MOONLIGHT symbol to disambiguate + MonoTouch and Moonlight code. + +2010-03-15 Atsushi Enomoto + + * ServiceEndpointCollection.cs : those overrides are rather to check + null arguments, not to skip contract duplicates. + 2010-03-12 Atsushi Enomoto * MessageDescription.cs : implement MessageName. diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ClientCredentials.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ClientCredentials.cs index fad6fbdd260..7e2c785cdfa 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ClientCredentials.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ClientCredentials.cs @@ -140,7 +140,7 @@ namespace System.ServiceModel.Description } #endif -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT void IEndpointBehavior.AddBindingParameters (ServiceEndpoint endpoint, BindingParameterCollection parameters) { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs index b7fd634fe54..a465525a410 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs @@ -153,7 +153,7 @@ namespace System.ServiceModel.Description foreach (OperationDescription od in Operations) { if (!proxy.Operations.Contains (od.Name)) PopulateClientOperation (proxy, od); -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT foreach (IOperationBehavior ob in od.Behaviors) ob.ApplyClientBehavior (od, proxy.Operations [od.Name]); #endif @@ -185,6 +185,10 @@ namespace System.ServiceModel.Description md.Body.ReturnValue.Type == typeof (Message)) o.DeserializeReply = false; } +#if !NET_2_1 + foreach (var fd in od.Faults) + o.FaultContractInfos.Add (new FaultContractInfo (fd.Action, fd.DetailType)); +#endif proxy.Operations.Add (o); } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs index 1a72a535648..1ad5843b6e7 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs @@ -245,8 +245,16 @@ namespace System.ServiceModel.Description foreach (ServiceKnownTypeAttribute a in serviceMethod.GetCustomAttributes (typeof (ServiceKnownTypeAttribute), false)) foreach (Type t in a.GetTypes ()) od.KnownTypes.Add (t); - foreach (FaultContractAttribute a in serviceMethod.GetCustomAttributes (typeof (FaultContractAttribute), false)) - od.Faults.Add (new FaultDescription (a.Action) { DetailType = a.DetailType, Name = a.Name, Namespace = a.Namespace }); + foreach (FaultContractAttribute a in mi.GetCustomAttributes (typeof (FaultContractAttribute), false)) { + var fname = a.Name ?? a.DetailType.Name + "Fault"; + var fns = a.Namespace ?? cd.Namespace; + var fd = new FaultDescription (a.Action ?? cd.Namespace + cd.Name + "/" + od.Name + fname) { DetailType = a.DetailType, Name = fname, Namespace = fns }; +#if !NET_2_1 + if (a.HasProtectionLevel) + fd.ProtectionLevel = a.ProtectionLevel; +#endif + od.Faults.Add (fd); + } cd.Operations.Add (od); } else if (oca.AsyncPattern && od.BeginMethod != null || diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/FaultDescription.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/FaultDescription.cs index 6621c18dbe2..8dee9eddb29 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/FaultDescription.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/FaultDescription.cs @@ -35,7 +35,6 @@ using System.ServiceModel; namespace System.ServiceModel.Description { - [MonoTODO] public class FaultDescription { string action, name, ns; @@ -43,8 +42,11 @@ namespace System.ServiceModel.Description bool has_protection_level; ProtectionLevel protection_level; - public FaultDescription (string name) + public FaultDescription (string action) { + if (action == null) + throw new ArgumentNullException ("action"); + this.action = action; } public string Action { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/HostedBindingBehavior.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/HostedBindingBehavior.cs deleted file mode 100644 index 20b73cd4eb9..00000000000 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/HostedBindingBehavior.cs +++ /dev/null @@ -1,72 +0,0 @@ -// -// HostedBindingBehavior.cs.cs -// -// Author: -// Atsushi Enomoto -// -// Copyright (C) 2005 Novell, Inc. http://www.novell.com -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -using System.Collections.ObjectModel; -using System.ServiceModel; -using System.ServiceModel.Channels; -using System.ServiceModel.Dispatcher; - -namespace System.ServiceModel.Description -{ - [MonoTODO] - internal sealed class HostedBindingBehavior : IServiceBehavior - { - string virtual_path; - - internal HostedBindingBehavior (string virtualPath) - { - virtual_path = virtualPath; - } - - public string VirtualPath { - get { return virtual_path; } - } - - void IServiceBehavior.AddBindingParameters ( - ServiceDescription description, - ServiceHostBase serviceHostBase, - Collection endpoints, - BindingParameterCollection parameters) - { - throw new NotImplementedException (); - } - - void IServiceBehavior.ApplyDispatchBehavior ( - ServiceDescription description, - ServiceHostBase serviceHostBase) - { - throw new NotImplementedException (); - } - - void IServiceBehavior.Validate ( - ServiceDescription description, - ServiceHostBase serviceHostBase) - { - throw new NotImplementedException (); - } - } -} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/IEndpointBehavior.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/IEndpointBehavior.cs index 1ba9d63f7e5..436dd438dc7 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/IEndpointBehavior.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/IEndpointBehavior.cs @@ -33,7 +33,7 @@ namespace System.ServiceModel.Description { public interface IEndpointBehavior { -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT void AddBindingParameters (ServiceEndpoint endpoint, BindingParameterCollection parameters); #if !NET_2_1 diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataExchangeBindings.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataExchangeBindings.cs index 469be47ce78..89fd2b3a0bb 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataExchangeBindings.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/MetadataExchangeBindings.cs @@ -34,26 +34,18 @@ namespace System.ServiceModel.Description { public static Binding CreateMexHttpBinding () { - //FIXME: .net uses WSHttpBinding.. - return new CustomBinding ( - "MetadataExchangeHttpBinding", - "http://schemas.microsoft.com/ws/2005/02/mex/bindings", - new TextMessageEncodingBindingElement ( - MessageVersion.Soap12WSAddressing10, - Encoding.UTF8), - new HttpTransportBindingElement ()); + var b = new WSHttpBinding (SecurityMode.None) { + Name = "MetadataExchangeHttpBinding", + Namespace = "http://schemas.microsoft.com/ws/2005/02/mex/bindings"}; + return b; } public static Binding CreateMexHttpsBinding () { - //FIXME: .net uses WSHttpBinding.. - return new CustomBinding ( - "MetadataExchangeHttpsBinding", - "http://schemas.microsoft.com/ws/2005/02/mex/bindings", - new TextMessageEncodingBindingElement ( - MessageVersion.Soap12WSAddressing10, - Encoding.UTF8), - new HttpsTransportBindingElement ()); + var b = (WSHttpBinding) CreateMexHttpBinding (); + b.Name = "MetadataExchangeHttpsBinding"; + b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; + return b; } public static Binding CreateMexNamedPipeBinding () diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationDescription.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationDescription.cs index 000960b2e89..2f2b47aa09c 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationDescription.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/OperationDescription.cs @@ -64,7 +64,6 @@ namespace System.ServiceModel.Description set { begin_method = value; } } - [MonoTODO] public KeyedByTypeCollection Behaviors { get { return behaviors; } } @@ -79,7 +78,6 @@ namespace System.ServiceModel.Description set { end_method = value; } } - [MonoTODO] public FaultDescriptionCollection Faults { get { return faults; } } @@ -105,7 +103,6 @@ namespace System.ServiceModel.Description set { is_terminating = value; } } - [MonoTODO] public Collection KnownTypes { get { return known_types; } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceEndpointCollection.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceEndpointCollection.cs index 58d0024e3de..191d411ed41 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceEndpointCollection.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceEndpointCollection.cs @@ -107,20 +107,18 @@ namespace System.ServiceModel.Description return list; } - [MonoTODO] protected override void InsertItem (int index, ServiceEndpoint item) { - if (Find (new XmlQualifiedName (item.Contract.Name, item.Contract.Namespace)) == null) - base.InsertItem (index, item); + if (item == null) + throw new ArgumentNullException ("item"); + base.InsertItem (index, item); } - [MonoTODO] protected override void SetItem (int index, ServiceEndpoint item) { - if (Find (new XmlQualifiedName (item.Contract.Name, item.Contract.Namespace)) == null) - base.SetItem (index, item); - else - base.RemoveItem (index); + if (item == null) + throw new ArgumentNullException ("item"); + base.SetItem (index, item); } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceMetadataExtension.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceMetadataExtension.cs index 36b7fdc8f63..fb39b485dfa 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceMetadataExtension.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ServiceMetadataExtension.cs @@ -66,13 +66,8 @@ namespace System.ServiceModel.Description public MetadataSet Metadata { get { if (metadata == null) { - MetadataExporter exporter = new WsdlExporter (); - foreach (ServiceEndpoint ep in owner.Description.Endpoints) { - if (ep.Contract.Name == ServiceMetadataBehavior.MexContractName) - continue; - - exporter.ExportEndpoint (ep); - } + var exporter = new WsdlExporter (); + exporter.ExportEndpoints (owner.Description.Endpoints, new XmlQualifiedName (owner.Description.Name, owner.Description.Namespace)); metadata = exporter.GetGeneratedMetadata (); } return metadata; @@ -139,11 +134,13 @@ namespace System.ServiceModel.Description ListenUri = uri, }; - var channelDispatcher = new DispatcherBuilder ().BuildChannelDispatcher (owner.Description.ServiceType, se, new BindingParameterCollection ()); + var channelDispatcher = new DispatcherBuilder (Owner).BuildChannelDispatcher (owner.Description.ServiceType, se, new BindingParameterCollection ()); // add HttpGetWsdl to indicate that the ChannelDispatcher is for mex or help. var listener = channelDispatcher.Listener as ChannelListenerBase; if (listener != null) listener.Properties.Add (new MetadataPublishingInfo () { SupportsMex = isMex, SupportsHelp = !isMex, Instance = instance }); + else + throw new InvalidOperationException ("FIXME: attempt to use ServiceMetadataExtension to not-supported channel listener: " + listener.GetType ()); channelDispatcher.Endpoints [0].DispatchRuntime.InstanceContextProvider = new SingletonInstanceContextProvider (new InstanceContext (owner, instance)); dispatchers.Add (uri, channelDispatcher); @@ -222,7 +219,7 @@ namespace System.ServiceModel.Description return CreateWsdlMessage (w); } - if (query_string [null] == "wsdl") { + if (String.Compare (query_string [null], "wsdl", StringComparison.OrdinalIgnoreCase) == 0) { WSServiceDescription wsdl = GetWsdl ("wsdl"); if (wsdl != null) return CreateWsdlMessage (wsdl); diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlExporter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlExporter.cs index 10a4fe2c3f8..0a5e892fe75 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlExporter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/WsdlExporter.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; using System.ServiceModel; using System.ServiceModel.Channels; using System.Web.Services.Description; @@ -50,10 +51,24 @@ namespace System.ServiceModel.Description [MonoTODO] public class WsdlExporter : MetadataExporter { + class ContractExportMap + { + public ContractExportMap (QName qname, ContractDescription contract, List results) + { + QName = qname; + Contract = contract; + Results = results; + } + + public QName QName { get; private set; } + public ContractDescription Contract { get; private set; } + public List Results { get; private set; } + } + private MetadataSet metadata; private ServiceDescriptionCollection wsdl_colln; private XsdDataContractExporter xsd_exporter; - private Hashtable exported_contracts; + private List exported_contracts; public override MetadataSet GetGeneratedMetadata () { @@ -74,16 +89,20 @@ namespace System.ServiceModel.Description public override void ExportContract (ContractDescription contract) { - ExportContractInternal (contract); + ExportContractInternal (contract, true); } - List ExportContractInternal (ContractDescription contract) + List ExportContractInternal (ContractDescription contract, bool rejectDuplicate) { QName qname = new QName (contract.Name, contract.Namespace); - if (ExportedContracts.ContainsKey (qname)) + var map = ExportedContracts.FirstOrDefault (m => m.QName == qname); + if (map != null) { + if (map.Results != null && !rejectDuplicate) + return null; // already exported. throw new ArgumentException (String.Format ( "A ContractDescription with Namespace : {0} and Name : {1} has already been exported.", contract.Namespace, contract.Name)); + } WSServiceDescription sd = GetServiceDescription (contract.Namespace); @@ -150,7 +169,7 @@ namespace System.ServiceModel.Description sd.Types.Schemas.Add (xs_import); sd.PortTypes.Add (ws_port); - ExportedContracts [qname] = contract; + ExportedContracts.Add (new ContractExportMap (qname, contract, extensions)); WsdlContractConversionContext context = new WsdlContractConversionContext (contract, ws_port); foreach (IWsdlExportExtension extn in extensions) @@ -161,7 +180,12 @@ namespace System.ServiceModel.Description public override void ExportEndpoint (ServiceEndpoint endpoint) { - List extensions = ExportContractInternal (endpoint.Contract); + ExportEndpoint (endpoint, true); + } + + void ExportEndpoint (ServiceEndpoint endpoint, bool rejectDuplicate) + { + List extensions = ExportContractInternal (endpoint.Contract, rejectDuplicate); //FIXME: Namespace WSServiceDescription sd = GetServiceDescription ("http://tempuri.org/"); @@ -251,8 +275,9 @@ namespace System.ServiceModel.Description WsdlEndpointConversionContext endpoint_context = new WsdlEndpointConversionContext ( contract_context, endpoint, ws_port, ws_binding); - foreach (IWsdlExportExtension extn in extensions) - extn.ExportEndpoint (this, endpoint_context); + if (extensions != null) + foreach (IWsdlExportExtension extn in extensions) + extn.ExportEndpoint (this, endpoint_context); } @@ -327,7 +352,17 @@ namespace System.ServiceModel.Description IEnumerable endpoints, XmlQualifiedName name) { - throw new NotImplementedException (); + if (endpoints == null) + throw new ArgumentNullException ("endpoints"); + if (name == null) + throw new ArgumentNullException ("name"); + + foreach (ServiceEndpoint ep in endpoints) { + if (ep.Contract.Name == ServiceMetadataBehavior.MexContractName) + continue; + + ExportEndpoint (ep, false); + } } XsdDataContractExporter XsdExporter { @@ -339,10 +374,10 @@ namespace System.ServiceModel.Description } } - Hashtable ExportedContracts { + List ExportedContracts { get { if (exported_contracts == null) - exported_contracts = new Hashtable (); + exported_contracts = new List (); return exported_contracts; } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs index e83398f78d7..363d9c6a807 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs @@ -72,10 +72,10 @@ namespace System.ServiceModel.Dispatcher if (md.IsTypedMessage || md.IsUntypedMessage) { if (isRpc && !isEncoded) throw new InvalidOperationException ("Message with action {0} is either strongly-typed or untyped, but defined as RPC and encoded."); - if (hasParameter) - throw new InvalidOperationException ("This operation contains a message with parameters. Strongly-typed or untyped message can be paired only with strongly-typed, untyped or void message."); - if (hasVoid) - throw new InvalidOperationException ("This operation is defined as RPC and contains a message with void, which is not allowed."); + if (hasParameter && !md.IsVoid) + throw new InvalidOperationException (String.Format ("Operation '{0}' contains a message with parameters. Strongly-typed or untyped message can be paired only with strongly-typed, untyped or void message.", od.Name)); + if (isRpc && hasVoid) + throw new InvalidOperationException (String.Format ("This operation '{0}' is defined as RPC and contains a message with void, which is not allowed.", od.Name)); } else { hasParameter |= !md.IsVoid; hasVoid |= md.IsVoid; diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog index 1424af7a9ef..820799d28ca 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChangeLog @@ -1,3 +1,77 @@ +2010-04-20 Atsushi Enomoto + + * OperationInvokerHandler.cs : workaround NRE issue in AsyncCallTest. + The original code was worse than this workaround. + +2010-04-05 Atsushi Enomoto + + * EndpointAddressMessageFilter.cs : check null arg. Return false for + no To header case and do not result in NRE.f + +2010-04-05 Atsushi Enomoto + + * BaseMessagesFormatter.cs : hasParameter check is incorrectly + restrictive to reject some kinds of pairs. + +2010-04-02 Atsushi Enomoto + + * FaultContractInfo.cs : add serializer property. + +2010-04-02 Atsushi Enomoto + + * ClientOperation.cs : do not automatically fill FaultContractInfos. + +2010-04-02 Atsushi Enomoto + + * OperationInvokerHandler.cs : implement FaultContractInfos support. + * ErrorProcessingHandler.cs : update comment. It is not relevant. + +2010-04-02 Atsushi Enomoto + + * EndpointDispatcher.cs : fill FaultContractInfos. + * DispatchOperation.cs : do not fill them dynamically/automatically. + * ErrorProcessingHandler.cs : added some FIXME notes. + +2010-03-30 Atsushi Enomoto + + * ChannelDispatcher.cs : differentiate EndpointNotFound and + ActionNotSupported so that FaultConverter can create appropriate + fault messages. Removed extra filter condition on null To item. + And create fault messages on *any* server side error, do not let + request client infinitely wait for the response until timeout. + + (RunDestinationUnreachableTest() is still not working but it works + when it is SOAP 1.2.) + +2010-03-30 Atsushi Enomoto + + * ChannelDispatcher.cs : for faults, use fault namespace, not that of + ReplyAction. Added FIXME comment regarding dispatcher. + +2010-03-25 Atsushi Enomoto + + * OperationInvokerHandler.cs : removed unused code. + +2010-03-24 Atsushi Enomoto + + * ChannelDispatcher.cs : return EndpointDispatcher at initializing + for internal use. Add some locks. Patch by Matt Dargavel. + +2010-03-24 Atsushi Enomoto + + * ChannelDispatcher.cs : fix wrong method call in open_delegate. + Patch by Matt Dargavel. + +2010-03-24 Atsushi Enomoto + + * ChannelDispatcher.cs : give the actual exception message instead + of "error occured". + +2010-03-18 Atsushi Enomoto + + * XPathMessageContext.cs : implement. + * XPathMessageFilterTable.cs : add some missing overloads. + 2010-02-26 Atsushi Enomoto * InputOrReplyRequestProcessor.cs : now ServiceRuntimeChannel is diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs index 713a62c2e76..157c08f6c8e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ChannelDispatcher.cs @@ -130,7 +130,7 @@ namespace System.ServiceModel.Dispatcher endpoints = new EndpointDispatcherCollection (this); } - internal void InitializeServiceEndpoint (Type serviceType, ServiceEndpoint se) + internal EndpointDispatcher InitializeServiceEndpoint (Type serviceType, ServiceEndpoint se) { this.MessageVersion = se.Binding.MessageVersion; if (this.MessageVersion == null) @@ -140,6 +140,7 @@ namespace System.ServiceModel.Dispatcher EndpointDispatcher ed = new EndpointDispatcher (se.Address, se.Contract.Name, se.Contract.Namespace); this.Endpoints.Add (ed); ed.InitializeServiceEndpoint (false, serviceType, se); + return ed; } public string BindingName { @@ -264,7 +265,7 @@ namespace System.ServiceModel.Dispatcher AsyncCallback callback, object state) { if (open_delegate == null) - open_delegate = new Action (OnClose); + open_delegate = new Action (OnOpen); return open_delegate.BeginInvoke (timeout, callback, state); } @@ -450,7 +451,7 @@ namespace System.ServiceModel.Dispatcher LoopCore (); } catch (Exception ex) { // FIXME: log it - Console.WriteLine ("ChannelDispatcher caught an exception inside dispatcher loop, which is likely thrown by the channel listener {0}", owner.Listener); + Console.WriteLine ("ListenerLoopManager caught an exception inside dispatcher loop, which is likely thrown by the channel listener {0}", owner.Listener); Console.WriteLine (ex); } finally { if (stop_handle != null) @@ -496,16 +497,19 @@ namespace System.ServiceModel.Dispatcher return; } - channels.Add (ch); + lock (channels) + channels.Add (ch); ch.Opened += delegate { ch.Faulted += delegate { - if (channels.Contains (ch)) - channels.Remove (ch); + lock (channels) + if (channels.Contains (ch)) + channels.Remove (ch); throttle_wait_handle.Set (); // release loop wait lock. }; ch.Closed += delegate { - if (channels.Contains (ch)) - channels.Remove (ch); + lock (channels) + if (channels.Contains (ch)) + channels.Remove (ch); throttle_wait_handle.Set (); // release loop wait lock. }; }; @@ -561,31 +565,21 @@ namespace System.ServiceModel.Dispatcher input.Close (); } - void SendEndpointNotFound (RequestContext rc, EndpointNotFoundException ex) - { - try { - - MessageVersion version = rc.RequestMessage.Version; - FaultCode fc = new FaultCode ("DestinationUnreachable", version.Addressing.Namespace); - Message res = Message.CreateMessage (version, fc, "error occured", rc.RequestMessage.Headers.Action); - rc.Reply (res); - } catch (Exception e) { - // FIXME: log it - Console.WriteLine ("Error on sending DestinationUnreachable fault message: " + e); - } - } - void ProcessRequest (IReplyChannel reply, RequestContext rc) { + var req = rc.RequestMessage; try { - EndpointDispatcher candidate = FindEndpointDispatcher (rc.RequestMessage); - new InputOrReplyRequestProcessor (candidate.DispatchRuntime, reply). - ProcessReply (rc); - } catch (EndpointNotFoundException ex) { - SendEndpointNotFound (rc, ex); + var ed = FindEndpointDispatcher (req); + new InputOrReplyRequestProcessor (ed.DispatchRuntime, reply).ProcessReply (rc); } catch (Exception ex) { // FIXME: log it. Console.WriteLine (ex); + + var conv = reply.GetProperty () ?? FaultConverter.GetDefaultFaultConverter (rc.RequestMessage.Version); + Message res; + if (!conv.TryCreateFaultMessage (ex, out res)) + res = Message.CreateMessage (req.Version, new FaultCode ("Receiver"), ex.Message, req.Version.Addressing.FaultNamespace); + rc.Reply (res); } finally { if (rc != null) rc.Close (); @@ -615,30 +609,30 @@ namespace System.ServiceModel.Dispatcher EndpointDispatcher FindEndpointDispatcher (Message message) { EndpointDispatcher candidate = null; - for (int i = 0; i < owner.Endpoints.Count; i++) { - if (MessageMatchesEndpointDispatcher (message, owner.Endpoints [i])) { - var newdis = owner.Endpoints [i]; + bool hasEndpointMatch = false; + foreach (var endpoint in owner.Endpoints) { + if (endpoint.AddressFilter.Match (message)) { + hasEndpointMatch = true; + if (!endpoint.ContractFilter.Match (message)) + continue; + var newdis = endpoint; if (candidate == null || candidate.FilterPriority < newdis.FilterPriority) candidate = newdis; else if (candidate.FilterPriority == newdis.FilterPriority) throw new MultipleFilterMatchesException (); } } - if (candidate == null && owner.Host != null) - owner.Host.OnUnknownMessageReceived (message); - return candidate; - } + if (candidate == null && !hasEndpointMatch) { + if (owner.Host != null) + owner.Host.OnUnknownMessageReceived (message); + // we have to return a fault to the client anyways... + throw new EndpointNotFoundException (); + } + else if (candidate == null) + // FIXME: It is not a good place to check, but anyways detach this error from EndpointNotFoundException. + throw new ActionNotSupportedException (String.Format ("Action '{0}' did not match any operations in the target contract", message.Headers.Action)); - bool MessageMatchesEndpointDispatcher (Message req, EndpointDispatcher endpoint) - { - // FIXME: handle AddressFilterMode.Prefix too. - - Uri to = req.Headers.To; - if (to == null) - return address_filter_mode == AddressFilterMode.Any; - if (to.AbsoluteUri == Constants.WsaAnonymousUri) - return false; - return endpoint.AddressFilter.Match (req) && endpoint.ContractFilter.Match (req); + return candidate; } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ClientOperation.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ClientOperation.cs index f197245b520..9d2c92e445b 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ClientOperation.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ClientOperation.cs @@ -61,7 +61,7 @@ namespace System.ServiceModel.Dispatcher SynchronizedCollection inspectors = new SynchronizedCollection (); #if !NET_2_1 - SynchronizedCollection fault_contract_infos; + SynchronizedCollection fault_contract_infos = new SynchronizedCollection (); #endif public ClientOperation (ClientRuntime parent, @@ -106,15 +106,7 @@ namespace System.ServiceModel.Dispatcher #if !NET_2_1 public SynchronizedCollection FaultContractInfos { - get { - if (fault_contract_infos == null) { - var l = new SynchronizedCollection (); - foreach (var f in Description.Faults) - l.Add (new FaultContractInfo (f.Action, f.DetailType)); - fault_contract_infos = l; - } - return fault_contract_infos; - } + get { return fault_contract_infos; } } #endif diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DispatchOperation.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DispatchOperation.cs index 832dc557009..cedc7e66693 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DispatchOperation.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/DispatchOperation.cs @@ -59,7 +59,8 @@ namespace System.ServiceModel.Dispatcher IOperationInvoker invoker; SynchronizedCollection inspectors = new SynchronizedCollection (); - SynchronizedCollection fault_contract_infos; + SynchronizedCollection fault_contract_infos + = new SynchronizedCollection (); SynchronizedCollection ctx_initializers = new SynchronizedCollection (); @@ -106,15 +107,7 @@ namespace System.ServiceModel.Dispatcher } public SynchronizedCollection FaultContractInfos { - get { - if (fault_contract_infos == null) { - var l = new SynchronizedCollection (); - foreach (var f in Description.Faults) - l.Add (new FaultContractInfo (f.Action, f.DetailType)); - fault_contract_infos = l; - } - return fault_contract_infos; - } + get { return fault_contract_infos; } } public IDispatchMessageFormatter Formatter { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointAddressMessageFilter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointAddressMessageFilter.cs index 49ce5704eee..aa7dc41a011 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointAddressMessageFilter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointAddressMessageFilter.cs @@ -44,6 +44,8 @@ namespace System.ServiceModel.Dispatcher public EndpointAddressMessageFilter (EndpointAddress address, bool includeHostNameInComparison) { + if (address == null) + throw new ArgumentNullException ("address"); this.address = address; cmp_host = includeHostNameInComparison; } @@ -63,10 +65,11 @@ namespace System.ServiceModel.Dispatcher throw new NotImplementedException (); } - [MonoTODO] public override bool Match (Message message) { Uri to = message.Headers.To; + if (to == null) + return false; bool path = ((String.CompareOrdinal (to.AbsolutePath, address.Uri.AbsolutePath) == 0) && (to.Port == address.Uri.Port)); bool host = IncludeHostNameInComparison diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointDispatcher.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointDispatcher.cs index c5c7deb28e9..f8568b7e078 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointDispatcher.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/EndpointDispatcher.cs @@ -159,6 +159,9 @@ namespace System.ServiceModel.Dispatcher } } + foreach (var fd in od.Faults) + o.FaultContractInfos.Add (new FaultContractInfo (fd.Action, fd.DetailType)); + // Setup Invoker o.Invoker = new DefaultOperationInvoker (od); diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ErrorProcessingHandler.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ErrorProcessingHandler.cs index 5157e4c7421..baa0f4ee0fb 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ErrorProcessingHandler.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/ErrorProcessingHandler.cs @@ -26,11 +26,14 @@ namespace System.ServiceModel.Dispatcher if (handler.HandleError (ex)) break; + // FIXME: remove them. FaultConverter also covers errors like EndpointNotFoundException, which this handler never covers. And checking converter twice is extraneous, so this part is just extraneous. + // FIXME: actually everything is done in OperationInvokerHandler now... FaultConverter fc = FaultConverter.GetDefaultFaultConverter (dispatchRuntime.ChannelDispatcher.MessageVersion); Message res = null; if (!fc.TryCreateFaultMessage (ex, out res)) throw ex; mrc.ReplyMessage = res; + if (duplex != null) mrc.Reply (duplex, true); else diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/FaultContractInfo.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/FaultContractInfo.cs index 98f44a5aef1..36d3255b67d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/FaultContractInfo.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/FaultContractInfo.cs @@ -25,6 +25,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; +using System.Runtime.Serialization; using System.ServiceModel; namespace System.ServiceModel.Dispatcher @@ -41,8 +42,18 @@ namespace System.ServiceModel.Dispatcher Detail = detail; } + DataContractSerializer serializer; + public string Action { get; private set; } public Type Detail { get; private set; } + + internal DataContractSerializer Serializer { + get { + if (serializer == null) + serializer = new DataContractSerializer (Detail); + return serializer; + } + } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/OperationInvokerHandler.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/OperationInvokerHandler.cs index f5504c8c181..cd4e28ded6c 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/OperationInvokerHandler.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/OperationInvokerHandler.cs @@ -49,7 +49,13 @@ namespace System.ServiceModel.Dispatcher object result = operation.Invoker.Invoke (instance, parameters, out outParams); HandleInvokeResult (mrc, outParams, result); } else { - var ar = operation.Invoker.InvokeBegin (instance, parameters, null, null); + AsyncCallback callback = delegate {}; + // FIXME: the original code passed null callback + // and null state, which is very wrong :( + // It is still wrong to pass dummy callback, but + // wrong code without obvious issues is better + // than code with an obvious issue. + var ar = operation.Invoker.InvokeBegin (instance, parameters, callback, null); object result = operation.Invoker.InvokeEnd (instance, out outParams, ar); HandleInvokeResult (mrc, outParams, result); } @@ -98,16 +104,6 @@ namespace System.ServiceModel.Dispatcher mrc.ReplyMessage = res; } - Message CreateActionNotSupported (Message req) - { - FaultCode fc = new FaultCode ( - req.Version.Addressing.ActionNotSupported, - req.Version.Addressing.Namespace); - // FIXME: set correct namespace URI - return Message.CreateMessage (req.Version, fc, - String.Format ("action '{0}' is not supported in this service contract.", req.Headers.Action), String.Empty); - } - void BuildInvokeParams (MessageProcessingContext mrc, out object [] parameters) { DispatchOperation operation = mrc.Operation; @@ -155,6 +151,14 @@ namespace System.ServiceModel.Dispatcher var req = mrc.IncomingMessage; + var fe = ex as FaultException; + if (fe != null && fe.GetType ().IsGenericType) { + var t = fe.GetType ().GetGenericArguments () [0]; + foreach (var fci in mrc.Operation.FaultContractInfos) + if (fci.Detail == t) + return Message.CreateMessage (req.Version, fe.CreateMessageFault (), fci.Action); + } + // FIXME: set correct name FaultCode fc = new FaultCode ( "InternalServiceFault", diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageContext.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageContext.cs index 434f459ca0e..3bef60dc7cf 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageContext.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageContext.cs @@ -34,22 +34,22 @@ using System.ServiceModel; namespace System.ServiceModel.Dispatcher { - [MonoTODO] public class XPathMessageContext : XsltContext { public XPathMessageContext () - : base () + : this (new NameTable ()) { } public XPathMessageContext (NameTable nameTable) : base (nameTable) { + AddNamespace ("s11", Constants.Soap11); + AddNamespace ("s12", Constants.Soap12); } - [MonoTODO] public override bool Whitespace { - get { throw new NotImplementedException (); } + get { return false; } // as documented. } public override int CompareDocument (string uri1, string uri2) @@ -57,24 +57,21 @@ namespace System.ServiceModel.Dispatcher return String.CompareOrdinal (uri1, uri2); } - [MonoTODO] public override bool PreserveWhitespace (XPathNavigator node) { - throw new NotImplementedException (); + return false; // as documented. } - [MonoTODO] public override IXsltContextFunction ResolveFunction ( string prefix, string name, XPathResultType [] argTypes) { - throw new NotImplementedException (); + return null; } - [MonoTODO] public override IXsltContextVariable ResolveVariable ( string prefix, string name) { - throw new NotImplementedException (); + return null; } } } \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageFilterTable.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageFilterTable.cs index b65b4e94e8b..71d7536fd34 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageFilterTable.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/XPathMessageFilterTable.cs @@ -147,6 +147,16 @@ namespace System.ServiceModel.Dispatcher throw new NotImplementedException (); } + public bool GetMatchingFilter (SeekableXPathNavigator navigator, out MessageFilter filter) + { + throw new NotImplementedException (); + } + + public bool GetMatchingFilter (XPathNavigator navigator, out MessageFilter filter) + { + throw new NotImplementedException (); + } + public bool GetMatchingFilters (Message message, ICollection results) { throw new NotImplementedException (); @@ -157,6 +167,16 @@ namespace System.ServiceModel.Dispatcher throw new NotImplementedException (); } + public bool GetMatchingFilters (SeekableXPathNavigator navigator, ICollection results) + { + throw new NotImplementedException (); + } + + public bool GetMatchingFilters (XPathNavigator navigator, ICollection results) + { + throw new NotImplementedException (); + } + public bool GetMatchingValue (Message message, out TFilterData data) { throw new NotImplementedException (); @@ -167,6 +187,16 @@ namespace System.ServiceModel.Dispatcher throw new NotImplementedException (); } + public bool GetMatchingValue (SeekableXPathNavigator navigator, out TFilterData data) + { + throw new NotImplementedException (); + } + + public bool GetMatchingValue (XPathNavigator navigator, out TFilterData data) + { + throw new NotImplementedException (); + } + public bool GetMatchingValues (Message message, ICollection results) { throw new NotImplementedException (); @@ -177,6 +207,16 @@ namespace System.ServiceModel.Dispatcher throw new NotImplementedException (); } + public bool GetMatchingValues (SeekableXPathNavigator navigator, ICollection results) + { + throw new NotImplementedException (); + } + + public bool GetMatchingValues (XPathNavigator navigator, ICollection results) + { + throw new NotImplementedException (); + } + public bool Remove (KeyValuePair item) { if (dict.ContainsKey (item.Key) && dict [item.Key].Equals (item.Value)) { @@ -188,29 +228,27 @@ namespace System.ServiceModel.Dispatcher public bool Remove (XPathMessageFilter filter) { - throw new NotImplementedException (); + return dict.Remove (filter); } public bool Remove (MessageFilter filter) { - return dict.Remove (filter); + return Remove ((XPathMessageFilter) filter); } - public bool TryGetValue (MessageFilter filter, out TFilterData filterData) + static Exception trim_to_size_error; + + public void TrimToSize () { - if (dict.ContainsKey (filter)) { - filterData = dict [filter]; - return true; - } else { - filterData = default (TFilterData); - return false; - } + // This is the documented behavior: throws NIE. + if (trim_to_size_error == null) + trim_to_size_error = new NotImplementedException (); + throw trim_to_size_error; } - [MonoTODO] - public void TrimToSize () + public bool TryGetValue (MessageFilter filter, out TFilterData data) { - throw new NotImplementedException (); + return dict.TryGetValue (filter, out data); } } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources index 7e74bcf267e..39586cfa16b 100755 --- a/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/System.ServiceModel.dll.sources @@ -257,7 +257,10 @@ System.ServiceModel.Channels/PeerInputChannel.cs System.ServiceModel.Channels/PeerOutputChannel.cs System.ServiceModel.Channels/PeerTransportBindingElement.cs System.ServiceModel.Channels/PnrpPeerResolverBindingElement.cs +System.ServiceModel.Channels/PrivacyNoticeBindingElement.cs +System.ServiceModel.Channels/ReliableSessionBindingElement.cs System.ServiceModel.Channels/ReliableSessionBindingElementImporter.cs +System.ServiceModel.Channels/RemoteEndpointMessageProperty.cs System.ServiceModel.Channels/ReplyChannelBase.cs System.ServiceModel.Channels/RequestChannelBase.cs System.ServiceModel.Channels/RequestContext.cs @@ -319,6 +322,8 @@ System.ServiceModel.Configuration/AuthorizationPolicyTypeElement.cs System.ServiceModel.Configuration/AuthorizationPolicyTypeElementCollection.cs System.ServiceModel.Configuration/BaseAddressElement.cs System.ServiceModel.Configuration/BaseAddressElementCollection.cs +System.ServiceModel.Configuration/BaseAddressPrefixFilterElementCollection.cs +System.ServiceModel.Configuration/BaseAddressPrefixFilterElement.cs System.ServiceModel.Configuration/BasicHttpBindingCollectionElement.cs System.ServiceModel.Configuration/BasicHttpBindingElement.cs System.ServiceModel.Configuration/BasicHttpMessageSecurityElement.cs @@ -540,7 +545,6 @@ System.ServiceModel.Description/DataContractSerializerMessageContractImporter.cs System.ServiceModel.Description/DataContractSerializerOperationBehavior.cs System.ServiceModel.Description/FaultDescription.cs System.ServiceModel.Description/FaultDescriptionCollection.cs -System.ServiceModel.Description/HostedBindingBehavior.cs System.ServiceModel.Description/IContractBehavior.cs System.ServiceModel.Description/IContractBehaviorAttribute.cs System.ServiceModel.Description/IEndpointBehavior.cs @@ -801,6 +805,7 @@ System.ServiceModel/BasicHttpBinding.cs System.ServiceModel/BasicHttpMessageSecurity.cs System.ServiceModel/BasicHttpSecurity.cs System.ServiceModel/CallbackBehaviorAttribute.cs +System.ServiceModel/ChannelTerminatedException.cs System.ServiceModel/ChannelFactory.cs System.ServiceModel/ChannelFactory_1.cs System.ServiceModel/ClientBase.cs diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog b/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog index d2d6c934443..dd610773554 100755 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog @@ -1,3 +1,77 @@ +2010-04-23 Atsushi Enomoto + + * ServiceHostBase.cs: + actually it should be ChannelDispatcher-to-HttpChannelListener, + to identify which dispatcher to send reqs. + +2010-04-23 Atsushi Enomoto + + * ServiceHostBase.cs : add host-to-http-listener mapping so that + they can be managed per host. + +2010-04-05 Atsushi Enomoto + + * ChannelTerminatedException.cs : new class. + +2010-04-02 Atsushi Enomoto + + * ClientRuntimeChannel.cs : hush on non-ml profile. + +2010-04-02 Atsushi Enomoto + + * ClientRuntimeChannel.cs : + use DataContractSerializer.IsStartObject() to check if the fault + detail reader is for the fault contract, in addition to Action. + +2010-04-02 Atsushi Enomoto + + * ClientRuntimeChannel.cs : fix moonlight build. + +2010-04-02 Atsushi Enomoto + + * ClientRuntimeChannel.cs : use FaultContractInfos to create custom + FaultException. (It's not picking the expected FCI yet.) + +2010-03-30 Atsushi Enomoto + + * ClientRuntimeChannel.cs : use correct buffer size. + +2010-03-26 Atsushi Enomoto + + * ClientRuntimeChannel.cs : use FaultConverter as documented at: + http://msdn.microsoft.com/en-us/library/ms789039%28VS.100%29.aspx + (Though I found _no_ use of this FC class in the world...) + +2010-03-24 Atsushi Enomoto + + * ServiceHostBase.cs : if there is an existing ChannelDispatcher + for the same endpoint URI, reuse it. Patch by Matt Dargavel. + +2010-03-18 Atsushi Enomoto + + * Constants.cs : add more. + +2010-03-18 Atsushi Enomoto + + * Dummy.cs : removed some dummy types (not dummy anymore). + +2010-03-17 Atsushi Enomoto + + * ServiceHostBase.cs : use namespace for mex binding comparison, to + cover other bindings than http (such as https). + * WSHttpBindingBase.cs : add some comment. + +2010-03-16 Jb Evain + + * ClientBase.cs, ClientRuntimeChannel.cs: use MOONLIGHT symbol to + disambiguate MonoTouch and Moonlight code. + +2010-03-15 Atsushi Enomoto + + * ServiceHostBase.cs : do not reject endpoints with an identical + contract to existing ones but with different binding, address or + listen URI. + 2010-03-09 Atsushi Enomoto * HttpTransportSecurity.cs : remove MonoTODOs. diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ChannelTerminatedException.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ChannelTerminatedException.cs new file mode 100644 index 00000000000..012b9b141ef --- /dev/null +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ChannelTerminatedException.cs @@ -0,0 +1,43 @@ +// +// ChannelTerminatedException.cs +// +// Author: Atsushi Enomoto +// +// Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; + +namespace System.ServiceModel +{ + [Serializable] + public class ChannelTerminatedException : CommunicationException + { + public ChannelTerminatedException () : base () {} + public ChannelTerminatedException (string msg) : base (msg) {} + public ChannelTerminatedException (string msg, Exception inner) : base (msg, inner) {} + protected ChannelTerminatedException (SerializationInfo info, StreamingContext context) : + base (info, context) {} + } +} diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs index 6281ba53bc8..d9e98a18567 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs @@ -39,13 +39,13 @@ namespace System.ServiceModel { [MonoTODO ("It somehow rejects classes, but dunno how we can do that besides our code wise.")] public abstract class ClientBase : -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT IDisposable, #endif ICommunicationObject where TChannel : class { static InstanceContext initialContxt = new InstanceContext (null); -#if NET_2_1 && !MONOTOUCH +#if MOONLIGHT static readonly PropertyInfo dispatcher_main_property; static readonly MethodInfo dispatcher_begin_invoke_method; @@ -222,7 +222,7 @@ namespace System.ServiceModel void RunCompletedCallback (SendOrPostCallback callback, InvokeAsyncCompletedEventArgs args) { -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT callback (args); #else object dispatcher = dispatcher_main_property.GetValue (null, null); @@ -276,7 +276,7 @@ namespace System.ServiceModel } IAsyncResult begin_async_result; -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT void IDisposable.Dispose () { Close (); @@ -402,7 +402,7 @@ namespace System.ServiceModel } } -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT protected object Invoke (string methodName, object [] args) { var cd = endpoint.Contract; diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs index ffd858cd256..a1c9a73258b 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs @@ -27,6 +27,7 @@ // using System; using System.Reflection; +using System.Runtime.Serialization; using System.ServiceModel.Channels; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; @@ -166,7 +167,7 @@ namespace System.ServiceModel.MonoInternal } } -#if !NET_2_1 || MONOTOUCH +#if !MOONLIGHT public override bool WaitOne (int millisecondsTimeout, bool exitContext) { return WaitHandle.WaitAll (ResultWaitHandles, millisecondsTimeout, exitContext); @@ -429,8 +430,10 @@ namespace System.ServiceModel.MonoInternal try { return DoProcess (method, operationName, parameters); } catch (Exception ex) { +#if MOONLIGHT // just for debugging Console.Write ("Exception in async operation: "); Console.WriteLine (ex); +#endif throw; } } @@ -482,20 +485,33 @@ namespace System.ServiceModel.MonoInternal Message res = Request (req, OperationTimeout); if (res.IsFault) { - MessageFault fault = MessageFault.CreateFault (res, runtime.MaxFaultSize); - if (fault.HasDetail && fault is MessageFault.SimpleMessageFault) { - MessageFault.SimpleMessageFault simpleFault = fault as MessageFault.SimpleMessageFault; - object detail = simpleFault.Detail; - Type t = detail.GetType (); - Type faultType = typeof (FaultException<>).MakeGenericType (t); - object [] constructorParams = new object [] { detail, fault.Reason, fault.Code, fault.Actor }; - FaultException fe = (FaultException) Activator.CreateInstance (faultType, constructorParams); - throw fe; - } - else { - // given a MessageFault, it is hard to figure out the type of the embedded detail - throw new FaultException(fault); + var resb = res.CreateBufferedCopy (runtime.MaxFaultSize); + MessageFault fault = MessageFault.CreateFault (resb.CreateMessage (), runtime.MaxFaultSize); + var conv = OperationChannel.GetProperty () ?? FaultConverter.GetDefaultFaultConverter (res.Version); + Exception ex; + if (!conv.TryCreateException (resb.CreateMessage (), fault, out ex)) { + if (fault.HasDetail) { + Type detailType = typeof (ExceptionDetail); + var freader = fault.GetReaderAtDetailContents (); + DataContractSerializer ds = null; +#if !NET_2_1 + foreach (var fci in op.FaultContractInfos) + if (res.Headers.Action == fci.Action || fci.Serializer.IsStartObject (freader)) { + detailType = fci.Detail; + ds = fci.Serializer; + break; + } +#endif + if (ds == null) + ds = new DataContractSerializer (detailType); + var detail = ds.ReadObject (freader); + ex = (Exception) Activator.CreateInstance (typeof (FaultException<>).MakeGenericType (detailType), new object [] {detail, fault.Reason, fault.Code, res.Headers.Action}); + } + + if (ex == null) + ex = new FaultException (fault); } + throw ex; } for (int i = 0; i < inspections.Length; i++) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/Constants.cs b/mcs/class/System.ServiceModel/System.ServiceModel/Constants.cs index 0c69185b2b7..8363da178a5 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/Constants.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/Constants.cs @@ -31,6 +31,9 @@ namespace System.ServiceModel { internal class Constants { + public const string Soap11 = "http://schemas.xmlsoap.org/soap/envelope/"; + public const string Soap12 = "http://www.w3.org/2003/05/soap-envelope"; + public const string WSBasicSecurityProfileCore1 = "http://ws-i.org/profiles/basic-security/core/1.0"; public const string WsaAnonymousUri = "http://www.w3.org/2005/08/addressing/anonymous"; diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/Dummy.cs b/mcs/class/System.ServiceModel/System.ServiceModel/Dummy.cs index faf46e474d3..5a1241df70a 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/Dummy.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/Dummy.cs @@ -17,9 +17,7 @@ namespace System.ServiceModel.Activation.Configuration namespace System.ServiceModel.Channels { - public class PrivacyNoticeBindingElement { } public class PrivacyNoticeBindingElementImporter { } - public class ReliableSessionBindingElement { } public class UseManagedPresentationBindingElementImporter { } public class XmlSerializerImportOptions { } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ServiceHostBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ServiceHostBase.cs index f799f9a3cd7..81b5608aabd 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ServiceHostBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ServiceHostBase.cs @@ -41,6 +41,9 @@ namespace System.ServiceModel public abstract partial class ServiceHostBase : CommunicationObject, IExtensibleObject, IDisposable { + // It is used for mapping a ServiceHostBase to HttpChannelListener precisely. + internal static ServiceHostBase CurrentServiceHostHack; + ServiceCredentials credentials; ServiceDescription description; UriSchemeKeyedCollection base_addresses; @@ -197,7 +200,7 @@ namespace System.ServiceModel Uri address, Uri listenUri) { EndpointAddress ea = BuildEndpointAddress (address, binding); - ContractDescription cd = GetContract (implementedContract, binding.Name == "MetadataExchangeHttpBinding"); + ContractDescription cd = GetContract (implementedContract, binding.Namespace == "http://schemas.microsoft.com/ws/2005/02/mex/bindings"); if (cd == null) throw new InvalidOperationException (String.Format ("Contract '{0}' was not found in the implemented contracts in this service host.", implementedContract)); return AddServiceEndpointCore (cd, binding, ea, listenUri); @@ -279,7 +282,7 @@ namespace System.ServiceModel ContractDescription cd, Binding binding, EndpointAddress address, Uri listenUri) { foreach (ServiceEndpoint e in Description.Endpoints) - if (e.Contract == cd) + if (e.Contract == cd && e.Binding == binding && e.Address == address && e.ListenUri.Equals (listenUri)) return e; ServiceEndpoint se = new ServiceEndpoint (cd, binding, address); se.ListenUri = listenUri.IsAbsoluteUri ? listenUri : new Uri (address.Uri, listenUri); @@ -287,7 +290,6 @@ namespace System.ServiceModel return se; } - [MonoTODO] protected virtual void ApplyConfiguration () { if (Description == null) @@ -316,7 +318,6 @@ namespace System.ServiceModel // services foreach (ServiceEndpointElement endpoint in service.Endpoints) { - // FIXME: consider BindingName as well ServiceEndpoint se = AddServiceEndpoint ( endpoint.Contract, ConfigUtil.CreateBinding (endpoint.Binding, endpoint.BindingConfiguration), @@ -377,18 +378,18 @@ namespace System.ServiceModel //Build all ChannelDispatchers, one dispatcher per user configured EndPoint. //We must keep thet ServiceEndpoints as a seperate collection, since the user //can change the collection in the description during the behaviors events. - Dictionary endPointToDispatcher = new Dictionary(); ServiceEndpoint[] endPoints = new ServiceEndpoint[Description.Endpoints.Count]; Description.Endpoints.CopyTo (endPoints, 0); + var builder = new DispatcherBuilder (this); foreach (ServiceEndpoint se in endPoints) { var commonParams = new BindingParameterCollection (); foreach (IServiceBehavior b in Description.Behaviors) b.AddBindingParameters (Description, this, Description.Endpoints, commonParams); - var channel = new DispatcherBuilder ().BuildChannelDispatcher (Description.ServiceType, se, commonParams); - ChannelDispatchers.Add (channel); - endPointToDispatcher[se] = channel; + var channel = builder.BuildChannelDispatcher (Description.ServiceType, se, commonParams); + if (!ChannelDispatchers.Contains (channel)) + ChannelDispatchers.Add (channel); } //After the ChannelDispatchers are created, and attached to the service host @@ -396,9 +397,7 @@ namespace System.ServiceModel foreach (IServiceBehavior b in Description.Behaviors) b.ApplyDispatchBehavior (Description, this); - foreach(KeyValuePair val in endPointToDispatcher) - foreach (var ed in val.Value.Endpoints) - ApplyDispatchBehavior (ed, val.Key); + builder.ApplyDispatchBehaviors (); } private void ValidateDescription () @@ -412,19 +411,6 @@ namespace System.ServiceModel throw new InvalidOperationException ("The ServiceHost must have at least one application endpoint (that does not include metadata exchange contract) defined by either configuration, behaviors or call to AddServiceEndpoint methods."); } - private void ApplyDispatchBehavior (EndpointDispatcher ed, ServiceEndpoint endPoint) - { - foreach (IContractBehavior b in endPoint.Contract.Behaviors) - b.ApplyDispatchBehavior (endPoint.Contract, endPoint, ed.DispatchRuntime); - foreach (IEndpointBehavior b in endPoint.Behaviors) - b.ApplyDispatchBehavior (endPoint, ed); - foreach (OperationDescription operation in endPoint.Contract.Operations) { - foreach (IOperationBehavior b in operation.Behaviors) - b.ApplyDispatchBehavior (operation, ed.DispatchRuntime.Operations [operation.Name]); - } - - } - [MonoTODO] protected void LoadConfigurationSection (ServiceElement element) { @@ -598,19 +584,76 @@ namespace System.ServiceModel */ } + /// + /// Builds ChannelDispatchers as appropriate to service the service endpoints. + /// + /// Will re-use ChannelDispatchers when two endpoint uris are the same partial class DispatcherBuilder { + ServiceHostBase host; + + public DispatcherBuilder (ServiceHostBase host) + { + this.host = host; + } + + List built_dispatchers = new List (); + Dictionary ep_to_dispatcher_ep = new Dictionary (); + + internal static Action ChannelDispatcherSetter; + internal ChannelDispatcher BuildChannelDispatcher (Type serviceType, ServiceEndpoint se, BindingParameterCollection commonParams) { //Let all behaviors add their binding parameters AddBindingParameters (commonParams, se); - //User the binding parameters to build the channel listener and Dispatcher - IChannelListener lf = BuildListener (se, commonParams); - ChannelDispatcher cd = new ChannelDispatcher ( - lf, se.Binding.Name); - cd.InitializeServiceEndpoint (serviceType, se); + + // See if there's an existing channel that matches this endpoint + ChannelDispatcher cd = FindExistingDispatcher (se); + EndpointDispatcher ep; + if (cd != null) { + ep = cd.InitializeServiceEndpoint (serviceType, se); + } else { + // Use the binding parameters to build the channel listener and Dispatcher. + lock (HttpTransportBindingElement.ListenerBuildLock) { + ServiceHostBase.CurrentServiceHostHack = host; + IChannelListener lf = BuildListener (se, commonParams); + cd = new ChannelDispatcher (lf, se.Binding.Name); + if (ChannelDispatcherSetter != null) { + ChannelDispatcherSetter (cd); + ChannelDispatcherSetter = null; + } + ServiceHostBase.CurrentServiceHostHack = null; + } + ep = cd.InitializeServiceEndpoint (serviceType, se); + built_dispatchers.Add (cd); + } + ep_to_dispatcher_ep[se] = ep; return cd; } + + ChannelDispatcher FindExistingDispatcher (ServiceEndpoint se) + { + return built_dispatchers.FirstOrDefault ((ChannelDispatcher cd) => (cd.Listener.Uri.Equals (se.ListenUri)) && cd.MessageVersion.Equals (se.Binding.MessageVersion)); + } + + internal void ApplyDispatchBehaviors () + { + foreach (KeyValuePair val in ep_to_dispatcher_ep) + ApplyDispatchBehavior (val.Value, val.Key); + } + + private void ApplyDispatchBehavior (EndpointDispatcher ed, ServiceEndpoint endPoint) + { + foreach (IContractBehavior b in endPoint.Contract.Behaviors) + b.ApplyDispatchBehavior (endPoint.Contract, endPoint, ed.DispatchRuntime); + foreach (IEndpointBehavior b in endPoint.Behaviors) + b.ApplyDispatchBehavior (endPoint, ed); + foreach (OperationDescription operation in endPoint.Contract.Operations) { + foreach (IOperationBehavior b in operation.Behaviors) + b.ApplyDispatchBehavior (operation, ed.DispatchRuntime.Operations [operation.Name]); + } + + } private void AddBindingParameters (BindingParameterCollection commonParams, ServiceEndpoint endPoint) { diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/WSHttpBindingBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel/WSHttpBindingBase.cs index 9f5fcac8879..ea294883a65 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/WSHttpBindingBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/WSHttpBindingBase.cs @@ -172,12 +172,13 @@ namespace System.ServiceModel } BindingElement tr = GetTransport (); List list = new List (); - list.Add (tx); + list.Add (tx); // it is always added. if (sec != null) list.Add (sec); list.Add (msg); if (tr != null) list.Add (tr); + // FIXME: add ReliableSessionBindingElement return new BindingElementCollection (list.ToArray ()); } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources b/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources index aaeadc7b8ff..2b8e7817b4e 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources +++ b/mcs/class/System.ServiceModel/System.ServiceModel_test.dll.sources @@ -1,3 +1,37 @@ +FeatureBased/Features.Client/AsyncCallTesterProxy.cs +FeatureBased/Features.Client/AsyncPatternServer.cs +FeatureBased/Features.Client/DataContractTesterProxy.cs +FeatureBased/Features.Client/ExitProcessHelperServer.cs +FeatureBased/Features.Client/FaultsTesterProxy.cs +FeatureBased/Features.Client/KnownTypeTesterProxy.cs +FeatureBased/Features.Client/MessageContractTesterProxy.cs +FeatureBased/Features.Client/OperationContractServer.cs +FeatureBased/Features.Client/PrimitiveTester.cs +FeatureBased/Features.Client/UntypedMessageTesterProxy.cs +FeatureBased/Features.Contracts/AsyncCallTester.cs +FeatureBased/Features.Contracts/AsyncPatternContract.cs +FeatureBased/Features.Contracts/DataContractTester.cs +FeatureBased/Features.Contracts/DualContract.cs +FeatureBased/Features.Contracts/ExitpProcessHelper.cs +FeatureBased/Features.Contracts/FaultsTester.cs +FeatureBased/Features.Contracts/KnownTypeTester.cs +FeatureBased/Features.Contracts/MessageContractTester.cs +FeatureBased/Features.Contracts/OperationContract.cs +FeatureBased/Features.Contracts/PrimitiveTester.cs +FeatureBased/Features.Contracts/UntypedMessageTester.cs +FeatureBased/Features.Serialization/AsyncCallTest.cs +FeatureBased/Features.Serialization/AsyncPatternTester.cs +FeatureBased/Features.Serialization/DataContractSerializerTest.cs +FeatureBased/Features.Serialization/DualContractTester.cs +FeatureBased/Features.Serialization/ExitProcessHelper.cs +FeatureBased/Features.Serialization/FaultsTest.cs +FeatureBased/Features.Serialization/KnownTypeTest.cs +FeatureBased/Features.Serialization/MessageContractTest.cs +FeatureBased/Features.Serialization/OperationContractTester.cs +FeatureBased/Features.Serialization/PrimitiveTesterTest.cs +FeatureBased/Features.Serialization/UntypedMessageTest.cs +FeatureBased/Features.Serialization/XmlComparer.cs +FeatureBased/TestFixtureBase.cs System.ServiceModel.Channels/AddressHeaderTest.cs System.ServiceModel.Channels/AddressingVersionTest.cs System.ServiceModel.Channels/AsymmetricSecurityBindingElementTest.cs @@ -67,11 +101,13 @@ System.ServiceModel.Configuration/StandardBindingElementTest.cs System.ServiceModel.Configuration/UserBinding.cs System.ServiceModel.Description/ClientCredentialsTest.cs System.ServiceModel.Description/ContractDescriptionTest.cs +System.ServiceModel.Description/FaultDescriptionTest.cs +System.ServiceModel.Description/MetadataExchangeBindingsTest.cs System.ServiceModel.Description/MetadataResolverTest.cs System.ServiceModel.Description/OperationDescriptionTest.cs System.ServiceModel.Description/ServiceAuthorizationBehaviorTest.cs -System.ServiceModel.Description/ServiceCredentialsTest.cs System.ServiceModel.Description/ServiceContractGeneratorTest.cs +System.ServiceModel.Description/ServiceCredentialsTest.cs System.ServiceModel.Description/ServiceDebugBehaviorTest.cs System.ServiceModel.Description/ServiceEndpointTest.cs System.ServiceModel.Description/ServiceMetadataBehaviorTest.cs @@ -80,6 +116,7 @@ System.ServiceModel.Description/TypedMessageConverterTest.cs System.ServiceModel.Description/WsdlExporterTest.cs System.ServiceModel.Description/WsdlImporterTest.cs System.ServiceModel.Dispatcher/ActionFilterTest.cs +System.ServiceModel.Dispatcher/ChannelDispatcherTest.cs System.ServiceModel.Dispatcher/DispatchOperationTest.cs System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs System.ServiceModel.Dispatcher/EndpointAddressMessageFilterTest.cs @@ -88,7 +125,7 @@ System.ServiceModel.Dispatcher/ExceptionHandlerTest.cs System.ServiceModel.Dispatcher/FilterTableTest.cs System.ServiceModel.Dispatcher/InvalidBodyAccessExceptionTest.cs System.ServiceModel.Dispatcher/PrefixEndpointAddressMessageFilterTest.cs -System.ServiceModel.Dispatcher/ChannelDispatcherTest.cs +System.ServiceModel.Dispatcher/XPathMessageContextTest.cs System.ServiceModel.PeerResolvers/CustomPeerResolverServiceTest.cs System.ServiceModel.PeerResolvers/PeerResolverSerializationTest.cs System.ServiceModel.Security.Tokens/IssuedSecurityTokenParametersTest.cs @@ -113,6 +150,7 @@ System.ServiceModel.Security/SecurityTokenSpeficicationTest.cs System.ServiceModel.Security/ServiceCredentialsSecurityTokenManagerTest.cs System.ServiceModel.Security/ServiceSecurityContextTest.cs System.ServiceModel.Security/SupportingTokenParametersTest.cs +System.ServiceModel.Security/TransportSecurityBindingElementTest.cs System.ServiceModel.Security/WSSecurityTokenSerializerTest.cs System.ServiceModel/BasicHttpBindingTest.cs System.ServiceModel/CallbackBehaviorAttributeTest.cs @@ -122,6 +160,7 @@ System.ServiceModel/ClientBaseTest.cs System.ServiceModel/ClientBase_InteractiveChannelInitializerTest.cs System.ServiceModel/ClientCredentialsSecurityTokenManagerTest.cs System.ServiceModel/CommonUseCases.cs +System.ServiceModel/Constants.cs System.ServiceModel/EndpointAddress10Test.cs System.ServiceModel/EndpointAddressBuilderTest.cs System.ServiceModel/EndpointAddressTest.cs @@ -129,12 +168,13 @@ System.ServiceModel/EndpointBehaviorCollectionTest.cs System.ServiceModel/EndpointIdentityTest.cs System.ServiceModel/ExtensionCollectionTest.cs System.ServiceModel/FaultCodeTest.cs +System.ServiceModel/FaultContractAttributeTest.cs System.ServiceModel/FaultReasonTest.cs System.ServiceModel/IntegratedConnectionTest.cs System.ServiceModel/MessageSecurityVersionTest.cs System.ServiceModel/NetMsmqBindingTest.cs -System.ServiceModel/NetTcpBindingTest.cs System.ServiceModel/NetPeerTcpBindingTest.cs +System.ServiceModel/NetTcpBindingTest.cs System.ServiceModel/OperationContextTest.cs System.ServiceModel/PeerNodeAddressTest.cs System.ServiceModel/ServiceAssert.cs @@ -147,23 +187,3 @@ System.ServiceModel/TransactionProtocolTest.cs System.ServiceModel/UriSchemeKeyedCollectionTest.cs System.ServiceModel/WSFederationHttpBindingTest.cs System.ServiceModel/WSHttpBindingTest.cs -FeatureBased/TestFixtureBase.cs -FeatureBased/Features.Client/DataContractTesterProxy.cs -FeatureBased/Features.Client/PrimitiveTester.cs -FeatureBased/Features.Contracts/DataContractTester.cs -FeatureBased/Features.Contracts/DualContract.cs -FeatureBased/Features.Contracts/MessageContractTester.cs -FeatureBased/Features.Contracts/PrimitiveTester.cs -FeatureBased/Features.Serialization/DataContractSerializerTest.cs -FeatureBased/Features.Serialization/DualContractTester.cs -FeatureBased/Features.Serialization/PrimitiveTesterTest.cs -FeatureBased/Features.Client/FaultsTesterProxy.cs -FeatureBased/Features.Client/KnownTypeTesterProxy.cs -FeatureBased/Features.Client/MessageContractTesterProxy.cs -FeatureBased/Features.Client/UntypedMessageTesterProxy.cs -FeatureBased/Features.Serialization/FaultsTest.cs -FeatureBased/Features.Contracts/FaultsTester.cs -FeatureBased/Features.Contracts/KnownTypeTester.cs -FeatureBased/Features.Serialization/MessageContractTest.cs -FeatureBased/Features.Contracts/UntypedMessageTester.cs -FeatureBased/Features.Serialization/XmlComparer.cs diff --git a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncCallTest.cs b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncCallTest.cs index d61a3eae06b..5be1171fbc5 100644 --- a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncCallTest.cs +++ b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncCallTest.cs @@ -9,8 +9,7 @@ using System.Threading; namespace MonoTests.Features.Serialization { [TestFixture] - [Category ("NotWorking")] // Can't even build in Mono. Missing public APIs. - public class AsyncCallTest : TestFixtureBase + public class AsyncCallTest : TestFixtureBase { bool client_QueryCompleted; string s = string.Empty; @@ -21,6 +20,7 @@ namespace MonoTests.Features.Serialization { } [Test] + [Category ("NotWorking")] public void TestAsyncCall () { ev = new AutoResetEvent(false); diff --git a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncPatternTester.cs b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncPatternTester.cs index 265751ed9ba..6d6a30ff542 100644 --- a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncPatternTester.cs +++ b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/AsyncPatternTester.cs @@ -14,7 +14,6 @@ namespace MonoTests.Features.Serialization { [Test] - [Category("NotWorking")] public void TestAsync () { Assert.AreEqual (ClientProxy.AsyncMethod (), 3, "Called method with AsyncPattern=true"); } diff --git a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/ChangeLog b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/ChangeLog index a8f889a7a48..c6604c5d252 100644 --- a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/ChangeLog @@ -1,3 +1,13 @@ +2010-04-21 Atsushi Enomoto + + * AsyncCallTest.cs : disable it again, it somehow does not work with + the latest code from trunk (ThreadPool?). + +2010-04-19 Atsushi Enomoto + + * AsyncPatternTester.cs, MessageContractTest.cs, AsyncCallTest.cs: + enable working tests. + 2009-02-24 Atsushi Enomoto * MessageContractTest.cs: diff --git a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/MessageContractTest.cs b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/MessageContractTest.cs index a429b00a32c..6b6bb2f95ab 100644 --- a/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/MessageContractTest.cs +++ b/mcs/class/System.ServiceModel/Test/FeatureBased/Features.Serialization/MessageContractTest.cs @@ -7,8 +7,7 @@ using NUnit.Framework; namespace MonoTests.Features.Serialization { [TestFixture] - [Category ("NotWorking")] // Serialization failure - public class MessageContractTest : TestFixtureBase + public class MessageContractTest : TestFixtureBase { [Test] [Ignore ("fails under .NET; I never bothered to fix the test")] diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog index 75c583db55a..54cb53aaaac 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/ChangeLog @@ -1,3 +1,51 @@ +2010-04-21 Atsushi Enomoto + + * CustomBindingTest.cs : enable BuildChannelListener test for no- + transport case. Test CanBuildChannelListener too. + +2010-04-01 Atsushi Enomoto + + * TcpTransportBindingElementTest.cs : GetProperty() here too. + +2010-04-01 Atsushi Enomoto + + * HttpsTransportBindingElementTest.cs : + added test for GetProperty(). + +2010-03-29 Atsushi Enomoto + + * FaultConverterTest.cs : added more TryCreateException() tests. + +2010-03-29 Atsushi Enomoto + + * MessageHeaderTest.cs : enable one, add not-working cosmetic one. + +2010-03-29 Atsushi Enomoto + + * MessageBufferTest.cs : enable not-working test. + +2010-03-29 Atsushi Enomoto + + * MessageFaultTest.cs : enable previous test. + +2010-03-29 Atsushi Enomoto + + * FaultConverterTest.cs : enable previous test. + +2010-03-26 Atsushi Enomoto + + * FaultConverterTest.cs, MessageFaultTest.cs : add new and not-working + tests. + +2010-03-26 Atsushi Enomoto + + * MessageBufferTest.cs : add test for copy of IsFault value. + +2010-03-25 Atsushi Enomoto + + * MessageTest.cs : add another IsFault tests, which exposed some + issues at client side. + 2010-01-21 Atsushi Enomoto * SslStreamSecurityBindingElementTest.cs : reduce extra base dep. diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CustomBindingTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CustomBindingTest.cs index a3948a36c71..02e209690b5 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CustomBindingTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CustomBindingTest.cs @@ -242,13 +242,20 @@ namespace MonoTests.System.ServiceModel.Channels } [Test] - [ExpectedException (typeof (ArgumentException))] - [Category ("NotWorking")] + [ExpectedException (typeof (InvalidOperationException))] + public void CanBuildChannelListenerNoTransport () + { + CustomBinding cb = new CustomBinding (); + BindingContext ctx = new BindingContext ( + cb, new BindingParameterCollection ()); + Assert.IsFalse (new TextMessageEncodingBindingElement ().CanBuildChannelListener (ctx), "#1"); + } + + [Test] + [ExpectedException (typeof (InvalidOperationException))] public void BuildChannelListenerNoTransport () { - CustomBinding cb = new CustomBinding ( - new TextMessageEncodingBindingElement (), - new CompositeDuplexBindingElement ()); + CustomBinding cb = new CustomBinding (); BindingContext ctx = new BindingContext ( cb, new BindingParameterCollection ()); new TextMessageEncodingBindingElement ().BuildChannelListener (ctx); diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/FaultConverterTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/FaultConverterTest.cs index 60587df22dc..7df58d9954f 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/FaultConverterTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/FaultConverterTest.cs @@ -38,7 +38,8 @@ namespace MonoTests.System.ServiceModel.Channels public class FaultConverterTest { static readonly FaultConverter s11 = FaultConverter.GetDefaultFaultConverter (MessageVersion.Soap11WSAddressing10); - static readonly FaultConverter s12 = FaultConverter.GetDefaultFaultConverter (MessageVersion.Default); + static readonly FaultConverter s12 = FaultConverter.GetDefaultFaultConverter (MessageVersion.Soap12WSAddressing10); + static readonly FaultConverter none = FaultConverter.GetDefaultFaultConverter (MessageVersion.None); XmlWriterSettings GetWriterSettings () { @@ -48,7 +49,7 @@ namespace MonoTests.System.ServiceModel.Channels } [Test] - public void TryCreateExceptionDefault () + public void TryCreateFaultMessageDefault () { Message msg; Assert.IsFalse (s12.TryCreateFaultMessage (new Exception ("error happened"), out msg), "#1-1"); @@ -57,11 +58,108 @@ namespace MonoTests.System.ServiceModel.Channels Assert.IsFalse (s12.TryCreateFaultMessage (new FaultException ("fault happened."), out msg), "#1-3"); + Assert.IsTrue (s12.TryCreateFaultMessage (new ActionNotSupportedException (), out msg), "#1-4"); + Assert.IsTrue (msg.IsFault, "#1-5"); + Assert.AreEqual ("http://www.w3.org/2005/08/addressing/fault", msg.Headers.Action, "#1-6"); + var f = MessageFault.CreateFault (msg, 1000); + Assert.AreEqual ("Sender", f.Code.Name, "#1-7"); + Assert.AreEqual ("http://www.w3.org/2003/05/soap-envelope", f.Code.Namespace, "#1-8"); + Assert.AreEqual ("ActionNotSupported", f.Code.SubCode.Name, "#1-9"); + Assert.AreEqual ("http://www.w3.org/2005/08/addressing", f.Code.SubCode.Namespace, "#1-10"); + Assert.IsFalse (s11.TryCreateFaultMessage (new Exception ("error happened"), out msg), "#2-1"); Assert.IsFalse (s11.TryCreateFaultMessage (new FaultException ("fault happened", FaultCode.CreateSenderFaultCode (new FaultCode ("IAmBroken"))), out msg), "#2-2"); Assert.IsFalse (s11.TryCreateFaultMessage (new FaultException ("fault happened."), out msg), "#2-3"); + + Assert.IsTrue (s11.TryCreateFaultMessage (new ActionNotSupportedException (), out msg), "#2-4"); + Assert.IsTrue (msg.IsFault, "#2-5"); + Assert.AreEqual ("http://www.w3.org/2005/08/addressing/fault", msg.Headers.Action, "#2-6"); + f = MessageFault.CreateFault (msg, 1000); + Assert.AreEqual ("ActionNotSupported", f.Code.Name, "#2-7"); + Assert.AreEqual ("http://www.w3.org/2005/08/addressing", f.Code.Namespace, "#2-8"); + + Assert.IsFalse (none.TryCreateFaultMessage (new Exception ("error happened"), out msg), "#3-1"); + + Assert.IsFalse (none.TryCreateFaultMessage (new FaultException ("fault happened", FaultCode.CreateSenderFaultCode (new FaultCode ("IAmBroken"))), out msg), "#3-2"); + + Assert.IsFalse (none.TryCreateFaultMessage (new FaultException ("fault happened."), out msg), "#3-3"); + + Assert.IsFalse (none.TryCreateFaultMessage (new ActionNotSupportedException (), out msg), "#3-4"); + + Assert.IsFalse (none.TryCreateFaultMessage (new EndpointNotFoundException (), out msg), "#3-5"); + } + + string xml1 = @" + + + http://www.w3.org/2005/08/addressing/fault + + + + a:ActionNotSupported + some error + + +"; + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TryCreateExceptionMessageNullDefault () + { + var msg = Message.CreateMessage (XmlReader.Create (new StringReader (xml1)), 0x1000, MessageVersion.Soap11WSAddressing10); + var mf = MessageFault.CreateFault (msg, 1000); + Exception ex; + s11.TryCreateException (null, mf, out ex); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void TryCreateExceptionFaultNullDefault () + { + var msg = Message.CreateMessage (XmlReader.Create (new StringReader (xml1)), 0x1000, MessageVersion.Soap11WSAddressing10); + Exception ex; + s11.TryCreateException (msg, null, out ex); + } + + [Test] + public void TryCreateExceptionDefault () + { + var msg = Message.CreateMessage (XmlReader.Create (new StringReader (xml1)), 0x1000, MessageVersion.Soap11WSAddressing10); + var mf = MessageFault.CreateFault (msg, 1000); + msg = Message.CreateMessage (XmlReader.Create (new StringReader (xml1)), 0x1000, MessageVersion.Soap11WSAddressing10); + Exception ex; + Assert.IsTrue (s11.TryCreateException (msg, mf, out ex), "#1"); + // foobar -> false + Assert.IsFalse (s11.TryCreateException (msg, MessageFault.CreateFault (new FaultCode ("foobar"), new FaultReason ("foobar reason")), out ex), "#2"); + // SOAP 1.1 ActionNotSupported -> true + Assert.IsTrue (s11.TryCreateException (msg, MessageFault.CreateFault (new FaultCode ("ActionNotSupported", Constants.WsaNamespace), new FaultReason ("foobar reason")), out ex), "#3"); + Assert.IsTrue (ex is ActionNotSupportedException, "#3-2"); + Assert.IsTrue (ex.Message.IndexOf ("foobar") >= 0, "#3-3"); + + // SOAP 1.1 Sender/ActionNotSupported -> false + mf = MessageFault.CreateFault (new FaultCode ("Sender", new FaultCode ("ActionNotSupported", Constants.WsaNamespace)), new FaultReason ("foobar reason")); + Assert.IsFalse (s11.TryCreateException (msg, mf, out ex), "#4"); + // SOAP 1.2 ActionNotSupported -> false + mf = MessageFault.CreateFault (new FaultCode ("ActionNotSupported", Constants.WsaNamespace), new FaultReason ("foobar reason")); + Assert.IsFalse (s12.TryCreateException (msg, mf, out ex), "#5"); + // SOAP 1.2 Sender/ActionNotSupported -> true + mf = MessageFault.CreateFault (new FaultCode ("Sender", new FaultCode ("ActionNotSupported", Constants.WsaNamespace)), new FaultReason ("foobar reason")); + Assert.IsTrue (s12.TryCreateException (msg, mf, out ex), "#6"); + Assert.IsTrue (ex is ActionNotSupportedException, "#6-2"); + Assert.IsTrue (ex.Message.IndexOf ("foobar") >= 0, "#6-3"); + } + + [Test] + public void TryCreateException2Default () + { + // test buffered copy (which used to fail) + var msg = Message.CreateMessage (XmlReader.Create (new StringReader (xml1)), 0x1000, MessageVersion.Soap11WSAddressing10); + var mb = msg.CreateBufferedCopy (1000); + var mf = MessageFault.CreateFault (mb.CreateMessage (), 1000); + Exception ex; + Assert.IsTrue (s11.TryCreateException (mb.CreateMessage (), mf, out ex), "#7"); } } } diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/HttpsTransportBindingElementTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/HttpsTransportBindingElementTest.cs index 0e827a934bb..caf0d7f827e 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/HttpsTransportBindingElementTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/HttpsTransportBindingElementTest.cs @@ -62,5 +62,23 @@ namespace MonoTests.System.ServiceModel.Channels b.Security.Mode = BasicHttpSecurityMode.Transport; b.BuildChannelListener (new Uri ("http://localhost:8080")); } + + [Test] + public void GetProperty () + { + var b = new HttpsTransportBindingElement (); + var s = b.GetProperty (new BindingContext (new CustomBinding (), new BindingParameterCollection ())); + Assert.IsNotNull (s, "#1"); + Assert.AreEqual (ProtectionLevel.EncryptAndSign, s.SupportedRequestProtectionLevel, "#2"); + Assert.AreEqual (ProtectionLevel.EncryptAndSign, s.SupportedResponseProtectionLevel, "#3"); + Assert.IsFalse (s.SupportsClientAuthentication, "#4"); + Assert.IsFalse (s.SupportsClientWindowsIdentity, "#5"); + Assert.IsTrue (s.SupportsServerAuthentication, "#6"); + + b.RequireClientCertificate = true; + s = b.GetProperty (new BindingContext (new CustomBinding (), new BindingParameterCollection ())); + Assert.IsTrue (s.SupportsClientAuthentication, "#7"); + Assert.IsTrue (s.SupportsClientWindowsIdentity, "#8"); + } } } diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageBufferTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageBufferTest.cs index 7bf87c60cfc..70868e4be2c 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageBufferTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageBufferTest.cs @@ -66,7 +66,6 @@ namespace MonoTests.System.ServiceModel.Channels } [Test] - [Category ("NotWorking")] public void TestWriteMessage () { Message m = Message.CreateMessage (MessageVersion.Default, "action", 1); @@ -175,6 +174,18 @@ namespace MonoTests.System.ServiceModel.Channels msg.WriteMessage (w); } } + + [Test] + public void IsFaultCopied () + { + var ret = Message.CreateMessage (MessageVersion.Soap12, + MessageFault.CreateFault (new FaultCode ("mycode"), "private affair"), + "http://tempuri.org/IFoo/Test"); + Assert.IsTrue (ret.IsFault, "#1"); + var mb = ret.CreateBufferedCopy (0x1000); + ret = mb.CreateMessage (); + Assert.IsTrue (ret.IsFault, "#2"); + } } internal class MyBodyWriter : BodyWriter diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs index 791dee7f7d9..eae3d7ca74b 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageFaultTest.cs @@ -58,5 +58,27 @@ namespace MonoTests.System.ServiceModel.Channels var msg = Message.CreateMessage (XmlReader.Create (new StreamReader ("Test/System.ServiceModel.Channels/soap-fault-incomplete4.xml")), 0x10000, MessageVersion.Default); MessageFault.CreateFault (msg, 0x10000); } + + [Test] + public void CreateFaultFromMessage () + { + var xml = @" + + + http://www.w3.org/2005/08/addressing/fault + + + + a:ActionNotSupported + some error + + +"; + var msg = Message.CreateMessage (XmlReader.Create (new StringReader (xml)), 0x1000, MessageVersion.Soap11WSAddressing10); + MessageFault.CreateFault (msg, 1000); + msg = Message.CreateMessage (XmlReader.Create (new StringReader (xml)), 0x1000, MessageVersion.Soap11WSAddressing10); + var mb = msg.CreateBufferedCopy (1000); + MessageFault.CreateFault (mb.CreateMessage (), 1000); + } } } diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageHeaderTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageHeaderTest.cs index 7b3e8bfcc56..79d3759c9cf 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageHeaderTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageHeaderTest.cs @@ -91,13 +91,22 @@ namespace MonoTests.System.ServiceModel.Channels } [Test] - [Category ("NotWorking")] public void TestWriteHeaderContent () { - int value = 1; + TestWriteHeaderContent (1, "1"); + } + [Test] + [Category ("NotWorking")] // too cosmetic, it just does not output xmlns:i. (insignificant) + public void TestWriteHeaderContent2 () + { + TestWriteHeaderContent (new UniqueId (new byte [] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5}), ""); + } + + void TestWriteHeaderContent (object value, string expected) + { MessageHeader h = MessageHeader.CreateHeader ("foo", "bar", value); - XmlObjectSerializer f = new DataContractSerializer (typeof (int)); + XmlObjectSerializer f = new DataContractSerializer (value.GetType ()); StringBuilder sb = new StringBuilder (); XmlWriterSettings settings = new XmlWriterSettings (); @@ -109,13 +118,18 @@ namespace MonoTests.System.ServiceModel.Channels h.WriteHeaderContents (w, MessageVersion.Soap12WSAddressing10); w.WriteEndElement (); w.Flush (); - string actual = sb.ToString (); + string actual2 = sb.ToString (); - f.WriteObject (w, value); - string expected = sb.ToString (); + sb.Length = 0; + w.WriteStartElement ("dummy-root"); + f.WriteObjectContent (w, value); + w.WriteEndElement (); + w.Flush (); + string actual1 = sb.ToString (); // the output of WriteHeaderContent is the same as XmlSerializer.Serialize - Assert.AreEqual (expected, actual); + Assert.AreEqual (expected, actual1, "#1"); + Assert.AreEqual (expected, actual2, "#2"); } [Test] diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageTest.cs index a54294c2674..992c7209fe9 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/MessageTest.cs @@ -320,6 +320,39 @@ namespace MonoTests.System.ServiceModel.Channels Assert.IsTrue (m.IsFault, "#2"); } + [Test] + public void IsFault2 () + { + string xml = @" + + + http://www.w3.org/2005/08/addressing/fault + + + + + s:Sender + + a:ActionNotSupported + + + + message + + + +"; + var msg = Message.CreateMessage (MessageVersion.Soap11, "urn:foo", XmlReader.Create (new StringReader (xml))); + Assert.AreEqual ("urn:foo", msg.Headers.Action, "#1"); + msg.ToString (); + Assert.IsFalse (msg.IsFault, "#2"); // version mismatch + + msg = Message.CreateMessage (MessageVersion.Soap12, "urn:foo", XmlReader.Create (new StringReader (xml))); + Assert.AreEqual ("urn:foo", msg.Headers.Action, "#3"); + msg.ToString (); + Assert.IsFalse (msg.IsFault, "#4"); // version match, but it doesn't set as true. It is set true only when it is constructed with fault objects. + } + [Test] public void State () { diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/TcpTransportBindingElementTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/TcpTransportBindingElementTest.cs index 9c528514572..63cef539a43 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/TcpTransportBindingElementTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/TcpTransportBindingElementTest.cs @@ -146,5 +146,22 @@ namespace MonoTests.System.ServiceModel.Channels Assert.IsFalse (be.CanBuildChannelListener (ctx), "#11"); Assert.IsFalse (be.CanBuildChannelListener (ctx), "#12"); } + + [Test] + public void GetPrpertyBindingDeliveryCapabilities () + { + var be = new TcpTransportBindingElement (); + var dc = be.GetProperty (new BindingContext (new CustomBinding (), new BindingParameterCollection ())); + Assert.IsTrue (dc.AssuresOrderedDelivery, "#1"); + Assert.IsFalse (dc.QueuedDelivery, "#2"); + } + + [Test] + public void GetPropertySecurityCapabilities () + { + var b = new TcpTransportBindingElement (); + var s = b.GetProperty (new BindingContext (new CustomBinding (), new BindingParameterCollection ())); + Assert.IsNull (s, "#1"); + } } } diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/ChangeLog b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/ChangeLog index a3cd0a70029..0550b6debf1 100755 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/ChangeLog @@ -1,3 +1,19 @@ +2010-04-05 Atsushi Enomoto + + * WsdlExporterTest.cs : fixed and enabled some working tests. + +2010-04-02 Atsushi Enomoto + + * FaultDescriptionTest.cs : add new test. + +2010-03-29 Atsushi Enomoto + + * MetadataResolverTest.cs : enable working tests. + +2010-03-17 Atsushi Enomoto + + * MetadataExchangeBindingsTest.cs : new test. + 2010-02-10 Atsushi Enomoto * WsdlImporterTest.cs : ignore whatever make dist broke. diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/FaultDescriptionTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/FaultDescriptionTest.cs new file mode 100644 index 00000000000..f1761546738 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/FaultDescriptionTest.cs @@ -0,0 +1,74 @@ +// +// FaultDescriptionTest.cs +// +// Author: +// Atsushi Enomoto +// +// Copyright (C) 2010 Novell, Inc. http://www.novell.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.ObjectModel; +using System.Net.Security; +using System.Reflection; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.Description +{ + [TestFixture] + public class FaultDescriptionTest + { + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void NullAction () + { + new FaultDescription (null); + } + + [Test] + public void SimpleUse () + { + var cd = ContractDescription.GetContract (typeof (ITestContract)); + var od = cd.Operations [0]; + Assert.AreEqual (1, od.Faults.Count, "#1"); + var fd = od.Faults [0]; + // automatically filled names + Assert.AreEqual ("http://tempuri.org/ITestContract/EchoMyDetailFault", fd.Action, "#2"); + Assert.AreEqual ("MyDetailFault", fd.Name, "#3"); + Assert.AreEqual ("http://tempuri.org/", fd.Namespace, "#4"); + } + + class MyDetail + { + } + + [ServiceContract] + interface ITestContract + { + [OperationContract] + [FaultContract (typeof (MyDetail))] + string Echo (string input); + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/MetadataExchangeBindingsTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/MetadataExchangeBindingsTest.cs new file mode 100644 index 00000000000..3b533c69e36 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/MetadataExchangeBindingsTest.cs @@ -0,0 +1,59 @@ +// +// MetadataResolverTest.cs +// +// Author: +// Atsushi Enomoto +// +// Copyright (C) 2010 Novell, Inc. http://www.novell.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Runtime.Serialization; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; + +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.Description +{ + [TestFixture] + public class MetadataExchangeBindingsTest + { + [Test] + public void CreateMexHttpBinding () + { + var b = MetadataExchangeBindings.CreateMexHttpBinding () as WSHttpBinding; + Assert.IsNotNull (b, "#1"); + Assert.AreEqual (SecurityMode.None, b.Security.Mode, "#2"); + Assert.IsFalse (b.TransactionFlow, "#3"); + Assert.IsFalse (b.ReliableSession.Enabled, "#4"); + Assert.IsFalse (b.CreateBindingElements ().Any (be => be is SecurityBindingElement), "#b1"); + Assert.IsTrue (b.CreateBindingElements ().Any (be => be is TransactionFlowBindingElement), "#b2"); + Assert.IsFalse (b.CreateBindingElements ().Any (be => be is ReliableSessionBindingElement), "#b3"); + Assert.IsTrue (new TransactionFlowBindingElement ().TransactionProtocol == TransactionProtocol.Default, "#x1"); + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/MetadataResolverTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/MetadataResolverTest.cs index 30c1ffdb200..75b7e27a222 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/MetadataResolverTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/MetadataResolverTest.cs @@ -153,10 +153,8 @@ namespace MonoTests.System.ServiceModel.Description [Test] [ExpectedException (typeof (InvalidOperationException))] - [Category ("NotWorking")] public void ErrResolve2 () { - /* Not working as HttpGet is not implemented yet */ //Mex cannot be fetched with HttpGet from the given url MetadataResolver.Resolve ( typeof (IEchoService), @@ -196,10 +194,8 @@ namespace MonoTests.System.ServiceModel.Description [Test] [ExpectedException (typeof (InvalidOperationException))] - [Category ("NotWorking")] public void ErrResolve5 () { - /* Not working as HttpGet is not implemented yet */ ContractDescription contract = ContractDescription.GetContract (typeof (IEchoService)); List contracts = new List (); contracts.Add (contract); diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlExporterTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlExporterTest.cs index 21551925f4e..fafcd01f62b 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlExporterTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Description/WsdlExporterTest.cs @@ -224,7 +224,6 @@ namespace MonoTests.System.ServiceModel.Description } [Test] - [Category ("NotWorking")] public void ExportMessageContract () { WsdlExporter we = new WsdlExporter (); @@ -270,18 +269,11 @@ namespace MonoTests.System.ServiceModel.Description } [Test] - //Currently throws InvalidDataContractException on mono, but once the code is - //moved to a IWsdlExportExtension, InvalidOperationException will get throw - [Category ("NotWorking")] - [Ignore ("fails under .NET; I never bothered to fix the test")] public void ExportBar1Contract () { WsdlExporter we = new WsdlExporter (); ContractDescription cd = ContractDescription.GetContract (typeof (Bar1)); - - //Cannot export as operation Foo has >1 param so Message param gets treated - //as any other param, but it is not serializable! - ExportContractExpectException (we, cd, typeof (InvalidOperationException), "ExportBar1Contract"); + we.ExportContract (cd); } //Helper methods diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/ChangeLog b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/ChangeLog index 31051bdbee8..d24f785e2f7 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/ChangeLog @@ -1,3 +1,20 @@ +2010-04-05 Atsushi Enomoto + + * EndpointAddressMessageFilterTest.cs : + Add null arg case. Enable working test. + +2010-04-05 Atsushi Enomoto + + * DispatchRuntimeTest.cs : enabled working tests again. + +2010-04-02 Atsushi Enomoto + + * DispatchOperationTest.cs : added not-working FaultContractInfo test. + +2010-03-18 Atsushi Enomoto + + * XPathMessageContextTest.cs : new. + 2010-01-06 Atsushi Enomoto * ChannelDispatcherTest.cs : format message correctly. diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchOperationTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchOperationTest.cs index 5b3eadec131..37b1210c88c 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchOperationTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchOperationTest.cs @@ -67,8 +67,7 @@ namespace MonoTests.System.ServiceModel.Dispatcher Assert.IsTrue (o.DeserializeRequest, "#1"); Assert.IsTrue (o.SerializeReply, "#2"); Assert.IsNull (o.Formatter, "#3"); - // FIXME: FaultDetailTypes -> FaultContractInfos - //Assert.AreEqual (0, o.FaultDetailTypes.Count, "#4"); + Assert.AreEqual (0, o.FaultContractInfos.Count, "#4"); Assert.IsNull (o.Invoker, "#5"); Assert.IsFalse (o.IsOneWay, "#6"); Assert.IsFalse (o.IsTerminating, "#7"); @@ -84,5 +83,59 @@ namespace MonoTests.System.ServiceModel.Dispatcher return new EndpointDispatcher ( new EndpointAddress ("http://localhost:8080"), "IFoo", "urn:foo").DispatchRuntime; } + + [Test] + public void FaultContractInfos () + { + var host = new ServiceHost (typeof (TestFaultContract)); + host.Description.Behaviors.Find ().IncludeExceptionDetailInFaults = true; + host.AddServiceEndpoint (typeof (ITestFaultContract), new BasicHttpBinding (), new Uri ("http://localhost:37564")); + host.Open (); + try { + var cf = new ChannelFactory (new BasicHttpBinding (), new EndpointAddress ("http://localhost:37564")); + var cli = cf.CreateChannel (); + cli.Run ("test"); + } catch (FaultException ex) { + var p = ex.Detail; + Assert.AreEqual (5, p.ErrorCode, "#1"); + Assert.AreEqual ("foobarerror", p.Text, "#2"); + } finally { + host.Close (); + } + } + + [ServiceContract] + public interface ITestFaultContract + { + [OperationContract] + [FaultContract (typeof (PrivateAffairError), Action = "urn:myfault")] + string Run (string input); + } + + class TestFaultContract : ITestFaultContract + { + public string Run (string input) + { + Assert.AreEqual (1, ContractDescription.GetContract (typeof (TestFaultContract)).Operations [0].Faults.Count, "s#0"); + + var dr = OperationContext.Current.EndpointDispatcher.DispatchRuntime; + Assert.AreEqual (1, dr.Operations.Count); + var dop = dr.Operations [0]; + Assert.AreEqual ("Run", dop.Name, "s#1"); + Assert.AreEqual (1, dop.FaultContractInfos.Count, "s#2"); + var fci = dop.FaultContractInfos [0]; + Assert.AreEqual (typeof (PrivateAffairError), fci.Detail, "s#3"); + throw new FaultException (new PrivateAffairError () { ErrorCode = 5, Text = "foobarerror" }); + } + } + + [DataContract] + class PrivateAffairError + { + [DataMember] + public int ErrorCode { get; set; } + [DataMember] + public string Text { get; set; } + } } } \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs index e6eeaacf662..013d55e9a6e 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs @@ -92,8 +92,7 @@ namespace MonoTests.System.ServiceModel.Dispatcher } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. - public void TestInstanceBehavior1() + public void TestInstanceBehavior1 () { Result res = new Result (); @@ -108,7 +107,6 @@ namespace MonoTests.System.ServiceModel.Dispatcher } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. public void TestInstanceBehavior2 () { Result res = new Result (); @@ -123,7 +121,6 @@ namespace MonoTests.System.ServiceModel.Dispatcher } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. public void TestInstanceBehavior3 () { Result res = new Result (); @@ -140,7 +137,6 @@ namespace MonoTests.System.ServiceModel.Dispatcher } [Test] - [Category ("NotWorking")] public void TestInstanceBehavior4 () { Result res = new Result (); diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/EndpointAddressMessageFilterTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/EndpointAddressMessageFilterTest.cs index b3859f2170c..5a5d4044ba2 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/EndpointAddressMessageFilterTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/EndpointAddressMessageFilterTest.cs @@ -54,7 +54,13 @@ namespace MonoTests.System.ServiceModel.Dispatcher } [Test] - [Category ("NotWorking")] + [ExpectedException (typeof (ArgumentNullException))] + public void CtorNoAddress () + { + new EndpointAddressMessageFilter (null, false); + } + + [Test] public void Match () { EndpointAddressMessageFilter f = diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/XPathMessageContextTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/XPathMessageContextTest.cs new file mode 100644 index 00000000000..6abe0e69263 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Dispatcher/XPathMessageContextTest.cs @@ -0,0 +1,58 @@ +// +// XPathMessageContextTest.cs +// +// Author: +// Atsushi Enomoto +// +// Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.ServiceModel; +using System.ServiceModel.Dispatcher; +using System.Xml; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.Dispatcher +{ + [TestFixture] + public class XPathMessageContextTest + { + XPathMessageContext ctx = new XPathMessageContext (); + + [Test] + public void PredefinedNamespaces () + { + Assert.AreEqual (Constants.Soap11, ctx.LookupNamespace ("s11"), "#1"); + Assert.AreEqual (Constants.Soap12, ctx.LookupNamespace ("s12"), "#2"); + // ... only them? + + foreach (char c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + Assert.IsNull (ctx.LookupNamespace (c + ""), "char:" + c); + + Assert.IsNull (ctx.LookupNamespace ("wsa"), "#3"); + Assert.IsNull (ctx.LookupNamespace ("wsu"), "#4"); + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/ChangeLog b/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/ChangeLog index cd47b63758d..306f17810d8 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/ChangeLog @@ -1,3 +1,7 @@ +2010-04-05 Atsushi Enomoto + + * CustomPeerResolverServiceTest.cs : enabled all disabled tests. + 2009-12-02 Atsushi Enomoto * CustomPeerResolverServiceTest.cs : diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/CustomPeerResolverServiceTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/CustomPeerResolverServiceTest.cs index fd92f7854e1..a6bc6c5e6fc 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/CustomPeerResolverServiceTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.PeerResolvers/CustomPeerResolverServiceTest.cs @@ -30,7 +30,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. public void CloseTest () { cprs.Open (); @@ -38,7 +37,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void CloseTest1 () { @@ -46,7 +44,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void GetServiceSettingsTest () { @@ -56,14 +53,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. - public void OpenTest () - { - cprs.Open (); - } - - [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (ArgumentException))] public void OpenTest1 () { @@ -72,7 +61,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (ArgumentException))] public void OpenTest2 () { @@ -81,7 +69,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (ArgumentException))] public void OpenTest3 () { @@ -91,16 +78,18 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void OpenTest4 () { cprs.Open (); - cprs.Open (); + try { + cprs.Open (); + } finally { + cprs.Close (); + } } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (ArgumentException))] public void RefreshTest () { @@ -108,7 +97,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void RefreshTest1 () { @@ -123,7 +111,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers //} [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof( ArgumentException))] public void RegisterTest () { @@ -131,7 +118,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void RegisterTest1 () { @@ -146,7 +132,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers //} [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (ArgumentException))] public void ResolveTest () { @@ -154,7 +139,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void ResolveTest1 () { @@ -169,7 +153,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers //} [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (ArgumentException))] public void UnregisterTest () { @@ -177,7 +160,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void UnregisterTest1 () { @@ -192,7 +174,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers //} [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (ArgumentException))] public void UpdateTest () { @@ -200,7 +181,6 @@ namespace MonoTests.System.ServiceModel.PeerResolvers } [Test] - [Category ("NotWorking")] // It somehow stopped working properly recently in Nov. 2009, not sure where the source of the problem lies. [ExpectedException (typeof (InvalidOperationException))] public void UpdateTest1 () { diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog index cb0ba913dc7..fabab751925 100755 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Security/ChangeLog @@ -1,3 +1,7 @@ +2010-03-24 Atsushi Enomoto + + * TransportSecurityBindingElementTest.cs : new test. + 2009-12-14 Atsushi Enomoto * WSSecurityTokenSerializerTest.cs : disable non-working test that diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Security/TransportSecurityBindingElementTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Security/TransportSecurityBindingElementTest.cs new file mode 100644 index 00000000000..c9d7e2a150d --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Security/TransportSecurityBindingElementTest.cs @@ -0,0 +1,51 @@ +// +// TransportSecurityBindingElementTest.cs +// +// Author: +// Atsushi Enomoto +// +// Copyright (C) 2009 Novell, Inc. http://www.novell.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.Collections.ObjectModel; +using System.Net; +using System.Net.Security; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Security; +using System.ServiceModel.Security.Tokens; +using System.Security.Cryptography.Xml; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel.Security +{ + [TestFixture] + public class TransportSecurityBindingElementTest + { + [Test] + public void DefaultValues () + { + var be = new TransportSecurityBindingElement (); + } + + } +} diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel/BasicHttpBindingTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel/BasicHttpBindingTest.cs index 8ccd21c004d..7b1fa57208c 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel/BasicHttpBindingTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel/BasicHttpBindingTest.cs @@ -36,7 +36,6 @@ using NUnit.Framework; using System.ServiceModel.Configuration; using System.Configuration; using System.Text; -using System.Net; namespace MonoTests.System.ServiceModel { diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel/ChangeLog b/mcs/class/System.ServiceModel/Test/System.ServiceModel/ChangeLog index 83dc1973513..4cc3bec77c3 100755 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel/ChangeLog +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel/ChangeLog @@ -1,3 +1,26 @@ +2010-04-01 Atsushi Enomoto + + * FaultContractAttributeTest.cs : new test. + +2010-04-01 Atsushi Enomoto + + * ServiceHostBaseTest.cs : enable RunDestinationUnreachableTest() + and add another case for different addressing version. + +2010-03-29 Atsushi Enomoto + + * EndpointIdentityTest.cs, EndpointAddress10Test.cs : + enable working tests. + +2010-03-25 Atsushi Enomoto + + * ServiceHostBaseTest.cs : add not-working ActionNotFound test by + Matt Dargavel. + +2010-03-18 Atsushi Enomoto + + * Constants.cs : copied from the lib itself. + 2010-02-05 Atsushi Enomoto * ServiceHostBaseTest.cs : on unixy filesystems "/foobar" diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel/Constants.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel/Constants.cs new file mode 100644 index 00000000000..8363da178a5 --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel/Constants.cs @@ -0,0 +1,263 @@ +// +// Constants.cs +// +// Author: +// Atsushi Enomoto +// +// Copyright (C) 2006 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System.Xml; + +namespace System.ServiceModel +{ + internal class Constants + { + public const string Soap11 = "http://schemas.xmlsoap.org/soap/envelope/"; + public const string Soap12 = "http://www.w3.org/2003/05/soap-envelope"; + + public const string WSBasicSecurityProfileCore1 = "http://ws-i.org/profiles/basic-security/core/1.0"; + + public const string WsaAnonymousUri = "http://www.w3.org/2005/08/addressing/anonymous"; + public const string WsaIdentityUri = "http://schemas.xmlsoap.org/ws/2006/02/addressingidentity"; + + public const string MSSerialization = "http://schemas.microsoft.com/2003/10/Serialization/"; + + public const string WssKeyIdentifierX509Thumbptint = "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1"; + + public const string WssBase64BinaryEncodingType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"; + + public const string WssKeyIdentifierEncryptedKey = "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1"; + + public const string XmlDsig = "http://www.w3.org/2000/09/xmldsig#"; + + public const string WSSSamlToken = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1"; + public const string WSSX509Token = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"; + public const string WssKeyIdentifierSamlAssertion = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID"; + public const string WSSUserNameToken = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken"; + public const string WsscContextToken = "http://schemas.xmlsoap.org/ws/2005/02/sc/sct"; + public const string WSSKerberosToken = "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ"; + public const string WSSEncryptedKeyToken = "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey"; + + public const string WstNamespace = "http://schemas.xmlsoap.org/ws/2005/02/trust"; + public const string WssNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; + public const string Wss11Namespace = "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"; + public const string WspNamespace = "http://schemas.xmlsoap.org/ws/2004/09/policy"; + public const string WsaNamespace = "http://www.w3.org/2005/08/addressing"; + public const string WsuNamespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"; + public const string WsscNamespace = "http://schemas.xmlsoap.org/ws/2005/02/sc"; + public const string WsidNamespace = "http://schemas.xmlsoap.org/ws/2005/05/identity"; + + public const string WstIssueAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue"; + public const string WstRenewAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Renew"; + public const string WstCancelAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Cancel"; + public const string WstValidateAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Validate"; + public const string WstIssueReplyAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue"; + public const string WstRenewReplyAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Renew"; + public const string WstCancelReplyAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Cancel"; + public const string WstValidateReplyAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Validate"; + + public const string WsscDefaultLabel = "WS-SecureConversationWS-SecureConversation"; + + // .NET BUG: it requires extra white space ! + public const string WstBinaryExchangeValueTls = " http://schemas.xmlsoap.org/ws/2005/02/trust/tlsnego"; + public const string WstBinaryExchangeValueGss = "http://schemas.xmlsoap.org/ws/2005/02/trust/spnego"; + + public const string MSTlsnegoTokenContent = "http://schemas.microsoft.com/ws/2006/05/security"; + + public const string WstTlsnegoProofTokenType = "http://schemas.xmlsoap.org/2005/02/trust/tlsnego#TLS_Wrap"; + public const string WstSpnegoProofTokenType = "http://schemas.xmlsoap.org/2005/02/trust/spnego#TLS_Wrap"; + + public const string WstIssueRequest = "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue"; + public const string WstRenewRequest = "http://schemas.xmlsoap.org/ws/2005/02/trust/Renew"; + public const string WstCancelRequest = "http://schemas.xmlsoap.org/ws/2005/02/trust/Cancel"; + public const string WstValidateRequest = "http://schemas.xmlsoap.org/ws/2005/02/trust/Validate"; + + public const string WstSymmetricKeyTypeUri = "http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey"; + public const string WstAsymmetricKeyTypeUri = "http://schemas.xmlsoap.org/ws/2005/02/trust/AsymmetricKey"; + + public const string LifetimeFormat = "yyyy-MM-dd'T'HH:mm:ss.fffZ"; + + // Those OIDs except for Kerberos5 are described here: + // http://www.alvestrand.no/objectid/ + // (searching web for those OIDs would give you pointers.) + public const string OidSpnego = "1.3.6.1.5.5.2"; + public const string OidNtlmSsp = "1.3.6.1.4.1.311.2.2.10"; + public const string OidKerberos5 = "1.2.840.48018.1.2.2"; + public const string OidMIT = "1.2.840.113554.1.2.2"; + + // Peer resolvers + public const string NetPeer = "http://schemas.microsoft.com/net/2006/05/peer"; + + // See [MC-NBFS] in Microsoft OSP. The strings are copied from the PDF, so the actual values might be wrong. + static readonly string [] dict_strings = { + "mustUnderstand", "Envelope", + "http://www.w3.org/2003/05/soap-envelope", + "http://www.w3.org/2005/08/addressing", "Header", "Action", "To", "Body", "Algorithm", "RelatesTo", + "http://www.w3.org/2005/08/addressing/anonymous", "URI", "Reference", "MessageID", "Id", "Identifier", + "http://schemas.xmlsoap.org/ws/2005/02/rm", "Transforms", "Transform", "DigestMethod", "DigestValue", "Address", "ReplyTo", "SequenceAcknowledgement", "AcknowledgementRange", "Upper", "Lower", "BufferRemaining", + "http://schemas.microsoft.com/ws/2006/05/rm", + "http://schemas.xmlsoap.org/ws/2005/02/rm/SequenceAcknowledgement", "SecurityTokenReference", "Sequence", "MessageNumber", + "http://www.w3.org/2000/09/xmldsig#", + "http://www.w3.org/2000/09/xmldsig#enveloped-signature", "KeyInfo", + "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", + "http://www.w3.org/2001/04/xmlenc#", + "http://schemas.xmlsoap.org/ws/2005/02/sc", "DerivedKeyToken", "Nonce", "Signature", "SignedInfo", "CanonicalizationMethod", "SignatureMethod", "SignatureValue", "DataReference", "EncryptedData", "EncryptionMethod", "CipherData", "CipherValue", + "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Security", "Timestamp", "Created", "Expires", "Length", "ReferenceList", "ValueType", "Type", "EncryptedHeader", + "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd", "RequestSecurityTokenResponseCollection", + "http://schemas.xmlsoap.org/ws/2005/02/trust", + "http://schemas.xmlsoap.org/ws/2005/02/trust#BinarySecret", + "http://schemas.microsoft.com/ws/2006/02/transactions", "s", "Fault", "MustUnderstand", "role", "relay", "Code", "Reason", "Text", "Node", "Role", "Detail", "Value", "Subcode", "NotUnderstood", "qname", "", "From", "FaultTo", "EndpointReference", "PortType", "ServiceName", "PortName", "ReferenceProperties", "RelationshipType", "Reply", "a", + "http://schemas.xmlsoap.org/ws/2006/02/addressingidentity", "Identity", "Spn", "Upn", "Rsa", "Dns", "X509v3Certificate", + "http://www.w3.org/2005/08/addressing/fault", "ReferenceParameters", "IsReferenceParameter", + "http://www.w3.org/2005/08/addressing/reply", + "http://www.w3.org/2005/08/addressing/none", "Metadata", + "http://schemas.xmlsoap.org/ws/2004/08/addressing", + "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous", + "http://schemas.xmlsoap.org/ws/2004/08/addressing/fault", + "http://schemas.xmlsoap.org/ws/2004/06/addressingex", "RedirectTo", "Via", + "http://www.w3.org/2001/10/xml-exc-c14n#", "PrefixList", "InclusiveNamespaces", "ec", "SecurityContextToken", "Generation", "Label", "Offset", "Properties", "Cookie", "wsc", + "http://schemas.xmlsoap.org/ws/2004/04/sc", + "http://schemas.xmlsoap.org/ws/2004/04/security/sc/dk", + "http://schemas.xmlsoap.org/ws/2004/04/security/sc/sct", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RST/SCT", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RSTR/SCT", "RenewNeeded", "BadContextToken", "c", + "http://schemas.xmlsoap.org/ws/2005/02/sc/dk", + "http://schemas.xmlsoap.org/ws/2005/02/sc/sct", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Renew", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT/Renew", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Cancel", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT/Cancel", + "http://www.w3.org/2001/04/xmlenc#aes128-cbc", + "http://www.w3.org/2001/04/xmlenc#kw-aes128", + "http://www.w3.org/2001/04/xmlenc#aes192-cbc", + "http://www.w3.org/2001/04/xmlenc#kw-aes192", + "http://www.w3.org/2001/04/xmlenc#aes256-cbc", + "http://www.w3.org/2001/04/xmlenc#kw-aes256", + "http://www.w3.org/2001/04/xmlenc#des-cbc", + "http://www.w3.org/2000/09/xmldsig#dsa-sha1", + "http://www.w3.org/2001/10/xml-exc-c14n#WithComments", + "http://www.w3.org/2000/09/xmldsig#hmac-sha1", + "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256", + "http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1", + "http://www.w3.org/2001/04/xmlenc#ripemd160", + "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p", + "http://www.w3.org/2000/09/xmldsig#rsa-sha1", + "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", + "http://www.w3.org/2001/04/xmlenc#rsa-1_5", + "http://www.w3.org/2000/09/xmldsig#sha1", + "http://www.w3.org/2001/04/xmlenc#sha256", + "http://www.w3.org/2001/04/xmlenc#sha512", + "http://www.w3.org/2001/04/xmlenc#tripledes-cbc", + "http://www.w3.org/2001/04/xmlenc#kw-tripledes", + "http://schemas.xmlsoap.org/2005/02/trust/tlsnego#TLS_Wrap", + "http://schemas.xmlsoap.org/2005/02/trust/spnego#GSS_Wrap", + "http://schemas.microsoft.com/ws/2006/05/security", "dnse", "o", "Password", "PasswordText", "Username", "UsernameToken", "BinarySecurityToken", "EncodingType", "KeyIdentifier", + "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary", + "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#HexBinary", + "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Text", + "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier", + "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ", + "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ1510", + "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID", "Assertion", "urn:oasis:names:tc:SAML:1.0:assertion", + "http://docs.oasis-open.org/wss/oasis-wss-rel-token-profile-1.0.pdf#license", "FailedAuthentication", "InvalidSecurityToken", "InvalidSecurity", "k", "SignatureConfirmation", "TokenType", + "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1", + "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey", + "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1", + "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1", + "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0", + "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID", "AUTH-HASH", "RequestSecurityTokenResponse", "KeySize", "RequestedTokenReference", "AppliesTo", "Authenticator", "CombinedHash", "BinaryExchange", "Lifetime", "RequestedSecurityToken", "Entropy", "RequestedProofToken", "ComputedKey", "RequestSecurityToken", "RequestType", "Context", "BinarySecret", + "http://schemas.xmlsoap.org/ws/2005/02/trust/spnego", + "http://schemas.xmlsoap.org/ws/2005/02/trust/tlsnego", "wst", + "http://schemas.xmlsoap.org/ws/2004/04/trust", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RST/Issue", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RSTR/Issue", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/CK/PSHA1", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/SymmetricKey", + "http://schemas.xmlsoap.org/ws/2004/04/security/trust/Nonce", "KeyType", + "http://schemas.xmlsoap.org/ws/2004/04/trust/SymmetricKey", + "http://schemas.xmlsoap.org/ws/2004/04/trust/PublicKey", "Claims", "InvalidRequest", "RequestFailed", "SignWith", "EncryptWith", "EncryptionAlgorithm", "CanonicalizationAlgorithm", "ComputedKeyAlgorithm", "UseKey", + "http://schemas.microsoft.com/net/2004/07/secext/WS-SPNego", + "http://schemas.microsoft.com/net/2004/07/secext/TLSNego", "t", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue", + "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue", + "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue", + "http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey", + "http://schemas.xmlsoap.org/ws/2005/02/trust/CK/PSHA1", + "http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce", "RenewTarget", "CancelTarget", "RequestedTokenCancelled", "RequestedAttachedReference", "RequestedUnattachedReference", "IssuedTokens", + "http://schemas.xmlsoap.org/ws/2005/02/trust/Renew", + "http://schemas.xmlsoap.org/ws/2005/02/trust/Cancel", + "http://schemas.xmlsoap.org/ws/2005/02/trust/PublicKey", "Access", "AccessDecision", "Advice", "AssertionID", "AssertionIDReference", "Attribute", "AttributeName", "AttributeNamespace", "AttributeStatement", "AttributeValue", "Audience", "AudienceRestrictionCondition", "AuthenticationInstant", "AuthenticationMethod", "AuthenticationStatement", "AuthorityBinding", "AuthorityKind", "AuthorizationDecisionStatement", "Binding", "Condition", "Conditions", "Decision", "DoNotCacheCondition", "Evidence", "IssueInstant", "Issuer", "Location", "MajorVersion", "MinorVersion", "NameIdentifier", "Format", "NameQualifier", "Namespace", "NotBefore", "NotOnOrAfter", "saml", "Statement", "Subject", "SubjectConfirmation", "SubjectConfirmationData", "ConfirmationMethod", "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key", "urn:oasis:names:tc:SAML:1.0:cm:sender-vouches", "SubjectLocality", "DNSAddress", "IPAddress", "SubjectStatement", "urn:oasis:names:tc:SAML:1.0:am:unspecified", "xmlns", "Resource", "UserName", "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName", "EmailName", "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "u", "ChannelInstance", + "http://schemas.microsoft.com/ws/2005/02/duplex", "Encoding", "MimeType", "CarriedKeyName", "Recipient", "EncryptedKey", "KeyReference", "e", + "http://www.w3.org/2001/04/xmlenc#Element", + "http://www.w3.org/2001/04/xmlenc#Content", "KeyName", "MgmtData", "KeyValue", "RSAKeyValue", "Modulus", "Exponent", "X509Data", "X509IssuerSerial", "X509IssuerName", "X509SerialNumber", "X509Certificate", "AckRequested", + "http://schemas.xmlsoap.org/ws/2005/02/rm/AckRequested", "AcksTo", "Accept", "CreateSequence", + "http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence", "CreateSequenceRefused", "CreateSequenceResponse", + "http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse", "FaultCode", "InvalidAcknowledgement", "LastMessage", + "http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage", "LastMessageNumberExceeded", "MessageNumberRollover", "Nack", "netrm", "Offer", "r", "SequenceFault", "SequenceTerminated", "TerminateSequence", + "http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence", "UnknownSequence", + "http://schemas.microsoft.com/ws/2006/02/tx/oletx", "oletx", "OleTxTransaction", "PropagationToken", + "http://schemas.xmlsoap.org/ws/2004/10/wscoor", "wscoor", "CreateCoordinationContext", "CreateCoordinationContextResponse", "CoordinationContext", "CurrentContext", "CoordinationType", "RegistrationService", "Register", "RegisterResponse", "ProtocolIdentifier", "CoordinatorProtocolService", "ParticipantProtocolService", + "http://schemas.xmlsoap.org/ws/2004/10/wscoor/CreateCoordinationContext", + "http://schemas.xmlsoap.org/ws/2004/10/wscoor/CreateCoordinationContextResponse", + "http://schemas.xmlsoap.org/ws/2004/10/wscoor/Register", + "http://schemas.xmlsoap.org/ws/2004/10/wscoor/RegisterResponse", + "http://schemas.xmlsoap.org/ws/2004/10/wscoor/fault", "ActivationCoordinatorPortType", "RegistrationCoordinatorPortType", "InvalidState", "InvalidProtocol", "InvalidParameters", "NoActivity", "ContextRefused", "AlreadyRegistered", + "http://schemas.xmlsoap.org/ws/2004/10/wsat", "wsat", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Completion", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Durable2PC", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Volatile2PC", "Prepare", "Prepared", "ReadOnly", "Commit", "Rollback", "Committed", "Aborted", "Replay", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Commit", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Rollback", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Committed", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Aborted", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Prepare", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Prepared", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/ReadOnly", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/Replay", + "http://schemas.xmlsoap.org/ws/2004/10/wsat/fault", "CompletionCoordinatorPortType", "CompletionParticipantPortType", "CoordinatorPortType", "ParticipantPortType", "InconsistentInternalState", "mstx", "Enlistment", "protocol", "LocalTransactionId", "IsolationLevel", "IsolationFlags", "Description", "Loopback", "RegisterInfo", "ContextId", "TokenId", "AccessDenied", "InvalidPolicy", "CoordinatorRegistrationFailed", "TooManyEnlistments", "Disabled", "ActivityId", + "http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics", + "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#Kerberosv5APREQSHA1", + "http://schemas.xmlsoap.org/ws/2002/12/policy", "FloodMessage", "LinkUtility", "Hops", + "http://schemas.microsoft.com/net/2006/05/peer/HopCount", "PeerVia", + "http://schemas.microsoft.com/net/2006/05/peer", "PeerFlooder", "PeerTo", + "http://schemas.microsoft.com/ws/2005/05/routing", "PacketRoutable", + "http://schemas.microsoft.com/ws/2005/05/addressing/none", + "http://schemas.microsoft.com/ws/2005/05/envelope/none", + "http://www.w3.org/2001/XMLSchema-instance", + "http://www.w3.org/2001/XMLSchema", "nil", "type", "char", "boolean", "byte", "unsignedByte", "short", "unsignedShort", "int", "unsignedInt", "long", "unsignedLong", "float", "double", "decimal", "dateTime", "string", "base64Binary", "anyType", "duration", "guid", "anyURI", "QName", "time", "date", "hexBinary", "gYearMonth", "gYear", "gMonthDay", "gDay", "gMonth", "integer", "positiveInteger", "negativeInteger", "nonPositiveInteger", "nonNegativeInteger", "normalizedString", "ConnectionLimitReached", + "http://schemas.xmlsoap.org/soap/envelope/", "Actor", "Faultcode", "Faultstring", "Faultactor", "Detail" + }; + + static Constants () + { + var d = new XmlDictionary (); + SoapDictionary = d; + foreach (var s in dict_strings) + d.Add (s); + } + + public static XmlDictionary SoapDictionary { get; private set; } + } +} diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointAddress10Test.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointAddress10Test.cs index 322f097c333..123ae4aad91 100755 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointAddress10Test.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointAddress10Test.cs @@ -72,7 +72,6 @@ namespace MonoTests.System.ServiceModel } [Test] - [Category ("NotWorking")] public void SerializeDeserialize () { StringWriter sw = new StringWriter (); diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointIdentityTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointIdentityTest.cs index 0d6597053bb..da3c8b6f7b5 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointIdentityTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel/EndpointIdentityTest.cs @@ -43,7 +43,6 @@ namespace MonoTests.System.ServiceModel static readonly X509Certificate2 cert = new X509Certificate2 ("Test/Resources/test.cer"); [Test] - [Category ("NotWorking")] // DataContractSerializer+base64 issue public void CreateX509CertificateIdentity () { X509CertificateEndpointIdentity identity = diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel/FaultContractAttributeTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel/FaultContractAttributeTest.cs new file mode 100644 index 00000000000..d4df3e782cd --- /dev/null +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel/FaultContractAttributeTest.cs @@ -0,0 +1,26 @@ +using System; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using NUnit.Framework; + +namespace MonoTests.System.ServiceModel +{ + [TestFixture] + public class FaultContractAttributeTest + { + [Test] + public void Defaults () + { + var a = new FaultContractAttribute (typeof (MyDetail)); + Assert.AreEqual (typeof (MyDetail), a.DetailType, "#1"); + Assert.IsNull (a.Action, "#2"); + Assert.IsNull (a.Name, "#3"); + Assert.IsNull (a.Namespace, "#4"); + } + + class MyDetail + { + } + } +} diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel/ServiceHostBaseTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel/ServiceHostBaseTest.cs index 5a1e9ea5551..8b91324af60 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel/ServiceHostBaseTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel/ServiceHostBaseTest.cs @@ -323,6 +323,44 @@ namespace MonoTests.System.ServiceModel Assert.Fail ("should not open"); } + [Test] + public void RunDestinationUnreachableTest () + { + RunDestinationUnreachableTest ("BasicHttp", new BasicHttpBinding ()); + } + + [Test] + public void RunDestinationUnreachableTest2 () + { + RunDestinationUnreachableTest ("CustomSoap12", new CustomBinding (new HttpTransportBindingElement ())); + } + + void RunDestinationUnreachableTest (string label, Binding binding) + { + string address = "http://localhost:37564/"; + var host = OpenHost (address, binding); + + try { + var client = new DestinationUnreachableClient (binding, address); + client.NotImplementedOperation (); + Assert.Fail (label + " ActionNotSupportedException is expected"); + } catch (ActionNotSupportedException) { + // catching it instead of ExpectedException to distinguish errors at service side. + } finally { + host.Close (); + } + } + + ServiceHost OpenHost (string address, Binding binding) + { + var baseAddresses = new Uri[] { new Uri(address) }; + + var host = new ServiceHost (typeof (DummyService), baseAddresses); + host.AddServiceEndpoint (typeof (IDummyService), binding, new Uri ("", UriKind.Relative)); + host.Open (); + return host; + } + #region helpers public enum Stage @@ -606,7 +644,39 @@ namespace MonoTests.System.ServiceModel #endregion } - #endregion + [ServiceContract] + public interface IDummyService + { + [OperationContract] + void DummyOperation (); + } + public class DummyService : IDummyService + { + public void DummyOperation () + { + // Do nothing + } + } + [ServiceContract] + public interface INotImplementedService + { + [OperationContract] + void NotImplementedOperation (); + } + public class DestinationUnreachableClient : ClientBase, INotImplementedService + { + public void NotImplementedOperation () + { + Channel.NotImplementedOperation (); + } + + public DestinationUnreachableClient (Binding binding, string address) + : base (binding, new EndpointAddress (address)) + { + } + } + + #endregion } } diff --git a/mcs/class/System.ServiceModel/monotouch_System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/monotouch_System.ServiceModel.dll.sources index 2870b466997..fbaa524eab3 100644 --- a/mcs/class/System.ServiceModel/monotouch_System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/monotouch_System.ServiceModel.dll.sources @@ -1,3 +1,3 @@ ../../build/common/Consts.cs ../../build/common/MonoTODOAttribute.cs -#include net_2_1_raw_System.ServiceModel.dll.sources +#include moonlight_raw_System.ServiceModel.dll.sources diff --git a/mcs/class/System.ServiceModel/moonlight_raw_System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/moonlight_raw_System.ServiceModel.dll.sources new file mode 100755 index 00000000000..010821335ea --- /dev/null +++ b/mcs/class/System.ServiceModel/moonlight_raw_System.ServiceModel.dll.sources @@ -0,0 +1,226 @@ +Assembly/AssemblyInfo.cs +Mono.CodeGeneration/CodeAdd.cs +Mono.CodeGeneration/CodeAnd.cs +Mono.CodeGeneration/CodeArgument.cs +Mono.CodeGeneration/CodeArgumentReference.cs +Mono.CodeGeneration/CodeArithmeticOperation.cs +Mono.CodeGeneration/CodeArrayItem.cs +Mono.CodeGeneration/CodeArrayLength.cs +Mono.CodeGeneration/CodeAssignment.cs +Mono.CodeGeneration/CodeBinaryComparison.cs +Mono.CodeGeneration/CodeBinaryOperation.cs +Mono.CodeGeneration/CodeBlock.cs +Mono.CodeGeneration/CodeBuilder.cs +Mono.CodeGeneration/CodeCast.cs +Mono.CodeGeneration/CodeClass.cs +Mono.CodeGeneration/CodeCustomAttribute.cs +Mono.CodeGeneration/CodeDecrement.cs +Mono.CodeGeneration/CodeEquals.cs +Mono.CodeGeneration/CodeExpression.cs +Mono.CodeGeneration/CodeFieldReference.cs +Mono.CodeGeneration/CodeFor.cs +Mono.CodeGeneration/CodeForeach.cs +Mono.CodeGeneration/CodeGenerationHelper.cs +Mono.CodeGeneration/CodeIf.cs +Mono.CodeGeneration/CodeIncrement.cs +Mono.CodeGeneration/CodeIs.cs +Mono.CodeGeneration/CodeItem.cs +Mono.CodeGeneration/CodeLiteral.cs +Mono.CodeGeneration/CodeMethod.cs +Mono.CodeGeneration/CodeMethodCall.cs +Mono.CodeGeneration/CodeModule.cs +Mono.CodeGeneration/CodeNew.cs +Mono.CodeGeneration/CodeNewArray.cs +Mono.CodeGeneration/CodeNotEquals.cs +Mono.CodeGeneration/CodeOr.cs +Mono.CodeGeneration/CodeProperty.cs +Mono.CodeGeneration/CodePropertyReference.cs +Mono.CodeGeneration/CodeReturn.cs +Mono.CodeGeneration/CodeSelect.cs +Mono.CodeGeneration/CodeTryBlock.cs +Mono.CodeGeneration/CodeSelfIncrement.cs +Mono.CodeGeneration/CodeUnaryOperation.cs +Mono.CodeGeneration/CodeValueReference.cs +Mono.CodeGeneration/CodeVariableDeclaration.cs +Mono.CodeGeneration/CodeVariableReference.cs +Mono.CodeGeneration/CodeWhen.cs +Mono.CodeGeneration/CodeWhile.cs +Mono.CodeGeneration/CodeWriter.cs +Mono.CodeGeneration/Exp.cs +System.Collections.Generic/KeyedByTypeCollection.cs +System.Collections.Generic/SynchronizedCollection.cs +System.Collections.Generic/SynchronizedKeyedCollection.cs +System.Collections.Generic/SynchronizedReadOnlyCollection.cs +System.ServiceModel.Channels/AddressHeader.cs +System.ServiceModel.Channels/AddressHeaderCollection.cs +System.ServiceModel.Channels/AddressingVersion.cs +System.ServiceModel.Channels/BinaryMessageEncoder.cs +System.ServiceModel.Channels/BinaryMessageEncoderFactory.cs +System.ServiceModel.Channels/BinaryMessageEncodingBindingElement.cs +System.ServiceModel.Channels/Binding.cs +System.ServiceModel.Channels/BindingContext.cs +System.ServiceModel.Channels/BindingElement.cs +System.ServiceModel.Channels/BindingElementCollection.cs +System.ServiceModel.Channels/BindingParameterCollection.cs +System.ServiceModel.Channels/BodyWriter.cs +System.ServiceModel.Channels/BufferManager.cs +System.ServiceModel.Channels/ChannelBase.cs +System.ServiceModel.Channels/ChannelFactoryBase.cs +System.ServiceModel.Channels/ChannelManagerBase.cs +System.ServiceModel.Channels/ChannelParameterCollection.cs +System.ServiceModel.Channels/ChannelPoolSettings.cs +System.ServiceModel.Channels/CommunicationObject.cs +System.ServiceModel.Channels/CustomBinding.cs +System.ServiceModel.Channels/FaultConverter.cs +System.ServiceModel.Channels/HtmlizedException.cs +System.ServiceModel.Channels/HttpChannelFactory.cs +System.ServiceModel.Channels/HttpCookieContainerBindingElement.cs +System.ServiceModel.Channels/HttpRequestChannel.cs +System.ServiceModel.Channels/HttpRequestMessageProperty.cs +System.ServiceModel.Channels/HttpResponseMessageProperty.cs +System.ServiceModel.Channels/HttpTransportBindingElement.cs +System.ServiceModel.Channels/HttpsTransportBindingElement.cs +System.ServiceModel.Channels/IBindingRuntimePreferences.cs +System.ServiceModel.Channels/IChannel.cs +System.ServiceModel.Channels/IChannelFactory.cs +System.ServiceModel.Channels/IDuplexChannel.cs +System.ServiceModel.Channels/IDuplexSession.cs +System.ServiceModel.Channels/IDuplexSessionChannel.cs +System.ServiceModel.Channels/IHttpCookieContainer.cs +System.ServiceModel.Channels/IInputChannel.cs +System.ServiceModel.Channels/IInputSession.cs +System.ServiceModel.Channels/IInputSessionChannel.cs +System.ServiceModel.Channels/IMessageProperty.cs +System.ServiceModel.Channels/IOutputChannel.cs +System.ServiceModel.Channels/IOutputSession.cs +System.ServiceModel.Channels/IOutputSessionChannel.cs +System.ServiceModel.Channels/IRequestChannel.cs +System.ServiceModel.Channels/IRequestSessionChannel.cs +System.ServiceModel.Channels/ISecurityCapabilities.cs +System.ServiceModel.Channels/ISession.cs +System.ServiceModel.Channels/ISessionChannel.cs +System.ServiceModel.Channels/LayeredCommunicationObject.cs +System.ServiceModel.Channels/LayeredOutputChannel.cs +System.ServiceModel.Channels/LayeredRequestChannel.cs +System.ServiceModel.Channels/LocalClientSecuritySettings.cs +System.ServiceModel.Channels/Message.cs +System.ServiceModel.Channels/MessageBuffer_2_1.cs +System.ServiceModel.Channels/MessageBufferImpl.cs +System.ServiceModel.Channels/MessageEncoder.cs +System.ServiceModel.Channels/MessageEncoderFactory.cs +System.ServiceModel.Channels/MessageEncodingBindingElement.cs +System.ServiceModel.Channels/MessageFault.cs +System.ServiceModel.Channels/MessageFaultBodyWriter.cs +System.ServiceModel.Channels/MessageHeader.cs +System.ServiceModel.Channels/MessageHeaderInfo.cs +System.ServiceModel.Channels/MessageHeaders.cs +System.ServiceModel.Channels/MessageImpl.cs +System.ServiceModel.Channels/MessageProperties.cs +System.ServiceModel.Channels/MessageVersion.cs +System.ServiceModel.Channels/OutputChannelBase.cs +System.ServiceModel.Channels/RequestChannelBase.cs +System.ServiceModel.Channels/RequestContext.cs +System.ServiceModel.Channels/SecurityBindingElement.cs +System.ServiceModel.Channels/TextMessageEncoder.cs +System.ServiceModel.Channels/TextMessageEncoderFactory.cs +System.ServiceModel.Channels/TextMessageEncodingBindingElement.cs +System.ServiceModel.Channels/TransportBindingElement.cs +System.ServiceModel.Channels/TransportSecurityBindingElement.cs +System.ServiceModel.Channels/UnderstoodHeaders.cs +System.ServiceModel.Channels/XmlObjectSerializerBodyWriter.cs +System.ServiceModel.Channels/XmlReaderBodyWriter.cs +System.ServiceModel.Description/ClientCredentials.cs +System.ServiceModel.Description/ContractDescription.cs +System.ServiceModel.Description/ContractDescriptionGenerator.cs +System.ServiceModel.Description/FaultDescription.cs +System.ServiceModel.Description/FaultDescriptionCollection.cs +System.ServiceModel.Description/IEndpointBehavior.cs +System.ServiceModel.Description/IOperationBehavior.cs +System.ServiceModel.Description/MessageBodyDescription.cs +System.ServiceModel.Description/MessageDescription.cs +System.ServiceModel.Description/MessageDescriptionCollection.cs +System.ServiceModel.Description/MessageHeaderDescription.cs +System.ServiceModel.Description/MessageHeaderDescriptionCollection.cs +System.ServiceModel.Description/MessagePartDescription.cs +System.ServiceModel.Description/MessagePartDescriptionCollection.cs +System.ServiceModel.Description/MessagePropertyDescription.cs +System.ServiceModel.Description/MessagePropertyDescriptionCollection.cs +System.ServiceModel.Description/OperationDescription.cs +System.ServiceModel.Description/OperationDescriptionCollection.cs +System.ServiceModel.Description/ServiceEndpoint.cs +System.ServiceModel.Description/XmlName.cs +System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs +System.ServiceModel.Dispatcher/ClientOperation.cs +System.ServiceModel.Dispatcher/ClientRuntime.cs +System.ServiceModel.Dispatcher/FaultContractInfo.cs +System.ServiceModel.Dispatcher/IChannelInitializer.cs +System.ServiceModel.Dispatcher/IClientMessageFormatter.cs +System.ServiceModel.Dispatcher/IClientMessageInspector.cs +System.ServiceModel.Dispatcher/IClientOperationSelector.cs +System.ServiceModel.Dispatcher/IDispatchMessageFormatter.cs +System.ServiceModel.Dispatcher/IInteractiveChannelInitializer.cs +System.ServiceModel.Dispatcher/IParameterInspector.cs +System.ServiceModel.Security/MessageSecurityException.cs +System.ServiceModel.Security/SecurityAccessDeniedException.cs +System.ServiceModel.Security/UserNamePasswordClientCredential.cs +System.ServiceModel/ActionNotSupportedException.cs +System.ServiceModel/AllEnums.cs +System.ServiceModel/BasicHttpBinding.cs +System.ServiceModel/BasicHttpSecurity_2_1.cs +System.ServiceModel/ChannelFactory.cs +System.ServiceModel/ChannelFactory_1.cs +System.ServiceModel/ClientBase.cs +System.ServiceModel/ClientProxyGenerator.cs +System.ServiceModel/ClientRuntimeChannel.cs +System.ServiceModel/CommunicationException.cs +System.ServiceModel/CommunicationObjectAbortedException.cs +System.ServiceModel/CommunicationObjectFaultedException.cs +System.ServiceModel/Constants.cs +System.ServiceModel/DataContractFormatAttribute.cs +System.ServiceModel/DefaultCommunicationTimeouts.cs +System.ServiceModel/Dummy.cs +System.ServiceModel/EndpointAddress.cs +System.ServiceModel/EndpointAddress10.cs +System.ServiceModel/EndpointAddressBuilder.cs +System.ServiceModel/EndpointNotFoundException.cs +System.ServiceModel/EnvelopeVersion.cs +System.ServiceModel/ExceptionDetail.cs +System.ServiceModel/ExtensionCollection.cs +System.ServiceModel/FaultCode.cs +System.ServiceModel/FaultContractAttribute.cs +System.ServiceModel/FaultException.cs +System.ServiceModel/FaultException_1.cs +System.ServiceModel/FaultReason.cs +System.ServiceModel/FaultReasonText.cs +System.ServiceModel/IClientChannel.cs +System.ServiceModel/ICommunicationObject.cs +System.ServiceModel/IContextChannel.cs +System.ServiceModel/IDefaultCommunicationTimeouts.cs +System.ServiceModel/IExtensibleObject.cs +System.ServiceModel/IExtension.cs +System.ServiceModel/IExtensionCollection.cs +System.ServiceModel/InvalidMessageContractException.cs +System.ServiceModel/MessageBodyAttribute.cs +System.ServiceModel/MessageContractAttribute.cs +System.ServiceModel/MessageContractMemberAttribute.cs +System.ServiceModel/MessageHeaderArrayAttribute.cs +System.ServiceModel/MessageHeaderAttribute.cs +System.ServiceModel/MessageHeaderException.cs +System.ServiceModel/MessageHeader_1.cs +System.ServiceModel/MessageParameterAttribute.cs +System.ServiceModel/MessagePropertyAttribute.cs +System.ServiceModel/OperationContext.cs +System.ServiceModel/OperationContextScope.cs +System.ServiceModel/OperationContractAttribute.cs +System.ServiceModel/ProtocolException.cs +System.ServiceModel/QuotaExceededException.cs +System.ServiceModel/ServerTooBusyException.cs +System.ServiceModel/ServiceActivationException.cs +System.ServiceModel/ServiceContractAttribute.cs +System.ServiceModel/ServiceKnownTypeAttribute.cs +System.ServiceModel/SilverlightClientConfigLoader.cs +System.ServiceModel/TransferMode.cs +System.ServiceModel/UnknownMessageReceivedEventArgs.cs +System.ServiceModel/UriSchemeKeyedCollection.cs +System.ServiceModel/XmlSerializerFormatAttribute.cs +Dummy_2_1.cs diff --git a/mcs/class/System.ServiceModel/net_2_1_raw_System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/net_2_1_raw_System.ServiceModel.dll.sources deleted file mode 100755 index 010821335ea..00000000000 --- a/mcs/class/System.ServiceModel/net_2_1_raw_System.ServiceModel.dll.sources +++ /dev/null @@ -1,226 +0,0 @@ -Assembly/AssemblyInfo.cs -Mono.CodeGeneration/CodeAdd.cs -Mono.CodeGeneration/CodeAnd.cs -Mono.CodeGeneration/CodeArgument.cs -Mono.CodeGeneration/CodeArgumentReference.cs -Mono.CodeGeneration/CodeArithmeticOperation.cs -Mono.CodeGeneration/CodeArrayItem.cs -Mono.CodeGeneration/CodeArrayLength.cs -Mono.CodeGeneration/CodeAssignment.cs -Mono.CodeGeneration/CodeBinaryComparison.cs -Mono.CodeGeneration/CodeBinaryOperation.cs -Mono.CodeGeneration/CodeBlock.cs -Mono.CodeGeneration/CodeBuilder.cs -Mono.CodeGeneration/CodeCast.cs -Mono.CodeGeneration/CodeClass.cs -Mono.CodeGeneration/CodeCustomAttribute.cs -Mono.CodeGeneration/CodeDecrement.cs -Mono.CodeGeneration/CodeEquals.cs -Mono.CodeGeneration/CodeExpression.cs -Mono.CodeGeneration/CodeFieldReference.cs -Mono.CodeGeneration/CodeFor.cs -Mono.CodeGeneration/CodeForeach.cs -Mono.CodeGeneration/CodeGenerationHelper.cs -Mono.CodeGeneration/CodeIf.cs -Mono.CodeGeneration/CodeIncrement.cs -Mono.CodeGeneration/CodeIs.cs -Mono.CodeGeneration/CodeItem.cs -Mono.CodeGeneration/CodeLiteral.cs -Mono.CodeGeneration/CodeMethod.cs -Mono.CodeGeneration/CodeMethodCall.cs -Mono.CodeGeneration/CodeModule.cs -Mono.CodeGeneration/CodeNew.cs -Mono.CodeGeneration/CodeNewArray.cs -Mono.CodeGeneration/CodeNotEquals.cs -Mono.CodeGeneration/CodeOr.cs -Mono.CodeGeneration/CodeProperty.cs -Mono.CodeGeneration/CodePropertyReference.cs -Mono.CodeGeneration/CodeReturn.cs -Mono.CodeGeneration/CodeSelect.cs -Mono.CodeGeneration/CodeTryBlock.cs -Mono.CodeGeneration/CodeSelfIncrement.cs -Mono.CodeGeneration/CodeUnaryOperation.cs -Mono.CodeGeneration/CodeValueReference.cs -Mono.CodeGeneration/CodeVariableDeclaration.cs -Mono.CodeGeneration/CodeVariableReference.cs -Mono.CodeGeneration/CodeWhen.cs -Mono.CodeGeneration/CodeWhile.cs -Mono.CodeGeneration/CodeWriter.cs -Mono.CodeGeneration/Exp.cs -System.Collections.Generic/KeyedByTypeCollection.cs -System.Collections.Generic/SynchronizedCollection.cs -System.Collections.Generic/SynchronizedKeyedCollection.cs -System.Collections.Generic/SynchronizedReadOnlyCollection.cs -System.ServiceModel.Channels/AddressHeader.cs -System.ServiceModel.Channels/AddressHeaderCollection.cs -System.ServiceModel.Channels/AddressingVersion.cs -System.ServiceModel.Channels/BinaryMessageEncoder.cs -System.ServiceModel.Channels/BinaryMessageEncoderFactory.cs -System.ServiceModel.Channels/BinaryMessageEncodingBindingElement.cs -System.ServiceModel.Channels/Binding.cs -System.ServiceModel.Channels/BindingContext.cs -System.ServiceModel.Channels/BindingElement.cs -System.ServiceModel.Channels/BindingElementCollection.cs -System.ServiceModel.Channels/BindingParameterCollection.cs -System.ServiceModel.Channels/BodyWriter.cs -System.ServiceModel.Channels/BufferManager.cs -System.ServiceModel.Channels/ChannelBase.cs -System.ServiceModel.Channels/ChannelFactoryBase.cs -System.ServiceModel.Channels/ChannelManagerBase.cs -System.ServiceModel.Channels/ChannelParameterCollection.cs -System.ServiceModel.Channels/ChannelPoolSettings.cs -System.ServiceModel.Channels/CommunicationObject.cs -System.ServiceModel.Channels/CustomBinding.cs -System.ServiceModel.Channels/FaultConverter.cs -System.ServiceModel.Channels/HtmlizedException.cs -System.ServiceModel.Channels/HttpChannelFactory.cs -System.ServiceModel.Channels/HttpCookieContainerBindingElement.cs -System.ServiceModel.Channels/HttpRequestChannel.cs -System.ServiceModel.Channels/HttpRequestMessageProperty.cs -System.ServiceModel.Channels/HttpResponseMessageProperty.cs -System.ServiceModel.Channels/HttpTransportBindingElement.cs -System.ServiceModel.Channels/HttpsTransportBindingElement.cs -System.ServiceModel.Channels/IBindingRuntimePreferences.cs -System.ServiceModel.Channels/IChannel.cs -System.ServiceModel.Channels/IChannelFactory.cs -System.ServiceModel.Channels/IDuplexChannel.cs -System.ServiceModel.Channels/IDuplexSession.cs -System.ServiceModel.Channels/IDuplexSessionChannel.cs -System.ServiceModel.Channels/IHttpCookieContainer.cs -System.ServiceModel.Channels/IInputChannel.cs -System.ServiceModel.Channels/IInputSession.cs -System.ServiceModel.Channels/IInputSessionChannel.cs -System.ServiceModel.Channels/IMessageProperty.cs -System.ServiceModel.Channels/IOutputChannel.cs -System.ServiceModel.Channels/IOutputSession.cs -System.ServiceModel.Channels/IOutputSessionChannel.cs -System.ServiceModel.Channels/IRequestChannel.cs -System.ServiceModel.Channels/IRequestSessionChannel.cs -System.ServiceModel.Channels/ISecurityCapabilities.cs -System.ServiceModel.Channels/ISession.cs -System.ServiceModel.Channels/ISessionChannel.cs -System.ServiceModel.Channels/LayeredCommunicationObject.cs -System.ServiceModel.Channels/LayeredOutputChannel.cs -System.ServiceModel.Channels/LayeredRequestChannel.cs -System.ServiceModel.Channels/LocalClientSecuritySettings.cs -System.ServiceModel.Channels/Message.cs -System.ServiceModel.Channels/MessageBuffer_2_1.cs -System.ServiceModel.Channels/MessageBufferImpl.cs -System.ServiceModel.Channels/MessageEncoder.cs -System.ServiceModel.Channels/MessageEncoderFactory.cs -System.ServiceModel.Channels/MessageEncodingBindingElement.cs -System.ServiceModel.Channels/MessageFault.cs -System.ServiceModel.Channels/MessageFaultBodyWriter.cs -System.ServiceModel.Channels/MessageHeader.cs -System.ServiceModel.Channels/MessageHeaderInfo.cs -System.ServiceModel.Channels/MessageHeaders.cs -System.ServiceModel.Channels/MessageImpl.cs -System.ServiceModel.Channels/MessageProperties.cs -System.ServiceModel.Channels/MessageVersion.cs -System.ServiceModel.Channels/OutputChannelBase.cs -System.ServiceModel.Channels/RequestChannelBase.cs -System.ServiceModel.Channels/RequestContext.cs -System.ServiceModel.Channels/SecurityBindingElement.cs -System.ServiceModel.Channels/TextMessageEncoder.cs -System.ServiceModel.Channels/TextMessageEncoderFactory.cs -System.ServiceModel.Channels/TextMessageEncodingBindingElement.cs -System.ServiceModel.Channels/TransportBindingElement.cs -System.ServiceModel.Channels/TransportSecurityBindingElement.cs -System.ServiceModel.Channels/UnderstoodHeaders.cs -System.ServiceModel.Channels/XmlObjectSerializerBodyWriter.cs -System.ServiceModel.Channels/XmlReaderBodyWriter.cs -System.ServiceModel.Description/ClientCredentials.cs -System.ServiceModel.Description/ContractDescription.cs -System.ServiceModel.Description/ContractDescriptionGenerator.cs -System.ServiceModel.Description/FaultDescription.cs -System.ServiceModel.Description/FaultDescriptionCollection.cs -System.ServiceModel.Description/IEndpointBehavior.cs -System.ServiceModel.Description/IOperationBehavior.cs -System.ServiceModel.Description/MessageBodyDescription.cs -System.ServiceModel.Description/MessageDescription.cs -System.ServiceModel.Description/MessageDescriptionCollection.cs -System.ServiceModel.Description/MessageHeaderDescription.cs -System.ServiceModel.Description/MessageHeaderDescriptionCollection.cs -System.ServiceModel.Description/MessagePartDescription.cs -System.ServiceModel.Description/MessagePartDescriptionCollection.cs -System.ServiceModel.Description/MessagePropertyDescription.cs -System.ServiceModel.Description/MessagePropertyDescriptionCollection.cs -System.ServiceModel.Description/OperationDescription.cs -System.ServiceModel.Description/OperationDescriptionCollection.cs -System.ServiceModel.Description/ServiceEndpoint.cs -System.ServiceModel.Description/XmlName.cs -System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs -System.ServiceModel.Dispatcher/ClientOperation.cs -System.ServiceModel.Dispatcher/ClientRuntime.cs -System.ServiceModel.Dispatcher/FaultContractInfo.cs -System.ServiceModel.Dispatcher/IChannelInitializer.cs -System.ServiceModel.Dispatcher/IClientMessageFormatter.cs -System.ServiceModel.Dispatcher/IClientMessageInspector.cs -System.ServiceModel.Dispatcher/IClientOperationSelector.cs -System.ServiceModel.Dispatcher/IDispatchMessageFormatter.cs -System.ServiceModel.Dispatcher/IInteractiveChannelInitializer.cs -System.ServiceModel.Dispatcher/IParameterInspector.cs -System.ServiceModel.Security/MessageSecurityException.cs -System.ServiceModel.Security/SecurityAccessDeniedException.cs -System.ServiceModel.Security/UserNamePasswordClientCredential.cs -System.ServiceModel/ActionNotSupportedException.cs -System.ServiceModel/AllEnums.cs -System.ServiceModel/BasicHttpBinding.cs -System.ServiceModel/BasicHttpSecurity_2_1.cs -System.ServiceModel/ChannelFactory.cs -System.ServiceModel/ChannelFactory_1.cs -System.ServiceModel/ClientBase.cs -System.ServiceModel/ClientProxyGenerator.cs -System.ServiceModel/ClientRuntimeChannel.cs -System.ServiceModel/CommunicationException.cs -System.ServiceModel/CommunicationObjectAbortedException.cs -System.ServiceModel/CommunicationObjectFaultedException.cs -System.ServiceModel/Constants.cs -System.ServiceModel/DataContractFormatAttribute.cs -System.ServiceModel/DefaultCommunicationTimeouts.cs -System.ServiceModel/Dummy.cs -System.ServiceModel/EndpointAddress.cs -System.ServiceModel/EndpointAddress10.cs -System.ServiceModel/EndpointAddressBuilder.cs -System.ServiceModel/EndpointNotFoundException.cs -System.ServiceModel/EnvelopeVersion.cs -System.ServiceModel/ExceptionDetail.cs -System.ServiceModel/ExtensionCollection.cs -System.ServiceModel/FaultCode.cs -System.ServiceModel/FaultContractAttribute.cs -System.ServiceModel/FaultException.cs -System.ServiceModel/FaultException_1.cs -System.ServiceModel/FaultReason.cs -System.ServiceModel/FaultReasonText.cs -System.ServiceModel/IClientChannel.cs -System.ServiceModel/ICommunicationObject.cs -System.ServiceModel/IContextChannel.cs -System.ServiceModel/IDefaultCommunicationTimeouts.cs -System.ServiceModel/IExtensibleObject.cs -System.ServiceModel/IExtension.cs -System.ServiceModel/IExtensionCollection.cs -System.ServiceModel/InvalidMessageContractException.cs -System.ServiceModel/MessageBodyAttribute.cs -System.ServiceModel/MessageContractAttribute.cs -System.ServiceModel/MessageContractMemberAttribute.cs -System.ServiceModel/MessageHeaderArrayAttribute.cs -System.ServiceModel/MessageHeaderAttribute.cs -System.ServiceModel/MessageHeaderException.cs -System.ServiceModel/MessageHeader_1.cs -System.ServiceModel/MessageParameterAttribute.cs -System.ServiceModel/MessagePropertyAttribute.cs -System.ServiceModel/OperationContext.cs -System.ServiceModel/OperationContextScope.cs -System.ServiceModel/OperationContractAttribute.cs -System.ServiceModel/ProtocolException.cs -System.ServiceModel/QuotaExceededException.cs -System.ServiceModel/ServerTooBusyException.cs -System.ServiceModel/ServiceActivationException.cs -System.ServiceModel/ServiceContractAttribute.cs -System.ServiceModel/ServiceKnownTypeAttribute.cs -System.ServiceModel/SilverlightClientConfigLoader.cs -System.ServiceModel/TransferMode.cs -System.ServiceModel/UnknownMessageReceivedEventArgs.cs -System.ServiceModel/UriSchemeKeyedCollection.cs -System.ServiceModel/XmlSerializerFormatAttribute.cs -Dummy_2_1.cs diff --git a/mcs/class/System.ServiceModel/net_4_0_System.ServiceModel.dll.sources b/mcs/class/System.ServiceModel/net_4_0_System.ServiceModel.dll.sources index 550ccf05bd4..f8b48c78c83 100644 --- a/mcs/class/System.ServiceModel/net_4_0_System.ServiceModel.dll.sources +++ b/mcs/class/System.ServiceModel/net_4_0_System.ServiceModel.dll.sources @@ -38,3 +38,8 @@ ../System.ServiceModel.Web/System.ServiceModel.Syndication/UrlSyndicationContent.cs ../System.ServiceModel.Web/System.ServiceModel.Syndication/Workspace.cs ../System.ServiceModel.Web/System.ServiceModel.Syndication/XmlSyndicationContent.cs +../System.ServiceModel.Web/System/UriTemplate.cs +../System.ServiceModel.Web/System/UriTemplateEquivalenceComparer.cs +../System.ServiceModel.Web/System/UriTemplateMatch.cs +../System.ServiceModel.Web/System/UriTemplateMatchException.cs +../System.ServiceModel.Web/System/UriTemplateTable.cs diff --git a/mcs/class/System.Web.Abstractions/System.Web/ChangeLog b/mcs/class/System.Web.Abstractions/System.Web/ChangeLog index 10163bbf4ac..a21492a7faa 100644 --- a/mcs/class/System.Web.Abstractions/System.Web/ChangeLog +++ b/mcs/class/System.Web.Abstractions/System.Web/ChangeLog @@ -1,3 +1,8 @@ +2010-04-26 Marek Habersack + + * HttpContextWrapper.cs: implemented two 4.0 methods: RemapHandler + and SetSessionStateBehavior + 2010-02-18 Marek Habersack * HttpFileCollectionWrapper.cs: Get (string) and this [string] diff --git a/mcs/class/System.Web.Abstractions/System.Web/HttpContextWrapper.cs b/mcs/class/System.Web.Abstractions/System.Web/HttpContextWrapper.cs index 4476eaa8ebb..66e99f26106 100644 --- a/mcs/class/System.Web.Abstractions/System.Web/HttpContextWrapper.cs +++ b/mcs/class/System.Web.Abstractions/System.Web/HttpContextWrapper.cs @@ -4,7 +4,7 @@ // Author: // Atsushi Enomoto // -// Copyright (C) 2008 Novell Inc. http://novell.com +// Copyright (C) 2008-2010 Novell Inc. http://novell.com // // @@ -36,6 +36,7 @@ using System.Security.Permissions; using System.Security.Principal; using System.Web.Caching; using System.Web.Profile; +using System.Web.SessionState; namespace System.Web { @@ -187,7 +188,12 @@ namespace System.Web { throw new NotImplementedException (); } - +#if NET_4_0 + public override void RemapHandler (IHttpHandler handler) + { + w.RemapHandler (handler); + } +#endif public override void RewritePath (string path) { w.RewritePath (path); @@ -207,5 +213,11 @@ namespace System.Web { w.RewritePath (filePath, pathInfo, queryString, setClientFilePath); } +#if NET_4_0 + public override void SetSessionStateBehavior (SessionStateBehavior sessionStateBehavior) + { + w.SetSessionStateBehavior (sessionStateBehavior); + } +#endif } } diff --git a/mcs/class/System.Web.Mvc/ChangeLog b/mcs/class/System.Web.Mvc/ChangeLog index 171a479d7fa..3815b79811d 100644 --- a/mcs/class/System.Web.Mvc/ChangeLog +++ b/mcs/class/System.Web.Mvc/ChangeLog @@ -1,3 +1,8 @@ +2010-03-15 Marek Habersack + + * Makefile (LIBRARY_COMPAT): added - this lib is installed in the + compat dir. + 2010-02-17 Marek Habersack * Makefile: RESX_RES is no more, it was replaced with diff --git a/mcs/class/System.Web.Mvc/Makefile b/mcs/class/System.Web.Mvc/Makefile index bc679372257..8f8ce46a161 100644 --- a/mcs/class/System.Web.Mvc/Makefile +++ b/mcs/class/System.Web.Mvc/Makefile @@ -4,6 +4,7 @@ include ../../build/rules.make LIBRARY = System.Web.Mvc.dll LIBRARY_USE_INTERMEDIATE_FILE = yes +LIBRARY_COMPAT = yes RESX_DIST = System.Web.Mvc/Resources/MvcResources.resx diff --git a/mcs/class/System.Web.Mvc2/ChangeLog b/mcs/class/System.Web.Mvc2/ChangeLog new file mode 100644 index 00000000000..07970aade72 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/ChangeLog @@ -0,0 +1,9 @@ +2010-03-18 Marek Habersack + + * Makefile: include resources in compilation + +2010-02-09 Marek Habersack + + * Makefile: added references to + System.ComponentModel.DataAnnotations and System.Data.Linq + diff --git a/mcs/class/System.Web.Mvc2/GlobalSuppressions.cs b/mcs/class/System.Web.Mvc2/GlobalSuppressions.cs new file mode 100644 index 00000000000..71130ae5011 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/GlobalSuppressions.cs @@ -0,0 +1,26 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. +// +// To add a suppression to this file, right-click the message in the +// Error List, point to "Suppress Message(s)", and click +// "In Project Suppression File". +// You do not need to add suppressions to this file manually. + +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1>.Contains(System.Collections.Generic.KeyValuePair`2)", + Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1>.CopyTo(System.Collections.Generic.KeyValuePair`2[],System.Int32)", + Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "System.Web.Mvc.TempDataDictionary.#System.Collections.Generic.ICollection`1>.IsReadOnly", + Justification = "There are no defined scenarios for wanting to derive from this class, but we don't want to prevent it either.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "System.Web.Mvc.Ajax", + Justification = "Helpers reside within a separate namespace to support alternate helper classes.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", + Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", + Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35", + Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")] +[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Data.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", + Justification = "MVC has a .NET Framework 3.5 SP1 dependency.")] diff --git a/mcs/class/System.Web.Mvc2/Makefile b/mcs/class/System.Web.Mvc2/Makefile new file mode 100644 index 00000000000..5aba709f26c --- /dev/null +++ b/mcs/class/System.Web.Mvc2/Makefile @@ -0,0 +1,50 @@ +thisdir = class/System.Web.Mvc2 +SUBDIRS = +include ../../build/rules.make + +LIBRARY = System.Web.Mvc.dll +LIBRARY_USE_INTERMEDIATE_FILE = yes + +RESX_DIST = System.Web.Mvc/Resources/MvcResources.resx + +LIB_MCS_FLAGS = \ + /warnaserror- \ + /noconfig \ + /keyfile:../winfx.pub \ + /r:System.dll \ + /r:System.Core.dll \ + /r:System.Configuration.dll \ + /r:System.Data.dll \ + /r:System.Xml.dll \ + /r:System.Web.dll \ + /r:System.Web.Abstractions.dll \ + /r:System.Web.Routing.dll \ + /r:System.Web.Extensions.dll \ + /r:System.ComponentModel.DataAnnotations.dll \ + /r:System.Data.Linq.dll \ + $(foreach r, $(RESOURCES), /resource:$(r),System.Web.Mvc.Resources.$(notdir $(r))) + +ifeq (2.0, $(FRAMEWORK_VERSION)) +# This is a .NET 3.5 only assembly, but built during the 2.0 build +LIB_MCS_FLAGS += -d:NET_3_5 -d:MONO +endif + +EXTRA_DISTFILES = $(RESX_DIST) + +# This is a .NET 3.5+ assembly - it must be built ONLY in the 2.0 profile +VALID_PROFILE := $(filter net_2_0, $(PROFILE)) +ifndef VALID_PROFILE +LIBRARY_NAME = dummy-System.Web.Mvc.dll +NO_INSTALL = yes +NO_SIGN_ASSEMBLY = yes +NO_TEST = yes +else +RESOURCES = $(RESX_DIST:.resx=.resources) +endif + +include ../../build/library.make + +$(build_lib): $(RESOURCES) + +$(RESOURCES): %.resources: %.resx + $(RESGEN) `echo $< | $(PLATFORM_CHANGE_SEPARATOR_CMD)` diff --git a/mcs/class/System.Web.Mvc2/Properties/AssemblyInfo.cs b/mcs/class/System.Web.Mvc2/Properties/AssemblyInfo.cs new file mode 100644 index 00000000000..4a06eb8c083 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/Properties/AssemblyInfo.cs @@ -0,0 +1,63 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("System.Web.Mvc.dll")] +[assembly: AssemblyDescription("System.Web.Mvc.dll")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft Corporation")] +[assembly: AssemblyProduct("Microsoft® .NET Framework")] +[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4b5f4208-c6b0-4c37-9a41-63325ffa52ad")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2.0.0.0")] +[assembly: AssemblyFileVersion("2.0.50217.0")] + +[assembly: AllowPartiallyTrustedCallers] +[assembly: SecurityTransparent] +[assembly: CLSCompliant(true)] +[assembly: NeutralResourcesLanguage("en-US")] + +[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", + Justification = "Assembly is delay-signed.")] + +[assembly: AssemblyDelaySign (true)] +[assembly: AssemblyKeyFile("../winfx.pub")] diff --git a/mcs/class/System.Web.Mvc2/Properties/ChangeLog b/mcs/class/System.Web.Mvc2/Properties/ChangeLog new file mode 100644 index 00000000000..6e4c8c6ef29 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/Properties/ChangeLog @@ -0,0 +1,5 @@ +2010-02-09 Marek Habersack + + * AssemblyInfo.cs: added Mono-specific attributes to delay-sign + the assembly and use the winfs.pub key + diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc.csproj b/mcs/class/System.Web.Mvc2/System.Web.Mvc.csproj new file mode 100644 index 00000000000..a47c38242a9 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc.csproj @@ -0,0 +1,381 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {3D3FFD8A-624D-4E9B-954B-E1C105507975} + Library + Properties + System.Web + System.Web.Mvc + v3.5 + 512 + prompt + 4 + true + 1609891840 + + + true + full + false + ..\..\bin\Debug\ + DEBUG;TRACE + + + pdbonly + true + ..\..\bin\Release\ + TRACE + + + + + 3.5 + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + + ASPXCodeBehind + + + ASPXCodeBehind + + + + + + + True + True + MvcResources.resx + + + + + ResXFileCodeGenerator + MvcResources.Designer.cs + Designer + + + + + + + + \ No newline at end of file diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc.dll.sources b/mcs/class/System.Web.Mvc2/System.Web.Mvc.dll.sources new file mode 100644 index 00000000000..9ecb0aa8b11 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc.dll.sources @@ -0,0 +1,279 @@ +../../build/common/Consts.cs +../../build/common/MonoTODOAttribute.cs + +GlobalSuppressions.cs +Properties/AssemblyInfo.cs +System.Web.Mvc/AcceptVerbsAttribute.cs +System.Web.Mvc/ActionDescriptor.cs +System.Web.Mvc/ActionExecutedContext.cs +System.Web.Mvc/ActionExecutingContext.cs +System.Web.Mvc/ActionFilterAttribute.cs +System.Web.Mvc/ActionMethodDispatcherCache.cs +System.Web.Mvc/ActionMethodDispatcher.cs +System.Web.Mvc/ActionMethodSelectorAttribute.cs +System.Web.Mvc/ActionMethodSelector.cs +System.Web.Mvc/ActionNameAttribute.cs +System.Web.Mvc/ActionNameSelectorAttribute.cs +System.Web.Mvc/ActionResult.cs +System.Web.Mvc/ActionSelector.cs +System.Web.Mvc/Ajax/AjaxExtensions.cs +System.Web.Mvc/Ajax/AjaxOptions.cs +System.Web.Mvc/AjaxHelper`1.cs +System.Web.Mvc/AjaxHelper.cs +System.Web.Mvc/Ajax/InsertionMode.cs +System.Web.Mvc/AjaxRequestExtensions.cs +System.Web.Mvc/AntiForgeryData.cs +System.Web.Mvc/AntiForgeryDataSerializer.cs +System.Web.Mvc/AreaHelpers.cs +System.Web.Mvc/AreaRegistrationContext.cs +System.Web.Mvc/AreaRegistration.cs +System.Web.Mvc/AssociatedMetadataProvider.cs +System.Web.Mvc/AssociatedValidatorProvider.cs +System.Web.Mvc/Async/ActionDescriptorCreator.cs +System.Web.Mvc/Async/AsyncActionDescriptor.cs +System.Web.Mvc/Async/AsyncActionMethodSelector.cs +System.Web.Mvc/Async/AsyncControllerActionInvoker.cs +System.Web.Mvc/Async/AsyncManager.cs +System.Web.Mvc/Async/AsyncResultWrapper.cs +System.Web.Mvc/Async/AsyncUtil.cs +System.Web.Mvc/Async/AsyncVoid.cs +System.Web.Mvc/Async/BeginInvokeDelegate.cs +System.Web.Mvc/AsyncController.cs +System.Web.Mvc/Async/EndInvokeDelegate`1.cs +System.Web.Mvc/Async/EndInvokeDelegate.cs +System.Web.Mvc/Async/IAsyncActionInvoker.cs +System.Web.Mvc/Async/IAsyncController.cs +System.Web.Mvc/Async/IAsyncManagerContainer.cs +System.Web.Mvc/Async/OperationCounter.cs +System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs +System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs +System.Web.Mvc/Async/SimpleAsyncResult.cs +System.Web.Mvc/Async/SingleEntryGate.cs +System.Web.Mvc/Async/SynchronizationContextUtil.cs +System.Web.Mvc/Async/SynchronousOperationException.cs +System.Web.Mvc/AsyncTimeoutAttribute.cs +System.Web.Mvc/Async/Trigger.cs +System.Web.Mvc/Async/TriggerListener.cs +System.Web.Mvc/AuthorizationContext.cs +System.Web.Mvc/AuthorizeAttribute.cs +System.Web.Mvc/BindAttribute.cs +System.Web.Mvc/BuildManagerWrapper.cs +System.Web.Mvc/ByteArrayModelBinder.cs +System.Web.Mvc/ChildActionOnlyAttribute.cs +System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs +System.Web.Mvc/ContentResult.cs +System.Web.Mvc/ControllerActionInvoker.cs +System.Web.Mvc/ControllerBase.cs +System.Web.Mvc/ControllerBuilder.cs +System.Web.Mvc/ControllerContext.cs +System.Web.Mvc/Controller.cs +System.Web.Mvc/ControllerDescriptorCache.cs +System.Web.Mvc/ControllerDescriptor.cs +System.Web.Mvc/ControllerTypeCache.cs +System.Web.Mvc/CustomModelBinderAttribute.cs +System.Web.Mvc/DataAnnotationsModelMetadata.cs +System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs +System.Web.Mvc/DataAnnotationsModelValidator`1.cs +System.Web.Mvc/DataAnnotationsModelValidator.cs +System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs +System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs +System.Web.Mvc/DefaultControllerFactory.cs +System.Web.Mvc/DefaultModelBinder.cs +System.Web.Mvc/DefaultViewLocationCache.cs +System.Web.Mvc/DescriptorUtil.cs +System.Web.Mvc/DictionaryHelpers.cs +System.Web.Mvc/DictionaryValueProvider`1.cs +System.Web.Mvc/DynamicTypeGenerator.cs +System.Web.Mvc/EmptyModelMetadataProvider.cs +System.Web.Mvc/EmptyModelValidatorProvider.cs +System.Web.Mvc/EmptyResult.cs +System.Web.Mvc/Error.cs +System.Web.Mvc/ExceptionContext.cs +System.Web.Mvc/ExpressionHelper.cs +System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs +System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs +System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs +System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs +System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs +System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs +System.Web.Mvc/ExpressionUtil/ExpressionParser.cs +System.Web.Mvc/ExpressionUtil/FastTrack`2.cs +System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs +System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs +System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs +System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs +System.Web.Mvc/ExpressionUtil/ParserContext.cs +System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs +System.Web.Mvc/FieldValidationMetadata.cs +System.Web.Mvc/FileContentResult.cs +System.Web.Mvc/FilePathResult.cs +System.Web.Mvc/FileResult.cs +System.Web.Mvc/FileStreamResult.cs +System.Web.Mvc/FilterAttribute.cs +System.Web.Mvc/FilterInfo.cs +System.Web.Mvc/FormCollection.cs +System.Web.Mvc/FormContext.cs +System.Web.Mvc/FormMethod.cs +System.Web.Mvc/FormValueProvider.cs +System.Web.Mvc/FormValueProviderFactory.cs +System.Web.Mvc/HandleErrorAttribute.cs +System.Web.Mvc/HandleErrorInfo.cs +System.Web.Mvc/HiddenInputAttribute.cs +System.Web.Mvc/Html/ChildActionExtensions.cs +System.Web.Mvc/Html/DefaultDisplayTemplates.cs +System.Web.Mvc/Html/DefaultEditorTemplates.cs +System.Web.Mvc/Html/DisplayExtensions.cs +System.Web.Mvc/Html/DisplayTextExtensions.cs +System.Web.Mvc/Html/EditorExtensions.cs +System.Web.Mvc/Html/FormExtensions.cs +System.Web.Mvc/HtmlHelper`1.cs +System.Web.Mvc/HtmlHelper.cs +System.Web.Mvc/Html/InputExtensions.cs +System.Web.Mvc/Html/LabelExtensions.cs +System.Web.Mvc/Html/LinkExtensions.cs +System.Web.Mvc/Html/MvcForm.cs +System.Web.Mvc/Html/PartialExtensions.cs +System.Web.Mvc/Html/RenderPartialExtensions.cs +System.Web.Mvc/Html/SelectExtensions.cs +System.Web.Mvc/Html/TemplateHelpers.cs +System.Web.Mvc/Html/TextAreaExtensions.cs +System.Web.Mvc/Html/ValidationExtensions.cs +System.Web.Mvc/HttpAntiForgeryException.cs +System.Web.Mvc/HttpDeleteAttribute.cs +System.Web.Mvc/HttpFileCollectionValueProvider.cs +System.Web.Mvc/HttpFileCollectionValueProviderFactory.cs +System.Web.Mvc/HttpGetAttribute.cs +System.Web.Mvc/HttpHandlerUtil.cs +System.Web.Mvc/HttpPostAttribute.cs +System.Web.Mvc/HttpPostedFileBaseModelBinder.cs +System.Web.Mvc/HttpPutAttribute.cs +System.Web.Mvc/HttpRequestExtensions.cs +System.Web.Mvc/HttpUnauthorizedResult.cs +System.Web.Mvc/HttpVerbs.cs +System.Web.Mvc/IActionFilter.cs +System.Web.Mvc/IActionInvoker.cs +System.Web.Mvc/IAuthorizationFilter.cs +System.Web.Mvc/IBuildManager.cs +System.Web.Mvc/IController.cs +System.Web.Mvc/IControllerFactory.cs +System.Web.Mvc/IExceptionFilter.cs +System.Web.Mvc/IModelBinder.cs +System.Web.Mvc/InputType.cs +System.Web.Mvc/IResultFilter.cs +System.Web.Mvc/IRouteWithArea.cs +System.Web.Mvc/ITempDataProvider.cs +System.Web.Mvc/IValueProvider.cs +System.Web.Mvc/IView.cs +System.Web.Mvc/IViewDataContainer.cs +System.Web.Mvc/IViewEngine.cs +System.Web.Mvc/IViewLocationCache.cs +System.Web.Mvc/JavaScriptResult.cs +System.Web.Mvc/JsonRequestBehavior.cs +System.Web.Mvc/JsonResult.cs +System.Web.Mvc/LinqBinaryModelBinder.cs +System.Web.Mvc/ModelBinderAttribute.cs +System.Web.Mvc/ModelBinderDictionary.cs +System.Web.Mvc/ModelBinders.cs +System.Web.Mvc/ModelBindingContext.cs +System.Web.Mvc/ModelClientValidationRangeRule.cs +System.Web.Mvc/ModelClientValidationRegexRule.cs +System.Web.Mvc/ModelClientValidationRequiredRule.cs +System.Web.Mvc/ModelClientValidationRule.cs +System.Web.Mvc/ModelClientValidationStringLengthRule.cs +System.Web.Mvc/ModelErrorCollection.cs +System.Web.Mvc/ModelError.cs +System.Web.Mvc/ModelMetadata.cs +System.Web.Mvc/ModelMetadataProvider.cs +System.Web.Mvc/ModelMetadataProviders.cs +System.Web.Mvc/ModelState.cs +System.Web.Mvc/ModelStateDictionary.cs +System.Web.Mvc/ModelValidationResult.cs +System.Web.Mvc/ModelValidator.cs +System.Web.Mvc/ModelValidatorProviderCollection.cs +System.Web.Mvc/ModelValidatorProvider.cs +System.Web.Mvc/ModelValidatorProviders.cs +System.Web.Mvc/MultiSelectList.cs +System.Web.Mvc/MvcHandler.cs +System.Web.Mvc/MvcHtmlString.cs +System.Web.Mvc/MvcHttpHandler.cs +System.Web.Mvc/MvcRouteHandler.cs +System.Web.Mvc/NameValueCollectionExtensions.cs +System.Web.Mvc/NameValueCollectionValueProvider.cs +System.Web.Mvc/NoAsyncTimeoutAttribute.cs +System.Web.Mvc/NonActionAttribute.cs +System.Web.Mvc/NullViewLocationCache.cs +System.Web.Mvc/OutputCacheAttribute.cs +System.Web.Mvc/ParameterBindingInfo.cs +System.Web.Mvc/ParameterDescriptor.cs +System.Web.Mvc/ParameterInfoUtil.cs +System.Web.Mvc/PartialViewResult.cs +System.Web.Mvc/PathHelpers.cs +System.Web.Mvc/QueryStringValueProvider.cs +System.Web.Mvc/QueryStringValueProviderFactory.cs +System.Web.Mvc/RangeAttributeAdapter.cs +System.Web.Mvc/ReaderWriterCache`2.cs +System.Web.Mvc/RedirectResult.cs +System.Web.Mvc/RedirectToRouteResult.cs +System.Web.Mvc/ReflectedActionDescriptor.cs +System.Web.Mvc/ReflectedControllerDescriptor.cs +System.Web.Mvc/ReflectedParameterBindingInfo.cs +System.Web.Mvc/ReflectedParameterDescriptor.cs +System.Web.Mvc/RegularExpressionAttributeAdapter.cs +System.Web.Mvc/RequiredAttributeAdapter.cs +System.Web.Mvc/RequireHttpsAttribute.cs +System.Web.Mvc/Resources/MvcResources.Designer.cs +System.Web.Mvc/ResultExecutedContext.cs +System.Web.Mvc/ResultExecutingContext.cs +System.Web.Mvc/RouteCollectionExtensions.cs +System.Web.Mvc/RouteDataValueProvider.cs +System.Web.Mvc/RouteDataValueProviderFactory.cs +System.Web.Mvc/RouteValuesHelpers.cs +System.Web.Mvc/SelectList.cs +System.Web.Mvc/SelectListItem.cs +System.Web.Mvc/SessionStateTempDataProvider.cs +System.Web.Mvc/StringLengthAttributeAdapter.cs +System.Web.Mvc/TagBuilder.cs +System.Web.Mvc/TagRenderMode.cs +System.Web.Mvc/TempDataDictionary.cs +System.Web.Mvc/TemplateInfo.cs +System.Web.Mvc/TryGetValueDelegate.cs +System.Web.Mvc/TypeCacheSerializer.cs +System.Web.Mvc/TypeCacheUtil.cs +System.Web.Mvc/TypeDescriptorHelper.cs +System.Web.Mvc/TypeHelpers.cs +System.Web.Mvc/UrlHelper.cs +System.Web.Mvc/UrlParameter.cs +System.Web.Mvc/ValidateAntiForgeryTokenAttribute.cs +System.Web.Mvc/ValidateInputAttribute.cs +System.Web.Mvc/ValueProviderCollection.cs +System.Web.Mvc/ValueProviderDictionary.cs +System.Web.Mvc/ValueProviderFactories.cs +System.Web.Mvc/ValueProviderFactoryCollection.cs +System.Web.Mvc/ValueProviderFactory.cs +System.Web.Mvc/ValueProviderResult.cs +System.Web.Mvc/ValueProviderUtil.cs +System.Web.Mvc/ViewContext.cs +System.Web.Mvc/ViewDataDictionary`1.cs +System.Web.Mvc/ViewDataDictionary.cs +System.Web.Mvc/ViewDataInfo.cs +System.Web.Mvc/ViewEngineCollection.cs +System.Web.Mvc/ViewEngineResult.cs +System.Web.Mvc/ViewEngines.cs +System.Web.Mvc/ViewMasterPage`1.cs +System.Web.Mvc/ViewMasterPage.cs +System.Web.Mvc/ViewPage`1.cs +System.Web.Mvc/ViewPageControlBuilder.cs +System.Web.Mvc/ViewPage.cs +System.Web.Mvc/ViewResultBase.cs +System.Web.Mvc/ViewResult.cs +System.Web.Mvc/ViewTemplateUserControl`1.cs +System.Web.Mvc/ViewTemplateUserControl.cs +System.Web.Mvc/ViewTypeControlBuilder.cs +System.Web.Mvc/ViewType.cs +System.Web.Mvc/ViewTypeParserFilter.cs +System.Web.Mvc/ViewUserControl`1.cs +System.Web.Mvc/ViewUserControlControlBuilder.cs +System.Web.Mvc/ViewUserControl.cs +System.Web.Mvc/VirtualPathProviderViewEngine.cs +System.Web.Mvc/WebFormView.cs +System.Web.Mvc/WebFormViewEngine.cs diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AcceptVerbsAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AcceptVerbsAttribute.cs new file mode 100644 index 00000000000..c0924a424ce --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AcceptVerbsAttribute.cs @@ -0,0 +1,71 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Reflection; + using System.Web.Mvc.Resources; + + [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", + Justification = "The accessor is exposed as an ICollection.")] + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public sealed class AcceptVerbsAttribute : ActionMethodSelectorAttribute { + public AcceptVerbsAttribute(HttpVerbs verbs) + : this(EnumToArray(verbs)) { + } + + public AcceptVerbsAttribute(params string[] verbs) { + if (verbs == null || verbs.Length == 0) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "verbs"); + } + + Verbs = new ReadOnlyCollection(verbs); + } + + public ICollection Verbs { + get; + private set; + } + + private static void AddEntryToList(HttpVerbs verbs, HttpVerbs match, List verbList, string entryText) { + if ((verbs & match) != 0) { + verbList.Add(entryText); + } + } + + internal static string[] EnumToArray(HttpVerbs verbs) { + List verbList = new List(); + + AddEntryToList(verbs, HttpVerbs.Get, verbList, "GET"); + AddEntryToList(verbs, HttpVerbs.Post, verbList, "POST"); + AddEntryToList(verbs, HttpVerbs.Put, verbList, "PUT"); + AddEntryToList(verbs, HttpVerbs.Delete, verbList, "DELETE"); + AddEntryToList(verbs, HttpVerbs.Head, verbList, "HEAD"); + + return verbList.ToArray(); + } + + public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + + string incomingVerb = controllerContext.HttpContext.Request.GetHttpMethodOverride(); + + return Verbs.Contains(incomingVerb, StringComparer.OrdinalIgnoreCase); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionDescriptor.cs new file mode 100644 index 00000000000..4041d790747 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionDescriptor.cs @@ -0,0 +1,230 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Linq; + using System.Reflection; + using System.Web.Mvc.Resources; + + public abstract class ActionDescriptor : ICustomAttributeProvider { + + private readonly static AllowMultipleAttributesCache _allowMultiplAttributesCache = new AllowMultipleAttributesCache(); + private readonly static ActionMethodDispatcherCache _staticDispatcherCache = new ActionMethodDispatcherCache(); + private ActionMethodDispatcherCache _instanceDispatcherCache; + + private static readonly ActionSelector[] _emptySelectors = new ActionSelector[0]; + + public abstract string ActionName { + get; + } + + public abstract ControllerDescriptor ControllerDescriptor { + get; + } + + internal ActionMethodDispatcherCache DispatcherCache { + get { + if (_instanceDispatcherCache == null) { + _instanceDispatcherCache = _staticDispatcherCache; + } + return _instanceDispatcherCache; + } + set { + _instanceDispatcherCache = value; + } + } + + public abstract object Execute(ControllerContext controllerContext, IDictionary parameters); + + internal static object ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary parameters, MethodInfo methodInfo) { + object value; + + if (!parameters.TryGetValue(parameterInfo.Name, out value)) { + // the key should always be present, even if the parameter value is null + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_ParameterNotInDictionary, + parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType); + throw new ArgumentException(message, "parameters"); + } + + if (value == null && !TypeHelpers.TypeAllowsNullValue(parameterInfo.ParameterType)) { + // tried to pass a null value for a non-nullable parameter type + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_ParameterCannotBeNull, + parameterInfo.Name, parameterInfo.ParameterType, methodInfo, methodInfo.DeclaringType); + throw new ArgumentException(message, "parameters"); + } + + if (value != null && !parameterInfo.ParameterType.IsInstanceOfType(value)) { + // value was supplied but is not of the proper type + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_ParameterValueHasWrongType, + parameterInfo.Name, methodInfo, methodInfo.DeclaringType, value.GetType(), parameterInfo.ParameterType); + throw new ArgumentException(message, "parameters"); + } + + return value; + } + + internal static object ExtractParameterOrDefaultFromDictionary(ParameterInfo parameterInfo, IDictionary parameters) { + Type parameterType = parameterInfo.ParameterType; + + object value; + parameters.TryGetValue(parameterInfo.Name, out value); + + // if wrong type, replace with default instance + if (parameterType.IsInstanceOfType(value)) { + return value; + } + else { + object defaultValue; + if (ParameterInfoUtil.TryGetDefaultValue(parameterInfo, out defaultValue)) { + return defaultValue; + } + else { + return TypeHelpers.GetDefaultValue(parameterType); + } + } + } + + public virtual object[] GetCustomAttributes(bool inherit) { + return GetCustomAttributes(typeof(object), inherit); + } + + public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { + if (attributeType == null) { + throw new ArgumentNullException("attributeType"); + } + + return (object[])Array.CreateInstance(attributeType, 0); + } + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", + Justification = "This method may perform non-trivial work.")] + public virtual FilterInfo GetFilters() { + return new FilterInfo(); + } + + internal static FilterInfo GetFilters(MethodInfo methodInfo) { + // Enumerable.OrderBy() is a stable sort, so this method preserves scope ordering. + FilterAttribute[] typeFilters = (FilterAttribute[])methodInfo.ReflectedType.GetCustomAttributes(typeof(FilterAttribute), true /* inherit */); + FilterAttribute[] methodFilters = (FilterAttribute[])methodInfo.GetCustomAttributes(typeof(FilterAttribute), true /* inherit */); + List orderedFilters = RemoveOverriddenFilters(typeFilters.Concat(methodFilters)).OrderBy(attr => attr.Order).ToList(); + + FilterInfo filterInfo = new FilterInfo(); + MergeFiltersIntoList(orderedFilters, filterInfo.ActionFilters); + MergeFiltersIntoList(orderedFilters, filterInfo.AuthorizationFilters); + MergeFiltersIntoList(orderedFilters, filterInfo.ExceptionFilters); + MergeFiltersIntoList(orderedFilters, filterInfo.ResultFilters); + return filterInfo; + } + + public abstract ParameterDescriptor[] GetParameters(); + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", + Justification = "This method may perform non-trivial work.")] + public virtual ICollection GetSelectors() { + return _emptySelectors; + } + + public virtual bool IsDefined(Type attributeType, bool inherit) { + if (attributeType == null) { + throw new ArgumentNullException("attributeType"); + } + + return false; + } + + internal static void MergeFiltersIntoList(IList allFilters, IList destFilters) where TFilter : class { + foreach (FilterAttribute filter in allFilters) { + TFilter castFilter = filter as TFilter; + if (castFilter != null) { + destFilters.Add(castFilter); + } + } + } + + internal static IEnumerable RemoveOverriddenFilters(IEnumerable filters) { + // If an attribute is declared on both the controller and on an action method and that attribute's + // type has AllowMultiple = false (which is the default for attributes), we should ignore the attributes + // declared on the controller. The CLR's reflection implementation follows a similar algorithm when it + // encounters an overridden virtual method where both the base and the override contain some + // AllowMultiple = false attribute. + + // Key = attribute type + // Value = -1 if AllowMultiple true, last index of this attribute type if AllowMultiple false + Dictionary attrsIndexes = new Dictionary(); + + FilterAttribute[] filtersList = filters.ToArray(); + for (int i = 0; i < filtersList.Length; i++) { + FilterAttribute filter = filtersList[i]; + Type filterType = filter.GetType(); + + int lastIndex; + if (attrsIndexes.TryGetValue(filterType, out lastIndex)) { + if (lastIndex >= 0) { + // this filter already exists and AllowMultiple = false, so clear last entry + filtersList[lastIndex] = null; + attrsIndexes[filterType] = i; + } + } + else { + // not found - add to dictionary + // exactly one AttributeUsageAttribute will always be present + bool allowMultiple = _allowMultiplAttributesCache.IsMultiUseAttribute(filterType); + attrsIndexes[filterType] = (allowMultiple) ? -1 : i; + } + } + + // any duplicated attributes have now been nulled out, so just return remaining attributes + return filtersList.Where(attr => attr != null); + } + + internal static string VerifyActionMethodIsCallable(MethodInfo methodInfo) { + // we can't call instance methods where the 'this' parameter is a type other than ControllerBase + if (!methodInfo.IsStatic && !typeof(ControllerBase).IsAssignableFrom(methodInfo.ReflectedType)) { + return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallInstanceMethodOnNonControllerType, + methodInfo, methodInfo.ReflectedType.FullName); + } + + // we can't call methods with open generic type parameters + if (methodInfo.ContainsGenericParameters) { + return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallOpenGenericMethods, + methodInfo, methodInfo.ReflectedType.FullName); + } + + // we can't call methods with ref/out parameters + ParameterInfo[] parameterInfos = methodInfo.GetParameters(); + foreach (ParameterInfo parameterInfo in parameterInfos) { + if (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef) { + return String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedActionDescriptor_CannotCallMethodsWithOutOrRefParameters, + methodInfo, methodInfo.ReflectedType.FullName, parameterInfo); + } + } + + // we can call this method + return null; + } + + private sealed class AllowMultipleAttributesCache : ReaderWriterCache { + public bool IsMultiUseAttribute(Type attributeType) { + return FetchOrCreateItem(attributeType, () => AttributeUsageAllowsMultiple(attributeType)); + } + + private static bool AttributeUsageAllowsMultiple(Type type) { + return (((AttributeUsageAttribute[])type.GetCustomAttributes(typeof(AttributeUsageAttribute), true))[0]).AllowMultiple; + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutedContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutedContext.cs new file mode 100644 index 00000000000..1dfaa174b16 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutedContext.cs @@ -0,0 +1,68 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + + public class ActionExecutedContext : ControllerContext { + + private ActionResult _result; + + // parameterless constructor used for mocking + public ActionExecutedContext() { + } + + [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", + Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")] + public ActionExecutedContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, bool canceled, Exception exception) + : base(controllerContext) { + if (actionDescriptor == null) { + throw new ArgumentNullException("actionDescriptor"); + } + + ActionDescriptor = actionDescriptor; + Canceled = canceled; + Exception = exception; + } + + public virtual ActionDescriptor ActionDescriptor { + get; + set; + } + + public virtual bool Canceled { + get; + set; + } + + public virtual Exception Exception { + get; + set; + } + + public bool ExceptionHandled { + get; + set; + } + + public ActionResult Result { + get { + return _result ?? EmptyResult.Instance; + } + set { + _result = value; + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutingContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutingContext.cs new file mode 100644 index 00000000000..4cc21e0999b --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionExecutingContext.cs @@ -0,0 +1,57 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + + public class ActionExecutingContext : ControllerContext { + + // parameterless constructor used for mocking + public ActionExecutingContext() { + } + + [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", + Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")] + public ActionExecutingContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary actionParameters) + : base(controllerContext) { + if (actionDescriptor == null) { + throw new ArgumentNullException("actionDescriptor"); + } + if (actionParameters == null) { + throw new ArgumentNullException("actionParameters"); + } + + ActionDescriptor = actionDescriptor; + ActionParameters = actionParameters; + } + + public virtual ActionDescriptor ActionDescriptor { + get; + set; + } + + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", + Justification = "The property setter is only here to support mocking this type and should not be called at runtime.")] + public virtual IDictionary ActionParameters { + get; + set; + } + + public ActionResult Result { + get; + set; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionFilterAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionFilterAttribute.cs new file mode 100644 index 00000000000..1069ccc7d63 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionFilterAttribute.cs @@ -0,0 +1,34 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter { + + // The OnXxx() methods are virtual rather than abstract so that a developer need override + // only the ones that interest him. + + public virtual void OnActionExecuting(ActionExecutingContext filterContext) { + } + + public virtual void OnActionExecuted(ActionExecutedContext filterContext) { + } + + public virtual void OnResultExecuting(ResultExecutingContext filterContext) { + } + + public virtual void OnResultExecuted(ResultExecutedContext filterContext) { + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcher.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcher.cs new file mode 100644 index 00000000000..0adafe2b695 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcher.cs @@ -0,0 +1,86 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Linq.Expressions; + using System.Reflection; + + // The methods in this class don't perform error checking; that is the responsibility of the + // caller. + internal sealed class ActionMethodDispatcher { + + private delegate object ActionExecutor(ControllerBase controller, object[] parameters); + private delegate void VoidActionExecutor(ControllerBase controller, object[] parameters); + + private ActionExecutor _executor; + + public ActionMethodDispatcher(MethodInfo methodInfo) { + _executor = GetExecutor(methodInfo); + MethodInfo = methodInfo; + } + + public MethodInfo MethodInfo { + get; + private set; + } + + public object Execute(ControllerBase controller, object[] parameters) { + return _executor(controller, parameters); + } + + private static ActionExecutor GetExecutor(MethodInfo methodInfo) { + // Parameters to executor + ParameterExpression controllerParameter = Expression.Parameter(typeof(ControllerBase), "controller"); + ParameterExpression parametersParameter = Expression.Parameter(typeof(object[]), "parameters"); + + // Build parameter list + List parameters = new List(); + ParameterInfo[] paramInfos = methodInfo.GetParameters(); + for (int i = 0; i < paramInfos.Length; i++) { + ParameterInfo paramInfo = paramInfos[i]; + BinaryExpression valueObj = Expression.ArrayIndex(parametersParameter, Expression.Constant(i)); + UnaryExpression valueCast = Expression.Convert(valueObj, paramInfo.ParameterType); + + // valueCast is "(Ti) parameters[i]" + parameters.Add(valueCast); + } + + // Call method + UnaryExpression instanceCast = (!methodInfo.IsStatic) ? Expression.Convert(controllerParameter, methodInfo.ReflectedType) : null; + MethodCallExpression methodCall = methodCall = Expression.Call(instanceCast, methodInfo, parameters); + + // methodCall is "((TController) controller) method((T0) parameters[0], (T1) parameters[1], ...)" + // Create function + if (methodCall.Type == typeof(void)) { + Expression lambda = Expression.Lambda(methodCall, controllerParameter, parametersParameter); + VoidActionExecutor voidExecutor = lambda.Compile(); + return WrapVoidAction(voidExecutor); + } + else { + // must coerce methodCall to match ActionExecutor signature + UnaryExpression castMethodCall = Expression.Convert(methodCall, typeof(object)); + Expression lambda = Expression.Lambda(castMethodCall, controllerParameter, parametersParameter); + return lambda.Compile(); + } + } + + private static ActionExecutor WrapVoidAction(VoidActionExecutor executor) { + return delegate(ControllerBase controller, object[] parameters) { + executor(controller, parameters); + return null; + }; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcherCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcherCache.cs new file mode 100644 index 00000000000..61b5333367c --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodDispatcherCache.cs @@ -0,0 +1,27 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Reflection; + + internal sealed class ActionMethodDispatcherCache : ReaderWriterCache { + + public ActionMethodDispatcherCache() { + } + + public ActionMethodDispatcher GetDispatcher(MethodInfo methodInfo) { + return FetchOrCreateItem(methodInfo, () => new ActionMethodDispatcher(methodInfo)); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelector.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelector.cs new file mode 100644 index 00000000000..4b765dba1ed --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelector.cs @@ -0,0 +1,125 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Reflection; + using System.Text; + using System.Web.Mvc.Resources; + + internal sealed class ActionMethodSelector { + + public ActionMethodSelector(Type controllerType) { + ControllerType = controllerType; + PopulateLookupTables(); + } + + public Type ControllerType { + get; + private set; + } + + public MethodInfo[] AliasedMethods { + get; + private set; + } + + public ILookup NonAliasedMethods { + get; + private set; + } + + private AmbiguousMatchException CreateAmbiguousMatchException(List ambiguousMethods, string actionName) { + StringBuilder exceptionMessageBuilder = new StringBuilder(); + foreach (MethodInfo methodInfo in ambiguousMethods) { + string controllerAction = Convert.ToString(methodInfo, CultureInfo.CurrentUICulture); + string controllerType = methodInfo.DeclaringType.FullName; + exceptionMessageBuilder.AppendLine(); + exceptionMessageBuilder.AppendFormat(CultureInfo.CurrentUICulture, MvcResources.ActionMethodSelector_AmbiguousMatchType, controllerAction, controllerType); + } + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ActionMethodSelector_AmbiguousMatch, + actionName, ControllerType.Name, exceptionMessageBuilder); + return new AmbiguousMatchException(message); + } + + public MethodInfo FindActionMethod(ControllerContext controllerContext, string actionName) { + List methodsMatchingName = GetMatchingAliasedMethods(controllerContext, actionName); + methodsMatchingName.AddRange(NonAliasedMethods[actionName]); + List finalMethods = RunSelectionFilters(controllerContext, methodsMatchingName); + + switch (finalMethods.Count) { + case 0: + return null; + + case 1: + return finalMethods[0]; + + default: + throw CreateAmbiguousMatchException(finalMethods, actionName); + } + } + + internal List GetMatchingAliasedMethods(ControllerContext controllerContext, string actionName) { + // find all aliased methods which are opting in to this request + // to opt in, all attributes defined on the method must return true + + var methods = from methodInfo in AliasedMethods + let attrs = (ActionNameSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionNameSelectorAttribute), true /* inherit */) + where attrs.All(attr => attr.IsValidName(controllerContext, actionName, methodInfo)) + select methodInfo; + return methods.ToList(); + } + + private static bool IsMethodDecoratedWithAliasingAttribute(MethodInfo methodInfo) { + return methodInfo.IsDefined(typeof(ActionNameSelectorAttribute), true /* inherit */); + } + + private static bool IsValidActionMethod(MethodInfo methodInfo) { + return !(methodInfo.IsSpecialName || + methodInfo.GetBaseDefinition().DeclaringType.IsAssignableFrom(typeof(Controller))); + } + + private void PopulateLookupTables() { + MethodInfo[] allMethods = ControllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public); + MethodInfo[] actionMethods = Array.FindAll(allMethods, IsValidActionMethod); + + AliasedMethods = Array.FindAll(actionMethods, IsMethodDecoratedWithAliasingAttribute); + NonAliasedMethods = actionMethods.Except(AliasedMethods).ToLookup(method => method.Name, StringComparer.OrdinalIgnoreCase); + } + + private static List RunSelectionFilters(ControllerContext controllerContext, List methodInfos) { + // remove all methods which are opting out of this request + // to opt out, at least one attribute defined on the method must return false + + List matchesWithSelectionAttributes = new List(); + List matchesWithoutSelectionAttributes = new List(); + + foreach (MethodInfo methodInfo in methodInfos) { + ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */); + if (attrs.Length == 0) { + matchesWithoutSelectionAttributes.Add(methodInfo); + } + else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) { + matchesWithSelectionAttributes.Add(methodInfo); + } + } + + // if a matching action method had a selection attribute, consider it more specific than a matching action method + // without a selection attribute + return (matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelectorAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelectorAttribute.cs new file mode 100644 index 00000000000..0a2fd297f99 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionMethodSelectorAttribute.cs @@ -0,0 +1,21 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Reflection; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public abstract class ActionMethodSelectorAttribute : Attribute { + public abstract bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo); + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameAttribute.cs new file mode 100644 index 00000000000..46ef66a39cd --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameAttribute.cs @@ -0,0 +1,39 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Reflection; + using System.Web.Mvc.Resources; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public sealed class ActionNameAttribute : ActionNameSelectorAttribute { + + public ActionNameAttribute(string name) { + if (String.IsNullOrEmpty(name)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name"); + } + + Name = name; + } + + public string Name { + get; + private set; + } + + public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) { + return String.Equals(actionName, Name, StringComparison.OrdinalIgnoreCase); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameSelectorAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameSelectorAttribute.cs new file mode 100644 index 00000000000..5ec4134dacc --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionNameSelectorAttribute.cs @@ -0,0 +1,21 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Reflection; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public abstract class ActionNameSelectorAttribute : Attribute { + public abstract bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo); + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionResult.cs new file mode 100644 index 00000000000..11bc79c84c0 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionResult.cs @@ -0,0 +1,21 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + + public abstract class ActionResult { + + public abstract void ExecuteResult(ControllerContext context); + + } + +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionSelector.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionSelector.cs new file mode 100644 index 00000000000..59891d6cf81 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ActionSelector.cs @@ -0,0 +1,17 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + + public delegate bool ActionSelector(ControllerContext controllerContext); + +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxExtensions.cs new file mode 100644 index 00000000000..a34122fd330 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxExtensions.cs @@ -0,0 +1,322 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Ajax { + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Web; + using System.Web.Mvc; + using System.Web.Mvc.Html; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public static class AjaxExtensions { + private const string LinkOnClickFormat = "Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), {0});"; + private const string FormOnClickValue = "Sys.Mvc.AsyncForm.handleClick(this, new Sys.UI.DomEvent(event));"; + private const string FormOnSubmitFormat = "Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event), {0});"; + private const string _globalizationScript = @""; + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, AjaxOptions ajaxOptions) { + return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, ajaxOptions); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions) { + return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) { + return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + return ActionLink(ajaxHelper, linkText, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, AjaxOptions ajaxOptions) { + return ActionLink(ajaxHelper, linkText, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) { + return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + RouteValueDictionary newValues = new RouteValueDictionary(routeValues); + Dictionary newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes); + return ActionLink(ajaxHelper, linkText, actionName, controllerName, newValues, ajaxOptions, newAttributes); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) { + return ActionLink(ajaxHelper, linkText, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + + string targetUrl = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */); + + return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes)); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + RouteValueDictionary newValues = new RouteValueDictionary(routeValues); + Dictionary newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes); + return ActionLink(ajaxHelper, linkText, actionName, controllerName, protocol, hostName, fragment, newValues, ajaxOptions, newAttributes); + } + + public static MvcHtmlString ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + + string targetUrl = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */); + + return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, ajaxOptions, htmlAttributes)); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, AjaxOptions ajaxOptions) { + string formAction = ajaxHelper.ViewContext.HttpContext.Request.RawUrl; + return FormHelper(ajaxHelper, formAction, ajaxOptions, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, AjaxOptions ajaxOptions) { + return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, ajaxOptions); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions) { + return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) { + return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + return BeginForm(ajaxHelper, actionName, (string)null /* controllerName */, routeValues, ajaxOptions, htmlAttributes); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, AjaxOptions ajaxOptions) { + return BeginForm(ajaxHelper, actionName, controllerName, null /* values */, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions) { + return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + RouteValueDictionary newValues = new RouteValueDictionary(routeValues); + Dictionary newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes); + return BeginForm(ajaxHelper, actionName, controllerName, newValues, ajaxOptions, newAttributes); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) { + return BeginForm(ajaxHelper, actionName, controllerName, routeValues, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcForm BeginForm(this AjaxHelper ajaxHelper, string actionName, string controllerName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + // get target URL + string formAction = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */); + return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes); + } + + public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, AjaxOptions ajaxOptions) { + return BeginRouteForm(ajaxHelper, routeName, null /* routeValues */, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions) { + return BeginRouteForm(ajaxHelper, routeName, (object)routeValues, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + Dictionary newAttributes = ObjectToCaseSensitiveDictionary(htmlAttributes); + return BeginRouteForm(ajaxHelper, routeName, new RouteValueDictionary(routeValues), ajaxOptions, newAttributes); + } + + public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) { + return BeginRouteForm(ajaxHelper, routeName, routeValues, ajaxOptions, null /* htmlAttributes */); + } + + public static MvcForm BeginRouteForm(this AjaxHelper ajaxHelper, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + string formAction = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */); + return FormHelper(ajaxHelper, formAction, ajaxOptions, htmlAttributes); + } + + private static MvcForm FormHelper(this AjaxHelper ajaxHelper, string formAction, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + TagBuilder builder = new TagBuilder("form"); + builder.MergeAttributes(htmlAttributes); + builder.MergeAttribute("action", formAction); + builder.MergeAttribute("method", "post"); + builder.MergeAttribute("onclick", FormOnClickValue); + builder.MergeAttribute("onsubmit", GenerateAjaxScript(GetAjaxOptions(ajaxOptions), FormOnSubmitFormat)); + + if (ajaxHelper.ViewContext.ClientValidationEnabled) { + // forms must have an ID for client validation + builder.GenerateId(ajaxHelper.ViewContext.FormIdGenerator()); + } + + ajaxHelper.ViewContext.Writer.Write(builder.ToString(TagRenderMode.StartTag)); + MvcForm theForm = new MvcForm(ajaxHelper.ViewContext); + + if (ajaxHelper.ViewContext.ClientValidationEnabled) { + ajaxHelper.ViewContext.FormContext.FormId = builder.Attributes["id"]; + } + + return theForm; + } + + public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper) { + return GlobalizationScript(ajaxHelper, CultureInfo.CurrentCulture); + } + + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "ajaxHelper", + Justification = "This is an extension method")] + public static MvcHtmlString GlobalizationScript(this AjaxHelper ajaxHelper, CultureInfo cultureInfo) { + return GlobalizationScriptHelper(AjaxHelper.GlobalizationScriptPath, cultureInfo); + } + + private static MvcHtmlString GlobalizationScriptHelper(string scriptPath, CultureInfo cultureInfo) { + if (cultureInfo == null) { + throw new ArgumentNullException("cultureInfo"); + } + + string src = VirtualPathUtility.AppendTrailingSlash(scriptPath) + cultureInfo.Name + ".js"; + string scriptWithCorrectNewLines = _globalizationScript.Replace("\r\n", Environment.NewLine); + string formatted = String.Format(CultureInfo.InvariantCulture, scriptWithCorrectNewLines, src); + + return MvcHtmlString.Create(formatted); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions) { + return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions, + new Dictionary()); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + return RouteLink(ajaxHelper, linkText, null /* routeName */, new RouteValueDictionary(routeValues), ajaxOptions, + ObjectToCaseSensitiveDictionary(htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) { + return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions, + new Dictionary()); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + return RouteLink(ajaxHelper, linkText, null /* routeName */, routeValues, ajaxOptions, htmlAttributes); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions) { + return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, + new Dictionary()); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, object htmlAttributes) { + return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, ObjectToCaseSensitiveDictionary(htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(), ajaxOptions, htmlAttributes); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions) { + return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions, + new Dictionary()); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, object routeValues, AjaxOptions ajaxOptions, object htmlAttributes) { + return RouteLink(ajaxHelper, linkText, routeName, new RouteValueDictionary(routeValues), ajaxOptions, + ObjectToCaseSensitiveDictionary(htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions) { + return RouteLink(ajaxHelper, linkText, routeName, routeValues, ajaxOptions, new Dictionary()); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + + string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */); + + return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this AjaxHelper ajaxHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + + string targetUrl = UrlHelper.GenerateUrl(routeName, null /* actionName */, null /* controllerName */, protocol, hostName, fragment, routeValues ?? new RouteValueDictionary(), ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */); + + return MvcHtmlString.Create(GenerateLink(linkText, targetUrl, GetAjaxOptions(ajaxOptions), htmlAttributes)); + } + + internal static string InsertionModeToString(InsertionMode insertionMode) { + switch (insertionMode) { + case InsertionMode.Replace: + return "Sys.Mvc.InsertionMode.replace"; + case InsertionMode.InsertBefore: + return "Sys.Mvc.InsertionMode.insertBefore"; + case InsertionMode.InsertAfter: + return "Sys.Mvc.InsertionMode.insertAfter"; + default: + return ((int)insertionMode).ToString(CultureInfo.InvariantCulture); + } + } + + private static Dictionary ObjectToCaseSensitiveDictionary(object values) { + Dictionary dict = new Dictionary(StringComparer.Ordinal); + if (values != null) { + foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(values)) { + object val = prop.GetValue(values); + dict[prop.Name] = val; + } + } + return dict; + } + + private static string GenerateLink(string linkText, string targetUrl, AjaxOptions ajaxOptions, IDictionary htmlAttributes) { + TagBuilder tag = new TagBuilder("a") { + InnerHtml = HttpUtility.HtmlEncode(linkText) + }; + + tag.MergeAttributes(htmlAttributes); + tag.MergeAttribute("href", targetUrl); + tag.MergeAttribute("onclick", GenerateAjaxScript(ajaxOptions, LinkOnClickFormat)); + + return tag.ToString(TagRenderMode.Normal); + } + + private static string GenerateAjaxScript(AjaxOptions ajaxOptions, string scriptFormat) { + string optionsString = ajaxOptions.ToJavascriptString(); + return String.Format(CultureInfo.InvariantCulture, scriptFormat, optionsString); + } + + private static AjaxOptions GetAjaxOptions(AjaxOptions ajaxOptions) { + return (ajaxOptions != null) ? ajaxOptions : new AjaxOptions(); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxOptions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxOptions.cs new file mode 100644 index 00000000000..ca04c64f007 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/AjaxOptions.cs @@ -0,0 +1,166 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Ajax { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Text; + using System.Web.Mvc.Resources; + + public class AjaxOptions { + private string _confirm; + private string _httpMethod; + private InsertionMode _insertionMode = InsertionMode.Replace; + private string _loadingElementId; + private string _onBegin; + private string _onComplete; + private string _onFailure; + private string _onSuccess; + private string _updateTargetId; + private string _url; + + public string Confirm { + get { + return _confirm ?? String.Empty; + } + set { + _confirm = value; + } + } + + public string HttpMethod { + get { + return _httpMethod ?? String.Empty; + } + set { + _httpMethod = value; + } + } + + public InsertionMode InsertionMode { + get { + return _insertionMode; + } + set { + switch (value) { + case InsertionMode.Replace: + case InsertionMode.InsertAfter: + case InsertionMode.InsertBefore: + _insertionMode = value; + return; + + default: + throw new ArgumentOutOfRangeException("value"); + } + } + } + + public string LoadingElementId { + get { + return _loadingElementId ?? String.Empty; + } + set { + _loadingElementId = value; + } + } + + public string OnBegin { + get { + return _onBegin ?? String.Empty; + } + set { + _onBegin = value; + } + } + + public string OnComplete { + get { + return _onComplete ?? String.Empty; + } + set { + _onComplete = value; + } + } + + public string OnFailure { + get { + return _onFailure ?? String.Empty; + } + set { + _onFailure = value; + } + } + + public string OnSuccess { + get { + return _onSuccess ?? String.Empty; + } + set { + _onSuccess = value; + } + } + + public string UpdateTargetId { + get { + return _updateTargetId ?? String.Empty; + } + set { + _updateTargetId = value; + } + } + + [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", + Justification = "This property is used by the optionsBuilder which always accepts a string.")] + public string Url { + get { + return _url ?? String.Empty; + } + set { + _url = value; + } + } + + internal string ToJavascriptString() { + // creates a string of the form { key1: value1, key2 : value2, ... } + StringBuilder optionsBuilder = new StringBuilder("{"); + optionsBuilder.Append(String.Format(CultureInfo.InvariantCulture, " insertionMode: {0},", AjaxExtensions.InsertionModeToString(InsertionMode))); + optionsBuilder.Append(PropertyStringIfSpecified("confirm", Confirm)); + optionsBuilder.Append(PropertyStringIfSpecified("httpMethod", HttpMethod)); + optionsBuilder.Append(PropertyStringIfSpecified("loadingElementId", LoadingElementId)); + optionsBuilder.Append(PropertyStringIfSpecified("updateTargetId", UpdateTargetId)); + optionsBuilder.Append(PropertyStringIfSpecified("url", Url)); + optionsBuilder.Append(EventStringIfSpecified("onBegin", OnBegin)); + optionsBuilder.Append(EventStringIfSpecified("onComplete", OnComplete)); + optionsBuilder.Append(EventStringIfSpecified("onFailure", OnFailure)); + optionsBuilder.Append(EventStringIfSpecified("onSuccess", OnSuccess)); + optionsBuilder.Length--; + optionsBuilder.Append(" }"); + return optionsBuilder.ToString(); + } + + private static string EventStringIfSpecified(string propertyName, string handler) { + if (!String.IsNullOrEmpty(handler)) { + return String.Format(CultureInfo.InvariantCulture, " {0}: Function.createDelegate(this, {1}),", propertyName, handler.ToString()); + } + return String.Empty; + } + + private static string PropertyStringIfSpecified(string propertyName, string propertyValue) { + if (!String.IsNullOrEmpty(propertyValue)) { + string escapedPropertyValue = propertyValue.Replace("'", @"\'"); + return String.Format(CultureInfo.InvariantCulture, " {0}: '{1}',", propertyName, escapedPropertyValue); + } + return String.Empty; + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/InsertionMode.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/InsertionMode.cs new file mode 100644 index 00000000000..de0eb4e24f5 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Ajax/InsertionMode.cs @@ -0,0 +1,19 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Ajax { + public enum InsertionMode { + Replace = 0, + InsertBefore = 1, + InsertAfter = 2 + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper.cs new file mode 100644 index 00000000000..7324a52d204 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper.cs @@ -0,0 +1,89 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Text; + using System.Web.Routing; + using System.Web.Script.Serialization; + + public class AjaxHelper { + + private static string _globalizationScriptPath; + + public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) + : this(viewContext, viewDataContainer, RouteTable.Routes) { + } + + public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection) { + if (viewContext == null) { + throw new ArgumentNullException("viewContext"); + } + if (viewDataContainer == null) { + throw new ArgumentNullException("viewDataContainer"); + } + if (routeCollection == null) { + throw new ArgumentNullException("routeCollection"); + } + ViewContext = viewContext; + ViewDataContainer = viewDataContainer; + RouteCollection = routeCollection; + } + + public static string GlobalizationScriptPath { + get { + if (String.IsNullOrEmpty(_globalizationScriptPath)) { + _globalizationScriptPath = "~/Scripts/Globalization"; + } + return _globalizationScriptPath; + } + set { + _globalizationScriptPath = value; + } + } + + public RouteCollection RouteCollection { + get; + private set; + } + + public ViewContext ViewContext { + get; + private set; + } + + public ViewDataDictionary ViewData { + get { + return ViewDataContainer.ViewData; + } + } + + public IViewDataContainer ViewDataContainer { + get; + private set; + } + + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", + Justification = "Instance method for consistency with other helpers.")] + public string JavaScriptStringEncode(string message) { + if (String.IsNullOrEmpty(message)) { + return message; + } + + StringBuilder builder = new StringBuilder(); + JavaScriptSerializer serializer = new JavaScriptSerializer(); + serializer.Serialize(message, builder); + return builder.ToString(1, builder.Length - 2); // remove first + last quote + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper`1.cs new file mode 100644 index 00000000000..1e1f2b95660 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxHelper`1.cs @@ -0,0 +1,35 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System.Web.Routing; + + public class AjaxHelper : AjaxHelper { + private ViewDataDictionary _viewData; + + public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer) + : this(viewContext, viewDataContainer, RouteTable.Routes) { + } + + public AjaxHelper(ViewContext viewContext, IViewDataContainer viewDataContainer, RouteCollection routeCollection) + : base(viewContext, viewDataContainer, routeCollection) { + + _viewData = new ViewDataDictionary(viewDataContainer.ViewData); + } + + public new ViewDataDictionary ViewData { + get { + return _viewData; + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxRequestExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxRequestExtensions.cs new file mode 100644 index 00000000000..411c25092c2 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AjaxRequestExtensions.cs @@ -0,0 +1,26 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + + public static class AjaxRequestExtensions { + + public static bool IsAjaxRequest(this HttpRequestBase request) { + if (request == null) { + throw new ArgumentNullException("request"); + } + + return (request["X-Requested-With"] == "XMLHttpRequest") || ((request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest")); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryData.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryData.cs new file mode 100644 index 00000000000..82252d44102 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryData.cs @@ -0,0 +1,129 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Security.Cryptography; + using System.Security.Principal; + using System.Text; + + internal sealed class AntiForgeryData { + + private const string AntiForgeryTokenFieldName = "__RequestVerificationToken"; + + private const int TokenLength = 128 / 8; + private readonly static RNGCryptoServiceProvider _prng = new RNGCryptoServiceProvider(); + + private DateTime _creationDate = DateTime.UtcNow; + private string _salt; + private string _username; + private string _value; + + public AntiForgeryData() { + } + + // copy constructor + public AntiForgeryData(AntiForgeryData token) { + if (token == null) { + throw new ArgumentNullException("token"); + } + + CreationDate = token.CreationDate; + Salt = token.Salt; + Username = token.Username; + Value = token.Value; + } + + public DateTime CreationDate { + get { + return _creationDate; + } + set { + _creationDate = value; + } + } + + public string Salt { + get { + return _salt ?? String.Empty; + } + set { + _salt = value; + } + } + + public string Username { + get { + return _username ?? String.Empty; + } + set { + _username = value; + } + } + + public string Value { + get { + return _value ?? String.Empty; + } + set { + _value = value; + } + } + + private static string Base64EncodeForCookieName(string s) { + byte[] rawBytes = Encoding.UTF8.GetBytes(s); + string base64String = Convert.ToBase64String(rawBytes); + + // replace base64-specific characters with characters that are safe for a cookie name + return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_'); + } + + private static string GenerateRandomTokenString() { + byte[] tokenBytes = new byte[TokenLength]; + _prng.GetBytes(tokenBytes); + + string token = Convert.ToBase64String(tokenBytes); + return token; + } + + // If the app path is provided, we're generating a cookie name rather than a field name, and the cookie names should + // be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on + // each other. + internal static string GetAntiForgeryTokenName(string appPath) { + if (String.IsNullOrEmpty(appPath)) { + return AntiForgeryTokenFieldName; + } + else { + return AntiForgeryTokenFieldName + "_" + Base64EncodeForCookieName(appPath); + } + } + + internal static string GetUsername(IPrincipal user) { + if (user != null) { + IIdentity identity = user.Identity; + if (identity != null && identity.IsAuthenticated) { + return identity.Name; + } + } + + return String.Empty; + } + + public static AntiForgeryData NewToken() { + string tokenString = GenerateRandomTokenString(); + return new AntiForgeryData() { + Value = tokenString + }; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryDataSerializer.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryDataSerializer.cs new file mode 100644 index 00000000000..cb068317e13 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AntiForgeryDataSerializer.cs @@ -0,0 +1,128 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.IO; + using System.Web; + using System.Web.Mvc.Resources; + using System.Web.UI; + + internal class AntiForgeryDataSerializer { + + private IStateFormatter _formatter; + + protected internal IStateFormatter Formatter { + get { + if (_formatter == null) { + _formatter = FormatterGenerator.GetFormatter(); + } + return _formatter; + } + set { + _formatter = value; + } + } + + private static HttpAntiForgeryException CreateValidationException(Exception innerException) { + return new HttpAntiForgeryException(MvcResources.AntiForgeryToken_ValidationFailed, innerException); + } + + public virtual AntiForgeryData Deserialize(string serializedToken) { + if (String.IsNullOrEmpty(serializedToken)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "serializedToken"); + } + + // call property getter outside try { } block so that exceptions bubble up for debugging + IStateFormatter formatter = Formatter; + + try { + object[] deserializedObj = (object[])formatter.Deserialize(serializedToken); + return new AntiForgeryData() { + Salt = (string)deserializedObj[0], + Value = (string)deserializedObj[1], + CreationDate = (DateTime)deserializedObj[2], + Username = (string)deserializedObj[3] + }; + } + catch (Exception ex) { + throw CreateValidationException(ex); + } + } + + public virtual string Serialize(AntiForgeryData token) { + if (token == null) { + throw new ArgumentNullException("token"); + } + + object[] objToSerialize = new object[] { + token.Salt, + token.Value, + token.CreationDate, + token.Username + }; + + string serializedValue = Formatter.Serialize(objToSerialize); + return serializedValue; + } + + // See http://www.yoda.arachsys.com/csharp/singleton.html (fifth version - fully lazy) for the singleton pattern + // used here. We need to defer the call to TokenPersister.CreateFormatterGenerator() until we're actually + // servicing a request, else HttpContext.Current might be invalid in TokenPersister.CreateFormatterGenerator(). + private static class FormatterGenerator { + + public static readonly Func GetFormatter = TokenPersister.CreateFormatterGenerator(); + + [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline", + Justification = "This type must not be marked 'beforefieldinit'.")] + static FormatterGenerator() { + } + + // This type is very difficult to unit-test because Page.ProcessRequest() requires mocking + // much of the hosting environment. For now, we can perform functional tests of this feature. + private sealed class TokenPersister : PageStatePersister { + private TokenPersister(Page page) + : base(page) { + } + + public static Func CreateFormatterGenerator() { + // This code instantiates a page and tricks it into thinking that it's servicing + // a postback scenario with encrypted ViewState, which is required to make the + // StateFormatter properly decrypt data. Specifically, this code sets the + // internal Page.ContainsEncryptedViewState flag. + TextWriter writer = TextWriter.Null; + HttpResponse response = new HttpResponse(writer); + HttpRequest request = new HttpRequest("DummyFile.aspx", HttpContext.Current.Request.Url.ToString(), "__EVENTTARGET=true&__VIEWSTATEENCRYPTED=true"); + HttpContext context = new HttpContext(request, response); + + Page page = new Page() { + EnableViewStateMac = true, + ViewStateEncryptionMode = ViewStateEncryptionMode.Always + }; + page.ProcessRequest(context); + + return () => new TokenPersister(page).StateFormatter; + } + + public override void Load() { + throw new NotImplementedException(); + } + + public override void Save() { + throw new NotImplementedException(); + } + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaHelpers.cs new file mode 100644 index 00000000000..723f834e15b --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaHelpers.cs @@ -0,0 +1,43 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Web.Routing; + + internal static class AreaHelpers { + + public static string GetAreaName(RouteBase route) { + IRouteWithArea routeWithArea = route as IRouteWithArea; + if (routeWithArea != null) { + return routeWithArea.Area; + } + + Route castRoute = route as Route; + if (castRoute != null && castRoute.DataTokens != null) { + return castRoute.DataTokens["area"] as string; + } + + return null; + } + + public static string GetAreaName(RouteData routeData) { + object area; + if (routeData.DataTokens.TryGetValue("area", out area)) { + return area as string; + } + + return GetAreaName(routeData.Route); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistration.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistration.cs new file mode 100644 index 00000000000..5725ddf7066 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistration.cs @@ -0,0 +1,62 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Web.Routing; + + public abstract class AreaRegistration { + + private const string _typeCacheName = "MVC-AreaRegistrationTypeCache.xml"; + + public abstract string AreaName { + get; + } + + internal void CreateContextAndRegister(RouteCollection routes, object state) { + AreaRegistrationContext context = new AreaRegistrationContext(AreaName, routes, state); + + string thisNamespace = GetType().Namespace; + if (thisNamespace != null) { + context.Namespaces.Add(thisNamespace + ".*"); + } + + RegisterArea(context); + } + + private static bool IsAreaRegistrationType(Type type) { + return + typeof(AreaRegistration).IsAssignableFrom(type) && + type.GetConstructor(Type.EmptyTypes) != null; + } + + public static void RegisterAllAreas() { + RegisterAllAreas(null); + } + + public static void RegisterAllAreas(object state) { + RegisterAllAreas(RouteTable.Routes, new BuildManagerWrapper(), state); + } + + internal static void RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state) { + List areaRegistrationTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsAreaRegistrationType, buildManager); + foreach (Type areaRegistrationType in areaRegistrationTypes) { + AreaRegistration registration = (AreaRegistration)Activator.CreateInstance(areaRegistrationType); + registration.CreateContextAndRegister(routes, state); + } + } + + public abstract void RegisterArea(AreaRegistrationContext context); + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistrationContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistrationContext.cs new file mode 100644 index 00000000000..869c1ac6dd4 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AreaRegistrationContext.cs @@ -0,0 +1,111 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Web.Routing; + + public class AreaRegistrationContext { + + private readonly HashSet _namespaces = new HashSet(StringComparer.OrdinalIgnoreCase); + + public AreaRegistrationContext(string areaName, RouteCollection routes) + : this(areaName, routes, null) { + } + + public AreaRegistrationContext(string areaName, RouteCollection routes, object state) { + if (String.IsNullOrEmpty(areaName)) { + throw Error.ParameterCannotBeNullOrEmpty("areaName"); + } + if (routes == null) { + throw new ArgumentNullException("routes"); + } + + AreaName = areaName; + Routes = routes; + State = state; + } + + public string AreaName { + get; + private set; + } + + public ICollection Namespaces { + get { + return _namespaces; + } + } + + public RouteCollection Routes { + get; + private set; + } + + public object State { + get; + private set; + } + + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", + Justification = "This is not a regular URL as it may contain special routing characters.")] + public Route MapRoute(string name, string url) { + return MapRoute(name, url, (object)null /* defaults */); + } + + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", + Justification = "This is not a regular URL as it may contain special routing characters.")] + public Route MapRoute(string name, string url, object defaults) { + return MapRoute(name, url, defaults, (object)null /* constraints */); + } + + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", + Justification = "This is not a regular URL as it may contain special routing characters.")] + public Route MapRoute(string name, string url, object defaults, object constraints) { + return MapRoute(name, url, defaults, constraints, null /* namespaces */); + } + + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", + Justification = "This is not a regular URL as it may contain special routing characters.")] + public Route MapRoute(string name, string url, string[] namespaces) { + return MapRoute(name, url, (object)null /* defaults */, namespaces); + } + + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", + Justification = "This is not a regular URL as it may contain special routing characters.")] + public Route MapRoute(string name, string url, object defaults, string[] namespaces) { + return MapRoute(name, url, defaults, null /* constraints */, namespaces); + } + + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", + Justification = "This is not a regular URL as it may contain special routing characters.")] + public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) { + if (namespaces == null && Namespaces != null) { + namespaces = Namespaces.ToArray(); + } + + Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces); + route.DataTokens["area"] = AreaName; + + // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up + // controllers belonging to other areas + bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0); + route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback; + + return route; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedMetadataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedMetadataProvider.cs new file mode 100644 index 00000000000..bd9248f811f --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedMetadataProvider.cs @@ -0,0 +1,95 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.ComponentModel.DataAnnotations; + using System.Globalization; + using System.Linq; + using System.Web.Mvc.Resources; + + // This class provides a good implementation of ModelMetadataProvider for people who will be + // using traditional classes with properties. It uses the buddy class support from + // DataAnnotations, and consolidates the three operations down to a single override + // for reading the attribute values and creating the metadata class. + public abstract class AssociatedMetadataProvider : ModelMetadataProvider { + protected abstract ModelMetadata CreateMetadata(IEnumerable attributes, Type containerType, Func modelAccessor, Type modelType, string propertyName); + + protected virtual IEnumerable FilterAttributes(Type containerType, PropertyDescriptor propertyDescriptor, IEnumerable attributes) { + if (typeof(ViewPage).IsAssignableFrom(containerType) || typeof(ViewUserControl).IsAssignableFrom(containerType)) { + return attributes.Where(a => !(a is ReadOnlyAttribute)); + } + + return attributes; + } + + public override IEnumerable GetMetadataForProperties(object container, Type containerType) { + if (containerType == null) { + throw new ArgumentNullException("containerType"); + } + + return GetMetadataForPropertiesImpl(container, containerType); + } + + private IEnumerable GetMetadataForPropertiesImpl(object container, Type containerType) { + foreach (PropertyDescriptor property in GetTypeDescriptor(containerType).GetProperties()) { + Func modelAccessor = container == null ? null : GetPropertyValueAccessor(container, property); + yield return GetMetadataForProperty(modelAccessor, containerType, property); + } + } + + public override ModelMetadata GetMetadataForProperty(Func modelAccessor, Type containerType, string propertyName) { + if (containerType == null) { + throw new ArgumentNullException("containerType"); + } + if (String.IsNullOrEmpty(propertyName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "propertyName"); + } + + ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(containerType); + PropertyDescriptor property = typeDescriptor.GetProperties().Find(propertyName, true); + if (property == null) { + throw new ArgumentException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.Common_PropertyNotFound, + containerType.FullName, propertyName)); + } + + return GetMetadataForProperty(modelAccessor, containerType, property); + } + + protected virtual ModelMetadata GetMetadataForProperty(Func modelAccessor, Type containerType, PropertyDescriptor propertyDescriptor) { + IEnumerable attributes = FilterAttributes(containerType, propertyDescriptor, propertyDescriptor.Attributes.Cast()); + return CreateMetadata(attributes, containerType, modelAccessor, propertyDescriptor.PropertyType, propertyDescriptor.Name); + } + + public override ModelMetadata GetMetadataForType(Func modelAccessor, Type modelType) { + if (modelType == null) { + throw new ArgumentNullException("modelType"); + } + + IEnumerable attributes = GetTypeDescriptor(modelType).GetAttributes().Cast(); + return CreateMetadata(attributes, null /* containerType */, modelAccessor, modelType, null /* propertyName */); + } + + private static Func GetPropertyValueAccessor(object container, PropertyDescriptor property) { + return () => property.GetValue(container); + } + + protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type) { + return TypeDescriptorHelper.Get(type); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedValidatorProvider.cs new file mode 100644 index 00000000000..f7b280ab39e --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AssociatedValidatorProvider.cs @@ -0,0 +1,63 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.ComponentModel.DataAnnotations; + using System.Globalization; + using System.Linq; + using System.Web.Mvc.Resources; + + public abstract class AssociatedValidatorProvider : ModelValidatorProvider { + protected virtual ICustomTypeDescriptor GetTypeDescriptor(Type type) { + return TypeDescriptorHelper.Get(type); + } + + public override sealed IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context) { + if (metadata == null) { + throw new ArgumentNullException("metadata"); + } + if (context == null) { + throw new ArgumentNullException("context"); + } + + if (metadata.ContainerType != null && !String.IsNullOrEmpty(metadata.PropertyName)) { + return GetValidatorsForProperty(metadata, context); + } + + return GetValidatorsForType(metadata, context); + } + + protected abstract IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable attributes); + + private IEnumerable GetValidatorsForProperty(ModelMetadata metadata, ControllerContext context) { + ICustomTypeDescriptor typeDescriptor = GetTypeDescriptor(metadata.ContainerType); + PropertyDescriptor property = typeDescriptor.GetProperties().Find(metadata.PropertyName, true); + if (property == null) { + throw new ArgumentException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.Common_PropertyNotFound, + metadata.ContainerType.FullName, metadata.PropertyName), + "metadata"); + } + + return GetValidators(metadata, context, property.Attributes.OfType()); + } + + private IEnumerable GetValidatorsForType(ModelMetadata metadata, ControllerContext context) { + return GetValidators(metadata, context, GetTypeDescriptor(metadata.ModelType).GetAttributes().Cast()); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ActionDescriptorCreator.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ActionDescriptorCreator.cs new file mode 100644 index 00000000000..19e1179a4a0 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ActionDescriptorCreator.cs @@ -0,0 +1,18 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + + internal delegate ActionDescriptor ActionDescriptorCreator(string actionName, ControllerDescriptor controllerDescriptor); + +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionDescriptor.cs new file mode 100644 index 00000000000..2b9ff2fe406 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionDescriptor.cs @@ -0,0 +1,40 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Collections.Generic; + + public abstract class AsyncActionDescriptor : ActionDescriptor { + + public abstract IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary parameters, AsyncCallback callback, object state); + + public abstract object EndExecute(IAsyncResult asyncResult); + + public override object Execute(ControllerContext controllerContext, IDictionary parameters) { + // execute an asynchronous task synchronously + IAsyncResult asyncResult = BeginExecute(controllerContext, parameters, null, null); + AsyncUtil.WaitForAsyncResultCompletion(asyncResult, controllerContext.HttpContext.ApplicationInstance); // blocks + return EndExecute(asyncResult); + } + + internal static AsyncManager GetAsyncManager(ControllerBase controller) { + IAsyncManagerContainer helperContainer = controller as IAsyncManagerContainer; + if (helperContainer == null) { + throw Error.AsyncCommon_ControllerMustImplementIAsyncManagerContainer(controller.GetType()); + } + + return helperContainer.AsyncManager; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionMethodSelector.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionMethodSelector.cs new file mode 100644 index 00000000000..efd00b153c8 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncActionMethodSelector.cs @@ -0,0 +1,206 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Reflection; + using System.Text; + using System.Web.Mvc.Resources; + + internal sealed class AsyncActionMethodSelector { + + public AsyncActionMethodSelector(Type controllerType) { + ControllerType = controllerType; + PopulateLookupTables(); + } + + public Type ControllerType { + get; + private set; + } + + public MethodInfo[] AliasedMethods { + get; + private set; + } + + public ILookup NonAliasedMethods { + get; + private set; + } + + private AmbiguousMatchException CreateAmbiguousActionMatchException(IEnumerable ambiguousMethods, string actionName) { + string ambiguityList = CreateAmbiguousMatchList(ambiguousMethods); + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ActionMethodSelector_AmbiguousMatch, + actionName, ControllerType.Name, ambiguityList); + return new AmbiguousMatchException(message); + } + + private AmbiguousMatchException CreateAmbiguousMethodMatchException(IEnumerable ambiguousMethods, string methodName) { + string ambiguityList = CreateAmbiguousMatchList(ambiguousMethods); + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.AsyncActionMethodSelector_AmbiguousMethodMatch, + methodName, ControllerType.Name, ambiguityList); + return new AmbiguousMatchException(message); + } + + private static string CreateAmbiguousMatchList(IEnumerable ambiguousMethods) { + StringBuilder exceptionMessageBuilder = new StringBuilder(); + foreach (MethodInfo methodInfo in ambiguousMethods) { + exceptionMessageBuilder.AppendLine(); + exceptionMessageBuilder.AppendFormat(CultureInfo.CurrentUICulture, MvcResources.ActionMethodSelector_AmbiguousMatchType, methodInfo, methodInfo.DeclaringType.FullName); + } + + return exceptionMessageBuilder.ToString(); + } + + public ActionDescriptorCreator FindAction(ControllerContext controllerContext, string actionName) { + List methodsMatchingName = GetMatchingAliasedMethods(controllerContext, actionName); + methodsMatchingName.AddRange(NonAliasedMethods[actionName]); + List finalMethods = RunSelectionFilters(controllerContext, methodsMatchingName); + + switch (finalMethods.Count) { + case 0: + return null; + + case 1: + MethodInfo entryMethod = finalMethods[0]; + return GetActionDescriptorDelegate(entryMethod); + + default: + throw CreateAmbiguousActionMatchException(finalMethods, actionName); + } + } + + private ActionDescriptorCreator GetActionDescriptorDelegate(MethodInfo entryMethod) { + // Is this the FooAsync() / FooCompleted() pattern? + if (IsAsyncSuffixedMethod(entryMethod)) { + string completionMethodName = entryMethod.Name.Substring(0, entryMethod.Name.Length - "Async".Length) + "Completed"; + MethodInfo completionMethod = GetMethodByName(completionMethodName); + if (completionMethod != null) { + return (actionName, controllerDescriptor) => new ReflectedAsyncActionDescriptor(entryMethod, completionMethod, actionName, controllerDescriptor); + } + else { + throw Error.AsyncActionMethodSelector_CouldNotFindMethod(completionMethodName, ControllerType); + } + } + + // Fallback to synchronous method + return (actionName, controllerDescriptor) => new ReflectedActionDescriptor(entryMethod, actionName, controllerDescriptor); + } + + private static string GetCanonicalMethodName(MethodInfo methodInfo) { + string methodName = methodInfo.Name; + return (IsAsyncSuffixedMethod(methodInfo)) + ? methodName.Substring(0, methodName.Length - "Async".Length) + : methodName; + } + + internal List GetMatchingAliasedMethods(ControllerContext controllerContext, string actionName) { + // find all aliased methods which are opting in to this request + // to opt in, all attributes defined on the method must return true + + var methods = from methodInfo in AliasedMethods + let attrs = (ActionNameSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionNameSelectorAttribute), true /* inherit */) + where attrs.All(attr => attr.IsValidName(controllerContext, actionName, methodInfo)) + select methodInfo; + return methods.ToList(); + } + + private static bool IsAsyncSuffixedMethod(MethodInfo methodInfo) { + return methodInfo.Name.EndsWith("Async", StringComparison.OrdinalIgnoreCase); + } + + private static bool IsCompletedSuffixedMethod(MethodInfo methodInfo) { + return methodInfo.Name.EndsWith("Completed", StringComparison.OrdinalIgnoreCase); + } + + private static bool IsMethodDecoratedWithAliasingAttribute(MethodInfo methodInfo) { + return methodInfo.IsDefined(typeof(ActionNameSelectorAttribute), true /* inherit */); + } + + private MethodInfo GetMethodByName(string methodName) { + List methods = (from MethodInfo methodInfo in ControllerType.GetMember(methodName, MemberTypes.Method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase) + where IsValidActionMethod(methodInfo, false /* stripInfrastructureMethods */) + select methodInfo).ToList(); + + switch (methods.Count) { + case 0: + return null; + + case 1: + return methods[0]; + + default: + throw CreateAmbiguousMethodMatchException(methods, methodName); + } + } + + private static bool IsValidActionMethod(MethodInfo methodInfo) { + return IsValidActionMethod(methodInfo, true /* stripInfrastructureMethods */); + } + + private static bool IsValidActionMethod(MethodInfo methodInfo, bool stripInfrastructureMethods) { + if (methodInfo.IsSpecialName) { + // not a normal method, e.g. a constructor or an event + return false; + } + + if (methodInfo.GetBaseDefinition().DeclaringType.IsAssignableFrom(typeof(AsyncController))) { + // is a method on Object, ControllerBase, Controller, or AsyncController + return false; + }; + + if (stripInfrastructureMethods) { + if (IsCompletedSuffixedMethod(methodInfo)) { + // do not match FooCompleted() methods, as these are infrastructure methods + return false; + } + } + + return true; + } + + private void PopulateLookupTables() { + MethodInfo[] allMethods = ControllerType.GetMethods(BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Public); + MethodInfo[] actionMethods = Array.FindAll(allMethods, IsValidActionMethod); + + AliasedMethods = Array.FindAll(actionMethods, IsMethodDecoratedWithAliasingAttribute); + NonAliasedMethods = actionMethods.Except(AliasedMethods).ToLookup(GetCanonicalMethodName, StringComparer.OrdinalIgnoreCase); + } + + private static List RunSelectionFilters(ControllerContext controllerContext, List methodInfos) { + // remove all methods which are opting out of this request + // to opt out, at least one attribute defined on the method must return false + + List matchesWithSelectionAttributes = new List(); + List matchesWithoutSelectionAttributes = new List(); + + foreach (MethodInfo methodInfo in methodInfos) { + ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])methodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */); + if (attrs.Length == 0) { + matchesWithoutSelectionAttributes.Add(methodInfo); + } + else if (attrs.All(attr => attr.IsValidForRequest(controllerContext, methodInfo))) { + matchesWithSelectionAttributes.Add(methodInfo); + } + } + + // if a matching action method had a selection attribute, consider it more specific than a matching action method + // without a selection attribute + return (matchesWithSelectionAttributes.Count > 0) ? matchesWithSelectionAttributes : matchesWithoutSelectionAttributes; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncControllerActionInvoker.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncControllerActionInvoker.cs new file mode 100644 index 00000000000..cf1349ec52d --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncControllerActionInvoker.cs @@ -0,0 +1,282 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Threading; + + public class AsyncControllerActionInvoker : ControllerActionInvoker, IAsyncActionInvoker { + + private static readonly object _invokeActionTag = new object(); + private static readonly object _invokeActionMethodTag = new object(); + private static readonly object _invokeActionMethodWithFiltersTag = new object(); + + public virtual IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + if (String.IsNullOrEmpty(actionName)) { + throw Error.ParameterCannotBeNullOrEmpty("actionName"); + } + + ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext); + ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); + if (actionDescriptor != null) { + FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor); + Action continuation = null; + + BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) { + try { + AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor); + if (authContext.Result != null) { + // the auth filter signaled that we should let it short-circuit the request + continuation = () => InvokeActionResult(controllerContext, authContext.Result); + } + else { + if (controllerContext.Controller.ValidateRequest) { + ValidateRequest(controllerContext); + } + + IDictionary parameters = GetParameterValues(controllerContext, actionDescriptor); + IAsyncResult asyncResult = BeginInvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters, asyncCallback, asyncState); + continuation = () => { + ActionExecutedContext postActionContext = EndInvokeActionMethodWithFilters(asyncResult); + InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result); + }; + return asyncResult; + } + } + catch (ThreadAbortException) { + // This type of exception occurs as a result of Response.Redirect(), but we special-case so that + // the filters don't see this as an error. + throw; + } + catch (Exception ex) { + // something blew up, so execute the exception filters + ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex); + if (!exceptionContext.ExceptionHandled) { + throw; + } + + continuation = () => InvokeActionResult(controllerContext, exceptionContext.Result); + } + + return BeginInvokeAction_MakeSynchronousAsyncResult(asyncCallback, asyncState); + }; + + EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { + try { + continuation(); + } + catch (ThreadAbortException) { + // This type of exception occurs as a result of Response.Redirect(), but we special-case so that + // the filters don't see this as an error. + throw; + } + catch (Exception ex) { + // something blew up, so execute the exception filters + ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex); + if (!exceptionContext.ExceptionHandled) { + throw; + } + InvokeActionResult(controllerContext, exceptionContext.Result); + } + + return true; + }; + + return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionTag); + } + else { + // Notify the controller that no action was found. + return BeginInvokeAction_ActionNotFound(callback, state); + } + } + + private static IAsyncResult BeginInvokeAction_ActionNotFound(AsyncCallback callback, object state) { + BeginInvokeDelegate beginDelegate = BeginInvokeAction_MakeSynchronousAsyncResult; + + EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { + return false; + }; + + return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionTag); + } + + private static IAsyncResult BeginInvokeAction_MakeSynchronousAsyncResult(AsyncCallback callback, object state) { + SimpleAsyncResult asyncResult = new SimpleAsyncResult(state); + asyncResult.MarkCompleted(true /* completedSynchronously */, callback); + return asyncResult; + } + + protected internal virtual IAsyncResult BeginInvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary parameters, AsyncCallback callback, object state) { + AsyncActionDescriptor asyncActionDescriptor = actionDescriptor as AsyncActionDescriptor; + if (asyncActionDescriptor != null) { + return BeginInvokeAsynchronousActionMethod(controllerContext, asyncActionDescriptor, parameters, callback, state); + } + else { + return BeginInvokeSynchronousActionMethod(controllerContext, actionDescriptor, parameters, callback, state); + } + } + + protected internal virtual IAsyncResult BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList filters, ActionDescriptor actionDescriptor, IDictionary parameters, AsyncCallback callback, object state) { + Func endContinuation = null; + + BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) { + ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters); + IAsyncResult innerAsyncResult = null; + + Func> beginContinuation = () => { + innerAsyncResult = BeginInvokeActionMethod(controllerContext, actionDescriptor, parameters, asyncCallback, asyncState); + return () => + new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */) { + Result = EndInvokeActionMethod(innerAsyncResult) + }; + }; + + // need to reverse the filter list because the continuations are built up backward + Func> thunk = filters.Reverse().Aggregate(beginContinuation, + (next, filter) => () => InvokeActionMethodFilterAsynchronously(filter, preContext, next)); + endContinuation = thunk(); + + if (innerAsyncResult != null) { + // we're just waiting for the inner result to complete + return innerAsyncResult; + } + else { + // something was short-circuited and the action was not called, so this was a synchronous operation + SimpleAsyncResult newAsyncResult = new SimpleAsyncResult(asyncState); + newAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback); + return newAsyncResult; + } + }; + + EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { + return endContinuation(); + }; + + return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodWithFiltersTag); + } + + private IAsyncResult BeginInvokeAsynchronousActionMethod(ControllerContext controllerContext, AsyncActionDescriptor actionDescriptor, IDictionary parameters, AsyncCallback callback, object state) { + BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) { + return actionDescriptor.BeginExecute(controllerContext, parameters, asyncCallback, asyncState); + }; + + EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { + object returnValue = actionDescriptor.EndExecute(asyncResult); + ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue); + return result; + }; + + return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _invokeActionMethodTag); + } + + private IAsyncResult BeginInvokeSynchronousActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary parameters, AsyncCallback callback, object state) { + return AsyncResultWrapper.BeginSynchronous(callback, state, + () => InvokeSynchronousActionMethod(controllerContext, actionDescriptor, parameters), + _invokeActionMethodTag); + } + + public virtual bool EndInvokeAction(IAsyncResult asyncResult) { + return AsyncResultWrapper.End(asyncResult, _invokeActionTag); + } + + protected internal virtual ActionResult EndInvokeActionMethod(IAsyncResult asyncResult) { + return AsyncResultWrapper.End(asyncResult, _invokeActionMethodTag); + } + + protected internal virtual ActionExecutedContext EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) { + return AsyncResultWrapper.End(asyncResult, _invokeActionMethodWithFiltersTag); + } + + protected override ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext) { + Type controllerType = controllerContext.Controller.GetType(); + ControllerDescriptor controllerDescriptor = DescriptorCache.GetDescriptor(controllerType, () => new ReflectedAsyncControllerDescriptor(controllerType)); + return controllerDescriptor; + } + + internal static Func InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func> nextInChain) { + filter.OnActionExecuting(preContext); + if (preContext.Result != null) { + ActionExecutedContext shortCircuitedPostContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) { + Result = preContext.Result + }; + return () => shortCircuitedPostContext; + } + + // There is a nested try / catch block here that contains much the same logic as the outer block. + // Since an exception can occur on either side of the asynchronous invocation, we need guards on + // on both sides. In the code below, the second side is represented by the nested delegate. This + // is really just a parallel of the synchronous ControllerActionInvoker.InvokeActionMethodFilter() + // method. + + try { + Func continuation = nextInChain(); + + // add our own continuation, then return the new function + return () => { + ActionExecutedContext postContext; + bool wasError = true; + + try { + postContext = continuation(); + wasError = false; + } + catch (ThreadAbortException) { + // This type of exception occurs as a result of Response.Redirect(), but we special-case so that + // the filters don't see this as an error. + postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); + filter.OnActionExecuted(postContext); + throw; + } + catch (Exception ex) { + postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); + filter.OnActionExecuted(postContext); + if (!postContext.ExceptionHandled) { + throw; + } + } + if (!wasError) { + filter.OnActionExecuted(postContext); + } + + return postContext; + }; + } + catch (ThreadAbortException) { + // This type of exception occurs as a result of Response.Redirect(), but we special-case so that + // the filters don't see this as an error. + ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); + filter.OnActionExecuted(postContext); + throw; + } + catch (Exception ex) { + ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); + filter.OnActionExecuted(postContext); + if (postContext.ExceptionHandled) { + return () => postContext; + } + else { + throw; + } + } + } + + private ActionResult InvokeSynchronousActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary parameters) { + return base.InvokeActionMethod(controllerContext, actionDescriptor, parameters); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncManager.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncManager.cs new file mode 100644 index 00000000000..082f460e7ec --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncManager.cs @@ -0,0 +1,79 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Collections.Generic; + using System.Threading; + + public class AsyncManager { + + private readonly SynchronizationContext _syncContext; + + // default timeout is 45 sec + // from: http://msdn.microsoft.com/en-us/library/system.web.ui.page.asynctimeout.aspx + private int _timeout = 45 * 1000; + + public AsyncManager() + : this(null /* syncContext */) { + } + + public AsyncManager(SynchronizationContext syncContext) { + _syncContext = syncContext ?? SynchronizationContextUtil.GetSynchronizationContext(); + + OutstandingOperations = new OperationCounter(); + OutstandingOperations.Completed += delegate { Finish(); }; + + Parameters = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + public OperationCounter OutstandingOperations { + get; + private set; + } + + public IDictionary Parameters { + get; + private set; + } + + public event EventHandler Finished; + + // the developer may call this function to signal that all operations are complete instead of + // waiting for the operation counter to reach zero + public virtual void Finish() { + EventHandler handler = Finished; + if (handler != null) { + handler(this, EventArgs.Empty); + } + } + + // executes a callback in the current synchronization context, which gives access to HttpContext and related items + public virtual void Sync(Action action) { + _syncContext.Sync(action); + } + + // measured in milliseconds, Timeout.Infinite means 'no timeout' + public int Timeout { + get { + return _timeout; + } + set { + if (value < -1) { + throw Error.AsyncCommon_InvalidTimeout("value"); + } + _timeout = value; + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncResultWrapper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncResultWrapper.cs new file mode 100644 index 00000000000..1f42f516388 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncResultWrapper.cs @@ -0,0 +1,265 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Threading; + + // This class is used for the following pattern: + + // public IAsyncResult BeginInner(..., callback, state); + // public TInnerResult EndInner(asyncResult); + // public IAsyncResult BeginOuter(..., callback, state); + // public TOuterResult EndOuter(asyncResult); + + // That is, Begin/EndOuter() wrap Begin/EndInner(), potentially with pre- and post-processing. + + internal static class AsyncResultWrapper { + + // helper methods + + private static Func MakeVoidDelegate(Action action) { + return () => { + action(); + return default(AsyncVoid); + }; + } + + private static EndInvokeDelegate MakeVoidDelegate(EndInvokeDelegate endDelegate) { + return ar => { + endDelegate(ar); + return default(AsyncVoid); + }; + } + + // kicks off an asynchronous operation + + public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate) { + return Begin(callback, state, beginDelegate, endDelegate, null /* tag */); + } + + public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag) { + return Begin(callback, state, beginDelegate, endDelegate, tag, Timeout.Infinite); + } + + public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag, int timeout) { + WrappedAsyncResult asyncResult = new WrappedAsyncResult(beginDelegate, endDelegate, tag); + asyncResult.Begin(callback, state, timeout); + return asyncResult; + } + + public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate) { + return Begin(callback, state, beginDelegate, endDelegate, null /* tag */); + } + + public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag) { + return Begin(callback, state, beginDelegate, endDelegate, tag, Timeout.Infinite); + } + + public static IAsyncResult Begin(AsyncCallback callback, object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag, int timeout) { + return Begin(callback, state, beginDelegate, MakeVoidDelegate(endDelegate), tag, timeout); + } + + // wraps a synchronous operation in an asynchronous wrapper, but still completes synchronously + + public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Func func) { + return BeginSynchronous(callback, state, func, null /* tag */); + } + + public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Func func, object tag) { + // Begin() doesn't perform any work on its own and returns immediately. + BeginInvokeDelegate beginDelegate = (asyncCallback, asyncState) => { + SimpleAsyncResult innerAsyncResult = new SimpleAsyncResult(asyncState); + innerAsyncResult.MarkCompleted(true /* completedSynchronously */, asyncCallback); + return innerAsyncResult; + }; + + // The End() method blocks. + EndInvokeDelegate endDelegate = _ => { + return func(); + }; + + WrappedAsyncResult asyncResult = new WrappedAsyncResult(beginDelegate, endDelegate, tag); + asyncResult.Begin(callback, state, Timeout.Infinite); + return asyncResult; + } + + public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Action action) { + return BeginSynchronous(callback, state, action, null /* tag */); + } + + public static IAsyncResult BeginSynchronous(AsyncCallback callback, object state, Action action, object tag) { + return BeginSynchronous(callback, state, MakeVoidDelegate(action), tag); + } + + // completes an asynchronous operation + + public static TResult End(IAsyncResult asyncResult) { + return End(asyncResult, null /* tag */); + } + + public static TResult End(IAsyncResult asyncResult, object tag) { + return WrappedAsyncResult.Cast(asyncResult, tag).End(); + } + + public static void End(IAsyncResult asyncResult) { + End(asyncResult, null /* tag */); + } + + public static void End(IAsyncResult asyncResult, object tag) { + End(asyncResult, tag); + } + + [SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", + Justification = "The Timer will be disposed of either when it fires or when the operation completes successfully.")] + private sealed class WrappedAsyncResult : IAsyncResult { + + private readonly BeginInvokeDelegate _beginDelegate; + private readonly object _beginDelegateLockObj = new object(); + private readonly EndInvokeDelegate _endDelegate; + private readonly SingleEntryGate _endExecutedGate = new SingleEntryGate(); // prevent End() from being called twice + private readonly SingleEntryGate _handleCallbackGate = new SingleEntryGate(); // prevent callback from being handled multiple times + private IAsyncResult _innerAsyncResult; + private AsyncCallback _originalCallback; + private readonly object _tag; // prevent an instance of this type from being passed to the wrong End() method + private volatile bool _timedOut; + private Timer _timer; + + public WrappedAsyncResult(BeginInvokeDelegate beginDelegate, EndInvokeDelegate endDelegate, object tag) { + _beginDelegate = beginDelegate; + _endDelegate = endDelegate; + _tag = tag; + } + + public object AsyncState { + get { + return _innerAsyncResult.AsyncState; + } + } + + public WaitHandle AsyncWaitHandle { + get { + return _innerAsyncResult.AsyncWaitHandle; + } + } + + public bool CompletedSynchronously { + get { + return _innerAsyncResult.CompletedSynchronously; + } + } + + public bool IsCompleted { + get { + return _innerAsyncResult.IsCompleted; + } + } + + // kicks off the process, instantiates a timer if requested + public void Begin(AsyncCallback callback, object state, int timeout) { + _originalCallback = callback; + bool completedSynchronously; + + // Force the target Begin() operation to complete before the callback can continue, + // since the target operation might perform post-processing of the data. + lock (_beginDelegateLockObj) { + _innerAsyncResult = _beginDelegate(HandleAsynchronousCompletion, state); + + completedSynchronously = _innerAsyncResult.CompletedSynchronously; + if (!completedSynchronously) { + if (timeout > Timeout.Infinite) { + CreateTimer(timeout); + } + } + } + + if (completedSynchronously) { + if (callback != null) { + callback(this); + } + } + } + + public static WrappedAsyncResult Cast(IAsyncResult asyncResult, object tag) { + if (asyncResult == null) { + throw new ArgumentNullException("asyncResult"); + } + + WrappedAsyncResult castResult = asyncResult as WrappedAsyncResult; + if (castResult != null && Object.Equals(castResult._tag, tag)) { + return castResult; + } + else { + throw Error.AsyncCommon_InvalidAsyncResult("asyncResult"); + } + } + + private void CreateTimer(int timeout) { + // this method should be called within a lock(_beginDelegateLockObj) + _timer = new Timer(HandleTimeout, null, timeout, Timeout.Infinite /* disable periodic signaling */); + } + + public TResult End() { + if (!_endExecutedGate.TryEnter()) { + throw Error.AsyncCommon_AsyncResultAlreadyConsumed(); + } + + if (_timedOut) { + throw new TimeoutException(); + } + WaitForBeginToCompleteAndDestroyTimer(); + + return _endDelegate(_innerAsyncResult); + } + + private void ExecuteAsynchronousCallback(bool timedOut) { + WaitForBeginToCompleteAndDestroyTimer(); + + if (_handleCallbackGate.TryEnter()) { + _timedOut = timedOut; + if (_originalCallback != null) { + _originalCallback(this); + } + } + } + + private void HandleAsynchronousCompletion(IAsyncResult asyncResult) { + if (asyncResult.CompletedSynchronously) { + // If the operation completed synchronously, the WrappedAsyncResult.Begin() method will handle it. + return; + } + + ExecuteAsynchronousCallback(false /* timedOut */); + } + + private void HandleTimeout(object state) { + ExecuteAsynchronousCallback(true /* timedOut */); + } + + private void WaitForBeginToCompleteAndDestroyTimer() { + lock (_beginDelegateLockObj) { + // Wait for the target Begin() method to complete, as it might be performing + // post-processing. This also forces a memory barrier, so _innerAsyncResult + // is guaranteed to be non-null at this point. + + if (_timer != null) { + _timer.Dispose(); + } + _timer = null; + } + } + + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncUtil.cs new file mode 100644 index 00000000000..64484cf325d --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncUtil.cs @@ -0,0 +1,75 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Threading; + + internal static class AsyncUtil { + + public static void WaitForAsyncResultCompletion(IAsyncResult asyncResult, HttpApplication app) { + // based on HttpServerUtility.ExecuteInternal() + + if (!asyncResult.IsCompleted) { + // suspend app lock while waiting, else might deadlock + bool needToRelock = false; + + try { + // .NET 2.0+ will not allow a ThreadAbortException to be thrown while a + // thread is inside a finally block, so this pattern ensures that the + // value of 'needToRelock' is correct. + try { } + finally { + Monitor.Exit(app); + needToRelock = true; + } + + WaitHandle waitHandle = asyncResult.AsyncWaitHandle; + + if (waitHandle != null) { + waitHandle.WaitOne(); + } + else { + while (!asyncResult.IsCompleted) { + Thread.Sleep(1); + } + } + } + finally { + if (needToRelock) { + Monitor.Enter(app); + } + } + } + } + + public static AsyncCallback WrapCallbackForSynchronizedExecution(AsyncCallback callback, SynchronizationContext syncContext) { + if (callback == null || syncContext == null) { + return callback; + } + + AsyncCallback newCallback = delegate(IAsyncResult asyncResult) { + if (asyncResult.CompletedSynchronously) { + callback(asyncResult); + } + else { + // Only take the application lock if this request completed asynchronously, + // else we might end up in a deadlock situation. + syncContext.Sync(() => callback(asyncResult)); + } + }; + + return newCallback; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncVoid.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncVoid.cs new file mode 100644 index 00000000000..95a81ce7f2b --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/AsyncVoid.cs @@ -0,0 +1,19 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + + // Dummy type used for passing something resembling 'void' to the async delegate functions + internal struct AsyncVoid { + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/BeginInvokeDelegate.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/BeginInvokeDelegate.cs new file mode 100644 index 00000000000..5d568f4a3b7 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/BeginInvokeDelegate.cs @@ -0,0 +1,17 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + + internal delegate IAsyncResult BeginInvokeDelegate(AsyncCallback callback, object state); +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate.cs new file mode 100644 index 00000000000..11308dff6a7 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate.cs @@ -0,0 +1,17 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + + internal delegate void EndInvokeDelegate(IAsyncResult asyncResult); +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate`1.cs new file mode 100644 index 00000000000..9e838960afd --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/EndInvokeDelegate`1.cs @@ -0,0 +1,17 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + + internal delegate TResult EndInvokeDelegate(IAsyncResult asyncResult); +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncActionInvoker.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncActionInvoker.cs new file mode 100644 index 00000000000..acd624bf7ef --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncActionInvoker.cs @@ -0,0 +1,20 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + + public interface IAsyncActionInvoker : IActionInvoker { + IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state); + bool EndInvokeAction(IAsyncResult asyncResult); + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncController.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncController.cs new file mode 100644 index 00000000000..fe256e84c26 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncController.cs @@ -0,0 +1,20 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System.Web.Routing; + + public interface IAsyncController : IController { + IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state); + void EndExecute(IAsyncResult asyncResult); + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncManagerContainer.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncManagerContainer.cs new file mode 100644 index 00000000000..f9aa6adbced --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/IAsyncManagerContainer.cs @@ -0,0 +1,22 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + + public interface IAsyncManagerContainer { + + AsyncManager AsyncManager { + get; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/OperationCounter.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/OperationCounter.cs new file mode 100644 index 00000000000..519f6ed2714 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/OperationCounter.cs @@ -0,0 +1,62 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Threading; + + public sealed class OperationCounter { + + private int _count; + + public int Count { + get { + return Thread.VolatileRead(ref _count); + } + } + + public event EventHandler Completed; + + private int AddAndExecuteCallbackIfCompleted(int value) { + int newCount = Interlocked.Add(ref _count, value); + if (newCount == 0) { + OnCompleted(); + } + + return newCount; + } + + public int Decrement() { + return AddAndExecuteCallbackIfCompleted(-1); + } + + public int Decrement(int value) { + return AddAndExecuteCallbackIfCompleted(-value); + } + + public int Increment() { + return AddAndExecuteCallbackIfCompleted(1); + } + + public int Increment(int value) { + return AddAndExecuteCallbackIfCompleted(value); + } + + private void OnCompleted() { + EventHandler handler = Completed; + if (handler != null) { + handler(this, EventArgs.Empty); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs new file mode 100644 index 00000000000..397a5a24ff8 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncActionDescriptor.cs @@ -0,0 +1,183 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using System.Threading; + + public class ReflectedAsyncActionDescriptor : AsyncActionDescriptor { + + private readonly object _executeTag = new object(); + + private readonly string _actionName; + private readonly ControllerDescriptor _controllerDescriptor; + private ParameterDescriptor[] _parametersCache; + + public ReflectedAsyncActionDescriptor(MethodInfo asyncMethodInfo, MethodInfo completedMethodInfo, string actionName, ControllerDescriptor controllerDescriptor) + : this(asyncMethodInfo, completedMethodInfo, actionName, controllerDescriptor, true /* validateMethods */) { + } + + internal ReflectedAsyncActionDescriptor(MethodInfo asyncMethodInfo, MethodInfo completedMethodInfo, string actionName, ControllerDescriptor controllerDescriptor, bool validateMethods) { + if (asyncMethodInfo == null) { + throw new ArgumentNullException("asyncMethodInfo"); + } + if (completedMethodInfo == null) { + throw new ArgumentNullException("completedMethodInfo"); + } + if (String.IsNullOrEmpty(actionName)) { + throw Error.ParameterCannotBeNullOrEmpty("actionName"); + } + if (controllerDescriptor == null) { + throw new ArgumentNullException("controllerDescriptor"); + } + + if (validateMethods) { + string asyncFailedMessage = VerifyActionMethodIsCallable(asyncMethodInfo); + if (asyncFailedMessage != null) { + throw new ArgumentException(asyncFailedMessage, "asyncMethodInfo"); + } + + string completedFailedMessage = VerifyActionMethodIsCallable(completedMethodInfo); + if (completedFailedMessage != null) { + throw new ArgumentException(completedFailedMessage, "completedMethodInfo"); + } + } + + AsyncMethodInfo = asyncMethodInfo; + CompletedMethodInfo = completedMethodInfo; + _actionName = actionName; + _controllerDescriptor = controllerDescriptor; + } + + public override string ActionName { + get { + return _actionName; + } + } + + public MethodInfo AsyncMethodInfo { + get; + private set; + } + + public MethodInfo CompletedMethodInfo { + get; + private set; + } + + public override ControllerDescriptor ControllerDescriptor { + get { + return _controllerDescriptor; + } + } + + public override IAsyncResult BeginExecute(ControllerContext controllerContext, IDictionary parameters, AsyncCallback callback, object state) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + if (parameters == null) { + throw new ArgumentNullException("parameters"); + } + + AsyncManager asyncManager = GetAsyncManager(controllerContext.Controller); + + BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) { + // call the XxxAsync() method + ParameterInfo[] parameterInfos = AsyncMethodInfo.GetParameters(); + var rawParameterValues = from parameterInfo in parameterInfos + select ExtractParameterFromDictionary(parameterInfo, parameters, AsyncMethodInfo); + object[] parametersArray = rawParameterValues.ToArray(); + + TriggerListener listener = new TriggerListener(); + SimpleAsyncResult asyncResult = new SimpleAsyncResult(asyncState); + + // hook the Finished event to notify us upon completion + Trigger finishTrigger = listener.CreateTrigger(); + asyncManager.Finished += delegate { finishTrigger.Fire(); }; + asyncManager.OutstandingOperations.Increment(); + + // to simplify the logic, force the rest of the pipeline to execute in an asynchronous callback + listener.SetContinuation(() => ThreadPool.QueueUserWorkItem(_ => asyncResult.MarkCompleted(false /* completedSynchronously */, asyncCallback))); + + // the inner operation might complete synchronously, so all setup work has to be done before this point + ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(AsyncMethodInfo); + dispatcher.Execute(controllerContext.Controller, parametersArray); // ignore return value from this method + + // now that the XxxAsync() method has completed, kick off any pending operations + asyncManager.OutstandingOperations.Decrement(); + listener.Activate(); + return asyncResult; + }; + + EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { + // call the XxxCompleted() method + ParameterInfo[] completionParametersInfos = CompletedMethodInfo.GetParameters(); + var rawCompletionParameterValues = from parameterInfo in completionParametersInfos + select ExtractParameterOrDefaultFromDictionary(parameterInfo, asyncManager.Parameters); + object[] completionParametersArray = rawCompletionParameterValues.ToArray(); + + ActionMethodDispatcher dispatcher = DispatcherCache.GetDispatcher(CompletedMethodInfo); + object actionReturnValue = dispatcher.Execute(controllerContext.Controller, completionParametersArray); + return actionReturnValue; + }; + + return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeTag, asyncManager.Timeout); + } + + public override object EndExecute(IAsyncResult asyncResult) { + return AsyncResultWrapper.End(asyncResult, _executeTag); + } + + public override object[] GetCustomAttributes(bool inherit) { + return AsyncMethodInfo.GetCustomAttributes(inherit); + } + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) { + return AsyncMethodInfo.GetCustomAttributes(attributeType, inherit); + } + + public override FilterInfo GetFilters() { + // By default, we only look at filters on the XxxAsync() method. + return GetFilters(AsyncMethodInfo); + } + + public override ParameterDescriptor[] GetParameters() { + ParameterDescriptor[] parameters = LazilyFetchParametersCollection(); + + // need to clone array so that user modifications aren't accidentally stored + return (ParameterDescriptor[])parameters.Clone(); + } + + public override ICollection GetSelectors() { + // By default, we only look at filters on the XxxAsync() method. + + ActionMethodSelectorAttribute[] attrs = (ActionMethodSelectorAttribute[])AsyncMethodInfo.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), true /* inherit */); + ActionSelector[] selectors = Array.ConvertAll(attrs, attr => (ActionSelector)(controllerContext => attr.IsValidForRequest(controllerContext, AsyncMethodInfo))); + return selectors; + } + + public override bool IsDefined(Type attributeType, bool inherit) { + return AsyncMethodInfo.IsDefined(attributeType, inherit); + } + + private ParameterDescriptor[] LazilyFetchParametersCollection() { + return DescriptorUtil.LazilyFetchOrCreateDescriptors( + ref _parametersCache /* cacheLocation */, + AsyncMethodInfo.GetParameters /* initializer */, + parameterInfo => new ReflectedParameterDescriptor(parameterInfo, this) /* converter */); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs new file mode 100644 index 00000000000..ebbc938a300 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/ReflectedAsyncControllerDescriptor.cs @@ -0,0 +1,72 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + + public class ReflectedAsyncControllerDescriptor : ControllerDescriptor { + + private static readonly ActionDescriptor[] _emptyCanonicalActions = new ActionDescriptor[0]; + + private readonly Type _controllerType; + private readonly AsyncActionMethodSelector _selector; + + public ReflectedAsyncControllerDescriptor(Type controllerType) { + if (controllerType == null) { + throw new ArgumentNullException("controllerType"); + } + + _controllerType = controllerType; + _selector = new AsyncActionMethodSelector(_controllerType); + } + + public sealed override Type ControllerType { + get { + return _controllerType; + } + } + + public override ActionDescriptor FindAction(ControllerContext controllerContext, string actionName) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + if (String.IsNullOrEmpty(actionName)) { + throw Error.ParameterCannotBeNullOrEmpty("actionName"); + } + + ActionDescriptorCreator creator = _selector.FindAction(controllerContext, actionName); + if (creator == null) { + return null; + } + + return creator(actionName, this); + } + + public override ActionDescriptor[] GetCanonicalActions() { + // everything is looked up dymanically, so there are no 'canonical' actions + return _emptyCanonicalActions; + } + + public override object[] GetCustomAttributes(bool inherit) { + return ControllerType.GetCustomAttributes(inherit); + } + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) { + return ControllerType.GetCustomAttributes(attributeType, inherit); + } + + public override bool IsDefined(Type attributeType, bool inherit) { + return ControllerType.IsDefined(attributeType, inherit); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SimpleAsyncResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SimpleAsyncResult.cs new file mode 100644 index 00000000000..74f39b51f77 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SimpleAsyncResult.cs @@ -0,0 +1,67 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Threading; + + internal sealed class SimpleAsyncResult : IAsyncResult { + + private readonly object _asyncState; + private bool _completedSynchronously; + private volatile bool _isCompleted; + + public SimpleAsyncResult(object asyncState) { + _asyncState = asyncState; + } + + public object AsyncState { + get { + return _asyncState; + } + } + + // ASP.NET IAsyncResult objects should never expose a WaitHandle due to potential deadlocking + public WaitHandle AsyncWaitHandle { + get { + return null; + } + } + + public bool CompletedSynchronously { + get { + return _completedSynchronously; + } + } + + public bool IsCompleted { + get { + return _isCompleted; + } + } + + // Proper order of execution: + // 1. Set the CompletedSynchronously property to the correct value + // 2. Set the IsCompleted flag + // 3. Execute the callback + // 4. Signal the WaitHandle (which we don't have) + public void MarkCompleted(bool completedSynchronously, AsyncCallback callback) { + _completedSynchronously = completedSynchronously; + _isCompleted = true; + + if (callback != null) { + callback(this); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SingleEntryGate.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SingleEntryGate.cs new file mode 100644 index 00000000000..c3e63a155c6 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SingleEntryGate.cs @@ -0,0 +1,32 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Threading; + + // used to synchronize access to a single-use consumable resource + internal sealed class SingleEntryGate { + + private const int NOT_ENTERED = 0; + private const int ENTERED = 1; + + private int _status; + + // returns true if this is the first call to TryEnter(), false otherwise + public bool TryEnter() { + int oldStatus = Interlocked.Exchange(ref _status, ENTERED); + return (oldStatus == NOT_ENTERED); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronizationContextUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronizationContextUtil.cs new file mode 100644 index 00000000000..5988091f8c4 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronizationContextUtil.cs @@ -0,0 +1,55 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Threading; + + internal static class SynchronizationContextUtil { + + public static SynchronizationContext GetSynchronizationContext() { + // In a runtime environment, SynchronizationContext.Current will be set to an instance + // of AspNetSynchronizationContext. In a unit test environment, the Current property + // won't be set and we have to create one on the fly. + return SynchronizationContext.Current ?? new SynchronizationContext(); + } + + public static T Sync(this SynchronizationContext syncContext, Func func) { + T theValue = default(T); + Exception thrownException = null; + + syncContext.Send(o => { + try { + theValue = func(); + } + catch (Exception ex) { + // by default, the AspNetSynchronizationContext type will swallow thrown exceptions, + // so we need to save and propagate them + thrownException = ex; + } + }, null); + + if (thrownException != null) { + throw Error.SynchronizationContextUtil_ExceptionThrown(thrownException); + } + return theValue; + } + + public static void Sync(this SynchronizationContext syncContext, Action action) { + Sync(syncContext, () => { + action(); + return default(AsyncVoid); + }); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronousOperationException.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronousOperationException.cs new file mode 100644 index 00000000000..8836e26137e --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/SynchronousOperationException.cs @@ -0,0 +1,39 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Runtime.Serialization; + + // This exception type is thrown by the SynchronizationContextUtil helper class since the AspNetSynchronizationContext + // type swallows exceptions. The inner exception contains the data the user cares about. + + [Serializable] + public sealed class SynchronousOperationException : HttpException { + + public SynchronousOperationException() { + } + + private SynchronousOperationException(SerializationInfo info, StreamingContext context) + : base(info, context) { + } + + public SynchronousOperationException(string message) + : base(message) { + } + + public SynchronousOperationException(string message, Exception innerException) + : base(message, innerException) { + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/Trigger.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/Trigger.cs new file mode 100644 index 00000000000..3ac944c503e --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/Trigger.cs @@ -0,0 +1,33 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Runtime.Serialization; + + // Provides a trigger for the TriggerListener class. + + internal sealed class Trigger { + + private readonly Action _fireAction; + + // Constructor should only be called by TriggerListener. + internal Trigger(Action fireAction) { + _fireAction = fireAction; + } + + public void Fire() { + _fireAction(); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/TriggerListener.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/TriggerListener.cs new file mode 100644 index 00000000000..eed509691ca --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Async/TriggerListener.cs @@ -0,0 +1,68 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Async { + using System; + using System.Threading; + + // This class is used to wait for triggers and a continuation. When the continuation has been provded + // and all triggers have been fired, the continuation is called. Similar to WaitHandle.WaitAll(). + // New instances of this type are initially in the inactive state; activation is enabled by a call + // to Activate(). + + // This class is thread-safe. + + internal sealed class TriggerListener { + + private readonly Trigger _activateTrigger; + private volatile Action _continuation; + private readonly SingleEntryGate _continuationFiredGate = new SingleEntryGate(); + private int _outstandingTriggers; + private readonly Trigger _setContinuationTrigger; + + public TriggerListener() { + _activateTrigger = CreateTrigger(); + _setContinuationTrigger = CreateTrigger(); + } + + public void Activate() { + _activateTrigger.Fire(); + } + + public Trigger CreateTrigger() { + Interlocked.Increment(ref _outstandingTriggers); + + SingleEntryGate triggerFiredGate = new SingleEntryGate(); + return new Trigger(() => { + if (triggerFiredGate.TryEnter()) { + HandleTriggerFired(); + } + }); + } + + private void HandleTriggerFired() { + if (Interlocked.Decrement(ref _outstandingTriggers) == 0) { + if (_continuationFiredGate.TryEnter()) { + _continuation(); + } + } + } + + public void SetContinuation(Action continuation) { + if (continuation != null) { + _continuation = continuation; + _setContinuationTrigger.Fire(); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncController.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncController.cs new file mode 100644 index 00000000000..975ce4fc3c3 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncController.cs @@ -0,0 +1,111 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Web.Mvc.Async; + using System.Web.Routing; + + public abstract class AsyncController : Controller, IAsyncManagerContainer, IAsyncController { + + private static readonly object _executeTag = new object(); + private static readonly object _executeCoreTag = new object(); + + private readonly AsyncManager _asyncManager = new AsyncManager(); + + public AsyncManager AsyncManager { + get { + return _asyncManager; + } + } + + protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) { + if (requestContext == null) { + throw new ArgumentNullException("requestContext"); + } + + VerifyExecuteCalledOnce(); + Initialize(requestContext); + return AsyncResultWrapper.Begin(callback, state, BeginExecuteCore, EndExecuteCore, _executeTag); + } + + protected virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) { + // If code in this method needs to be updated, please also check the ExecuteCore() method + // of Controller to see if that code also must be updated. + + PossiblyLoadTempData(); + try { + string actionName = RouteData.GetRequiredString("action"); + IActionInvoker invoker = ActionInvoker; + IAsyncActionInvoker asyncInvoker = invoker as IAsyncActionInvoker; + if (asyncInvoker != null) { + // asynchronous invocation + BeginInvokeDelegate beginDelegate = delegate(AsyncCallback asyncCallback, object asyncState) { + return asyncInvoker.BeginInvokeAction(ControllerContext, actionName, asyncCallback, asyncState); + }; + + EndInvokeDelegate endDelegate = delegate(IAsyncResult asyncResult) { + if (!asyncInvoker.EndInvokeAction(asyncResult)) { + HandleUnknownAction(actionName); + } + }; + + return AsyncResultWrapper.Begin(callback, state, beginDelegate, endDelegate, _executeCoreTag); + } + else { + // synchronous invocation + Action action = () => { + if (!invoker.InvokeAction(ControllerContext, actionName)) { + HandleUnknownAction(actionName); + } + }; + return AsyncResultWrapper.BeginSynchronous(callback, state, action, _executeCoreTag); + } + } + catch { + PossiblySaveTempData(); + throw; + } + } + + protected override IActionInvoker CreateActionInvoker() { + return new AsyncControllerActionInvoker(); + } + + protected virtual void EndExecute(IAsyncResult asyncResult) { + AsyncResultWrapper.End(asyncResult, _executeTag); + } + + protected virtual void EndExecuteCore(IAsyncResult asyncResult) { + // If code in this method needs to be updated, please also check the ExecuteCore() method + // of Controller to see if that code also must be updated. + + try { + AsyncResultWrapper.End(asyncResult, _executeCoreTag); + } + finally { + PossiblySaveTempData(); + } + } + + #region IAsyncController Members + IAsyncResult IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, object state) { + return BeginExecute(requestContext, callback, state); + } + + void IAsyncController.EndExecute(IAsyncResult asyncResult) { + EndExecute(asyncResult); + } + #endregion + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncTimeoutAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncTimeoutAttribute.cs new file mode 100644 index 00000000000..9622e25ea64 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AsyncTimeoutAttribute.cs @@ -0,0 +1,53 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Web.Mvc.Async; + + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", + Justification = "Unsealed so that subclassed types can set properties in the default constructor.")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public class AsyncTimeoutAttribute : ActionFilterAttribute { + + // duration is specified in milliseconds + public AsyncTimeoutAttribute(int duration) { + if (duration < -1) { + throw Error.AsyncCommon_InvalidTimeout("duration"); + } + + Duration = duration; + } + + public int Duration { + get; + private set; + } + + public override void OnActionExecuting(ActionExecutingContext filterContext) { + if (filterContext == null) { + throw new ArgumentNullException("filterContext"); + } + + IAsyncManagerContainer container = filterContext.Controller as IAsyncManagerContainer; + if (container == null) { + throw Error.AsyncCommon_ControllerMustImplementIAsyncManagerContainer(filterContext.Controller.GetType()); + } + + container.AsyncManager.Timeout = Duration; + + base.OnActionExecuting(filterContext); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizationContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizationContext.cs new file mode 100644 index 00000000000..8cd68084b46 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizationContext.cs @@ -0,0 +1,50 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + + public class AuthorizationContext : ControllerContext { + + // parameterless constructor used for mocking + public AuthorizationContext() { + } + + [Obsolete("The recommended alternative is the constructor AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor).")] + public AuthorizationContext(ControllerContext controllerContext) + : base(controllerContext) { + } + + [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", + Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")] + public AuthorizationContext(ControllerContext controllerContext, ActionDescriptor actionDescriptor) + : base(controllerContext) { + if (actionDescriptor == null) { + throw new ArgumentNullException("actionDescriptor"); + } + + ActionDescriptor = actionDescriptor; + } + + public virtual ActionDescriptor ActionDescriptor { + get; + set; + } + + public ActionResult Result { + get; + set; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizeAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizeAttribute.cs new file mode 100644 index 00000000000..3b07bcaf50d --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/AuthorizeAttribute.cs @@ -0,0 +1,135 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Security.Principal; + using System.Web; + + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", + Justification = "Unsealed so that subclassed types can set properties in the default constructor or override our behavior.")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] + public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter { + + private readonly object _typeId = new object(); + + private string _roles; + private string[] _rolesSplit = new string[0]; + private string _users; + private string[] _usersSplit = new string[0]; + + public string Roles { + get { + return _roles ?? String.Empty; + } + set { + _roles = value; + _rolesSplit = SplitString(value); + } + } + + public override object TypeId { + get { + return _typeId; + } + } + + public string Users { + get { + return _users ?? String.Empty; + } + set { + _users = value; + _usersSplit = SplitString(value); + } + } + + // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method. + protected virtual bool AuthorizeCore(HttpContextBase httpContext) { + if (httpContext == null) { + throw new ArgumentNullException("httpContext"); + } + + IPrincipal user = httpContext.User; + if (!user.Identity.IsAuthenticated) { + return false; + } + + if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) { + return false; + } + + if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) { + return false; + } + + return true; + } + + private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) { + validationStatus = OnCacheAuthorization(new HttpContextWrapper(context)); + } + + public virtual void OnAuthorization(AuthorizationContext filterContext) { + if (filterContext == null) { + throw new ArgumentNullException("filterContext"); + } + + if (AuthorizeCore(filterContext.HttpContext)) { + // ** IMPORTANT ** + // Since we're performing authorization at the action level, the authorization code runs + // after the output caching module. In the worst case this could allow an authorized user + // to cause the page to be cached, then an unauthorized user would later be served the + // cached page. We work around this by telling proxies not to cache the sensitive page, + // then we hook our custom authorization code into the caching mechanism so that we have + // the final say on whether a page should be served from the cache. + + HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache; + cachePolicy.SetProxyMaxAge(new TimeSpan(0)); + cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */); + } + else { + HandleUnauthorizedRequest(filterContext); + } + } + + protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) { + // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs. + filterContext.Result = new HttpUnauthorizedResult(); + } + + // This method must be thread-safe since it is called by the caching module. + protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext) { + if (httpContext == null) { + throw new ArgumentNullException("httpContext"); + } + + bool isAuthorized = AuthorizeCore(httpContext); + return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest; + } + + internal static string[] SplitString(string original) { + if (String.IsNullOrEmpty(original)) { + return new string[0]; + } + + var split = from piece in original.Split(',') + let trimmed = piece.Trim() + where !String.IsNullOrEmpty(trimmed) + select trimmed; + return split.ToArray(); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/BindAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/BindAttribute.cs new file mode 100644 index 00000000000..5f3b1bee55a --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/BindAttribute.cs @@ -0,0 +1,63 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Linq; + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)] + public sealed class BindAttribute : Attribute { + + private string _exclude; + private string[] _excludeSplit = new string[0]; + private string _include; + private string[] _includeSplit = new string[0]; + + public string Exclude { + get { + return _exclude ?? String.Empty; + } + set { + _exclude = value; + _excludeSplit = AuthorizeAttribute.SplitString(value); + } + } + + public string Include { + get { + return _include ?? String.Empty; + } + set { + _include = value; + _includeSplit = AuthorizeAttribute.SplitString(value); + } + } + + public string Prefix { + get; + set; + } + + internal static bool IsPropertyAllowed(string propertyName, string[] includeProperties, string[] excludeProperties) { + // We allow a property to be bound if its both in the include list AND not in the exclude list. + // An empty include list implies all properties are allowed. + // An empty exclude list implies no properties are disallowed. + bool includeProperty = (includeProperties == null) || (includeProperties.Length == 0) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase); + bool excludeProperty = (excludeProperties != null) && excludeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase); + return includeProperty && !excludeProperty; + } + + public bool IsPropertyAllowed(string propertyName) { + return IsPropertyAllowed(propertyName, _includeSplit, _excludeSplit); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/BuildManagerWrapper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/BuildManagerWrapper.cs new file mode 100644 index 00000000000..f8959ecd1e0 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/BuildManagerWrapper.cs @@ -0,0 +1,43 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System.Collections; + using System.IO; + using System.Web.Compilation; + + internal sealed class BuildManagerWrapper : IBuildManager { + private static readonly Func _readCachedFileDelegate = + TypeHelpers.CreateDelegate>(typeof(BuildManager), "ReadCachedFile", null /* thisParameter */); + private static readonly Func _createCachedFileDelegate = + TypeHelpers.CreateDelegate>(typeof(BuildManager), "CreateCachedFile", null /* thisParameter */); + + #region IBuildManager Members + object IBuildManager.CreateInstanceFromVirtualPath(string virtualPath, Type requiredBaseType) { + return BuildManager.CreateInstanceFromVirtualPath(virtualPath, requiredBaseType); + } + + ICollection IBuildManager.GetReferencedAssemblies() { + return BuildManager.GetReferencedAssemblies(); + } + + // ASP.NET 4 methods + Stream IBuildManager.ReadCachedFile(string fileName) { + return (_readCachedFileDelegate != null) ? _readCachedFileDelegate(fileName) : null; + } + + Stream IBuildManager.CreateCachedFile(string fileName) { + return (_createCachedFileDelegate != null) ? _createCachedFileDelegate(fileName) : null; + } + #endregion + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ByteArrayModelBinder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ByteArrayModelBinder.cs new file mode 100644 index 00000000000..ad62a139d65 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ByteArrayModelBinder.cs @@ -0,0 +1,43 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + + public class ByteArrayModelBinder : IModelBinder { + public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { + if (bindingContext == null) { + throw new ArgumentNullException("bindingContext"); + } + + ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); + + // case 1: there was no element containing this data + if (valueResult == null) { + return null; + } + + string value = valueResult.AttemptedValue; + + // case 2: there was an element but it was left blank + if (String.IsNullOrEmpty(value)) { + return null; + } + + // Future proofing. If the byte array is actually an instance of System.Data.Linq.Binary + // then we need to remove these quotes put in place by the ToString() method. + string realValue = value.Replace("\"", String.Empty); + return Convert.FromBase64String(realValue); + } + } + +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ChildActionOnlyAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ChildActionOnlyAttribute.cs new file mode 100644 index 00000000000..398546bfc08 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ChildActionOnlyAttribute.cs @@ -0,0 +1,30 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] + public sealed class ChildActionOnlyAttribute : FilterAttribute, IAuthorizationFilter { + + public void OnAuthorization(AuthorizationContext filterContext) { + if (filterContext == null) { + throw new ArgumentNullException("filterContext"); + } + + if (!filterContext.IsChildAction) { + throw Error.ChildActionOnlyAttribute_MustBeInChildRequest(filterContext.ActionDescriptor); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs new file mode 100644 index 00000000000..54c2519aa02 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ClientDataTypeModelValidatorProvider.cs @@ -0,0 +1,79 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Web.Mvc.Resources; + + public class ClientDataTypeModelValidatorProvider : ModelValidatorProvider { + + private static readonly HashSet _numericTypes = new HashSet(new Type[] { + typeof(byte), typeof(sbyte), + typeof(short), typeof(ushort), + typeof(int), typeof(uint), + typeof(long), typeof(ulong), + typeof(float), typeof(double), typeof(decimal) + }); + + public override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context) { + if (metadata == null) { + throw new ArgumentNullException("metadata"); + } + if (context == null) { + throw new ArgumentNullException("context"); + } + + return GetValidatorsImpl(metadata, context); + } + + private static IEnumerable GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) { + Type type = metadata.ModelType; + if (IsNumericType(type)) { + yield return new NumericModelValidator(metadata, context); + } + } + + private static bool IsNumericType(Type type) { + Type underlyingType = Nullable.GetUnderlyingType(type); // strip off the Nullable<> + return _numericTypes.Contains(underlyingType ?? type); + } + + internal sealed class NumericModelValidator : ModelValidator { + public NumericModelValidator(ModelMetadata metadata, ControllerContext controllerContext) + : base(metadata, controllerContext) { + } + + public override IEnumerable GetClientValidationRules() { + ModelClientValidationRule rule = new ModelClientValidationRule() { + ValidationType = "number", + ErrorMessage = MakeErrorString(Metadata.GetDisplayName()) + }; + + return new ModelClientValidationRule[] { rule }; + } + + private static string MakeErrorString(string displayName) { + // use CurrentCulture since this message is intended for the site visitor + return String.Format(CultureInfo.CurrentCulture, MvcResources.ClientDataTypeModelValidatorProvider_FieldMustBeNumeric, displayName); + } + + public override IEnumerable Validate(object container) { + // this is not a server-side validator + return Enumerable.Empty(); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ContentResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ContentResult.cs new file mode 100644 index 00000000000..37ecb71a70c --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ContentResult.cs @@ -0,0 +1,53 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Text; + using System.Web; + + public class ContentResult : ActionResult { + + public string Content { + get; + set; + } + + public Encoding ContentEncoding { + get; + set; + } + + public string ContentType { + get; + set; + } + + public override void ExecuteResult(ControllerContext context) { + if (context == null) { + throw new ArgumentNullException("context"); + } + + HttpResponseBase response = context.HttpContext.Response; + + if (!String.IsNullOrEmpty(ContentType)) { + response.ContentType = ContentType; + } + if (ContentEncoding != null) { + response.ContentEncoding = ContentEncoding; + } + if (Content != null) { + response.Write(Content); + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Controller.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Controller.cs new file mode 100644 index 00000000000..04f4bc41280 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Controller.cs @@ -0,0 +1,599 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.IO; + using System.Security.Principal; + using System.Text; + using System.Web; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public abstract class Controller : ControllerBase, IActionFilter, IAuthorizationFilter, IDisposable, IExceptionFilter, IResultFilter { + + private IActionInvoker _actionInvoker; + private ModelBinderDictionary _binders; + private RouteCollection _routeCollection; + private ITempDataProvider _tempDataProvider; + + public IActionInvoker ActionInvoker { + get { + if (_actionInvoker == null) { + _actionInvoker = CreateActionInvoker(); + } + return _actionInvoker; + } + set { + _actionInvoker = value; + } + } + + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", + Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")] + protected internal ModelBinderDictionary Binders { + get { + if (_binders == null) { + _binders = ModelBinders.Binders; + } + return _binders; + } + set { + _binders = value; + } + } + + public HttpContextBase HttpContext { + get { + return ControllerContext == null ? null : ControllerContext.HttpContext; + } + } + + public ModelStateDictionary ModelState { + get { + return ViewData.ModelState; + } + } + + public HttpRequestBase Request { + get { + return HttpContext == null ? null : HttpContext.Request; + } + } + + public HttpResponseBase Response { + get { + return HttpContext == null ? null : HttpContext.Response; + } + } + + internal RouteCollection RouteCollection { + get { + if (_routeCollection == null) { + _routeCollection = RouteTable.Routes; + } + return _routeCollection; + } + set { + _routeCollection = value; + } + } + + public RouteData RouteData { + get { + return ControllerContext == null ? null : ControllerContext.RouteData; + } + } + + public HttpServerUtilityBase Server { + get { + return HttpContext == null ? null : HttpContext.Server; + } + } + + public HttpSessionStateBase Session { + get { + return HttpContext == null ? null : HttpContext.Session; + } + } + + public ITempDataProvider TempDataProvider { + get { + if (_tempDataProvider == null) { + _tempDataProvider = CreateTempDataProvider(); + } + return _tempDataProvider; + } + set { + _tempDataProvider = value; + } + } + + public UrlHelper Url { + get; + set; + } + + public IPrincipal User { + get { + return HttpContext == null ? null : HttpContext.User; + } + } + + [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", + Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")] + protected internal ContentResult Content(string content) { + return Content(content, null /* contentType */); + } + + [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", + Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")] + protected internal ContentResult Content(string content, string contentType) { + return Content(content, contentType, null /* contentEncoding */); + } + + [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", + Justification = "'Content' refers to ContentResult type; 'content' refers to ContentResult.Content property.")] + protected internal virtual ContentResult Content(string content, string contentType, Encoding contentEncoding) { + return new ContentResult { + Content = content, + ContentType = contentType, + ContentEncoding = contentEncoding + }; + } + + protected virtual IActionInvoker CreateActionInvoker() { + return new ControllerActionInvoker(); + } + + protected virtual ITempDataProvider CreateTempDataProvider() { + return new SessionStateTempDataProvider(); + } + + // The default invoker will never match methods defined on the Controller type, so + // the Dispose() method is not web-callable. However, in general, since implicitly- + // implemented interface methods are public, they are web-callable unless decorated with + // [NonAction]. + public void Dispose() { + Dispose(true /* disposing */); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) { + } + + protected override void ExecuteCore() { + // If code in this method needs to be updated, please also check the BeginExecuteCore() and + // EndExecuteCore() methods of AsyncController to see if that code also must be updated. + + PossiblyLoadTempData(); + try { + string actionName = RouteData.GetRequiredString("action"); + if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) { + HandleUnknownAction(actionName); + } + } + finally { + PossiblySaveTempData(); + } + } + + protected internal FileContentResult File(byte[] fileContents, string contentType) { + return File(fileContents, contentType, null /* fileDownloadName */); + } + + protected internal virtual FileContentResult File(byte[] fileContents, string contentType, string fileDownloadName) { + return new FileContentResult(fileContents, contentType) { FileDownloadName = fileDownloadName }; + } + + protected internal FileStreamResult File(Stream fileStream, string contentType) { + return File(fileStream, contentType, null /* fileDownloadName */); + } + + protected internal virtual FileStreamResult File(Stream fileStream, string contentType, string fileDownloadName) { + return new FileStreamResult(fileStream, contentType) { FileDownloadName = fileDownloadName }; + } + + protected internal FilePathResult File(string fileName, string contentType) { + return File(fileName, contentType, null /* fileDownloadName */); + } + + protected internal virtual FilePathResult File(string fileName, string contentType, string fileDownloadName) { + return new FilePathResult(fileName, contentType) { FileDownloadName = fileDownloadName }; + } + + protected virtual void HandleUnknownAction(string actionName) { + throw new HttpException(404, String.Format(CultureInfo.CurrentUICulture, + MvcResources.Controller_UnknownAction, actionName, GetType().FullName)); + } + + protected internal virtual JavaScriptResult JavaScript(string script) { + return new JavaScriptResult { Script = script }; + } + + protected internal JsonResult Json(object data) { + return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet); + } + + protected internal JsonResult Json(object data, string contentType) { + return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet); + } + + protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) { + return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet); + } + + protected internal JsonResult Json(object data, JsonRequestBehavior behavior) { + return Json(data, null /* contentType */, null /* contentEncoding */, behavior); + } + + protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior) { + return Json(data, contentType, null /* contentEncoding */, behavior); + } + + protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { + return new JsonResult { + Data = data, + ContentType = contentType, + ContentEncoding = contentEncoding, + JsonRequestBehavior = behavior + }; + } + + protected override void Initialize(RequestContext requestContext) { + base.Initialize(requestContext); + Url = new UrlHelper(requestContext); + } + + protected virtual void OnActionExecuting(ActionExecutingContext filterContext) { + } + + protected virtual void OnActionExecuted(ActionExecutedContext filterContext) { + } + + protected virtual void OnAuthorization(AuthorizationContext filterContext) { + } + + protected virtual void OnException(ExceptionContext filterContext) { + } + + protected virtual void OnResultExecuted(ResultExecutedContext filterContext) { + } + + protected virtual void OnResultExecuting(ResultExecutingContext filterContext) { + } + + protected internal PartialViewResult PartialView() { + return PartialView(null /* viewName */, null /* model */); + } + + protected internal PartialViewResult PartialView(object model) { + return PartialView(null /* viewName */, model); + } + + protected internal PartialViewResult PartialView(string viewName) { + return PartialView(viewName, null /* model */); + } + + protected internal virtual PartialViewResult PartialView(string viewName, object model) { + if (model != null) { + ViewData.Model = model; + } + + return new PartialViewResult { + ViewName = viewName, + ViewData = ViewData, + TempData = TempData + }; + } + + internal void PossiblyLoadTempData() { + if (!ControllerContext.IsChildAction) { + TempData.Load(ControllerContext, TempDataProvider); + } + } + + internal void PossiblySaveTempData() { + if (!ControllerContext.IsChildAction) { + TempData.Save(ControllerContext, TempDataProvider); + } + } + + [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", + Justification = "Instance method for consistency with other helpers.")] + [SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", + Justification = "Response.Redirect() takes its URI as a string parameter.")] + protected internal virtual RedirectResult Redirect(string url) { + if (String.IsNullOrEmpty(url)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "url"); + } + return new RedirectResult(url); + } + + protected internal RedirectToRouteResult RedirectToAction(string actionName) { + return RedirectToAction(actionName, (RouteValueDictionary)null); + } + + protected internal RedirectToRouteResult RedirectToAction(string actionName, object routeValues) { + return RedirectToAction(actionName, new RouteValueDictionary(routeValues)); + } + + protected internal RedirectToRouteResult RedirectToAction(string actionName, RouteValueDictionary routeValues) { + return RedirectToAction(actionName, null /* controllerName */, routeValues); + } + + protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName) { + return RedirectToAction(actionName, controllerName, (RouteValueDictionary)null); + } + + protected internal RedirectToRouteResult RedirectToAction(string actionName, string controllerName, object routeValues) { + return RedirectToAction(actionName, controllerName, new RouteValueDictionary(routeValues)); + } + + protected internal virtual RedirectToRouteResult RedirectToAction(string actionName, string controllerName, RouteValueDictionary routeValues) { + RouteValueDictionary mergedRouteValues; + + if (RouteData == null) { + mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, null, routeValues, true /* includeImplicitMvcValues */); + } + else { + mergedRouteValues = RouteValuesHelpers.MergeRouteValues(actionName, controllerName, RouteData.Values, routeValues, true /* includeImplicitMvcValues */); + } + + return new RedirectToRouteResult(mergedRouteValues); + } + + protected internal RedirectToRouteResult RedirectToRoute(object routeValues) { + return RedirectToRoute(new RouteValueDictionary(routeValues)); + } + + protected internal RedirectToRouteResult RedirectToRoute(RouteValueDictionary routeValues) { + return RedirectToRoute(null /* routeName */, routeValues); + } + + protected internal RedirectToRouteResult RedirectToRoute(string routeName) { + return RedirectToRoute(routeName, (RouteValueDictionary)null); + } + + protected internal RedirectToRouteResult RedirectToRoute(string routeName, object routeValues) { + return RedirectToRoute(routeName, new RouteValueDictionary(routeValues)); + } + + protected internal virtual RedirectToRouteResult RedirectToRoute(string routeName, RouteValueDictionary routeValues) { + return new RedirectToRouteResult(routeName, RouteValuesHelpers.GetRouteValues(routeValues)); + } + + protected internal bool TryUpdateModel(TModel model) where TModel : class { + return TryUpdateModel(model, null, null, null, ValueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string prefix) where TModel : class { + return TryUpdateModel(model, prefix, null, null, ValueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string[] includeProperties) where TModel : class { + return TryUpdateModel(model, null, includeProperties, null, ValueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string prefix, string[] includeProperties) where TModel : class { + return TryUpdateModel(model, prefix, includeProperties, null, ValueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class { + return TryUpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider); + } + + protected internal bool TryUpdateModel(TModel model, IValueProvider valueProvider) where TModel : class { + return TryUpdateModel(model, null, null, null, valueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string prefix, IValueProvider valueProvider) where TModel : class { + return TryUpdateModel(model, prefix, null, null, valueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class { + return TryUpdateModel(model, null, includeProperties, null, valueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class { + return TryUpdateModel(model, prefix, includeProperties, null, valueProvider); + } + + protected internal bool TryUpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class { + if (model == null) { + throw new ArgumentNullException("model"); + } + if (valueProvider == null) { + throw new ArgumentNullException("valueProvider"); + } + + Predicate propertyFilter = propertyName => BindAttribute.IsPropertyAllowed(propertyName, includeProperties, excludeProperties); + IModelBinder binder = Binders.GetBinder(typeof(TModel)); + + ModelBindingContext bindingContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, typeof(TModel)), + ModelName = prefix, + ModelState = ModelState, + PropertyFilter = propertyFilter, + ValueProvider = valueProvider + }; + binder.BindModel(ControllerContext, bindingContext); + return ModelState.IsValid; + } + + protected internal bool TryValidateModel(object model) { + return TryValidateModel(model, null /* prefix */); + } + + protected internal bool TryValidateModel(object model, string prefix) { + if (model == null) { + throw new ArgumentNullException("model"); + } + + ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()); + + foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(metadata, ControllerContext).Validate(null)) { + ModelState.AddModelError(DefaultModelBinder.CreateSubPropertyName(prefix, validationResult.MemberName), validationResult.Message); + } + + return ModelState.IsValid; + } + + protected internal void UpdateModel(TModel model) where TModel : class { + UpdateModel(model, null, null, null, ValueProvider); + } + + protected internal void UpdateModel(TModel model, string prefix) where TModel : class { + UpdateModel(model, prefix, null, null, ValueProvider); + } + + protected internal void UpdateModel(TModel model, string[] includeProperties) where TModel : class { + UpdateModel(model, null, includeProperties, null, ValueProvider); + } + + protected internal void UpdateModel(TModel model, string prefix, string[] includeProperties) where TModel : class { + UpdateModel(model, prefix, includeProperties, null, ValueProvider); + } + + protected internal void UpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class { + UpdateModel(model, prefix, includeProperties, excludeProperties, ValueProvider); + } + + protected internal void UpdateModel(TModel model, IValueProvider valueProvider) where TModel : class { + UpdateModel(model, null, null, null, valueProvider); + } + + protected internal void UpdateModel(TModel model, string prefix, IValueProvider valueProvider) where TModel : class { + UpdateModel(model, prefix, null, null, valueProvider); + } + + protected internal void UpdateModel(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class { + UpdateModel(model, null, includeProperties, null, valueProvider); + } + + protected internal void UpdateModel(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class { + UpdateModel(model, prefix, includeProperties, null, valueProvider); + } + + protected internal void UpdateModel(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class { + bool success = TryUpdateModel(model, prefix, includeProperties, excludeProperties, valueProvider); + if (!success) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.Controller_UpdateModel_UpdateUnsuccessful, + typeof(TModel).FullName); + throw new InvalidOperationException(message); + } + } + + protected internal void ValidateModel(object model) { + ValidateModel(model, null /* prefix */); + } + + protected internal void ValidateModel(object model, string prefix) { + if (!TryValidateModel(model, prefix)) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.Controller_Validate_ValidationFailed, + model.GetType().FullName + ) + ); + } + } + + protected internal ViewResult View() { + return View(null /* viewName */, null /* masterName */, null /* model */); + } + + protected internal ViewResult View(object model) { + return View(null /* viewName */, null /* masterName */, model); + } + + protected internal ViewResult View(string viewName) { + return View(viewName, null /* masterName */, null /* model */); + } + + protected internal ViewResult View(string viewName, string masterName) { + return View(viewName, masterName, null /* model */); + } + + protected internal ViewResult View(string viewName, object model) { + return View(viewName, null /* masterName */, model); + } + + protected internal virtual ViewResult View(string viewName, string masterName, object model) { + if (model != null) { + ViewData.Model = model; + } + + return new ViewResult { + ViewName = viewName, + MasterName = masterName, + ViewData = ViewData, + TempData = TempData + }; + } + + [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", + Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")] + protected internal ViewResult View(IView view) { + return View(view, null /* model */); + } + + [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "0#", + Justification = "The method name 'View' is a convenient shorthand for 'CreateViewResult'.")] + protected internal virtual ViewResult View(IView view, object model) { + if (model != null) { + ViewData.Model = model; + } + + return new ViewResult { + View = view, + ViewData = ViewData, + TempData = TempData + }; + } + + #region IActionFilter Members + void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { + OnActionExecuting(filterContext); + } + + void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext) { + OnActionExecuted(filterContext); + } + #endregion + + #region IAuthorizationFilter Members + void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext) { + OnAuthorization(filterContext); + } + #endregion + + #region IExceptionFilter Members + void IExceptionFilter.OnException(ExceptionContext filterContext) { + OnException(filterContext); + } + #endregion + + #region IResultFilter Members + void IResultFilter.OnResultExecuting(ResultExecutingContext filterContext) { + OnResultExecuting(filterContext); + } + + void IResultFilter.OnResultExecuted(ResultExecutedContext filterContext) { + OnResultExecuted(filterContext); + } + #endregion + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerActionInvoker.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerActionInvoker.cs new file mode 100644 index 00000000000..aad3e814bc1 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerActionInvoker.cs @@ -0,0 +1,333 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Linq; + using System.Threading; + using System.Web; + using System.Web.Mvc.Resources; + + public class ControllerActionInvoker : IActionInvoker { + + private readonly static ControllerDescriptorCache _staticDescriptorCache = new ControllerDescriptorCache(); + + private ModelBinderDictionary _binders; + private ControllerDescriptorCache _instanceDescriptorCache; + + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", + Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")] + protected internal ModelBinderDictionary Binders { + get { + if (_binders == null) { + _binders = ModelBinders.Binders; + } + return _binders; + } + set { + _binders = value; + } + } + + internal ControllerDescriptorCache DescriptorCache { + get { + if (_instanceDescriptorCache == null) { + _instanceDescriptorCache = _staticDescriptorCache; + } + return _instanceDescriptorCache; + } + set { + _instanceDescriptorCache = value; + } + } + + private static void AddControllerToFilterList(ControllerBase controller, IList filterList) where TFilter : class { + TFilter controllerAsFilter = controller as TFilter; + if (controllerAsFilter != null) { + filterList.Insert(0, controllerAsFilter); + } + } + + protected virtual ActionResult CreateActionResult(ControllerContext controllerContext, ActionDescriptor actionDescriptor, object actionReturnValue) { + if (actionReturnValue == null) { + return new EmptyResult(); + } + + ActionResult actionResult = (actionReturnValue as ActionResult) ?? + new ContentResult { Content = Convert.ToString(actionReturnValue, CultureInfo.InvariantCulture) }; + return actionResult; + } + + protected virtual ControllerDescriptor GetControllerDescriptor(ControllerContext controllerContext) { + Type controllerType = controllerContext.Controller.GetType(); + ControllerDescriptor controllerDescriptor = DescriptorCache.GetDescriptor(controllerType, () => new ReflectedControllerDescriptor(controllerType)); + return controllerDescriptor; + } + + protected virtual ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) { + ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); + return actionDescriptor; + } + + protected virtual FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { + FilterInfo filters = actionDescriptor.GetFilters(); + + // if the current controller implements one of the filter interfaces, it should be added to the list at position 0 + ControllerBase controller = controllerContext.Controller; + AddControllerToFilterList(controller, filters.ActionFilters); + AddControllerToFilterList(controller, filters.ResultFilters); + AddControllerToFilterList(controller, filters.AuthorizationFilters); + AddControllerToFilterList(controller, filters.ExceptionFilters); + + return filters; + } + + private IModelBinder GetModelBinder(ParameterDescriptor parameterDescriptor) { + // look on the parameter itself, then look in the global table + return parameterDescriptor.BindingInfo.Binder ?? Binders.GetBinder(parameterDescriptor.ParameterType); + } + + protected virtual object GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) { + // collect all of the necessary binding properties + Type parameterType = parameterDescriptor.ParameterType; + IModelBinder binder = GetModelBinder(parameterDescriptor); + IValueProvider valueProvider = controllerContext.Controller.ValueProvider; + string parameterName = parameterDescriptor.BindingInfo.Prefix ?? parameterDescriptor.ParameterName; + Predicate propertyFilter = GetPropertyFilter(parameterDescriptor); + + // finally, call into the binder + ModelBindingContext bindingContext = new ModelBindingContext() { + FallbackToEmptyPrefix = (parameterDescriptor.BindingInfo.Prefix == null), // only fall back if prefix not specified + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, parameterType), + ModelName = parameterName, + ModelState = controllerContext.Controller.ViewData.ModelState, + PropertyFilter = propertyFilter, + ValueProvider = valueProvider + }; + + object result = binder.BindModel(controllerContext, bindingContext); + return result ?? parameterDescriptor.DefaultValue; + } + + protected virtual IDictionary GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { + Dictionary parametersDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + ParameterDescriptor[] parameterDescriptors = actionDescriptor.GetParameters(); + + foreach (ParameterDescriptor parameterDescriptor in parameterDescriptors) { + parametersDict[parameterDescriptor.ParameterName] = GetParameterValue(controllerContext, parameterDescriptor); + } + return parametersDict; + } + + private static Predicate GetPropertyFilter(ParameterDescriptor parameterDescriptor) { + ParameterBindingInfo bindingInfo = parameterDescriptor.BindingInfo; + return propertyName => BindAttribute.IsPropertyAllowed(propertyName, bindingInfo.Include.ToArray(), bindingInfo.Exclude.ToArray()); + } + + public virtual bool InvokeAction(ControllerContext controllerContext, string actionName) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + if (String.IsNullOrEmpty(actionName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName"); + } + + ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext); + ActionDescriptor actionDescriptor = FindAction(controllerContext, controllerDescriptor, actionName); + if (actionDescriptor != null) { + FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor); + + try { + AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor); + if (authContext.Result != null) { + // the auth filter signaled that we should let it short-circuit the request + InvokeActionResult(controllerContext, authContext.Result); + } + else { + if (controllerContext.Controller.ValidateRequest) { + ValidateRequest(controllerContext); + } + + IDictionary parameters = GetParameterValues(controllerContext, actionDescriptor); + ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters); + InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result); + } + } + catch (ThreadAbortException) { + // This type of exception occurs as a result of Response.Redirect(), but we special-case so that + // the filters don't see this as an error. + throw; + } + catch (Exception ex) { + // something blew up, so execute the exception filters + ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex); + if (!exceptionContext.ExceptionHandled) { + throw; + } + InvokeActionResult(controllerContext, exceptionContext.Result); + } + + return true; + } + + // notify controller that no method matched + return false; + } + + protected virtual ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary parameters) { + object returnValue = actionDescriptor.Execute(controllerContext, parameters); + ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue); + return result; + } + + internal static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func continuation) { + filter.OnActionExecuting(preContext); + if (preContext.Result != null) { + return new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) { + Result = preContext.Result + }; + } + + bool wasError = false; + ActionExecutedContext postContext = null; + try { + postContext = continuation(); + } + catch (ThreadAbortException) { + // This type of exception occurs as a result of Response.Redirect(), but we special-case so that + // the filters don't see this as an error. + postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); + filter.OnActionExecuted(postContext); + throw; + } + catch (Exception ex) { + wasError = true; + postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); + filter.OnActionExecuted(postContext); + if (!postContext.ExceptionHandled) { + throw; + } + } + if (!wasError) { + filter.OnActionExecuted(postContext); + } + return postContext; + } + + protected virtual ActionExecutedContext InvokeActionMethodWithFilters(ControllerContext controllerContext, IList filters, ActionDescriptor actionDescriptor, IDictionary parameters) { + ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters); + Func continuation = () => + new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */) { + Result = InvokeActionMethod(controllerContext, actionDescriptor, parameters) + }; + + // need to reverse the filter list because the continuations are built up backward + Func thunk = filters.Reverse().Aggregate(continuation, + (next, filter) => () => InvokeActionMethodFilter(filter, preContext, next)); + return thunk(); + } + + protected virtual void InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) { + actionResult.ExecuteResult(controllerContext); + } + + internal static ResultExecutedContext InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func continuation) { + filter.OnResultExecuting(preContext); + if (preContext.Cancel) { + return new ResultExecutedContext(preContext, preContext.Result, true /* canceled */, null /* exception */); + } + + bool wasError = false; + ResultExecutedContext postContext = null; + try { + postContext = continuation(); + } + catch (ThreadAbortException) { + // This type of exception occurs as a result of Response.Redirect(), but we special-case so that + // the filters don't see this as an error. + postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, null /* exception */); + filter.OnResultExecuted(postContext); + throw; + } + catch (Exception ex) { + wasError = true; + postContext = new ResultExecutedContext(preContext, preContext.Result, false /* canceled */, ex); + filter.OnResultExecuted(postContext); + if (!postContext.ExceptionHandled) { + throw; + } + } + if (!wasError) { + filter.OnResultExecuted(postContext); + } + return postContext; + } + + protected virtual ResultExecutedContext InvokeActionResultWithFilters(ControllerContext controllerContext, IList filters, ActionResult actionResult) { + ResultExecutingContext preContext = new ResultExecutingContext(controllerContext, actionResult); + Func continuation = delegate { + InvokeActionResult(controllerContext, actionResult); + return new ResultExecutedContext(controllerContext, actionResult, false /* canceled */, null /* exception */); + }; + + // need to reverse the filter list because the continuations are built up backward + Func thunk = filters.Reverse().Aggregate(continuation, + (next, filter) => () => InvokeActionResultFilter(filter, preContext, next)); + return thunk(); + } + + protected virtual AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList filters, ActionDescriptor actionDescriptor) { + AuthorizationContext context = new AuthorizationContext(controllerContext, actionDescriptor); + foreach (IAuthorizationFilter filter in filters) { + filter.OnAuthorization(context); + // short-circuit evaluation + if (context.Result != null) { + break; + } + } + + return context; + } + + protected virtual ExceptionContext InvokeExceptionFilters(ControllerContext controllerContext, IList filters, Exception exception) { + ExceptionContext context = new ExceptionContext(controllerContext, exception); + foreach (IExceptionFilter filter in filters) { + filter.OnException(context); + } + + return context; + } + + [SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "rawUrl", + Justification = "We only care about the property getter's side effects, not the returned value.")] + internal static void ValidateRequest(ControllerContext controllerContext) { + if (controllerContext.IsChildAction) { + return; + } + + // DevDiv 214040: Enable Request Validation by default for all controller requests + // + // Note that we grab the Request's RawUrl to force it to be validated. Calling ValidateInput() + // doesn't actually validate anything. It just sets flags indicating that on the next usage of + // certain inputs that they should be validated. We special case RawUrl because the URL has already + // been consumed by routing and thus might contain dangerous data. By forcing the RawUrl to be + // re-read we're making sure that it gets validated by ASP.NET. + + controllerContext.HttpContext.Request.ValidateInput(); + string rawUrl = controllerContext.HttpContext.Request.RawUrl; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBase.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBase.cs new file mode 100644 index 00000000000..b5902bd3a66 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBase.cs @@ -0,0 +1,116 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Web.Mvc.Async; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public abstract class ControllerBase : IController { + + private readonly SingleEntryGate _executeWasCalledGate = new SingleEntryGate(); + + private TempDataDictionary _tempDataDictionary; + private bool _validateRequest = true; + private IValueProvider _valueProvider; + private ViewDataDictionary _viewDataDictionary; + + public ControllerContext ControllerContext { + get; + set; + } + + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", + Justification = "This property is settable so that unit tests can provide mock implementations.")] + public TempDataDictionary TempData { + get { + if (ControllerContext != null && ControllerContext.IsChildAction) { + return ControllerContext.ParentActionViewContext.TempData; + } + if (_tempDataDictionary == null) { + _tempDataDictionary = new TempDataDictionary(); + } + return _tempDataDictionary; + } + set { + _tempDataDictionary = value; + } + } + + public bool ValidateRequest { + get { + return _validateRequest; + } + set { + _validateRequest = value; + } + } + + public IValueProvider ValueProvider { + get { + if (_valueProvider == null) { + _valueProvider = ValueProviderFactories.Factories.GetValueProvider(ControllerContext); + } + return _valueProvider; + } + set { + _valueProvider = value; + } + } + + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", + Justification = "This property is settable so that unit tests can provide mock implementations.")] + public ViewDataDictionary ViewData { + get { + if (_viewDataDictionary == null) { + _viewDataDictionary = new ViewDataDictionary(); + } + return _viewDataDictionary; + } + set { + _viewDataDictionary = value; + } + } + + protected virtual void Execute(RequestContext requestContext) { + if (requestContext == null) { + throw new ArgumentNullException("requestContext"); + } + + VerifyExecuteCalledOnce(); + Initialize(requestContext); + ExecuteCore(); + } + + protected abstract void ExecuteCore(); + + protected virtual void Initialize(RequestContext requestContext) { + ControllerContext = new ControllerContext(requestContext, this); + } + + internal void VerifyExecuteCalledOnce() { + if (!_executeWasCalledGate.TryEnter()) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ControllerBase_CannotHandleMultipleRequests, GetType()); + throw new InvalidOperationException(message); + } + } + + #region IController Members + void IController.Execute(RequestContext requestContext) { + Execute(requestContext); + } + #endregion + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBuilder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBuilder.cs new file mode 100644 index 00000000000..c86f740fd42 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerBuilder.cs @@ -0,0 +1,87 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Web.Mvc.Resources; + + public class ControllerBuilder { + + private Func _factoryThunk; + private static ControllerBuilder _instance = new ControllerBuilder(); + private HashSet _namespaces = new HashSet(StringComparer.OrdinalIgnoreCase); + + public ControllerBuilder() { + SetControllerFactory(new DefaultControllerFactory() { + ControllerBuilder = this + }); + } + + public static ControllerBuilder Current { + get { + return _instance; + } + } + + public HashSet DefaultNamespaces { + get { + return _namespaces; + } + } + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", + Justification = "Calling method multiple times might return different objects.")] + public IControllerFactory GetControllerFactory() { + IControllerFactory controllerFactoryInstance = _factoryThunk(); + return controllerFactoryInstance; + } + + public void SetControllerFactory(IControllerFactory controllerFactory) { + if (controllerFactory == null) { + throw new ArgumentNullException("controllerFactory"); + } + + _factoryThunk = () => controllerFactory; + } + + public void SetControllerFactory(Type controllerFactoryType) { + if (controllerFactoryType == null) { + throw new ArgumentNullException("controllerFactoryType"); + } + if (!typeof(IControllerFactory).IsAssignableFrom(controllerFactoryType)) { + throw new ArgumentException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.ControllerBuilder_MissingIControllerFactory, + controllerFactoryType), + "controllerFactoryType"); + } + + _factoryThunk = delegate() { + try { + return (IControllerFactory)Activator.CreateInstance(controllerFactoryType); + } + catch (Exception ex) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.ControllerBuilder_ErrorCreatingControllerFactory, + controllerFactoryType), + ex); + } + }; + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerContext.cs new file mode 100644 index 00000000000..22625019d48 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerContext.cs @@ -0,0 +1,134 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Web; + using System.Web.Routing; + using System.Web.Mvc.Html; + + // Though many of the properties on ControllerContext and its subclassed types are virtual, there are still sealed + // properties (like ControllerContext.RequestContext, ActionExecutingContext.Result, etc.). If these properties + // were virtual, a mocking framework might override them with incorrect behavior (property getters would return + // null, property setters would be no-ops). By sealing these properties, we are forcing them to have the default + // "get or store a value" semantics that they were intended to have. + + public class ControllerContext { + + private HttpContextBase _httpContext; + private RequestContext _requestContext; + private RouteData _routeData; + + internal const string PARENT_ACTION_VIEWCONTEXT = "ParentActionViewContext"; + + // parameterless constructor used for mocking + public ControllerContext() { + } + + // copy constructor - allows for subclassed types to take an existing ControllerContext as a parameter + // and we'll automatically set the appropriate properties + [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", + Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")] + protected ControllerContext(ControllerContext controllerContext) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + + Controller = controllerContext.Controller; + RequestContext = controllerContext.RequestContext; + } + + public ControllerContext(HttpContextBase httpContext, RouteData routeData, ControllerBase controller) + : this(new RequestContext(httpContext, routeData), controller) { + } + + [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", + Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")] + public ControllerContext(RequestContext requestContext, ControllerBase controller) { + if (requestContext == null) { + throw new ArgumentNullException("requestContext"); + } + if (controller == null) { + throw new ArgumentNullException("controller"); + } + + RequestContext = requestContext; + Controller = controller; + } + + public virtual ControllerBase Controller { + get; + set; + } + + public virtual HttpContextBase HttpContext { + get { + if (_httpContext == null) { + _httpContext = (_requestContext != null) ? _requestContext.HttpContext : new EmptyHttpContext(); + } + return _httpContext; + } + set { + _httpContext = value; + } + } + + public virtual bool IsChildAction { + get { + RouteData routeData = RouteData; + if (routeData == null) { + return false; + } + return routeData.DataTokens.ContainsKey(PARENT_ACTION_VIEWCONTEXT); + } + } + + public ViewContext ParentActionViewContext { + get { + return RouteData.DataTokens[PARENT_ACTION_VIEWCONTEXT] as ViewContext; + } + } + + public RequestContext RequestContext { + get { + if (_requestContext == null) { + // still need explicit calls to constructors since the property getters are virtual and might return null + HttpContextBase httpContext = HttpContext ?? new EmptyHttpContext(); + RouteData routeData = RouteData ?? new RouteData(); + + _requestContext = new RequestContext(httpContext, routeData); + } + return _requestContext; + } + set { + _requestContext = value; + } + } + + public virtual RouteData RouteData { + get { + if (_routeData == null) { + _routeData = (_requestContext != null) ? _requestContext.RouteData : new RouteData(); + } + return _routeData; + } + set { + _routeData = value; + } + } + + private sealed class EmptyHttpContext : HttpContextBase { + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptor.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptor.cs new file mode 100644 index 00000000000..abb7c236c47 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptor.cs @@ -0,0 +1,59 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Reflection; + + public abstract class ControllerDescriptor : ICustomAttributeProvider { + + public virtual string ControllerName { + get { + string typeName = ControllerType.Name; + if (typeName.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)) { + return typeName.Substring(0, typeName.Length - "Controller".Length); + } + + return typeName; + } + } + + public abstract Type ControllerType { + get; + } + + public abstract ActionDescriptor FindAction(ControllerContext controllerContext, string actionName); + + public abstract ActionDescriptor[] GetCanonicalActions(); + + public virtual object[] GetCustomAttributes(bool inherit) { + return GetCustomAttributes(typeof(object), inherit); + } + + public virtual object[] GetCustomAttributes(Type attributeType, bool inherit) { + if (attributeType == null) { + throw new ArgumentNullException("attributeType"); + } + + return (object[])Array.CreateInstance(attributeType, 0); + } + + public virtual bool IsDefined(Type attributeType, bool inherit) { + if (attributeType == null) { + throw new ArgumentNullException("attributeType"); + } + + return false; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptorCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptorCache.cs new file mode 100644 index 00000000000..43ed25ee0db --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerDescriptorCache.cs @@ -0,0 +1,26 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + + internal sealed class ControllerDescriptorCache : ReaderWriterCache { + + public ControllerDescriptorCache() { + } + + public ControllerDescriptor GetDescriptor(Type controllerType, Func creator) { + return FetchOrCreateItem(controllerType, creator); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerTypeCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerTypeCache.cs new file mode 100644 index 00000000000..bea8005bb74 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ControllerTypeCache.cs @@ -0,0 +1,127 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + + internal sealed class ControllerTypeCache { + + private const string _typeCacheName = "MVC-ControllerTypeCache.xml"; + + private Dictionary> _cache; + private object _lockObj = new object(); + + internal int Count { + get { + int count = 0; + foreach (var lookup in _cache.Values) { + foreach (var grouping in lookup) { + count += grouping.Count(); + } + } + return count; + } + } + + public void EnsureInitialized(IBuildManager buildManager) { + if (_cache == null) { + lock (_lockObj) { + if (_cache == null) { + List controllerTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(_typeCacheName, IsControllerType, buildManager); + var groupedByName = controllerTypes.GroupBy( + t => t.Name.Substring(0, t.Name.Length - "Controller".Length), + StringComparer.OrdinalIgnoreCase); + _cache = groupedByName.ToDictionary( + g => g.Key, + g => g.ToLookup(t => t.Namespace ?? String.Empty, StringComparer.OrdinalIgnoreCase), + StringComparer.OrdinalIgnoreCase); + } + } + } + } + + public ICollection GetControllerTypes(string controllerName, HashSet namespaces) { + HashSet matchingTypes = new HashSet(); + + ILookup nsLookup; + if (_cache.TryGetValue(controllerName, out nsLookup)) { + // this friendly name was located in the cache, now cycle through namespaces + if (namespaces != null) { + foreach (string requestedNamespace in namespaces) { + foreach (var targetNamespaceGrouping in nsLookup) { + if (IsNamespaceMatch(requestedNamespace, targetNamespaceGrouping.Key)) { + matchingTypes.UnionWith(targetNamespaceGrouping); + } + } + } + } + else { + // if the namespaces parameter is null, search *every* namespace + foreach (var nsGroup in nsLookup) { + matchingTypes.UnionWith(nsGroup); + } + } + } + + return matchingTypes; + } + + internal static bool IsControllerType(Type t) { + return + t != null && + t.IsPublic && + t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) && + !t.IsAbstract && + typeof(IController).IsAssignableFrom(t); + } + + internal static bool IsNamespaceMatch(string requestedNamespace, string targetNamespace) { + // degenerate cases + if (requestedNamespace == null) { + return false; + } + else if (requestedNamespace.Length == 0) { + return true; + } + + if (!requestedNamespace.EndsWith(".*", StringComparison.OrdinalIgnoreCase)) { + // looking for exact namespace match + return String.Equals(requestedNamespace, targetNamespace, StringComparison.OrdinalIgnoreCase); + } + else { + // looking for exact or sub-namespace match + requestedNamespace = requestedNamespace.Substring(0, requestedNamespace.Length - ".*".Length); + if (!targetNamespace.StartsWith(requestedNamespace, StringComparison.OrdinalIgnoreCase)) { + return false; + } + + if (requestedNamespace.Length == targetNamespace.Length) { + // exact match + return true; + } + else if (targetNamespace[requestedNamespace.Length] == '.') { + // good prefix match, e.g. requestedNamespace = "Foo.Bar" and targetNamespace = "Foo.Bar.Baz" + return true; + } + else { + // bad prefix match, e.g. requestedNamespace = "Foo.Bar" and targetNamespace = "Foo.Bar2" + return false; + } + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/CustomModelBinderAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/CustomModelBinderAttribute.cs new file mode 100644 index 00000000000..c086781f1f3 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/CustomModelBinderAttribute.cs @@ -0,0 +1,27 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + + [AttributeUsage(ValidTargets, AllowMultiple = false, Inherited = false)] + public abstract class CustomModelBinderAttribute : Attribute { + + internal const AttributeTargets ValidTargets = AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.Struct; + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", + Justification = "This method can potentially perform a non-trivial amount of work.")] + public abstract IModelBinder GetBinder(); + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadata.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadata.cs new file mode 100644 index 00000000000..aba69faa9f7 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadata.cs @@ -0,0 +1,63 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.ComponentModel.DataAnnotations; + using System.Globalization; + using System.Reflection; + using System.Web.Mvc.Resources; + + public class DataAnnotationsModelMetadata : ModelMetadata { + private DisplayColumnAttribute _displayColumnAttribute; + + public DataAnnotationsModelMetadata(DataAnnotationsModelMetadataProvider provider, Type containerType, + Func modelAccessor, Type modelType, string propertyName, + DisplayColumnAttribute displayColumnAttribute) + : base(provider, containerType, modelAccessor, modelType, propertyName) { + _displayColumnAttribute = displayColumnAttribute; + } + + protected override string GetSimpleDisplayText() { + if (Model != null) { + if (_displayColumnAttribute != null && !String.IsNullOrEmpty(_displayColumnAttribute.DisplayColumn)) { + PropertyInfo displayColumnProperty = ModelType.GetProperty(_displayColumnAttribute.DisplayColumn, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance); + ValidateDisplayColumnAttribute(_displayColumnAttribute, displayColumnProperty, ModelType); + + object simpleDisplayTextValue = displayColumnProperty.GetValue(Model, new object[0]); + if (simpleDisplayTextValue != null) { + return simpleDisplayTextValue.ToString(); + } + } + } + + return base.GetSimpleDisplayText(); + } + + private static void ValidateDisplayColumnAttribute(DisplayColumnAttribute displayColumnAttribute, PropertyInfo displayColumnProperty, Type modelType) { + if (displayColumnProperty == null) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.DataAnnotationsModelMetadataProvider_UnknownProperty, + modelType.FullName, displayColumnAttribute.DisplayColumn)); + } + if (displayColumnProperty.GetGetMethod() == null) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.DataAnnotationsModelMetadataProvider_UnreadableProperty, + modelType.FullName, displayColumnAttribute.DisplayColumn)); + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs new file mode 100644 index 00000000000..7dffa9b7f39 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelMetadataProvider.cs @@ -0,0 +1,83 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.ComponentModel.DataAnnotations; + using System.Linq; + + public class DataAnnotationsModelMetadataProvider : AssociatedMetadataProvider { + protected override ModelMetadata CreateMetadata(IEnumerable attributes, Type containerType, Func modelAccessor, Type modelType, string propertyName) { + List attributeList = new List(attributes); + DisplayColumnAttribute displayColumnAttribute = attributeList.OfType().FirstOrDefault(); + DataAnnotationsModelMetadata result = new DataAnnotationsModelMetadata(this, containerType, modelAccessor, modelType, propertyName, displayColumnAttribute); + + // Do [HiddenInput] before [UIHint], so you can override the template hint + HiddenInputAttribute hiddenInputAttribute = attributeList.OfType().FirstOrDefault(); + if (hiddenInputAttribute != null) { + result.TemplateHint = "HiddenInput"; + result.HideSurroundingHtml = !hiddenInputAttribute.DisplayValue; + } + + // We prefer [UIHint("...", PresentationLayer = "MVC")] but will fall back to [UIHint("...")] + IEnumerable uiHintAttributes = attributeList.OfType(); + UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => String.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase)) + ?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer)); + if (uiHintAttribute != null) { + result.TemplateHint = uiHintAttribute.UIHint; + } + + DataTypeAttribute dataTypeAttribute = attributeList.OfType().FirstOrDefault(); + if (dataTypeAttribute != null) { + result.DataTypeName = dataTypeAttribute.GetDataTypeName(); + } + + ReadOnlyAttribute readOnlyAttribute = attributeList.OfType().FirstOrDefault(); + if (readOnlyAttribute != null) { + result.IsReadOnly = readOnlyAttribute.IsReadOnly; + } + + DisplayFormatAttribute displayFormatAttribute = attributeList.OfType().FirstOrDefault(); + if (displayFormatAttribute == null && dataTypeAttribute != null) { + displayFormatAttribute = dataTypeAttribute.DisplayFormat; + } + if (displayFormatAttribute != null) { + result.NullDisplayText = displayFormatAttribute.NullDisplayText; + result.DisplayFormatString = displayFormatAttribute.DataFormatString; + result.ConvertEmptyStringToNull = displayFormatAttribute.ConvertEmptyStringToNull; + + if (displayFormatAttribute.ApplyFormatInEditMode) { + result.EditFormatString = displayFormatAttribute.DataFormatString; + } + } + + ScaffoldColumnAttribute scaffoldColumnAttribute = attributeList.OfType().FirstOrDefault(); + if (scaffoldColumnAttribute != null) { + result.ShowForDisplay = result.ShowForEdit = scaffoldColumnAttribute.Scaffold; + } + + DisplayNameAttribute displayNameAttribute = attributeList.OfType().FirstOrDefault(); + if (displayNameAttribute != null) { + result.DisplayName = displayNameAttribute.DisplayName; + } + + RequiredAttribute requiredAttribute = attributeList.OfType().FirstOrDefault(); + if (requiredAttribute != null) { + result.IsRequired = true; + } + + return result; + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator.cs new file mode 100644 index 00000000000..7b83c66225b --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator.cs @@ -0,0 +1,55 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + + public class DataAnnotationsModelValidator : ModelValidator { + public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) + : base(metadata, context) { + + if (attribute == null) { + throw new ArgumentNullException("attribute"); + } + + Attribute = attribute; + } + + protected internal ValidationAttribute Attribute { get; private set; } + + protected internal string ErrorMessage { + get { + return Attribute.FormatErrorMessage(Metadata.GetDisplayName()); + } + } + + public override bool IsRequired { + get { + return Attribute is RequiredAttribute; + } + } + + internal static ModelValidator Create(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) { + return new DataAnnotationsModelValidator(metadata, context, attribute); + } + + public override IEnumerable Validate(object container) { + if (!Attribute.IsValid(Metadata.Model)) { + yield return new ModelValidationResult { + Message = ErrorMessage + }; + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs new file mode 100644 index 00000000000..3e0c97f9ba2 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidatorProvider.cs @@ -0,0 +1,187 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.ComponentModel.DataAnnotations; + using System.Globalization; + using System.Linq; + using System.Reflection; + using System.Threading; + using System.Web.Mvc.Resources; + + public delegate ModelValidator DataAnnotationsModelValidationFactory(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute); + + public class DataAnnotationsModelValidatorProvider : AssociatedValidatorProvider { + private static bool _addImplicitRequiredAttributeForValueTypes = true; + private static ReaderWriterLockSlim _adaptersLock = new ReaderWriterLockSlim(); + + internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory = DataAnnotationsModelValidator.Create; + internal static Dictionary AttributeFactories = new Dictionary() { + { + typeof(RangeAttribute), + (metadata, context, attribute) => new RangeAttributeAdapter(metadata, context, (RangeAttribute)attribute) + }, + { + typeof(RegularExpressionAttribute), + (metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute) + }, + { + typeof(RequiredAttribute), + (metadata, context, attribute) => new RequiredAttributeAdapter(metadata, context, (RequiredAttribute)attribute) + }, + { + typeof(StringLengthAttribute), + (metadata, context, attribute) => new StringLengthAttributeAdapter(metadata, context, (StringLengthAttribute)attribute) + }, + }; + + public static bool AddImplicitRequiredAttributeForValueTypes { + get { + return _addImplicitRequiredAttributeForValueTypes; + } + set { + _addImplicitRequiredAttributeForValueTypes = value; + } + } + + protected override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable attributes) { + _adaptersLock.EnterReadLock(); + + try { + List results = new List(); + + if (AddImplicitRequiredAttributeForValueTypes && + metadata.IsRequired && + !attributes.Any(a => a is RequiredAttribute)) { + attributes = attributes.Concat(new[] { new RequiredAttribute() }); + } + + foreach (ValidationAttribute attribute in attributes.OfType()) { + DataAnnotationsModelValidationFactory factory; + if (!AttributeFactories.TryGetValue(attribute.GetType(), out factory)) { + factory = DefaultAttributeFactory; + } + results.Add(factory(metadata, context, attribute)); + } + + return results; + } + finally { + _adaptersLock.ExitReadLock(); + } + } + + public static void RegisterAdapter(Type attributeType, Type adapterType) { + ValidateAttributeType(attributeType); + ValidateAdapterType(adapterType); + ConstructorInfo constructor = GetAdapterConstructor(attributeType, adapterType); + + _adaptersLock.EnterWriteLock(); + + try { + AttributeFactories[attributeType] = (metadata, context, attribute) => (ModelValidator)constructor.Invoke(new object[] { metadata, context, attribute }); + } + finally { + _adaptersLock.ExitWriteLock(); + } + } + + public static void RegisterAdapterFactory(Type attributeType, DataAnnotationsModelValidationFactory factory) { + ValidateAttributeType(attributeType); + ValidateFactory(factory); + + _adaptersLock.EnterWriteLock(); + + try { + AttributeFactories[attributeType] = factory; + } + finally { + _adaptersLock.ExitWriteLock(); + } + } + + public static void RegisterDefaultAdapter(Type adapterType) { + ValidateAdapterType(adapterType); + ConstructorInfo constructor = GetAdapterConstructor(typeof(ValidationAttribute), adapterType); + + DefaultAttributeFactory = (metadata, context, attribute) => (ModelValidator)constructor.Invoke(new object[] { metadata, context, attribute }); + } + + public static void RegisterDefaultAdapterFactory(DataAnnotationsModelValidationFactory factory) { + ValidateFactory(factory); + + DefaultAttributeFactory = factory; + } + + // Helpers + + private static ConstructorInfo GetAdapterConstructor(Type attributeType, Type adapterType) { + ConstructorInfo constructor = adapterType.GetConstructor(new[] { typeof(ModelMetadata), typeof(ControllerContext), attributeType }); + if (constructor == null) { + throw new ArgumentException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.DataAnnotationsModelValidatorProvider_ConstructorRequirements, + adapterType.FullName, + typeof(ModelMetadata).FullName, + typeof(ControllerContext).FullName, + attributeType.FullName + ), + "adapterType" + ); + } + + return constructor; + } + + private static void ValidateAdapterType(Type adapterType) { + if (adapterType == null) { + throw new ArgumentNullException("adapterType"); + } + if (!typeof(ModelValidator).IsAssignableFrom(adapterType)) { + throw new ArgumentException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.Common_TypeMustDriveFromType, + adapterType.FullName, + typeof(ModelValidator).FullName + ), + "adapterType" + ); + } + } + + private static void ValidateAttributeType(Type attributeType) { + if (attributeType == null) { + throw new ArgumentNullException("attributeType"); + } + if (!typeof(ValidationAttribute).IsAssignableFrom(attributeType)) { + throw new ArgumentException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.Common_TypeMustDriveFromType, + attributeType.FullName, + typeof(ValidationAttribute).FullName + ), + "attributeType"); + } + } + + private static void ValidateFactory(DataAnnotationsModelValidationFactory factory) { + if (factory == null) { + throw new ArgumentNullException("factory"); + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator`1.cs new file mode 100644 index 00000000000..d8d981279ca --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataAnnotationsModelValidator`1.cs @@ -0,0 +1,26 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System.ComponentModel.DataAnnotations; + + public class DataAnnotationsModelValidator : DataAnnotationsModelValidator where TAttribute : ValidationAttribute { + public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, TAttribute attribute) + : base(metadata, context, attribute) { } + + protected new TAttribute Attribute { + get { + return (TAttribute)base.Attribute; + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs new file mode 100644 index 00000000000..eb10e5a8edb --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DataErrorInfoModelValidatorProvider.cs @@ -0,0 +1,87 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.ComponentModel; + using System.Linq; + + public class DataErrorInfoModelValidatorProvider : ModelValidatorProvider { + + public override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context) { + if (metadata == null) { + throw new ArgumentNullException("metadata"); + } + if (context == null) { + throw new ArgumentNullException("context"); + } + + return GetValidatorsImpl(metadata, context); + } + + private static IEnumerable GetValidatorsImpl(ModelMetadata metadata, ControllerContext context) { + // If the metadata describes a model that implements IDataErrorInfo, we should call its + // Error property at the appropriate time. + if (TypeImplementsIDataErrorInfo(metadata.ModelType)) { + yield return new DataErrorInfoClassModelValidator(metadata, context); + } + + // If the metadata describes a property of a container that implements IDataErrorInfo, + // we should call its Item indexer at the appropriate time. + if (TypeImplementsIDataErrorInfo(metadata.ContainerType)) { + yield return new DataErrorInfoPropertyModelValidator(metadata, context); + } + } + + private static bool TypeImplementsIDataErrorInfo(Type type) { + return typeof(IDataErrorInfo).IsAssignableFrom(type); + } + + internal sealed class DataErrorInfoClassModelValidator : ModelValidator { + public DataErrorInfoClassModelValidator(ModelMetadata metadata, ControllerContext controllerContext) + : base(metadata, controllerContext) { + } + public override IEnumerable Validate(object container) { + IDataErrorInfo castModel = Metadata.Model as IDataErrorInfo; + if (castModel != null) { + string errorMessage = castModel.Error; + if (!String.IsNullOrEmpty(errorMessage)) { + return new ModelValidationResult[] { + new ModelValidationResult() { Message = errorMessage } + }; + } + } + return Enumerable.Empty(); + } + } + + internal sealed class DataErrorInfoPropertyModelValidator : ModelValidator { + public DataErrorInfoPropertyModelValidator(ModelMetadata metadata, ControllerContext controllerContext) + : base(metadata, controllerContext) { + } + public override IEnumerable Validate(object container) { + IDataErrorInfo castContainer = container as IDataErrorInfo; + if (castContainer != null && !String.Equals(Metadata.PropertyName, "error", StringComparison.OrdinalIgnoreCase)) { + string errorMessage = castContainer[Metadata.PropertyName]; + if (!String.IsNullOrEmpty(errorMessage)) { + return new ModelValidationResult[] { + new ModelValidationResult() { Message = errorMessage } + }; + } + } + return Enumerable.Empty(); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultControllerFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultControllerFactory.cs new file mode 100644 index 00000000000..bb651892279 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultControllerFactory.cs @@ -0,0 +1,187 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Text; + using System.Web; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public class DefaultControllerFactory : IControllerFactory { + + private IBuildManager _buildManager; + private ControllerBuilder _controllerBuilder; + private ControllerTypeCache _instanceControllerTypeCache; + private static ControllerTypeCache _staticControllerTypeCache = new ControllerTypeCache(); + + internal IBuildManager BuildManager { + get { + if (_buildManager == null) { + _buildManager = new BuildManagerWrapper(); + } + return _buildManager; + } + set { + _buildManager = value; + } + } + + internal ControllerBuilder ControllerBuilder { + get { + return _controllerBuilder ?? ControllerBuilder.Current; + } + set { + _controllerBuilder = value; + } + } + + internal ControllerTypeCache ControllerTypeCache { + get { + return _instanceControllerTypeCache ?? _staticControllerTypeCache; + } + set { + _instanceControllerTypeCache = value; + } + } + + internal static InvalidOperationException CreateAmbiguousControllerException(RouteBase route, string controllerName, ICollection matchingTypes) { + // we need to generate an exception containing all the controller types + StringBuilder typeList = new StringBuilder(); + foreach (Type matchedType in matchingTypes) { + typeList.AppendLine(); + typeList.Append(matchedType.FullName); + } + + string errorText; + Route castRoute = route as Route; + if (castRoute != null) { + errorText = String.Format(CultureInfo.CurrentUICulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithRouteUrl, + controllerName, castRoute.Url, typeList); + } + else { + errorText = String.Format(CultureInfo.CurrentUICulture, MvcResources.DefaultControllerFactory_ControllerNameAmbiguous_WithoutRouteUrl, + controllerName, typeList); + } + + return new InvalidOperationException(errorText); + } + + public virtual IController CreateController(RequestContext requestContext, string controllerName) { + if (requestContext == null) { + throw new ArgumentNullException("requestContext"); + } + if (String.IsNullOrEmpty(controllerName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName"); + } + Type controllerType = GetControllerType(requestContext, controllerName); + IController controller = GetControllerInstance(requestContext, controllerType); + return controller; + } + + protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) { + if (controllerType == null) { + throw new HttpException(404, + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.DefaultControllerFactory_NoControllerFound, + requestContext.HttpContext.Request.Path)); + } + if (!typeof(IController).IsAssignableFrom(controllerType)) { + throw new ArgumentException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase, + controllerType), + "controllerType"); + } + try { + return (IController)Activator.CreateInstance(controllerType); + } + catch (Exception ex) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.DefaultControllerFactory_ErrorCreatingController, + controllerType), + ex); + } + } + + protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName) { + if (String.IsNullOrEmpty(controllerName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName"); + } + + // first search in the current route's namespace collection + object routeNamespacesObj; + Type match; + if (requestContext != null && requestContext.RouteData.DataTokens.TryGetValue("Namespaces", out routeNamespacesObj)) { + IEnumerable routeNamespaces = routeNamespacesObj as IEnumerable; + if (routeNamespaces != null && routeNamespaces.Any()) { + HashSet nsHash = new HashSet(routeNamespaces, StringComparer.OrdinalIgnoreCase); + match = GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, nsHash); + + // the UseNamespaceFallback key might not exist, in which case its value is implicitly "true" + if (match != null || false.Equals(requestContext.RouteData.DataTokens["UseNamespaceFallback"])) { + // got a match or the route requested we stop looking + return match; + } + } + } + + // then search in the application's default namespace collection + if (ControllerBuilder.DefaultNamespaces.Count > 0) { + HashSet nsDefaults = new HashSet(ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase); + match = GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, nsDefaults); + if (match != null) { + return match; + } + } + + // if all else fails, search every namespace + return GetControllerTypeWithinNamespaces(requestContext.RouteData.Route, controllerName, null /* namespaces */); + } + + private Type GetControllerTypeWithinNamespaces(RouteBase route, string controllerName, HashSet namespaces) { + // Once the master list of controllers has been created we can quickly index into it + ControllerTypeCache.EnsureInitialized(BuildManager); + + ICollection matchingTypes = ControllerTypeCache.GetControllerTypes(controllerName, namespaces); + switch (matchingTypes.Count) { + case 0: + // no matching types + return null; + + case 1: + // single matching type + return matchingTypes.First(); + + default: + // multiple matching types + throw CreateAmbiguousControllerException(route, controllerName, matchingTypes); + } + } + + public virtual void ReleaseController(IController controller) { + IDisposable disposable = controller as IDisposable; + if (disposable != null) { + disposable.Dispose(); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultModelBinder.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultModelBinder.cs new file mode 100644 index 00000000000..02507e6056e --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultModelBinder.cs @@ -0,0 +1,709 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections; + using System.Collections.Generic; + using System.ComponentModel; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Linq; + using System.Reflection; + using System.Runtime.CompilerServices; + using System.Web.Mvc.Resources; + + public class DefaultModelBinder : IModelBinder { + + private ModelBinderDictionary _binders; + private static string _resourceClassKey; + + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", + Justification = "Property is settable so that the dictionary can be provided for unit testing purposes.")] + protected internal ModelBinderDictionary Binders { + get { + if (_binders == null) { + _binders = ModelBinders.Binders; + } + return _binders; + } + set { + _binders = value; + } + } + + public static string ResourceClassKey { + get { + return _resourceClassKey ?? String.Empty; + } + set { + _resourceClassKey = value; + } + } + + private static void AddValueRequiredMessageToModelState(ControllerContext controllerContext, ModelStateDictionary modelState, string modelStateKey, Type elementType, object value) { + if (value == null && !TypeHelpers.TypeAllowsNullValue(elementType) && modelState.IsValidField(modelStateKey)) { + modelState.AddModelError(modelStateKey, GetValueRequiredResource(controllerContext)); + } + } + + internal void BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) { + // need to replace the property filter + model object and create an inner binding context + ModelBindingContext newBindingContext = CreateComplexElementalModelBindingContext(controllerContext, bindingContext, model); + + // validation + if (OnModelUpdating(controllerContext, newBindingContext)) { + BindProperties(controllerContext, newBindingContext); + OnModelUpdated(controllerContext, newBindingContext); + } + } + + internal object BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { + object model = bindingContext.Model; + Type modelType = bindingContext.ModelType; + + // if we're being asked to create an array, create a list instead, then coerce to an array after the list is created + if (model == null && modelType.IsArray) { + Type elementType = modelType.GetElementType(); + Type listType = typeof(List<>).MakeGenericType(elementType); + object collection = CreateModel(controllerContext, bindingContext, listType); + + ModelBindingContext arrayBindingContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => collection, listType), + ModelName = bindingContext.ModelName, + ModelState = bindingContext.ModelState, + PropertyFilter = bindingContext.PropertyFilter, + ValueProvider = bindingContext.ValueProvider + }; + IList list = (IList)UpdateCollection(controllerContext, arrayBindingContext, elementType); + + if (list == null) { + return null; + } + + Array array = Array.CreateInstance(elementType, list.Count); + list.CopyTo(array, 0); + return array; + } + + if (model == null) { + model = CreateModel(controllerContext, bindingContext, modelType); + } + + // special-case IDictionary<,> and ICollection<> + Type dictionaryType = TypeHelpers.ExtractGenericInterface(modelType, typeof(IDictionary<,>)); + if (dictionaryType != null) { + Type[] genericArguments = dictionaryType.GetGenericArguments(); + Type keyType = genericArguments[0]; + Type valueType = genericArguments[1]; + + ModelBindingContext dictionaryBindingContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, modelType), + ModelName = bindingContext.ModelName, + ModelState = bindingContext.ModelState, + PropertyFilter = bindingContext.PropertyFilter, + ValueProvider = bindingContext.ValueProvider + }; + object dictionary = UpdateDictionary(controllerContext, dictionaryBindingContext, keyType, valueType); + return dictionary; + } + + Type enumerableType = TypeHelpers.ExtractGenericInterface(modelType, typeof(IEnumerable<>)); + if (enumerableType != null) { + Type elementType = enumerableType.GetGenericArguments()[0]; + + Type collectionType = typeof(ICollection<>).MakeGenericType(elementType); + if (collectionType.IsInstanceOfType(model)) { + ModelBindingContext collectionBindingContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, modelType), + ModelName = bindingContext.ModelName, + ModelState = bindingContext.ModelState, + PropertyFilter = bindingContext.PropertyFilter, + ValueProvider = bindingContext.ValueProvider + }; + object collection = UpdateCollection(controllerContext, collectionBindingContext, elementType); + return collection; + } + } + + // otherwise, just update the properties on the complex type + BindComplexElementalModel(controllerContext, bindingContext, model); + return model; + } + + public virtual object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { + if (bindingContext == null) { + throw new ArgumentNullException("bindingContext"); + } + + bool performedFallback = false; + + if (!String.IsNullOrEmpty(bindingContext.ModelName) && !bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName)) { + // We couldn't find any entry that began with the prefix. If this is the top-level element, fall back + // to the empty prefix. + if (bindingContext.FallbackToEmptyPrefix) { + bindingContext = new ModelBindingContext() { + ModelMetadata = bindingContext.ModelMetadata, + ModelState = bindingContext.ModelState, + PropertyFilter = bindingContext.PropertyFilter, + ValueProvider = bindingContext.ValueProvider + }; + performedFallback = true; + } + else { + return null; + } + } + + // Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string)) + // or by seeing if a value in the request exactly matches the name of the model we're binding. + // Complex type = everything else. + if (!performedFallback) { + ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); + if (vpResult != null) { + return BindSimpleModel(controllerContext, bindingContext, vpResult); + } + } + if (!bindingContext.ModelMetadata.IsComplexType) { + return null; + } + + return BindComplexModel(controllerContext, bindingContext); + } + + private void BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) { + IEnumerable properties = GetFilteredModelProperties(controllerContext, bindingContext); + foreach (PropertyDescriptor property in properties) { + BindProperty(controllerContext, bindingContext, property); + } + } + + protected virtual void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) { + // need to skip properties that aren't part of the request, else we might hit a StackOverflowException + string fullPropertyKey = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name); + if (!bindingContext.ValueProvider.ContainsPrefix(fullPropertyKey)) { + return; + } + + // call into the property's model binder + IModelBinder propertyBinder = Binders.GetBinder(propertyDescriptor.PropertyType); + object originalPropertyValue = propertyDescriptor.GetValue(bindingContext.Model); + ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name]; + propertyMetadata.Model = originalPropertyValue; + ModelBindingContext innerBindingContext = new ModelBindingContext() { + ModelMetadata = propertyMetadata, + ModelName = fullPropertyKey, + ModelState = bindingContext.ModelState, + ValueProvider = bindingContext.ValueProvider + }; + object newPropertyValue = GetPropertyValue(controllerContext, innerBindingContext, propertyDescriptor, propertyBinder); + propertyMetadata.Model = newPropertyValue; + + // validation + ModelState modelState = bindingContext.ModelState[fullPropertyKey]; + if (modelState == null || modelState.Errors.Count == 0) { + if (OnPropertyValidating(controllerContext, bindingContext, propertyDescriptor, newPropertyValue)) { + SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue); + OnPropertyValidated(controllerContext, bindingContext, propertyDescriptor, newPropertyValue); + } + } + else { + SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue); + + // Convert FormatExceptions (type conversion failures) into InvalidValue messages + foreach (ModelError error in modelState.Errors.Where(err => String.IsNullOrEmpty(err.ErrorMessage) && err.Exception != null).ToList()) { + for (Exception exception = error.Exception; exception != null; exception = exception.InnerException) { + if (exception is FormatException) { + string displayName = propertyMetadata.GetDisplayName(); + string errorMessageTemplate = GetValueInvalidResource(controllerContext); + string errorMessage = String.Format(CultureInfo.CurrentUICulture, errorMessageTemplate, modelState.Value.AttemptedValue, displayName); + modelState.Errors.Remove(error); + modelState.Errors.Add(errorMessage); + break; + } + } + } + } + } + + internal object BindSimpleModel(ControllerContext controllerContext, ModelBindingContext bindingContext, ValueProviderResult valueProviderResult) { + bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); + + // if the value provider returns an instance of the requested data type, we can just short-circuit + // the evaluation and return that instance + if (bindingContext.ModelType.IsInstanceOfType(valueProviderResult.RawValue)) { + return valueProviderResult.RawValue; + } + + // since a string is an IEnumerable, we want it to skip the two checks immediately following + if (bindingContext.ModelType != typeof(string)) { + + // conversion results in 3 cases, as below + if (bindingContext.ModelType.IsArray) { + // case 1: user asked for an array + // ValueProviderResult.ConvertTo() understands array types, so pass in the array type directly + object modelArray = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, bindingContext.ModelType); + return modelArray; + } + + Type enumerableType = TypeHelpers.ExtractGenericInterface(bindingContext.ModelType, typeof(IEnumerable<>)); + if (enumerableType != null) { + // case 2: user asked for a collection rather than an array + // need to call ConvertTo() on the array type, then copy the array to the collection + object modelCollection = CreateModel(controllerContext, bindingContext, bindingContext.ModelType); + Type elementType = enumerableType.GetGenericArguments()[0]; + Type arrayType = elementType.MakeArrayType(); + object modelArray = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, arrayType); + + Type collectionType = typeof(ICollection<>).MakeGenericType(elementType); + if (collectionType.IsInstanceOfType(modelCollection)) { + CollectionHelpers.ReplaceCollection(elementType, modelCollection, modelArray); + } + return modelCollection; + } + } + + // case 3: user asked for an individual element + object model = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, bindingContext.ModelType); + return model; + } + + private static bool CanUpdateReadonlyTypedReference(Type type) { + // value types aren't strictly immutable, but because they have copy-by-value semantics + // we can't update a value type that is marked readonly + if (type.IsValueType) { + return false; + } + + // arrays are mutable, but because we can't change their length we shouldn't try + // to update an array that is referenced readonly + if (type.IsArray) { + return false; + } + + // special-case known common immutable types + if (type == typeof(string)) { + return false; + } + + return true; + } + + [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)", + Justification = "The target object should make the correct culture determination, not this method.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", + Justification = "We're recording this exception so that we can act on it later.")] + private static object ConvertProviderResult(ModelStateDictionary modelState, string modelStateKey, ValueProviderResult valueProviderResult, Type destinationType) { + try { + object convertedValue = valueProviderResult.ConvertTo(destinationType); + return convertedValue; + } + catch (Exception ex) { + modelState.AddModelError(modelStateKey, ex); + return null; + } + } + + internal ModelBindingContext CreateComplexElementalModelBindingContext(ControllerContext controllerContext, ModelBindingContext bindingContext, object model) { + BindAttribute bindAttr = (BindAttribute)GetTypeDescriptor(controllerContext, bindingContext).GetAttributes()[typeof(BindAttribute)]; + Predicate newPropertyFilter = (bindAttr != null) + ? propertyName => bindAttr.IsPropertyAllowed(propertyName) && bindingContext.PropertyFilter(propertyName) + : bindingContext.PropertyFilter; + + ModelBindingContext newBindingContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, bindingContext.ModelType), + ModelName = bindingContext.ModelName, + ModelState = bindingContext.ModelState, + PropertyFilter = newPropertyFilter, + ValueProvider = bindingContext.ValueProvider + }; + + return newBindingContext; + } + + protected virtual object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { + Type typeToCreate = modelType; + + // we can understand some collection interfaces, e.g. IList<>, IDictionary<,> + if (modelType.IsGenericType) { + Type genericTypeDefinition = modelType.GetGenericTypeDefinition(); + if (genericTypeDefinition == typeof(IDictionary<,>)) { + typeToCreate = typeof(Dictionary<,>).MakeGenericType(modelType.GetGenericArguments()); + } + else if (genericTypeDefinition == typeof(IEnumerable<>) || genericTypeDefinition == typeof(ICollection<>) || genericTypeDefinition == typeof(IList<>)) { + typeToCreate = typeof(List<>).MakeGenericType(modelType.GetGenericArguments()); + } + } + + // fallback to the type's default constructor + return Activator.CreateInstance(typeToCreate); + } + + protected static string CreateSubIndexName(string prefix, int index) { + return String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", prefix, index); + } + + protected static string CreateSubIndexName(string prefix, string index) { + return String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", prefix, index); + } + + protected internal static string CreateSubPropertyName(string prefix, string propertyName) { + if (String.IsNullOrEmpty(prefix)) { + return propertyName; + } + else if (String.IsNullOrEmpty(propertyName)) { + return prefix; + } + else { + return prefix + "." + propertyName; + } + } + + protected IEnumerable GetFilteredModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) { + PropertyDescriptorCollection properties = GetModelProperties(controllerContext, bindingContext); + Predicate propertyFilter = bindingContext.PropertyFilter; + + return from PropertyDescriptor property in properties + where ShouldUpdateProperty(property, propertyFilter) + select property; + } + + [SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.Web.Mvc.ValueProviderResult.ConvertTo(System.Type)", + Justification = "ValueProviderResult already handles culture conversion appropriately.")] + private static void GetIndexes(ModelBindingContext bindingContext, out bool stopOnIndexNotFound, out IEnumerable indexes) { + string indexKey = CreateSubPropertyName(bindingContext.ModelName, "index"); + ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(indexKey); + + if (vpResult != null) { + string[] indexesArray = vpResult.ConvertTo(typeof(string[])) as string[]; + if (indexesArray != null) { + stopOnIndexNotFound = false; + indexes = indexesArray; + return; + } + } + + // just use a simple zero-based system + stopOnIndexNotFound = true; + indexes = GetZeroBasedIndexes(); + } + + protected virtual PropertyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) { + return GetTypeDescriptor(controllerContext, bindingContext).GetProperties(); + } + + protected virtual object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) { + object value = propertyBinder.BindModel(controllerContext, bindingContext); + + if (bindingContext.ModelMetadata.ConvertEmptyStringToNull && Object.Equals(value, String.Empty)) { + return null; + } + + return value; + } + + protected virtual ICustomTypeDescriptor GetTypeDescriptor(ControllerContext controllerContext, ModelBindingContext bindingContext) { + return TypeDescriptorHelper.Get(bindingContext.ModelType); + } + + // If the user specified a ResourceClassKey try to load the resource they specified. + // If the class key is invalid, an exception will be thrown. + // If the class key is valid but the resource is not found, it returns null, in which + // case it will fall back to the MVC default error message. + private static string GetUserResourceString(ControllerContext controllerContext, string resourceName) { + string result = null; + + if (!String.IsNullOrEmpty(ResourceClassKey) && (controllerContext != null) && (controllerContext.HttpContext != null)) { + result = controllerContext.HttpContext.GetGlobalResourceObject(ResourceClassKey, resourceName, CultureInfo.CurrentUICulture) as string; + } + + return result; + } + + private static string GetValueInvalidResource(ControllerContext controllerContext) { + return GetUserResourceString(controllerContext, "PropertyValueInvalid") ?? MvcResources.DefaultModelBinder_ValueInvalid; + } + + private static string GetValueRequiredResource(ControllerContext controllerContext) { + return GetUserResourceString(controllerContext, "PropertyValueRequired") ?? MvcResources.DefaultModelBinder_ValueRequired; + } + + private static IEnumerable GetZeroBasedIndexes() { + for (int i = 0; ; i++) { + yield return i.ToString(CultureInfo.InvariantCulture); + } + } + + protected static bool IsModelValid(ModelBindingContext bindingContext) { + if (bindingContext == null) { + throw new ArgumentNullException("bindingContext"); + } + if (String.IsNullOrEmpty(bindingContext.ModelName)) { + return bindingContext.ModelState.IsValid; + } + return bindingContext.ModelState.IsValidField(bindingContext.ModelName); + } + + protected virtual void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) { + Dictionary startedValid = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (ModelValidationResult validationResult in ModelValidator.GetModelValidator(bindingContext.ModelMetadata, controllerContext).Validate(null)) { + string subPropertyName = CreateSubPropertyName(bindingContext.ModelName, validationResult.MemberName); + + if (!startedValid.ContainsKey(subPropertyName)) { + startedValid[subPropertyName] = bindingContext.ModelState.IsValidField(subPropertyName); + } + + if (startedValid[subPropertyName]) { + bindingContext.ModelState.AddModelError(subPropertyName, validationResult.Message); + } + } + } + + protected virtual bool OnModelUpdating(ControllerContext controllerContext, ModelBindingContext bindingContext) { + // default implementation does nothing + return true; + } + + protected virtual void OnPropertyValidated(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) { + // default implementation does nothing + } + + protected virtual bool OnPropertyValidating(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) { + // default implementation does nothing + return true; + } + + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", + Justification = "We're recording this exception so that we can act on it later.")] + protected virtual void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value) { + + ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name]; + propertyMetadata.Model = value; + string modelStateKey = CreateSubPropertyName(bindingContext.ModelName, propertyMetadata.PropertyName); + + // If the value is null, and the validation system can find a Required validator for + // us, we'd prefer to run it before we attempt to set the value; otherwise, property + // setters which throw on null (f.e., Entity Framework properties which are backed by + // non-nullable strings in the DB) will get their error message in ahead of us. + // + // We are effectively using the special validator -- Required -- as a helper to the + // binding system, which is why this code is here instead of in the Validating/Validated + // methods, which are really the old-school validation hooks. + if (value == null && bindingContext.ModelState.IsValidField(modelStateKey)) { + ModelValidator requiredValidator = ModelValidatorProviders.Providers.GetValidators(propertyMetadata, controllerContext).Where(v => v.IsRequired).FirstOrDefault(); + if (requiredValidator != null) { + foreach (ModelValidationResult validationResult in requiredValidator.Validate(bindingContext.Model)) { + bindingContext.ModelState.AddModelError(modelStateKey, validationResult.Message); + } + } + } + + bool isNullValueOnNonNullableType = + value == null && + !TypeHelpers.TypeAllowsNullValue(propertyDescriptor.PropertyType); + + // Try to set a value into the property unless we know it will fail (read-only + // properties and null values with non-nullable types) + if (!propertyDescriptor.IsReadOnly && !isNullValueOnNonNullableType) { + try { + propertyDescriptor.SetValue(bindingContext.Model, value); + } + catch (Exception ex) { + // Only add if we're not already invalid + if (bindingContext.ModelState.IsValidField(modelStateKey)) { + bindingContext.ModelState.AddModelError(modelStateKey, ex); + } + } + } + + // Last chance for an error on null values with non-nullable types, we'll use + // the default "A value is required." message. + if (isNullValueOnNonNullableType && bindingContext.ModelState.IsValidField(modelStateKey)) { + bindingContext.ModelState.AddModelError(modelStateKey, GetValueRequiredResource(controllerContext)); + } + } + + private static bool ShouldUpdateProperty(PropertyDescriptor property, Predicate propertyFilter) { + if (property.IsReadOnly && !CanUpdateReadonlyTypedReference(property.PropertyType)) { + return false; + } + + // if this property is rejected by the filter, move on + if (!propertyFilter(property.Name)) { + return false; + } + + // otherwise, allow + return true; + } + + internal object UpdateCollection(ControllerContext controllerContext, ModelBindingContext bindingContext, Type elementType) { + bool stopOnIndexNotFound; + IEnumerable indexes; + GetIndexes(bindingContext, out stopOnIndexNotFound, out indexes); + IModelBinder elementBinder = Binders.GetBinder(elementType); + + // build up a list of items from the request + List modelList = new List(); + foreach (string currentIndex in indexes) { + string subIndexKey = CreateSubIndexName(bindingContext.ModelName, currentIndex); + if (!bindingContext.ValueProvider.ContainsPrefix(subIndexKey)) { + if (stopOnIndexNotFound) { + // we ran out of elements to pull + break; + } + else { + continue; + } + } + + ModelBindingContext innerContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, elementType), + ModelName = subIndexKey, + ModelState = bindingContext.ModelState, + PropertyFilter = bindingContext.PropertyFilter, + ValueProvider = bindingContext.ValueProvider + }; + object thisElement = elementBinder.BindModel(controllerContext, innerContext); + + // we need to merge model errors up + AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, subIndexKey, elementType, thisElement); + modelList.Add(thisElement); + } + + // if there weren't any elements at all in the request, just return + if (modelList.Count == 0) { + return null; + } + + // replace the original collection + object collection = bindingContext.Model; + CollectionHelpers.ReplaceCollection(elementType, collection, modelList); + return collection; + } + + internal object UpdateDictionary(ControllerContext controllerContext, ModelBindingContext bindingContext, Type keyType, Type valueType) { + bool stopOnIndexNotFound; + IEnumerable indexes; + GetIndexes(bindingContext, out stopOnIndexNotFound, out indexes); + + IModelBinder keyBinder = Binders.GetBinder(keyType); + IModelBinder valueBinder = Binders.GetBinder(valueType); + + // build up a list of items from the request + List> modelList = new List>(); + foreach (string currentIndex in indexes) { + string subIndexKey = CreateSubIndexName(bindingContext.ModelName, currentIndex); + string keyFieldKey = CreateSubPropertyName(subIndexKey, "key"); + string valueFieldKey = CreateSubPropertyName(subIndexKey, "value"); + + if (!(bindingContext.ValueProvider.ContainsPrefix(keyFieldKey) && bindingContext.ValueProvider.ContainsPrefix(valueFieldKey))) { + if (stopOnIndexNotFound) { + // we ran out of elements to pull + break; + } + else { + continue; + } + } + + // bind the key + ModelBindingContext keyBindingContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, keyType), + ModelName = keyFieldKey, + ModelState = bindingContext.ModelState, + ValueProvider = bindingContext.ValueProvider + }; + object thisKey = keyBinder.BindModel(controllerContext, keyBindingContext); + + // we need to merge model errors up + AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, keyFieldKey, keyType, thisKey); + if (!keyType.IsInstanceOfType(thisKey)) { + // we can't add an invalid key, so just move on + continue; + } + + // bind the value + ModelBindingContext valueBindingContext = new ModelBindingContext() { + ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, valueType), + ModelName = valueFieldKey, + ModelState = bindingContext.ModelState, + PropertyFilter = bindingContext.PropertyFilter, + ValueProvider = bindingContext.ValueProvider + }; + object thisValue = valueBinder.BindModel(controllerContext, valueBindingContext); + + // we need to merge model errors up + AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, valueFieldKey, valueType, thisValue); + KeyValuePair kvp = new KeyValuePair(thisKey, thisValue); + modelList.Add(kvp); + } + + // if there weren't any elements at all in the request, just return + if (modelList.Count == 0) { + return null; + } + + // replace the original collection + object dictionary = bindingContext.Model; + CollectionHelpers.ReplaceDictionary(keyType, valueType, dictionary, modelList); + return dictionary; + } + + // This helper type is used because we're working with strongly-typed collections, but we don't know the Ts + // ahead of time. By using the generic methods below, we can consolidate the collection-specific code in a + // single helper type rather than having reflection-based calls spread throughout the DefaultModelBinder type. + // There is a single point of entry to each of the methods below, so they're fairly simple to maintain. + + private static class CollectionHelpers { + + private static readonly MethodInfo _replaceCollectionMethod = typeof(CollectionHelpers).GetMethod("ReplaceCollectionImpl", BindingFlags.Static | BindingFlags.NonPublic); + private static readonly MethodInfo _replaceDictionaryMethod = typeof(CollectionHelpers).GetMethod("ReplaceDictionaryImpl", BindingFlags.Static | BindingFlags.NonPublic); + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + public static void ReplaceCollection(Type collectionType, object collection, object newContents) { + MethodInfo targetMethod = _replaceCollectionMethod.MakeGenericMethod(collectionType); + targetMethod.Invoke(null, new object[] { collection, newContents }); + } + + private static void ReplaceCollectionImpl(ICollection collection, IEnumerable newContents) { + collection.Clear(); + if (newContents != null) { + foreach (object item in newContents) { + // if the item was not a T, some conversion failed. the error message will be propagated, + // but in the meanwhile we need to make a placeholder element in the array. + T castItem = (item is T) ? (T)item : default(T); + collection.Add(castItem); + } + } + } + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] + public static void ReplaceDictionary(Type keyType, Type valueType, object dictionary, object newContents) { + MethodInfo targetMethod = _replaceDictionaryMethod.MakeGenericMethod(keyType, valueType); + targetMethod.Invoke(null, new object[] { dictionary, newContents }); + } + + private static void ReplaceDictionaryImpl(IDictionary dictionary, IEnumerable> newContents) { + dictionary.Clear(); + foreach (KeyValuePair item in newContents) { + // if the item was not a T, some conversion failed. the error message will be propagated, + // but in the meanwhile we need to make a placeholder element in the dictionary. + TKey castKey = (TKey)item.Key; // this cast shouldn't fail + TValue castValue = (item.Value is TValue) ? (TValue)item.Value : default(TValue); + dictionary[castKey] = castValue; + } + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultViewLocationCache.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultViewLocationCache.cs new file mode 100644 index 00000000000..f0479f42123 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DefaultViewLocationCache.cs @@ -0,0 +1,60 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Web.Caching; + using System.Web.Mvc.Resources; + + [SuppressMessage("Microsoft.Security", "CA2112:SecuredTypesShouldNotExposeFields", + Justification = "The Null field does not have access to secure information")] + public class DefaultViewLocationCache : IViewLocationCache { + private static readonly TimeSpan _defaultTimeSpan = new TimeSpan(0, 15, 0); + + public DefaultViewLocationCache() + : this(_defaultTimeSpan) { + } + + public DefaultViewLocationCache(TimeSpan timeSpan) { + if (timeSpan.Ticks < 0) { + throw new InvalidOperationException(MvcResources.DefaultViewLocationCache_NegativeTimeSpan); + } + TimeSpan = timeSpan; + } + + [SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", + Justification = "The reference type is immutable. ")] + public static readonly IViewLocationCache Null = new NullViewLocationCache(); + + public TimeSpan TimeSpan { + get; + private set; + } + + #region IViewLocationCache Members + public string GetViewLocation(HttpContextBase httpContext, string key) { + if (httpContext == null) { + throw new ArgumentNullException("httpContext"); + } + return (string)httpContext.Cache[key]; + } + + public void InsertViewLocation(HttpContextBase httpContext, string key, string virtualPath) { + if (httpContext == null) { + throw new ArgumentNullException("httpContext"); + } + httpContext.Cache.Insert(key, virtualPath, null /* dependencies */, Cache.NoAbsoluteExpiration, TimeSpan); + } + #endregion + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DescriptorUtil.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DescriptorUtil.cs new file mode 100644 index 00000000000..a19c90f89f3 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DescriptorUtil.cs @@ -0,0 +1,34 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Linq; + using System.Threading; + + internal static class DescriptorUtil { + + public static TDescriptor[] LazilyFetchOrCreateDescriptors(ref TDescriptor[] cacheLocation, Func initializer, Func converter) { + // did we already calculate this once? + TDescriptor[] existingCache = Interlocked.CompareExchange(ref cacheLocation, null, null); + if (existingCache != null) { + return existingCache; + } + + TReflection[] memberInfos = initializer(); + TDescriptor[] descriptors = memberInfos.Select(converter).Where(descriptor => descriptor != null).ToArray(); + TDescriptor[] updatedCache = Interlocked.CompareExchange(ref cacheLocation, descriptors, null); + return updatedCache ?? descriptors; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryHelpers.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryHelpers.cs new file mode 100644 index 00000000000..7eb761f55fe --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryHelpers.cs @@ -0,0 +1,52 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Linq; + + internal static class DictionaryHelpers { + + public static IEnumerable> FindKeysWithPrefix(IDictionary dictionary, string prefix) { + TValue exactMatchValue; + if (dictionary.TryGetValue(prefix, out exactMatchValue)) { + yield return new KeyValuePair(prefix, exactMatchValue); + } + + foreach (var entry in dictionary) { + string key = entry.Key; + + if (key.Length <= prefix.Length) { + continue; + } + + if (!key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { + continue; + } + + char charAfterPrefix = key[prefix.Length]; + switch (charAfterPrefix) { + case '[': + case '.': + yield return entry; + break; + } + } + } + + public static bool DoesAnyKeyHavePrefix(IDictionary dictionary, string prefix) { + return FindKeysWithPrefix(dictionary, prefix).Any(); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryValueProvider`1.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryValueProvider`1.cs new file mode 100644 index 00000000000..b1e8845da46 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DictionaryValueProvider`1.cs @@ -0,0 +1,64 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Globalization; + + public class DictionaryValueProvider : IValueProvider { + + private readonly HashSet _prefixes = new HashSet(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary _values = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public DictionaryValueProvider(IDictionary dictionary, CultureInfo culture) { + if (dictionary == null) { + throw new ArgumentNullException("dictionary"); + } + + AddValues(dictionary, culture); + } + + private void AddValues(IDictionary dictionary, CultureInfo culture) { + if (dictionary.Count > 0) { + _prefixes.Add(""); + } + + foreach (var entry in dictionary) { + _prefixes.UnionWith(ValueProviderUtil.GetPrefixes(entry.Key)); + + object rawValue = entry.Value; + string attemptedValue = Convert.ToString(rawValue, culture); + _values[entry.Key] = new ValueProviderResult(rawValue, attemptedValue, culture); + } + } + + public virtual bool ContainsPrefix(string prefix) { + if (prefix == null) { + throw new ArgumentNullException("prefix"); + } + + return _prefixes.Contains(prefix); + } + + public virtual ValueProviderResult GetValue(string key) { + if (key == null) { + throw new ArgumentNullException("key"); + } + + ValueProviderResult vpResult; + _values.TryGetValue(key, out vpResult); + return vpResult; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/DynamicTypeGenerator.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DynamicTypeGenerator.cs new file mode 100644 index 00000000000..eefc9f87b07 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/DynamicTypeGenerator.cs @@ -0,0 +1,125 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Reflection; + using System.Reflection.Emit; + using System.Security; + + internal static class DynamicTypeGenerator { + + private static readonly ModuleBuilder _dynamicModule = CreateDynamicModule(); + + private static ModuleBuilder CreateDynamicModule() { + // DDB 226615 - since MVC is [SecurityTransparent], the dynamic assembly must declare itself likewise + CustomAttributeBuilder builder = new CustomAttributeBuilder( + typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes), new object[0]); + CustomAttributeBuilder[] assemblyAttributes = new CustomAttributeBuilder[] { builder }; + AssemblyBuilder dynamicAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly( + new AssemblyName("System.Web.Mvc.{Dynamic}"), AssemblyBuilderAccess.Run, assemblyAttributes); + ModuleBuilder dynamicModule = dynamicAssembly.DefineDynamicModule("System.Web.Mvc.{Dynamic}.dll"); + return dynamicModule; + } + + // Creates a new dynamic type that is a subclassed type of baseType and also implements methods of the specified + // interfaces. The base type must already have method signatures that implicitly implement the given + // interfaces. The signatures of all public (e.g. not private / internal) constructors from the baseType + // will be duplicated for the subclassed type and the new constructors made public. + public static Type GenerateType(string dynamicTypeName, Type baseType, IEnumerable interfaceTypes) { + TypeBuilder newType = _dynamicModule.DefineType( + "System.Web.Mvc.{Dynamic}." + dynamicTypeName, + TypeAttributes.AutoLayout | TypeAttributes.Public | TypeAttributes.Class, + baseType); + + foreach (Type interfaceType in interfaceTypes) { + newType.AddInterfaceImplementation(interfaceType); + foreach (MethodInfo interfaceMethod in interfaceType.GetMethods()) { + ImplementInterfaceMethod(newType, interfaceMethod); + } + } + + // generate new constructors for each accessible base constructor + foreach (ConstructorInfo ctor in baseType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { + switch (ctor.Attributes & MethodAttributes.MemberAccessMask) { + case MethodAttributes.Family: + case MethodAttributes.Public: + case MethodAttributes.FamORAssem: + ImplementConstructor(newType, ctor); + break; + } + } + + Type bakedType = newType.CreateType(); + return bakedType; + } + + // generates this constructor: + // public NewType(param0, param1, ...) : base(param0, param1, ...) { } + private static void ImplementConstructor(TypeBuilder newType, ConstructorInfo baseCtor) { + ParameterInfo[] parameters = baseCtor.GetParameters(); + Type[] parameterTypes = (from p in parameters select p.ParameterType).ToArray(); + + ConstructorBuilder newCtor = newType.DefineConstructor( + (baseCtor.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Public /* force public constructor */, + baseCtor.CallingConvention, parameterTypes); + + // parameter 0 is 'this', so we start at index 1 + for (int i = 0; i < parameters.Length; i++) { + newCtor.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name); + } + + // load all arguments (including 'this') in proper order, then call and return + ILGenerator ilGen = newCtor.GetILGenerator(); + for (int i = 0; i <= parameterTypes.Length; i++) { + ilGen.Emit(OpCodes.Ldarg_S, (byte)i); + } + ilGen.Emit(OpCodes.Call, baseCtor); + ilGen.Emit(OpCodes.Ret); + } + + // generates this explicit interface method: + // public new Interface.Method(param0, param1, ...) { + // return base.Method(param0, param1, ...); + // } + private static void ImplementInterfaceMethod(TypeBuilder newType, MethodInfo interfaceMethod) { + ParameterInfo[] parameters = interfaceMethod.GetParameters(); + Type[] parameterTypes = (from p in parameters select p.ParameterType).ToArray(); + + // based on http://msdn.microsoft.com/en-us/library/system.reflection.emit.typebuilder.definemethodoverride.aspx + MethodBuilder newMethod = newType.DefineMethod(interfaceMethod.DeclaringType.Name + "." + interfaceMethod.Name, + MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, + interfaceMethod.ReturnType, parameterTypes); + + MethodInfo baseMethod = newType.BaseType.GetMethod(interfaceMethod.Name, parameterTypes); + + // parameter 0 is 'this', so we start at index 1 + for (int i = 0; i < parameters.Length; i++) { + newMethod.DefineParameter(i + 1, parameters[i].Attributes, parameters[i].Name); + } + + // load all arguments (including 'this') in proper order, then call and return + ILGenerator ilGen = newMethod.GetILGenerator(); + for (int i = 0; i <= parameterTypes.Length; i++) { + ilGen.Emit(OpCodes.Ldarg_S, (byte)i); + } + ilGen.Emit(OpCodes.Call, baseMethod); + ilGen.Emit(OpCodes.Ret); + + // finally, hook the new method up to the interface mapping + newType.DefineMethodOverride(newMethod, interfaceMethod); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelMetadataProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelMetadataProvider.cs new file mode 100644 index 00000000000..984924b95ab --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelMetadataProvider.cs @@ -0,0 +1,23 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Reflection; + + public class EmptyModelMetadataProvider : AssociatedMetadataProvider { + protected override ModelMetadata CreateMetadata(IEnumerable attributes, Type containerType, Func modelAccessor, Type modelType, string propertyName) { + return new ModelMetadata(this, containerType, modelAccessor, modelType, propertyName); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelValidatorProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelValidatorProvider.cs new file mode 100644 index 00000000000..63fb1a26bdf --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyModelValidatorProvider.cs @@ -0,0 +1,22 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System.Collections.Generic; + using System.Linq; + + public class EmptyModelValidatorProvider : ModelValidatorProvider { + public override IEnumerable GetValidators(ModelMetadata metadata, ControllerContext context) { + return Enumerable.Empty(); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyResult.cs new file mode 100644 index 00000000000..3fef8eed4ca --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/EmptyResult.cs @@ -0,0 +1,29 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + + // represents a result that doesn't do anything, like a controller action returning null + public class EmptyResult : ActionResult { + + private static readonly EmptyResult _singleton = new EmptyResult(); + + internal static EmptyResult Instance { + get { + return _singleton; + } + } + + public override void ExecuteResult(ControllerContext context) { + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Error.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Error.cs new file mode 100644 index 00000000000..26e86f8748d --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Error.cs @@ -0,0 +1,84 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Globalization; + using System.Web.Mvc.Async; + using System.Web.Mvc.Resources; + + internal static class Error { + + public static InvalidOperationException AsyncActionMethodSelector_CouldNotFindMethod(string methodName, Type controllerType) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.AsyncActionMethodSelector_CouldNotFindMethod, + methodName, controllerType); + return new InvalidOperationException(message); + } + + public static InvalidOperationException AsyncCommon_AsyncResultAlreadyConsumed() { + return new InvalidOperationException(MvcResources.AsyncCommon_AsyncResultAlreadyConsumed); + } + + public static InvalidOperationException AsyncCommon_ControllerMustImplementIAsyncManagerContainer(Type actualControllerType) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.AsyncCommon_ControllerMustImplementIAsyncManagerContainer, + actualControllerType); + return new InvalidOperationException(message); + } + + public static ArgumentException AsyncCommon_InvalidAsyncResult(string parameterName) { + return new ArgumentException(MvcResources.AsyncCommon_InvalidAsyncResult, parameterName); + } + + public static ArgumentOutOfRangeException AsyncCommon_InvalidTimeout(string parameterName) { + return new ArgumentOutOfRangeException(parameterName, MvcResources.AsyncCommon_InvalidTimeout); + } + + public static InvalidOperationException ReflectedAsyncActionDescriptor_CannotExecuteSynchronously(string actionName) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ReflectedAsyncActionDescriptor_CannotExecuteSynchronously, + actionName); + return new InvalidOperationException(message); + } + + public static InvalidOperationException ChildActionOnlyAttribute_MustBeInChildRequest(ActionDescriptor actionDescriptor) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ChildActionOnlyAttribute_MustBeInChildRequest, + actionDescriptor.ActionName); + return new InvalidOperationException(message); + } + + public static ArgumentException ParameterCannotBeNullOrEmpty(string parameterName) { + return new ArgumentException(MvcResources.Common_NullOrEmpty, parameterName); + } + + public static InvalidOperationException PropertyCannotBeNullOrEmpty(string propertyName) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.Common_PropertyCannotBeNullOrEmpty, + propertyName); + return new InvalidOperationException(message); + } + + public static SynchronousOperationException SynchronizationContextUtil_ExceptionThrown(Exception innerException) { + return new SynchronousOperationException(MvcResources.SynchronizationContextUtil_ExceptionThrown, innerException); + } + + public static InvalidOperationException ViewDataDictionary_WrongTModelType(Type valueType, Type modelType) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ViewDataDictionary_WrongTModelType, + valueType, modelType); + return new InvalidOperationException(message); + } + + public static InvalidOperationException ViewDataDictionary_ModelCannotBeNull(Type modelType) { + string message = String.Format(CultureInfo.CurrentUICulture, MvcResources.ViewDataDictionary_ModelCannotBeNull, + modelType); + return new InvalidOperationException(message); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExceptionContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExceptionContext.cs new file mode 100644 index 00000000000..937dd233c43 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExceptionContext.cs @@ -0,0 +1,56 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + + public class ExceptionContext : ControllerContext { + + private ActionResult _result; + + // parameterless constructor used for mocking + public ExceptionContext() { + } + + [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", + Justification = "The virtual property setters are only to support mocking frameworks, in which case this constructor shouldn't be called anyway.")] + public ExceptionContext(ControllerContext controllerContext, Exception exception) + : base(controllerContext) { + if (exception == null) { + throw new ArgumentNullException("exception"); + } + + Exception = exception; + } + + public virtual Exception Exception { + get; + set; + } + + public bool ExceptionHandled { + get; + set; + } + + public ActionResult Result { + get { + return _result ?? EmptyResult.Instance; + } + set { + _result = value; + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionHelper.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionHelper.cs new file mode 100644 index 00000000000..e72d94d8eeb --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionHelper.cs @@ -0,0 +1,123 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Globalization; + using System.Linq; + using System.Linq.Expressions; + using System.Reflection; + using System.Web.Mvc.Resources; + + public static class ExpressionHelper { + public static string GetExpressionText(string expression) { + return + String.Equals(expression, "model", StringComparison.OrdinalIgnoreCase) + ? String.Empty // If it's exactly "model", then give them an empty string, to replicate the lambda behavior + : expression; + } + + public static string GetExpressionText(LambdaExpression expression) { + // Crack the expression string for property/field accessors to create its name + Stack nameParts = new Stack(); + Expression part = expression.Body; + + while (part != null) { + if (part.NodeType == ExpressionType.Call) { + MethodCallExpression methodExpression = (MethodCallExpression)part; + + if (!IsSingleArgumentIndexer(methodExpression)) { + break; + } + + nameParts.Push( + GetIndexerInvocation( + methodExpression.Arguments.Single(), + expression.Parameters.ToArray() + ) + ); + + part = methodExpression.Object; + } + else if (part.NodeType == ExpressionType.ArrayIndex) { + BinaryExpression binaryExpression = (BinaryExpression)part; + + nameParts.Push( + GetIndexerInvocation( + binaryExpression.Right, + expression.Parameters.ToArray() + ) + ); + + part = binaryExpression.Left; + } + else if (part.NodeType == ExpressionType.MemberAccess) { + MemberExpression memberExpressionPart = (MemberExpression)part; + nameParts.Push("." + memberExpressionPart.Member.Name); + part = memberExpressionPart.Expression; + } + else { + break; + } + } + + // If it starts with "model", then strip that away + if (nameParts.Count > 0 && String.Equals(nameParts.Peek(), ".model", StringComparison.OrdinalIgnoreCase)) { + nameParts.Pop(); + } + + if (nameParts.Count > 0) { + return nameParts.Aggregate((left, right) => left + right).TrimStart('.'); + } + + return String.Empty; + } + + private static string GetIndexerInvocation(Expression expression, ParameterExpression[] parameters) { + Expression converted = Expression.Convert(expression, typeof(object)); + ParameterExpression fakeParameter = Expression.Parameter(typeof(object), null); + Expression> lambda = Expression.Lambda>(converted, fakeParameter); + Func func; + + try { + func = ExpressionUtil.CachedExpressionCompiler.Process(lambda); + } + catch (InvalidOperationException ex) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.ExpressionHelper_InvalidIndexerExpression, + expression, + parameters[0].Name + ), + ex + ); + } + + return "[" + Convert.ToString(func(null), CultureInfo.InvariantCulture) + "]"; + } + + internal static bool IsSingleArgumentIndexer(Expression expression) { + MethodCallExpression methodExpression = expression as MethodCallExpression; + if (methodExpression == null || methodExpression.Arguments.Count != 1) { + return false; + } + + return methodExpression.Method + .DeclaringType + .GetDefaultMembers() + .OfType() + .Any(p => p.GetGetMethod() == methodExpression.Method); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs new file mode 100644 index 00000000000..90e1fd4fccd --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/BinaryExpressionFingerprint.cs @@ -0,0 +1,111 @@ +#pragma warning disable 659 // overrides AddToHashCodeCombiner instead + +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Linq.Expressions; + using System.Reflection; + + // BinaryExpression fingerprint class + // Useful for things like array[index] + // + // This particular fingerprint doesn't support the BinaryExpression.Conversion property, + // which is used in some coalescing operations. + [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", + Justification = "Overrides AddToHashCodeCombiner() instead.")] + internal sealed class BinaryExpressionFingerprint : ExpressionFingerprint { + + private BinaryExpressionFingerprint(BinaryExpression expression) + : base(expression) { + // don't care about UnaryExpression.IsLifted since it's not necessary to uniquely describe the expression, + // but IsLiftedToNull *is* required + + IsLiftedToNull = expression.IsLiftedToNull; + Method = expression.Method; + } + + public bool IsLiftedToNull { + get; + private set; + } + + public ExpressionFingerprint Left { + get; + private set; + } + + public MethodInfo Method { + get; + private set; + } + + public ExpressionFingerprint Right { + get; + private set; + } + + internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) { + base.AddToHashCodeCombiner(combiner); + + combiner.AddInt32(IsLiftedToNull.GetHashCode()); + combiner.AddFingerprint(Left); + combiner.AddObject(Method); + combiner.AddFingerprint(Right); + } + + public static BinaryExpressionFingerprint Create(BinaryExpression expression, ParserContext parserContext) { + if (expression.Conversion != null) { + // we don't support the Conversion property + return null; + } + + // if any fingerprinting fails, bail out + ExpressionFingerprint left = Create(expression.Left, parserContext); + if (left == null && expression.Left != null) { + return null; + } + + ExpressionFingerprint right = Create(expression.Right, parserContext); + if (right == null && expression.Right != null) { + return null; + } + + return new BinaryExpressionFingerprint(expression) { + Left = left, + Right = right + }; + } + + public override bool Equals(object obj) { + BinaryExpressionFingerprint other = obj as BinaryExpressionFingerprint; + if (other == null) { + return false; + } + + return (this.IsLiftedToNull == other.IsLiftedToNull + && Object.Equals(this.Left, other.Left) + && this.Method == other.Method + && Object.Equals(this.Right, other.Right) + && base.Equals(other)); + } + + public override Expression ToExpression(ParserContext parserContext) { + Expression leftExpr = ToExpression(Left, parserContext); + Expression rightExpr = ToExpression(Right, parserContext); + return Expression.MakeBinary(NodeType, leftExpr, rightExpr, IsLiftedToNull, Method); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs new file mode 100644 index 00000000000..29078b69a6f --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CachedExpressionCompiler.cs @@ -0,0 +1,86 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Linq.Expressions; + + internal static class CachedExpressionCompiler { + + // This is the entry point to the cached expression tree compiler. The processor will perform a series of checks + // and optimizations in order to return a fully-compiled func as quickly as possible to the caller. If the + // input expression is particularly obscure, the system will fall back to a slow but correct compilation step. + public static Func Process(Expression> lambdaExpression) { + return Processor.GetFunc(lambdaExpression); + } + + private static class Processor { + + private static readonly Cache _cache = new Cache(); + + public static Func GetFunc(Expression> lambdaExpression) { + // look for common patterns that don't need to be fingerprinted + Func func = GetFuncFastTrack(lambdaExpression); + if (func != null) { + return func; + } + + // not a common pattern, so try fingerprinting (slower, but cached) + func = GetFuncFingerprinted(lambdaExpression); + if (func != null) { + return func; + } + + // pattern not recognized by fingerprinting routine, so compile directly (slowest) + return GetFuncSlow(lambdaExpression); + } + + private static Func GetFuncFastTrack(Expression> lambdaExpression) { + ParameterExpression modelParameter = lambdaExpression.Parameters[0]; + Expression body = lambdaExpression.Body; + + return FastTrack.GetFunc(modelParameter, body); + } + + private static Func GetFuncFingerprinted(Expression> lambdaExpression) { + ParserContext context = ExpressionParser.Parse(lambdaExpression); + if (context.Fingerprint == null) { + // fingerprinting failed + return null; + } + + object[] hoistedValues = context.HoistedValues.ToArray(); + var del = _cache.GetDelegate(context); + return model => del(model, hoistedValues); + } + + private static Func GetFuncSlow(Expression> lambdaExpression) { + Func del = lambdaExpression.Compile(); + return del; + } + + private sealed class Cache : ReaderWriterCache> { + private static CompiledExpressionDelegate CreateDelegate(ParserContext context) { + var bodyExpr = context.Fingerprint.ToExpression(context); + var lambdaExpr = Expression.Lambda>(bodyExpr, context.ModelParameter, ParserContext.HoistedValuesParameter); + var del = lambdaExpr.Compile(); + return del; + } + public CompiledExpressionDelegate GetDelegate(ParserContext context) { + return FetchOrCreateItem(context.Fingerprint, () => CreateDelegate(context)); + } + } + + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs new file mode 100644 index 00000000000..dc95a908da7 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/CompiledExpressionDelegate`2.cs @@ -0,0 +1,18 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + + internal delegate TValue CompiledExpressionDelegate(TModel model, object[] hoistedValues); + +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs new file mode 100644 index 00000000000..80e29f0a564 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConditionalExpressionFingerprint.cs @@ -0,0 +1,97 @@ +#pragma warning disable 659 // overrides AddToHashCodeCombiner instead + +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Linq.Expressions; + + // ConditionalExpression fingerprint class + // Expression of form (test) ? ifTrue : ifFalse + [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", + Justification = "Overrides AddToHashCodeCombiner() instead.")] + internal sealed class ConditionalExpressionFingerprint : ExpressionFingerprint { + + private ConditionalExpressionFingerprint(ConditionalExpression expression) + : base(expression) { + } + + public ExpressionFingerprint Test { + get; + private set; + } + + public ExpressionFingerprint IfTrue { + get; + private set; + } + + public ExpressionFingerprint IfFalse { + get; + private set; + } + + internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) { + base.AddToHashCodeCombiner(combiner); + + combiner.AddFingerprint(Test); + combiner.AddFingerprint(IfTrue); + combiner.AddFingerprint(IfFalse); + } + + public static ConditionalExpressionFingerprint Create(ConditionalExpression expression, ParserContext parserContext) { + // if any fingerprinting fails, bail out + ExpressionFingerprint test = Create(expression.Test, parserContext); + if (test == null && expression.Test != null) { + return null; + } + + ExpressionFingerprint ifTrue = Create(expression.IfTrue, parserContext); + if (ifTrue == null && expression.IfTrue != null) { + return null; + } + + ExpressionFingerprint ifFalse = Create(expression.IfFalse, parserContext); + if (ifFalse == null && expression.IfFalse != null) { + return null; + } + + return new ConditionalExpressionFingerprint(expression) { + Test = test, + IfTrue = ifTrue, + IfFalse = ifFalse + }; + } + + public override bool Equals(object obj) { + ConditionalExpressionFingerprint other = obj as ConditionalExpressionFingerprint; + if (other == null) { + return false; + } + + return (Object.Equals(this.Test, other.Test) + && Object.Equals(this.IfTrue, other.IfTrue) + && Object.Equals(this.IfFalse, other.IfFalse) + && base.Equals(other)); + } + + public override Expression ToExpression(ParserContext parserContext) { + Expression testExpr = ToExpression(Test, parserContext); + Expression ifTrueExpr = ToExpression(IfTrue, parserContext); + Expression ifFalseExpr = ToExpression(IfFalse, parserContext); + return Expression.Condition(testExpr, ifTrueExpr, ifFalseExpr); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs new file mode 100644 index 00000000000..96e08bc8ee3 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ConstantExpressionFingerprint.cs @@ -0,0 +1,72 @@ +#pragma warning disable 659 // overrides AddToHashCodeCombiner instead + +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Linq.Expressions; + + // ConstantExpression fingerprint class + // + // A ConstantExpression might represent a captured local variable, so we can't compile + // the value directly into the cached function. Instead, a placeholder is generated + // and the value is hoisted into a local variables array. This placeholder can then + // be compiled and cached, and the array lookup happens at runtime. + [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", + Justification = "Overrides AddToHashCodeCombiner() instead.")] + internal sealed class ConstantExpressionFingerprint : ExpressionFingerprint { + + private ConstantExpressionFingerprint(ConstantExpression expression) + : base(expression) { + } + + public int HoistedLocalsIndex { + get; + private set; + } + + internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) { + base.AddToHashCodeCombiner(combiner); + + combiner.AddInt32(HoistedLocalsIndex); + } + + public static ConstantExpressionFingerprint Create(ConstantExpression expression, ParserContext parserContext) { + ConstantExpressionFingerprint fingerprint = new ConstantExpressionFingerprint(expression) { + HoistedLocalsIndex = parserContext.HoistedValues.Count + }; + + parserContext.HoistedValues.Add(expression.Value); + return fingerprint; + } + + public override bool Equals(object obj) { + ConstantExpressionFingerprint other = obj as ConstantExpressionFingerprint; + if (other == null) { + return false; + } + + return (this.HoistedLocalsIndex == other.HoistedLocalsIndex + && base.Equals(other)); + } + + public override Expression ToExpression(ParserContext parserContext) { + // (Type) HoistedValues[HoistedLocalsIndex] + BinaryExpression arrayIndex = Expression.ArrayIndex(ParserContext.HoistedValuesParameter, Expression.Constant(HoistedLocalsIndex)); + UnaryExpression castExpr = Expression.Convert(arrayIndex, Type); + return castExpr; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs new file mode 100644 index 00000000000..c942d9bb1b5 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionFingerprint.cs @@ -0,0 +1,174 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Linq; + using System.Linq.Expressions; + + // Expression fingerprint class + // Contains information used for generalizing, comparing, and recreating Expression instances + // + // Since Expression objects are immutable and are recreated for every invocation of an expression + // helper method, they can't be compared directly. Fingerprinting Expression objects allows + // information about them to be abstracted away, and the fingerprints can be directly compared. + // Consider the process of fingerprinting that all values (parameters, constants, etc.) are hoisted + // and replaced with dummies. What remains can be decomposed into a sequence of operations on specific + // types and specific inputs. + // + // Some sample fingerprints: + // + // 2 + 4 -> OP_ADD(CONST:int, CONST:int):int + // 2 + 8 -> OP_ADD(CONST:int, CONST:int):int + // 2.0 + 4.0 -> OP_ADD(CONST:double, CONST:double):double + // + // 2 + 4 and 2 + 8 have the same fingerprint, but 2.0 + 4.0 has a different fingerprint since its + // underlying types differ. + // + // "Hello " + "world" -> OP_ADD(CONST:string, CONST:string):string + // "Hello " + {model} -> OP_ADD(CONST:string, PARAM:string):string + // + // These string concatenations have different fingerprints since the inputs are provided differently: + // one is a hoisted local, the other is a parameter. + // + // ({model} ?? "sample").Length -> MEMBER_ACCESS(String.Length, OP_COALESCE(PARAM:string, CONST:string):string):int + // ({model} ?? "other sample").Length -> MEMBER_ACCESS(String.Length, OP_COALESCE(PARAM:string, CONST:string):string):int + // + // These expressions have the same fingerprint. + internal abstract class ExpressionFingerprint { + + protected ExpressionFingerprint(Expression expression) { + // since the fingerprints are cached potentially forever, don't keep a reference + // to the original expression + + NodeType = expression.NodeType; + Type = expression.Type; + } + + // the type of expression node, e.g. OP_ADD, MEMBER_ACCESS, etc. + public ExpressionType NodeType { + get; + private set; + } + + // the CLR type resulting from this expression, e.g. int, string, etc. + public Type Type { + get; + private set; + } + + internal virtual void AddToHashCodeCombiner(HashCodeCombiner combiner) { + combiner.AddObject(NodeType); + combiner.AddObject(Type); + } + + public static ExpressionFingerprint Create(Expression expression, ParserContext parserContext) { + { + BinaryExpression binaryExpression = expression as BinaryExpression; + if (binaryExpression != null) { + return BinaryExpressionFingerprint.Create(binaryExpression, parserContext); + } + } + + { + ConditionalExpression conditionalExpression = expression as ConditionalExpression; + if (conditionalExpression != null) { + return ConditionalExpressionFingerprint.Create(conditionalExpression, parserContext); + } + } + + { + ConstantExpression constantExpression = expression as ConstantExpression; + if (constantExpression != null) { + return ConstantExpressionFingerprint.Create(constantExpression, parserContext); + } + } + + { + MemberExpression memberExpression = expression as MemberExpression; + if (memberExpression != null) { + return MemberExpressionFingerprint.Create(memberExpression, parserContext); + } + } + + { + MethodCallExpression methodCallExpression = expression as MethodCallExpression; + if (methodCallExpression != null) { + return MethodCallExpressionFingerprint.Create(methodCallExpression, parserContext); + } + } + + { + ParameterExpression parameterExpression = expression as ParameterExpression; + if (parameterExpression != null) { + return ParameterExpressionFingerprint.Create(parameterExpression, parserContext); + } + } + + { + UnaryExpression unaryExpression = expression as UnaryExpression; + if (unaryExpression != null) { + return UnaryExpressionFingerprint.Create(unaryExpression, parserContext); + } + } + + // unknown expression + return null; + } + + public static ReadOnlyCollection Create(IEnumerable expressions, ParserContext parserContext) { + List fingerprints = new List(); + foreach (Expression expression in expressions) { + ExpressionFingerprint fingerprint = Create(expression, parserContext); + if (fingerprint == null && expression != null) { + // something couldn't be parsed properly + return null; + } + else { + fingerprints.Add(fingerprint); + } + } + return new ReadOnlyCollection(fingerprints); + } + + public override int GetHashCode() { + HashCodeCombiner combiner = new HashCodeCombiner(); + combiner.AddObject(GetType()); + AddToHashCodeCombiner(combiner); + return combiner.CombinedHash; + } + + public override bool Equals(object obj) { + ExpressionFingerprint other = obj as ExpressionFingerprint; + if (other == null) { + return false; + } + + return (this.NodeType == other.NodeType + && this.Type == other.Type + && this.GetType() == other.GetType()); + } + + protected static Expression ToExpression(ExpressionFingerprint fingerprint, ParserContext parserContext) { + return (fingerprint != null) ? fingerprint.ToExpression(parserContext) : null; + } + + protected static IEnumerable ToExpression(IEnumerable fingerprints, ParserContext parserContext) { + return from fingerprint in fingerprints select ToExpression(fingerprint, parserContext); + } + + public abstract Expression ToExpression(ParserContext parserContext); + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionParser.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionParser.cs new file mode 100644 index 00000000000..f277a9f56bb --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ExpressionParser.cs @@ -0,0 +1,30 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Linq.Expressions; + + internal static class ExpressionParser { + + public static ParserContext Parse(Expression> expression) { + ParserContext context = new ParserContext() { + ModelParameter = expression.Parameters[0] + }; + + Expression body = expression.Body; + context.Fingerprint = ExpressionFingerprint.Create(body, context); + return context; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/FastTrack`2.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/FastTrack`2.cs new file mode 100644 index 00000000000..ec20c8c0780 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/FastTrack`2.cs @@ -0,0 +1,112 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Linq.Expressions; + using System.Reflection; + + internal static class FastTrack { + + private static Func _identityFunc; + + private static readonly ConstMemberLookupCache _constMemberLookupCache = new ConstMemberLookupCache(); + private static readonly ModelMemberLookupCache _modelMemberLookupCache = new ModelMemberLookupCache(); + + public static Func GetFunc(ParameterExpression modelParameter, Expression body) { + { // model => model + if (modelParameter == body) { + return GetIdentityFunc(); + } + } + + { // model => {const} + ConstantExpression constantExpression = body as ConstantExpression; + if (constantExpression != null) { + TValue value = (TValue)constantExpression.Value; + return _ => value; + } + } + + { + MemberExpression memberExpression = body as MemberExpression; + if (memberExpression != null) { + if (memberExpression.Expression == null) { + // model => {static member} + return GetModelMemberLookupFunc(memberExpression.Member, true /* isStatic */); + } + else if (memberExpression.Expression == modelParameter) { + // model => model.Member + return GetModelMemberLookupFunc(memberExpression.Member, false /* isStatic */); + } + else { + ConstantExpression constantExpression = memberExpression.Expression as ConstantExpression; + if (constantExpression != null) { + // model => {const}.Member, e.g. captured local variable in a foreach + return GetConstMemberLookupFunc(memberExpression.Member, constantExpression.Value); + } + } + } + } + + // don't know how to fast-track + return null; + } + + private static Func GetIdentityFunc() { + // don't need to worry about locking since all identity funcs are the same + if (_identityFunc == null) { + ParameterExpression modelParameter = Expression.Parameter(typeof(TModel), "model"); + Expression> identityLambda = Expression.Lambda>(modelParameter, modelParameter); + _identityFunc = identityLambda.Compile(); + } + + return _identityFunc; + } + + private static Func GetModelMemberLookupFunc(MemberInfo member, bool isStatic) { + return _modelMemberLookupCache.GetFunc(member, isStatic); + } + + private static Func GetConstMemberLookupFunc(MemberInfo member, object constValue) { + Func innerFunc = _constMemberLookupCache.GetFunc(member); + return _ => innerFunc(constValue); + } + + private sealed class ConstMemberLookupCache : ReaderWriterCache> { + private static Func CreateFunc(MemberInfo member) { + ParameterExpression constParam = Expression.Parameter(typeof(object), "constValue"); + // cast is necessary since the constant value comes in as a standard 'object' + UnaryExpression castExpr = Expression.Convert(constParam, member.DeclaringType); + MemberExpression memberExpr = Expression.MakeMemberAccess(castExpr, member); + Expression> lambda = Expression.Lambda>(memberExpr, constParam); + return lambda.Compile(); + } + public Func GetFunc(MemberInfo member) { + return FetchOrCreateItem(member, () => CreateFunc(member)); + } + } + + private sealed class ModelMemberLookupCache : ReaderWriterCache> { + private static Func CreateFunc(MemberInfo member, bool isStatic) { + ParameterExpression modelParam = Expression.Parameter(typeof(TModel), "model"); + MemberExpression memberExpr = Expression.MakeMemberAccess((!isStatic) ? modelParam : null, member); + Expression> lambda = Expression.Lambda>(memberExpr, modelParam); + return lambda.Compile(); + } + public Func GetFunc(MemberInfo member, bool isStatic) { + return FetchOrCreateItem(member, () => CreateFunc(member, isStatic)); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs new file mode 100644 index 00000000000..5abdded6872 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/HashCodeCombiner.cs @@ -0,0 +1,61 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Collections; + + // based on System.Web.Util.HashCodeCombiner + internal class HashCodeCombiner { + + private long _combinedHash64 = 0x1505L; + + public void AddFingerprint(ExpressionFingerprint fingerprint) { + if (fingerprint != null) { + fingerprint.AddToHashCodeCombiner(this); + } + else { + AddInt32(0); + } + } + + public void AddEnumerable(IEnumerable e) { + if (e == null) { + AddInt32(0); + } + else { + int count = 0; + foreach (object o in e) { + AddObject(o); + count++; + } + AddInt32(count); + } + } + + public void AddInt32(int i) { + _combinedHash64 = ((_combinedHash64 << 5) + _combinedHash64) ^ i; + } + + public void AddObject(object o) { + int oHashCode = (o != null) ? o.GetHashCode() : 0; + AddInt32(oHashCode); + } + + public int CombinedHash { + get { + return _combinedHash64.GetHashCode(); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs new file mode 100644 index 00000000000..6a55769576c --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MemberExpressionFingerprint.cs @@ -0,0 +1,78 @@ +#pragma warning disable 659 // overrides AddToHashCodeCombiner instead + +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Linq.Expressions; + using System.Reflection; + + // MemberExpression fingerprint class + // Expression of form xxx.FieldOrProperty + [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", + Justification = "Overrides AddToHashCodeCombiner() instead.")] + internal sealed class MemberExpressionFingerprint : ExpressionFingerprint { + + private MemberExpressionFingerprint(MemberExpression expression) + : base(expression) { + + Member = expression.Member; + } + + public MemberInfo Member { + get; + private set; + } + + public ExpressionFingerprint Target { + get; + private set; + } + + internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) { + base.AddToHashCodeCombiner(combiner); + + combiner.AddObject(Member); + combiner.AddFingerprint(Target); + } + + public static MemberExpressionFingerprint Create(MemberExpression expression, ParserContext parserContext) { + ExpressionFingerprint target = Create(expression.Expression, parserContext); + if (target == null && expression.Expression != null) { + return null; + } + + return new MemberExpressionFingerprint(expression) { + Target = target + }; + } + + public override bool Equals(object obj) { + MemberExpressionFingerprint other = obj as MemberExpressionFingerprint; + if (other == null) { + return false; + } + + return (this.Member == other.Member + && Object.Equals(this.Target, other.Target) + && base.Equals(other)); + } + + public override Expression ToExpression(ParserContext parserContext) { + Expression targetExpr = ToExpression(Target, parserContext); + return Expression.MakeMemberAccess(targetExpr, Member); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs new file mode 100644 index 00000000000..7b8455cdb51 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/MethodCallExpressionFingerprint.cs @@ -0,0 +1,95 @@ +#pragma warning disable 659 // overrides AddToHashCodeCombiner instead + +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Linq.Expressions; + using System.Reflection; + + // MethodCallExpression fingerprint class + // Expression of form xxx.Foo(...), xxx[...] (get_Item()), etc. + [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", + Justification = "Overrides AddToHashCodeCombiner() instead.")] + internal sealed class MethodCallExpressionFingerprint : ExpressionFingerprint { + + private MethodCallExpressionFingerprint(MethodCallExpression expression) + : base(expression) { + + Method = expression.Method; + } + + public ReadOnlyCollection Arguments { + get; + private set; + } + + public MethodInfo Method { + get; + private set; + } + + public ExpressionFingerprint Target { + get; + private set; + } + + internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) { + base.AddToHashCodeCombiner(combiner); + + combiner.AddEnumerable(Arguments); + combiner.AddObject(Method); + combiner.AddFingerprint(Target); + } + + public static MethodCallExpressionFingerprint Create(MethodCallExpression expression, ParserContext parserContext) { + ReadOnlyCollection arguments = Create(expression.Arguments, parserContext); + if (arguments == null) { + return null; + } + + ExpressionFingerprint target = Create(expression.Object, parserContext); + if (target == null && expression.Object != null) { + return null; + } + + return new MethodCallExpressionFingerprint(expression) { + Arguments = arguments, + Target = target + }; + } + + public override bool Equals(object obj) { + MethodCallExpressionFingerprint other = obj as MethodCallExpressionFingerprint; + if (other == null) { + return false; + } + + return (this.Arguments.SequenceEqual(other.Arguments) + && this.Method == other.Method + && Object.Equals(this.Target, other.Target) + && base.Equals(other)); + } + + public override Expression ToExpression(ParserContext parserContext) { + Expression targetExpr = ToExpression(Target, parserContext); + IEnumerable argumentsExpr = ToExpression(Arguments, parserContext); + return Expression.Call(targetExpr, Method, argumentsExpr); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs new file mode 100644 index 00000000000..399f686e1a8 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParameterExpressionFingerprint.cs @@ -0,0 +1,42 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Linq.Expressions; + + // ParameterExpression fingerprint class + // Specifically, instances of this type represent the model parameter + internal sealed class ParameterExpressionFingerprint : ExpressionFingerprint { + + private ParameterExpressionFingerprint(ParameterExpression expression) + : base(expression) { + } + + public static ParameterExpressionFingerprint Create(ParameterExpression expression, ParserContext parserContext) { + if (expression == parserContext.ModelParameter) { + return new ParameterExpressionFingerprint(expression); + } + else { + // degenerate case - uncaptured parameter expression passed into the system + return null; + } + } + + public override Expression ToExpression(ParserContext parserContext) { + // The only time an instance of this class exists is if it represents the actual model parameter, + // so just return it directly. + return parserContext.ModelParameter; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParserContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParserContext.cs new file mode 100644 index 00000000000..38281c34389 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/ParserContext.cs @@ -0,0 +1,27 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Linq.Expressions; + using System.Collections.Generic; + + internal class ParserContext { + + public static readonly ParameterExpression HoistedValuesParameter = Expression.Parameter(typeof(object[]), "hoistedValues"); + + public ExpressionFingerprint Fingerprint; + public readonly List HoistedValues = new List(); + public ParameterExpression ModelParameter; + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs new file mode 100644 index 00000000000..8ba8cfa21cf --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/ExpressionUtil/UnaryExpressionFingerprint.cs @@ -0,0 +1,87 @@ +#pragma warning disable 659 // overrides AddToHashCodeCombiner instead + +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.ExpressionUtil { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Linq.Expressions; + using System.Reflection; + + // UnaryExpression fingerprint class + // The most common appearance of a UnaryExpression is a cast or other conversion operator + [SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", + Justification = "Overrides AddToHashCodeCombiner() instead.")] + internal sealed class UnaryExpressionFingerprint : ExpressionFingerprint { + + private UnaryExpressionFingerprint(UnaryExpression expression) + : base(expression) { + // don't care about UnaryExpression.IsLifted / IsLiftedToNull since they're not necessary to uniquely describe the expression + + Method = expression.Method; + } + + public MethodInfo Method { + get; + private set; + } + + public ExpressionFingerprint Operand { + get; + private set; + } + + internal override void AddToHashCodeCombiner(HashCodeCombiner combiner) { + base.AddToHashCodeCombiner(combiner); + + combiner.AddObject(Method); + combiner.AddFingerprint(Operand); + } + + public static UnaryExpressionFingerprint Create(UnaryExpression expression, ParserContext parserContext) { + ExpressionFingerprint operand = Create(expression.Operand, parserContext); + if (operand == null && expression.Operand != null) { + // couldn't convert the operand, so bail + return null; + } + + return new UnaryExpressionFingerprint(expression) { + Operand = operand + }; + } + + public override bool Equals(object obj) { + UnaryExpressionFingerprint other = obj as UnaryExpressionFingerprint; + if (other == null) { + return false; + } + + return (this.Method == other.Method + && Object.Equals(this.Operand, other.Operand) + && base.Equals(other)); + } + + public override Expression ToExpression(ParserContext parserContext) { + Expression operandExpr = ToExpression(Operand, parserContext); + + // in .NET 3.5 SP1, Expression.MakeUnary() throws if NodeType is UnaryPlus, so special-case + if (NodeType == ExpressionType.UnaryPlus) { + return Expression.UnaryPlus(operandExpr, Method); + } + else { + return Expression.MakeUnary(NodeType, operandExpr, Type, Method); + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FieldValidationMetadata.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FieldValidationMetadata.cs new file mode 100644 index 00000000000..5dda0446d28 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FieldValidationMetadata.cs @@ -0,0 +1,49 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + + public class FieldValidationMetadata { + + private string _fieldName; + private readonly Collection _validationRules = new Collection(); + + public string FieldName { + get { + return _fieldName ?? String.Empty; + } + set { + _fieldName = value; + } + } + + public bool ReplaceValidationMessageContents { + get; + set; + } + + public string ValidationMessageId { + get; + set; + } + + public ICollection ValidationRules { + get { + return _validationRules; + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileContentResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileContentResult.cs new file mode 100644 index 00000000000..8a2fdc0f6f5 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileContentResult.cs @@ -0,0 +1,41 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Web; + + public class FileContentResult : FileResult { + + public FileContentResult(byte[] fileContents, string contentType) + : base(contentType) { + if (fileContents == null) { + throw new ArgumentNullException("fileContents"); + } + + FileContents = fileContents; + } + + [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays", + Justification = "There's no reason to tamper-proof this array since it's supplied to the type's constructor.")] + public byte[] FileContents { + get; + private set; + } + + protected override void WriteFile(HttpResponseBase response) { + response.OutputStream.Write(FileContents, 0, FileContents.Length); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilePathResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilePathResult.cs new file mode 100644 index 00000000000..550113f9aba --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilePathResult.cs @@ -0,0 +1,39 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Web; + using System.Web.Mvc.Resources; + + public class FilePathResult : FileResult { + + public FilePathResult(string fileName, string contentType) + : base(contentType) { + if (String.IsNullOrEmpty(fileName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "fileName"); + } + + FileName = fileName; + } + + public string FileName { + get; + private set; + } + + protected override void WriteFile(HttpResponseBase response) { + response.TransmitFile(FileName); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileResult.cs new file mode 100644 index 00000000000..8127e46216b --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileResult.cs @@ -0,0 +1,143 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Net.Mime; + using System.Text; + using System.Web; + using System.Web.Mvc.Resources; + + public abstract class FileResult : ActionResult { + + protected FileResult(string contentType) { + if (String.IsNullOrEmpty(contentType)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "contentType"); + } + + ContentType = contentType; + } + + private string _fileDownloadName; + + public string ContentType { + get; + private set; + } + + public string FileDownloadName { + get { + return _fileDownloadName ?? String.Empty; + } + set { + _fileDownloadName = value; + } + } + + public override void ExecuteResult(ControllerContext context) { + if (context == null) { + throw new ArgumentNullException("context"); + } + + HttpResponseBase response = context.HttpContext.Response; + response.ContentType = ContentType; + + if (!String.IsNullOrEmpty(FileDownloadName)) { + // From RFC 2183, Sec. 2.3: + // The sender may want to suggest a filename to be used if the entity is + // detached and stored in a separate file. If the receiving MUA writes + // the entity to a file, the suggested filename should be used as a + // basis for the actual filename, where possible. + string headerValue = ContentDispositionUtil.GetHeaderValue(FileDownloadName); + context.HttpContext.Response.AddHeader("Content-Disposition", headerValue); + } + + WriteFile(response); + } + + protected abstract void WriteFile(HttpResponseBase response); + + private static class ContentDispositionUtil { + private const string _hexDigits = "0123456789ABCDEF"; + + private static void AddByteToStringBuilder(byte b, StringBuilder builder) { + builder.Append('%'); + + int i = b; + AddHexDigitToStringBuilder(i >> 4, builder); + AddHexDigitToStringBuilder(i % 16, builder); + } + + private static void AddHexDigitToStringBuilder(int digit, StringBuilder builder) { + builder.Append(_hexDigits[digit]); + } + + private static string CreateRfc2231HeaderValue(string filename) { + StringBuilder builder = new StringBuilder("attachment; filename*=UTF-8''"); + + byte[] filenameBytes = Encoding.UTF8.GetBytes(filename); + foreach (byte b in filenameBytes) { + if (IsByteValidHeaderValueCharacter(b)) { + builder.Append((char)b); + } + else { + AddByteToStringBuilder(b, builder); + } + } + + return builder.ToString(); + } + + public static string GetHeaderValue(string fileName) { + try { + // first, try using the .NET built-in generator + ContentDisposition disposition = new ContentDisposition() { FileName = fileName }; + return disposition.ToString(); + } + catch (FormatException) { + // otherwise, fall back to RFC 2231 extensions generator + return CreateRfc2231HeaderValue(fileName); + } + } + + // Application of RFC 2231 Encoding to Hypertext Transfer Protocol (HTTP) Header Fields, sec. 3.2 + // http://greenbytes.de/tech/webdav/draft-reschke-rfc2231-in-http-latest.html + private static bool IsByteValidHeaderValueCharacter(byte b) { + if ((byte)'0' <= b && b <= (byte)'9') { + return true; // is digit + } + if ((byte)'a' <= b && b <= (byte)'z') { + return true; // lowercase letter + } + if ((byte)'A' <= b && b <= (byte)'Z') { + return true; // uppercase letter + } + + switch (b) { + case (byte)'-': + case (byte)'.': + case (byte)'_': + case (byte)'~': + case (byte)':': + case (byte)'!': + case (byte)'$': + case (byte)'&': + case (byte)'+': + return true; + } + + return false; + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileStreamResult.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileStreamResult.cs new file mode 100644 index 00000000000..a6e1a6fb89e --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FileStreamResult.cs @@ -0,0 +1,56 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.IO; + using System.Web; + + public class FileStreamResult : FileResult { + + // default buffer size as defined in BufferedStream type + private const int _bufferSize = 0x1000; + + public FileStreamResult(Stream fileStream, string contentType) + : base(contentType) { + if (fileStream == null) { + throw new ArgumentNullException("fileStream"); + } + + FileStream = fileStream; + } + + public Stream FileStream { + get; + private set; + } + + protected override void WriteFile(HttpResponseBase response) { + // grab chunks of data and write to the output stream + Stream outputStream = response.OutputStream; + using (FileStream) { + byte[] buffer = new byte[_bufferSize]; + + while (true) { + int bytesRead = FileStream.Read(buffer, 0, _bufferSize); + if (bytesRead == 0) { + // no more data + break; + } + + outputStream.Write(buffer, 0, bytesRead); + } + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterAttribute.cs new file mode 100644 index 00000000000..1cda086a21c --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterAttribute.cs @@ -0,0 +1,35 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Web.Mvc.Resources; + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] + public abstract class FilterAttribute : Attribute { + + private int _order = -1; + + public int Order { + get { + return _order; + } + set { + if (value < -1) { + throw new ArgumentOutOfRangeException("value", + MvcResources.FilterAttribute_OrderOutOfRange); + } + _order = value; + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterInfo.cs new file mode 100644 index 00000000000..031ffe34d97 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FilterInfo.cs @@ -0,0 +1,48 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System.Collections.Generic; + + public class FilterInfo { + + private List _actionFilters = new List(); + private List _authorizationFilters = new List(); + private List _exceptionFilters = new List(); + private List _resultFilters = new List(); + + public IList ActionFilters { + get { + return _actionFilters; + } + } + + public IList AuthorizationFilters { + get { + return _authorizationFilters; + } + } + + public IList ExceptionFilters { + get { + return _exceptionFilters; + } + } + + public IList ResultFilters { + get { + return _resultFilters; + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormCollection.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormCollection.cs new file mode 100644 index 00000000000..3736bae1d4b --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormCollection.cs @@ -0,0 +1,89 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Specialized; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Web.Mvc.Resources; + + [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable", + Justification = "It is not anticipated that users will need to serialize this type.")] + [SuppressMessage("Microsoft.Design", "CA1035:ICollectionImplementationsHaveStronglyTypedMembers", + Justification = "It is not anticipated that users will call FormCollection.CopyTo().")] + [FormCollectionBinder] + public sealed class FormCollection : NameValueCollection, IValueProvider { + + public FormCollection() { + } + + public FormCollection(NameValueCollection collection) { + if (collection == null) { + throw new ArgumentNullException("collection"); + } + + Add(collection); + } + + public ValueProviderResult GetValue(string name) { + if (name == null) { + throw new ArgumentNullException("name"); + } + + string[] rawValue = GetValues(name); + if (rawValue == null) { + return null; + } + + string attemptedValue = this[name]; + return new ValueProviderResult(rawValue, attemptedValue, CultureInfo.CurrentCulture); + } + + public IValueProvider ToValueProvider() { + return this; + } + + #region IValueProvider Members + bool IValueProvider.ContainsPrefix(string prefix) { + return ValueProviderUtil.CollectionContainsPrefix(AllKeys, prefix); + } + + ValueProviderResult IValueProvider.GetValue(string key) { + return GetValue(key); + } + #endregion + + private sealed class FormCollectionBinderAttribute : CustomModelBinderAttribute { + + // since the FormCollectionModelBinder.BindModel() method is thread-safe, we only need to keep + // a single instance of the binder around + private static readonly FormCollectionModelBinder _binder = new FormCollectionModelBinder(); + + public override IModelBinder GetBinder() { + return _binder; + } + + // this class is used for generating a FormCollection object + private sealed class FormCollectionModelBinder : IModelBinder { + public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + + return new FormCollection(controllerContext.HttpContext.Request.Form); + } + } + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormContext.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormContext.cs new file mode 100644 index 00000000000..a2c6ec83f6a --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormContext.cs @@ -0,0 +1,84 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Web.Script.Serialization; + + public class FormContext { + + private readonly Dictionary _fieldValidators = new Dictionary(); + + public IDictionary FieldValidators { + get { + return _fieldValidators; + } + } + + public string FormId { + get; + set; + } + + public bool ReplaceValidationSummary { + get; + set; + } + + public string ValidationSummaryId { + get; + set; + } + + [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", + Justification = "Performs a potentially time-consuming conversion.")] + public string GetJsonValidationMetadata() { + JavaScriptSerializer serializer = new JavaScriptSerializer(); + + SortedDictionary dict = new SortedDictionary() { + { "Fields", FieldValidators.Values }, + { "FormId", FormId } + }; + if (!String.IsNullOrEmpty(ValidationSummaryId)) { + dict["ValidationSummaryId"] = ValidationSummaryId; + } + dict["ReplaceValidationSummary"] = ReplaceValidationSummary; + + return serializer.Serialize(dict); + } + + public FieldValidationMetadata GetValidationMetadataForField(string fieldName) { + return GetValidationMetadataForField(fieldName, false /* createIfNotFound */); + } + + public FieldValidationMetadata GetValidationMetadataForField(string fieldName, bool createIfNotFound) { + if (String.IsNullOrEmpty(fieldName)) { + throw Error.ParameterCannotBeNullOrEmpty("fieldName"); + } + + FieldValidationMetadata metadata; + if (!FieldValidators.TryGetValue(fieldName, out metadata)) { + if (createIfNotFound) { + metadata = new FieldValidationMetadata() { + FieldName = fieldName + }; + FieldValidators[fieldName] = metadata; + } + } + return metadata; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormMethod.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormMethod.cs new file mode 100644 index 00000000000..0c9ebc89432 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormMethod.cs @@ -0,0 +1,18 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + public enum FormMethod { + Get, + Post + } +} \ No newline at end of file diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProvider.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProvider.cs new file mode 100644 index 00000000000..73497341ec3 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProvider.cs @@ -0,0 +1,25 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Collections.Specialized; + using System.Globalization; + + public sealed class FormValueProvider : NameValueCollectionValueProvider { + + public FormValueProvider(ControllerContext controllerContext) + : base(controllerContext.HttpContext.Request.Form, CultureInfo.CurrentCulture) { + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProviderFactory.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProviderFactory.cs new file mode 100644 index 00000000000..686f3abe40d --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/FormValueProviderFactory.cs @@ -0,0 +1,27 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + + public sealed class FormValueProviderFactory : ValueProviderFactory { + + public override IValueProvider GetValueProvider(ControllerContext controllerContext) { + if (controllerContext == null) { + throw new ArgumentNullException("controllerContext"); + } + + return new FormValueProvider(controllerContext); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorAttribute.cs new file mode 100644 index 00000000000..99b40cfecf8 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorAttribute.cs @@ -0,0 +1,119 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Web; + using System.Web.Mvc.Resources; + + [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", + Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] + public class HandleErrorAttribute : FilterAttribute, IExceptionFilter { + + private const string _defaultView = "Error"; + + private readonly object _typeId = new object(); + + private Type _exceptionType = typeof(Exception); + private string _master; + private string _view; + + public Type ExceptionType { + get { + return _exceptionType; + } + set { + if (value == null) { + throw new ArgumentNullException("value"); + } + if (!typeof(Exception).IsAssignableFrom(value)) { + throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, + MvcResources.ExceptionViewAttribute_NonExceptionType, value.FullName)); + } + + _exceptionType = value; + } + } + + public string Master { + get { + return _master ?? String.Empty; + } + set { + _master = value; + } + } + + public override object TypeId { + get { + return _typeId; + } + } + + public string View { + get { + return (!String.IsNullOrEmpty(_view)) ? _view : _defaultView; + } + set { + _view = value; + } + } + + public virtual void OnException(ExceptionContext filterContext) { + if (filterContext == null) { + throw new ArgumentNullException("filterContext"); + } + if (filterContext.IsChildAction) { + return; + } + + // If custom errors are disabled, we need to let the normal ASP.NET exception handler + // execute so that the user can see useful debugging information. + if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) { + return; + } + + Exception exception = filterContext.Exception; + + // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method), + // ignore it. + if (new HttpException(null, exception).GetHttpCode() != 500) { + return; + } + + if (!ExceptionType.IsInstanceOfType(exception)) { + return; + } + + string controllerName = (string)filterContext.RouteData.Values["controller"]; + string actionName = (string)filterContext.RouteData.Values["action"]; + HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); + filterContext.Result = new ViewResult { + ViewName = View, + MasterName = Master, + ViewData = new ViewDataDictionary(model), + TempData = filterContext.Controller.TempData + }; + filterContext.ExceptionHandled = true; + filterContext.HttpContext.Response.Clear(); + filterContext.HttpContext.Response.StatusCode = 500; + + // Certain versions of IIS will sometimes use their own error page when + // they detect a server error. Setting this property indicates that we + // want it to try to render ASP.NET MVC's error page instead. + filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; + } + } +} \ No newline at end of file diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorInfo.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorInfo.cs new file mode 100644 index 00000000000..d02f911de5e --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HandleErrorInfo.cs @@ -0,0 +1,51 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + using System.Web.Mvc.Resources; + + public class HandleErrorInfo { + + public HandleErrorInfo(Exception exception, string controllerName, string actionName) { + if (exception == null) { + throw new ArgumentNullException("exception"); + } + if (String.IsNullOrEmpty(controllerName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "controllerName"); + } + if (string.IsNullOrEmpty(actionName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName"); + } + + Exception = exception; + ControllerName = controllerName; + ActionName = actionName; + } + + public string ActionName { + get; + private set; + } + + public string ControllerName { + get; + private set; + } + + public Exception Exception { + get; + private set; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/HiddenInputAttribute.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HiddenInputAttribute.cs new file mode 100644 index 00000000000..b1778d4cf73 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/HiddenInputAttribute.cs @@ -0,0 +1,24 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc { + using System; + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + public sealed class HiddenInputAttribute : Attribute { + public HiddenInputAttribute() { + DisplayValue = true; + } + + public bool DisplayValue { get; set; } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ChildActionExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ChildActionExtensions.cs new file mode 100644 index 00000000000..cd22769a6ac --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/ChildActionExtensions.cs @@ -0,0 +1,150 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System.Collections.Generic; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public static class ChildActionExtensions { + + // Action + + public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName) { + return Action(htmlHelper, actionName, null /* controllerName */, null /* routeValues */); + } + + public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, object routeValues) { + return Action(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues)); + } + + public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) { + return Action(htmlHelper, actionName, null /* controllerName */, routeValues); + } + + public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName) { + return Action(htmlHelper, actionName, controllerName, null /* routeValues */); + } + + public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) { + return Action(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues)); + } + + public static MvcHtmlString Action(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) { + StringWriter writer = new StringWriter(CultureInfo.CurrentCulture); + ActionHelper(htmlHelper, actionName, controllerName, routeValues, writer); + return MvcHtmlString.Create(writer.ToString()); + } + + // RenderAction + + public static void RenderAction(this HtmlHelper htmlHelper, string actionName) { + RenderAction(htmlHelper, actionName, null /* controllerName */, null /* routeValues */); + } + + public static void RenderAction(this HtmlHelper htmlHelper, string actionName, object routeValues) { + RenderAction(htmlHelper, actionName, null /* controllerName */, new RouteValueDictionary(routeValues)); + } + + public static void RenderAction(this HtmlHelper htmlHelper, string actionName, RouteValueDictionary routeValues) { + RenderAction(htmlHelper, actionName, null /* controllerName */, routeValues); + } + + public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName) { + RenderAction(htmlHelper, actionName, controllerName, null /* routeValues */); + } + + public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) { + RenderAction(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues)); + } + + public static void RenderAction(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) { + ActionHelper(htmlHelper, actionName, controllerName, routeValues, htmlHelper.ViewContext.Writer); + } + + // Helpers + + internal static void ActionHelper(HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, TextWriter textWriter) { + if (htmlHelper == null) { + throw new ArgumentNullException("htmlHelper"); + } + if (String.IsNullOrEmpty(actionName)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName"); + } + + routeValues = MergeDictionaries(routeValues, htmlHelper.ViewContext.RouteData.Values); + routeValues["action"] = actionName; + if (!String.IsNullOrEmpty(controllerName)) { + routeValues["controller"] = controllerName; + } + + bool usingAreas; + VirtualPathData vpd = htmlHelper.RouteCollection.GetVirtualPathForArea(htmlHelper.ViewContext.RequestContext, null /* name */, routeValues, out usingAreas); + if (vpd == null) { + throw new InvalidOperationException(MvcResources.Common_NoRouteMatched); + } + + if (usingAreas) { + routeValues.Remove("area"); + } + RouteData routeData = CreateRouteData(vpd.Route, routeValues, vpd.DataTokens, htmlHelper.ViewContext); + HttpContextBase httpContext = htmlHelper.ViewContext.HttpContext; + RequestContext requestContext = new RequestContext(httpContext, routeData); + ChildActionMvcHandler handler = new ChildActionMvcHandler(requestContext); + httpContext.Server.Execute(HttpHandlerUtil.WrapForServerExecute(handler), textWriter, true /* preserveForm */); + } + + private static RouteData CreateRouteData(RouteBase route, RouteValueDictionary routeValues, RouteValueDictionary dataTokens, ViewContext parentViewContext) { + RouteData routeData = new RouteData(); + + foreach (KeyValuePair kvp in routeValues) { + routeData.Values.Add(kvp.Key, kvp.Value); + } + + foreach (KeyValuePair kvp in dataTokens) { + routeData.DataTokens.Add(kvp.Key, kvp.Value); + } + + routeData.Route = route; + routeData.DataTokens[ControllerContext.PARENT_ACTION_VIEWCONTEXT] = parentViewContext; + return routeData; + } + + private static RouteValueDictionary MergeDictionaries(params RouteValueDictionary[] dictionaries) { + // Merge existing route values with the user provided values + var result = new RouteValueDictionary(); + + foreach (RouteValueDictionary dictionary in dictionaries.Where(d => d != null)) { + foreach (KeyValuePair kvp in dictionary) { + if (!result.ContainsKey(kvp.Key)) { + result.Add(kvp.Key, kvp.Value); + } + } + } + + return result; + } + + internal class ChildActionMvcHandler : MvcHandler { + public ChildActionMvcHandler(RequestContext context) + : base(context) { + } + + protected internal override void AddVersionHeader(HttpContextBase httpContext) { + // No version header for child actions + } + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultDisplayTemplates.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultDisplayTemplates.cs new file mode 100644 index 00000000000..7edcb3be4a0 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultDisplayTemplates.cs @@ -0,0 +1,206 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.Collections; + using System.Collections.Generic; + using System.Data; + using System.Globalization; + using System.Linq; + using System.Text; + using System.Web.Mvc.Resources; + using System.Web.UI.WebControls; + + internal static class DefaultDisplayTemplates { + internal static string BooleanTemplate(HtmlHelper html) { + bool? value = null; + if (html.ViewContext.ViewData.Model != null) { + value = Convert.ToBoolean(html.ViewContext.ViewData.Model, CultureInfo.InvariantCulture); + } + + return html.ViewContext.ViewData.ModelMetadata.IsNullableValueType + ? BooleanTemplateDropDownList(value) + : BooleanTemplateCheckbox(value ?? false); + } + + private static string BooleanTemplateCheckbox(bool value) { + TagBuilder inputTag = new TagBuilder("input"); + inputTag.AddCssClass("check-box"); + inputTag.Attributes["disabled"] = "disabled"; + inputTag.Attributes["type"] = "checkbox"; + if (value) { + inputTag.Attributes["checked"] = "checked"; + } + + return inputTag.ToString(TagRenderMode.SelfClosing); + } + + private static string BooleanTemplateDropDownList(bool? value) { + StringBuilder builder = new StringBuilder(); + + TagBuilder selectTag = new TagBuilder("select"); + selectTag.AddCssClass("list-box"); + selectTag.AddCssClass("tri-state"); + selectTag.Attributes["disabled"] = "disabled"; + builder.Append(selectTag.ToString(TagRenderMode.StartTag)); + + foreach (SelectListItem item in DefaultEditorTemplates.TriStateValues(value)) { + builder.Append(SelectExtensions.ListItemToOption(item)); + } + + builder.Append(selectTag.ToString(TagRenderMode.EndTag)); + return builder.ToString(); + } + + internal static string CollectionTemplate(HtmlHelper html) { + return CollectionTemplate(html, TemplateHelpers.TemplateHelper); + } + + internal static string CollectionTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) { + object model = html.ViewContext.ViewData.ModelMetadata.Model; + if (model == null) { + return String.Empty; + } + + IEnumerable collection = model as IEnumerable; + if (collection == null) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.Templates_TypeMustImplementIEnumerable, + model.GetType().FullName + ) + ); + } + + Type typeInCollection = typeof(string); + Type genericEnumerableType = TypeHelpers.ExtractGenericInterface(collection.GetType(), typeof(IEnumerable<>)); + if (genericEnumerableType != null) { + typeInCollection = genericEnumerableType.GetGenericArguments()[0]; + } + bool typeInCollectionIsNullableValueType = TypeHelpers.IsNullableValueType(typeInCollection); + + string oldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix; + + try { + html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty; + + string fieldNameBase = oldPrefix; + StringBuilder result = new StringBuilder(); + int index = 0; + + foreach (object item in collection) { + Type itemType = typeInCollection; + if (item != null && !typeInCollectionIsNullableValueType) { + itemType = item.GetType(); + } + ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => item, itemType); + string fieldName = String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++); + string output = templateHelper(html, metadata, fieldName, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */); + result.Append(output); + } + + return result.ToString(); + } + finally { + html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix; + } + } + + internal static string DecimalTemplate(HtmlHelper html) { + if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model) { + html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model); + } + + return StringTemplate(html); + } + + internal static string EmailAddressTemplate(HtmlHelper html) { + return String.Format(CultureInfo.InvariantCulture, + "{1}", + html.AttributeEncode(html.ViewContext.ViewData.Model), + html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue)); + } + + internal static string HiddenInputTemplate(HtmlHelper html) { + if (html.ViewContext.ViewData.ModelMetadata.HideSurroundingHtml) { + return String.Empty; + } + return StringTemplate(html); + } + + internal static string HtmlTemplate(HtmlHelper html) { + return html.ViewContext.ViewData.TemplateInfo.FormattedModelValue.ToString(); + } + + internal static string ObjectTemplate(HtmlHelper html) { + return ObjectTemplate(html, TemplateHelpers.TemplateHelper); + } + + internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) { + ViewDataDictionary viewData = html.ViewContext.ViewData; + TemplateInfo templateInfo = viewData.TemplateInfo; + ModelMetadata modelMetadata = viewData.ModelMetadata; + StringBuilder builder = new StringBuilder(); + + if (modelMetadata.Model == null) { // DDB #225237 + return modelMetadata.NullDisplayText; + } + + if (templateInfo.TemplateDepth > 1) { // DDB #224751 + return modelMetadata.SimpleDisplayText; + } + + foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) { + if (!propertyMetadata.HideSurroundingHtml) { + string label = propertyMetadata.GetDisplayName(); + if (!String.IsNullOrEmpty(label)) { + builder.AppendFormat(CultureInfo.InvariantCulture, "
{0}
", label); + builder.AppendLine(); + } + + builder.Append("
"); + } + + builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */)); + + if (!propertyMetadata.HideSurroundingHtml) { + builder.AppendLine("
"); + } + } + + return builder.ToString(); + } + + private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo) { + return + metadata.ShowForDisplay +#if false + && metadata.ModelType != typeof(EntityState) +#endif + && !metadata.IsComplexType + && !templateInfo.Visited(metadata); + } + + internal static string StringTemplate(HtmlHelper html) { + return html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue); + } + + internal static string UrlTemplate(HtmlHelper html) { + return String.Format(CultureInfo.InvariantCulture, + "{1}", + html.AttributeEncode(html.ViewContext.ViewData.Model), + html.Encode(html.ViewContext.ViewData.TemplateInfo.FormattedModelValue)); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultEditorTemplates.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultEditorTemplates.cs new file mode 100644 index 00000000000..a478dbc5b03 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DefaultEditorTemplates.cs @@ -0,0 +1,215 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.Collections; + using System.Collections.Generic; + using System.Data; + using System.Data.Linq; + using System.Globalization; + using System.Linq; + using System.Text; + using System.Web.Mvc.Resources; + using System.Web.UI.WebControls; + + internal static class DefaultEditorTemplates { + internal static string BooleanTemplate(HtmlHelper html) { + bool? value = null; + if (html.ViewContext.ViewData.Model != null) { + value = Convert.ToBoolean(html.ViewContext.ViewData.Model, CultureInfo.InvariantCulture); + } + + return html.ViewContext.ViewData.ModelMetadata.IsNullableValueType + ? BooleanTemplateDropDownList(html, value) + : BooleanTemplateCheckbox(html, value ?? false); + } + + private static string BooleanTemplateCheckbox(HtmlHelper html, bool value) { + return html.CheckBox(String.Empty, value, CreateHtmlAttributes("check-box")).ToHtmlString(); + } + + private static string BooleanTemplateDropDownList(HtmlHelper html, bool? value) { + return html.DropDownList(String.Empty, TriStateValues(value), CreateHtmlAttributes("list-box tri-state")).ToHtmlString(); + + } + + internal static string CollectionTemplate(HtmlHelper html) { + return CollectionTemplate(html, TemplateHelpers.TemplateHelper); + } + + internal static string CollectionTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) { + object model = html.ViewContext.ViewData.ModelMetadata.Model; + if (model == null) { + return String.Empty; + } + + IEnumerable collection = model as IEnumerable; + if (collection == null) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentCulture, + MvcResources.Templates_TypeMustImplementIEnumerable, + model.GetType().FullName + ) + ); + } + + Type typeInCollection = typeof(string); + Type genericEnumerableType = TypeHelpers.ExtractGenericInterface(collection.GetType(), typeof(IEnumerable<>)); + if (genericEnumerableType != null) { + typeInCollection = genericEnumerableType.GetGenericArguments()[0]; + } + bool typeInCollectionIsNullableValueType = TypeHelpers.IsNullableValueType(typeInCollection); + + string oldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix; + + try { + html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty; + + string fieldNameBase = oldPrefix; + StringBuilder result = new StringBuilder(); + int index = 0; + + foreach (object item in collection) { + Type itemType = typeInCollection; + if (item != null && !typeInCollectionIsNullableValueType) { + itemType = item.GetType(); + } + ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => item, itemType); + string fieldName = String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++); + string output = templateHelper(html, metadata, fieldName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */); + result.Append(output); + } + + return result.ToString(); + } + finally { + html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix; + } + } + + internal static string DecimalTemplate(HtmlHelper html) { + if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model) { + html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model); + } + + return StringTemplate(html); + } + + internal static string HiddenInputTemplate(HtmlHelper html) { + string result; + + if (html.ViewContext.ViewData.ModelMetadata.HideSurroundingHtml) { + result = String.Empty; + } + else { + result = DefaultDisplayTemplates.StringTemplate(html); + } + + object model = html.ViewContext.ViewData.Model; + + Binary modelAsBinary = model as Binary; + if (modelAsBinary != null) { + model = Convert.ToBase64String(modelAsBinary.ToArray()); + } + else { + byte[] modelAsByteArray = model as byte[]; + if (modelAsByteArray != null) { + model = Convert.ToBase64String(modelAsByteArray); + } + } + + result += html.Hidden(String.Empty, model).ToHtmlString(); + return result; + } + + internal static string MultilineTextTemplate(HtmlHelper html) { + return html.TextArea(String.Empty, + html.ViewContext.ViewData.TemplateInfo.FormattedModelValue.ToString(), + 0 /* rows */, 0 /* columns */, + CreateHtmlAttributes("text-box multi-line")).ToHtmlString(); + } + + private static IDictionary CreateHtmlAttributes(string className) { + return new Dictionary() { + { "class", className } + }; + } + + internal static string ObjectTemplate(HtmlHelper html) { + return ObjectTemplate(html, TemplateHelpers.TemplateHelper); + } + + internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) { + ViewDataDictionary viewData = html.ViewContext.ViewData; + TemplateInfo templateInfo = viewData.TemplateInfo; + ModelMetadata modelMetadata = viewData.ModelMetadata; + StringBuilder builder = new StringBuilder(); + + if (templateInfo.TemplateDepth > 1) { // DDB #224751 + return modelMetadata.Model == null ? modelMetadata.NullDisplayText : modelMetadata.SimpleDisplayText; + } + + foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) { + if (!propertyMetadata.HideSurroundingHtml) { + string label = LabelExtensions.LabelHelper(html, propertyMetadata, propertyMetadata.PropertyName).ToHtmlString(); + if (!String.IsNullOrEmpty(label)) { + builder.AppendFormat(CultureInfo.InvariantCulture, "
{0}
\r\n", label); + } + + builder.Append("
"); + } + + builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */)); + + if (!propertyMetadata.HideSurroundingHtml) { + builder.Append(" "); + builder.Append(html.ValidationMessage(propertyMetadata.PropertyName)); + builder.Append("
\r\n"); + } + } + + return builder.ToString(); + } + + internal static string PasswordTemplate(HtmlHelper html) { + return html.Password(String.Empty, + html.ViewContext.ViewData.TemplateInfo.FormattedModelValue, + CreateHtmlAttributes("text-box single-line password")).ToHtmlString(); + } + + private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo) { + return + metadata.ShowForEdit +#if false + && metadata.ModelType != typeof(EntityState) +#endif + && !metadata.IsComplexType + && !templateInfo.Visited(metadata); + } + + internal static string StringTemplate(HtmlHelper html) { + return html.TextBox(String.Empty, + html.ViewContext.ViewData.TemplateInfo.FormattedModelValue, + CreateHtmlAttributes("text-box single-line")).ToHtmlString(); + } + + internal static List TriStateValues(bool? value) { + return new List { + new SelectListItem { Text = MvcResources.Common_TriState_NotSet, Value = String.Empty, Selected = !value.HasValue }, + new SelectListItem { Text = MvcResources.Common_TriState_True, Value = "true", Selected = value.HasValue && value.Value }, + new SelectListItem { Text = MvcResources.Common_TriState_False, Value = "false", Selected = value.HasValue && !value.Value }, + }; + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayExtensions.cs new file mode 100644 index 00000000000..372caf02529 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayExtensions.cs @@ -0,0 +1,102 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System.Linq.Expressions; + using System.Web.UI.WebControls; + + public static class DisplayExtensions { + public static MvcHtmlString Display(this HtmlHelper html, string expression) { + return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */); + } + + public static MvcHtmlString Display(this HtmlHelper html, string expression, object additionalViewData) { + return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData); + } + + public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName) { + return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */); + } + + public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, object additionalViewData) { + return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData); + } + + public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, string htmlFieldName) { + return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, null /* additionalViewData */); + } + + public static MvcHtmlString Display(this HtmlHelper html, string expression, string templateName, string htmlFieldName, object additionalViewData) { + return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, additionalViewData); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DisplayFor(this HtmlHelper html, Expression> expression) { + return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DisplayFor(this HtmlHelper html, Expression> expression, object additionalViewData) { + return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DisplayFor(this HtmlHelper html, Expression> expression, string templateName) { + return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DisplayFor(this HtmlHelper html, Expression> expression, string templateName, object additionalViewData) { + return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.ReadOnly, additionalViewData); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DisplayFor(this HtmlHelper html, Expression> expression, string templateName, string htmlFieldName) { + return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, null /* additionalViewData */); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DisplayFor(this HtmlHelper html, Expression> expression, string templateName, string htmlFieldName, object additionalViewData) { + return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.ReadOnly, additionalViewData); + } + + public static MvcHtmlString DisplayForModel(this HtmlHelper html) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.ReadOnly, null /* additionalViewData */)); + } + + public static MvcHtmlString DisplayForModel(this HtmlHelper html, object additionalViewData) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.ReadOnly, additionalViewData)); + } + + public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.ReadOnly, null /* additionalViewData */)); + } + + public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, object additionalViewData) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.ReadOnly, additionalViewData )); + } + + public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, string htmlFieldName) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.ReadOnly, null /* additionalViewData */)); + } + + public static MvcHtmlString DisplayForModel(this HtmlHelper html, string templateName, string htmlFieldName, object additionalViewData) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.ReadOnly, additionalViewData)); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayTextExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayTextExtensions.cs new file mode 100644 index 00000000000..272ab0e74e6 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/DisplayTextExtensions.cs @@ -0,0 +1,32 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.Linq.Expressions; + + public static class DisplayTextExtensions { + public static MvcHtmlString DisplayText(this HtmlHelper html, string name) { + return DisplayTextHelper(ModelMetadata.FromStringExpression(name, html.ViewContext.ViewData)); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DisplayTextFor(this HtmlHelper html, Expression> expression) { + return DisplayTextHelper(ModelMetadata.FromLambdaExpression(expression, html.ViewData)); + } + + private static MvcHtmlString DisplayTextHelper(ModelMetadata metadata) { + return MvcHtmlString.Create(metadata.SimpleDisplayText); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/EditorExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/EditorExtensions.cs new file mode 100644 index 00000000000..b022f5c3665 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/EditorExtensions.cs @@ -0,0 +1,103 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.Linq.Expressions; + using System.Web.UI.WebControls; + + public static class EditorExtensions { + public static MvcHtmlString Editor(this HtmlHelper html, string expression) { + return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */); + } + + public static MvcHtmlString Editor(this HtmlHelper html, string expression, object additionalViewData) { + return TemplateHelpers.Template(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData); + } + + public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName) { + return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */); + } + + public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, object additionalViewData) { + return TemplateHelpers.Template(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData); + } + + public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, string htmlFieldName) { + return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, null /* additionalViewData */); + } + + public static MvcHtmlString Editor(this HtmlHelper html, string expression, string templateName, string htmlFieldName, object additionalViewData) { + return TemplateHelpers.Template(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, additionalViewData); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString EditorFor(this HtmlHelper html, Expression> expression) { + return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString EditorFor(this HtmlHelper html, Expression> expression, object additionalViewData) { + return TemplateHelpers.TemplateFor(html, expression, null /* templateName */, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString EditorFor(this HtmlHelper html, Expression> expression, string templateName) { + return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, null /* additionalViewData */); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString EditorFor(this HtmlHelper html, Expression> expression, string templateName, object additionalViewData) { + return TemplateHelpers.TemplateFor(html, expression, templateName, null /* htmlFieldName */, DataBoundControlMode.Edit, additionalViewData); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString EditorFor(this HtmlHelper html, Expression> expression, string templateName, string htmlFieldName) { + return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, null /* additionalViewData */); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", + Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString EditorFor(this HtmlHelper html, Expression> expression, string templateName, string htmlFieldName, object additionalViewData) { + return TemplateHelpers.TemplateFor(html, expression, templateName, htmlFieldName, DataBoundControlMode.Edit, additionalViewData); + } + + public static MvcHtmlString EditorForModel(this HtmlHelper html) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */)); + } + + public static MvcHtmlString EditorForModel(this HtmlHelper html, object additionalViewData) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, null /* templateName */, DataBoundControlMode.Edit, additionalViewData)); + } + + public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.Edit, null /* additionalViewData */)); + } + + public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, object additionalViewData) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, String.Empty, templateName, DataBoundControlMode.Edit, additionalViewData)); + } + + public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, string htmlFieldName) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.Edit, null /* additionalViewData */)); + } + + public static MvcHtmlString EditorForModel(this HtmlHelper html, string templateName, string htmlFieldName, object additionalViewData) { + return MvcHtmlString.Create(TemplateHelpers.TemplateHelper(html, html.ViewData.ModelMetadata, htmlFieldName, templateName, DataBoundControlMode.Edit, additionalViewData)); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/FormExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/FormExtensions.cs new file mode 100644 index 00000000000..b5df159c6ac --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/FormExtensions.cs @@ -0,0 +1,152 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System.Collections.Generic; + using System.Web.Routing; + using System.Globalization; + + public static class FormExtensions { + public static MvcForm BeginForm(this HtmlHelper htmlHelper) { + // generates
...
+ string formAction = htmlHelper.ViewContext.HttpContext.Request.RawUrl; + return FormHelper(htmlHelper, formAction, FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, object routeValues) { + return BeginForm(htmlHelper, null, null, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, RouteValueDictionary routeValues) { + return BeginForm(htmlHelper, null, null, routeValues, FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName) { + return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues) { + return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues) { + return BeginForm(htmlHelper, actionName, controllerName, routeValues, FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method) { + return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method) { + return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method) { + return BeginForm(htmlHelper, actionName, controllerName, routeValues, method, new RouteValueDictionary()); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, object htmlAttributes) { + return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, FormMethod method, IDictionary htmlAttributes) { + return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(), method, htmlAttributes); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, object routeValues, FormMethod method, object htmlAttributes) { + return BeginForm(htmlHelper, actionName, controllerName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcForm BeginForm(this HtmlHelper htmlHelper, string actionName, string controllerName, RouteValueDictionary routeValues, FormMethod method, IDictionary htmlAttributes) { + string formAction = UrlHelper.GenerateUrl(null /* routeName */, actionName, controllerName, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true /* includeImplicitMvcValues */); + return FormHelper(htmlHelper, formAction, method, htmlAttributes); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, object routeValues) { + return BeginRouteForm(htmlHelper, null /* routeName */, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, RouteValueDictionary routeValues) { + return BeginRouteForm(htmlHelper, null /* routeName */, routeValues, FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName) { + return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues) { + return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues) { + return BeginRouteForm(htmlHelper, routeName, routeValues, FormMethod.Post, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method) { + return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues, FormMethod method) { + return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues, FormMethod method) { + return BeginRouteForm(htmlHelper, routeName, routeValues, method, new RouteValueDictionary()); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method, object htmlAttributes) { + return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, FormMethod method, IDictionary htmlAttributes) { + return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(), method, htmlAttributes); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, object routeValues, FormMethod method, object htmlAttributes) { + return BeginRouteForm(htmlHelper, routeName, new RouteValueDictionary(routeValues), method, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcForm BeginRouteForm(this HtmlHelper htmlHelper, string routeName, RouteValueDictionary routeValues, FormMethod method, IDictionary htmlAttributes) { + string formAction = UrlHelper.GenerateUrl(routeName, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, false /* includeImplicitMvcValues */); + return FormHelper(htmlHelper, formAction, method, htmlAttributes); + } + + public static void EndForm(this HtmlHelper htmlHelper) { + htmlHelper.ViewContext.Writer.Write(""); + htmlHelper.ViewContext.OutputClientValidation(); + } + + private static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary htmlAttributes) { + TagBuilder tagBuilder = new TagBuilder("form"); + tagBuilder.MergeAttributes(htmlAttributes); + // action is implicitly generated, so htmlAttributes take precedence. + tagBuilder.MergeAttribute("action", formAction); + // method is an explicit parameter, so it takes precedence over the htmlAttributes. + tagBuilder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true); + + if (htmlHelper.ViewContext.ClientValidationEnabled) { + // forms must have an ID for client validation + tagBuilder.GenerateId(htmlHelper.ViewContext.FormIdGenerator()); + } + + htmlHelper.ViewContext.Writer.Write(tagBuilder.ToString(TagRenderMode.StartTag)); + MvcForm theForm = new MvcForm(htmlHelper.ViewContext); + + if (htmlHelper.ViewContext.ClientValidationEnabled) { + htmlHelper.ViewContext.FormContext.FormId = tagBuilder.Attributes["id"]; + } + + return theForm; + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/InputExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/InputExtensions.cs new file mode 100644 index 00000000000..5d56f83bb65 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/InputExtensions.cs @@ -0,0 +1,398 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.Collections.Generic; + using System.Data.Linq; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Linq.Expressions; + using System.Text; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public static class InputExtensions { + // CheckBox + + public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name) { + return CheckBox(htmlHelper, name, (object)null /* htmlAttributes */); + } + + public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked) { + return CheckBox(htmlHelper, name, isChecked, (object)null /* htmlAttributes */); + } + + public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, object htmlAttributes) { + return CheckBox(htmlHelper, name, isChecked, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, object htmlAttributes) { + return CheckBox(htmlHelper, name, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, IDictionary htmlAttributes) { + return CheckBoxHelper(htmlHelper, name, null /* isChecked */, htmlAttributes); + } + + public static MvcHtmlString CheckBox(this HtmlHelper htmlHelper, string name, bool isChecked, IDictionary htmlAttributes) { + return CheckBoxHelper(htmlHelper, name, isChecked, htmlAttributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString CheckBoxFor(this HtmlHelper htmlHelper, Expression> expression) { + return CheckBoxFor(htmlHelper, expression, null /* htmlAttributes */); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString CheckBoxFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes) { + return CheckBoxFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString CheckBoxFor(this HtmlHelper htmlHelper, Expression> expression, IDictionary htmlAttributes) { + if (expression == null) { + throw new ArgumentNullException("expression"); + } + + ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); + bool? isChecked = null; + if (metadata.Model != null) { + bool modelChecked; + if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked)) { + isChecked = modelChecked; + } + } + + return CheckBoxHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), isChecked, htmlAttributes); + } + + private static MvcHtmlString CheckBoxHelper(HtmlHelper htmlHelper, string name, bool? isChecked, IDictionary htmlAttributes) { + RouteValueDictionary attributes = + htmlAttributes == null ? new RouteValueDictionary() + : new RouteValueDictionary(htmlAttributes); + + bool explicitValue = isChecked.HasValue; + if (explicitValue) { + attributes.Remove("checked"); // Explicit value must override dictionary + } + + return InputHelper(htmlHelper, InputType.CheckBox, name, "true", !explicitValue /* useViewData */, isChecked ?? false, true /* setId */, false /* isExplicitValue */, attributes); + } + + // Hidden + + public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name) { + return Hidden(htmlHelper, name, null /* value */, null /* htmlAttributes */); + } + + public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value) { + return Hidden(htmlHelper, name, value, null /* hmtlAttributes */); + } + + public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) { + return Hidden(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString Hidden(this HtmlHelper htmlHelper, string name, object value, IDictionary htmlAttributes) { + return HiddenHelper(htmlHelper, + value, + value == null /* useViewData */, + name, + htmlAttributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString HiddenFor(this HtmlHelper htmlHelper, Expression> expression) { + return HiddenFor(htmlHelper, expression, (IDictionary)null); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString HiddenFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes) { + return HiddenFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString HiddenFor(this HtmlHelper htmlHelper, Expression> expression, IDictionary htmlAttributes) { + return HiddenHelper(htmlHelper, + ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model, + false, + ExpressionHelper.GetExpressionText(expression), + htmlAttributes); + } + + private static MvcHtmlString HiddenHelper(HtmlHelper htmlHelper, object value, bool useViewData, string expression, IDictionary htmlAttributes) { + Binary binaryValue = value as Binary; + if (binaryValue != null) { + value = binaryValue.ToArray(); + } + + byte[] byteArrayValue = value as byte[]; + if (byteArrayValue != null) { + value = Convert.ToBase64String(byteArrayValue); + } + + return InputHelper(htmlHelper, InputType.Hidden, expression, value, useViewData, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes); + } + + // Password + + public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name) { + return Password(htmlHelper, name, null /* value */); + } + + public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value) { + return Password(htmlHelper, name, value, null /* htmlAttributes */); + } + + public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) { + return Password(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString Password(this HtmlHelper htmlHelper, string name, object value, IDictionary htmlAttributes) { + return PasswordHelper(htmlHelper, name, value, htmlAttributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString PasswordFor(this HtmlHelper htmlHelper, Expression> expression) { + return PasswordFor(htmlHelper, expression, null /* htmlAttributes */); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString PasswordFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes) { + return PasswordFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString PasswordFor(this HtmlHelper htmlHelper, Expression> expression, IDictionary htmlAttributes) { + if (expression == null) { + throw new ArgumentNullException("expression"); + } + + return PasswordHelper(htmlHelper, + ExpressionHelper.GetExpressionText(expression), + null /* value */, + htmlAttributes); + } + + private static MvcHtmlString PasswordHelper(HtmlHelper htmlHelper, string name, object value, IDictionary htmlAttributes) { + return InputHelper(htmlHelper, InputType.Password, name, value, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes); + } + + // RadioButton + + public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value) { + return RadioButton(htmlHelper, name, value, (object)null /* htmlAttributes */); + } + + public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) { + return RadioButton(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, IDictionary htmlAttributes) { + // Determine whether or not to render the checked attribute based on the contents of ViewData. + string valueString = Convert.ToString(value, CultureInfo.CurrentCulture); + bool isChecked = (!String.IsNullOrEmpty(name)) && (String.Equals(htmlHelper.EvalString(name), valueString, StringComparison.OrdinalIgnoreCase)); + // checked attributes is implicit, so we need to ensure that the dictionary takes precedence. + RouteValueDictionary attributes = htmlAttributes == null ? new RouteValueDictionary() : new RouteValueDictionary(htmlAttributes); + if (attributes.ContainsKey("checked")) { + return InputHelper(htmlHelper, InputType.Radio, name, value, false, false, true, true /* isExplicitValue */, attributes); + } + + return RadioButton(htmlHelper, name, value, isChecked, htmlAttributes); + } + + public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked) { + return RadioButton(htmlHelper, name, value, isChecked, (object)null /* htmlAttributes */); + } + + public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, object htmlAttributes) { + return RadioButton(htmlHelper, name, value, isChecked, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString RadioButton(this HtmlHelper htmlHelper, string name, object value, bool isChecked, IDictionary htmlAttributes) { + if (value == null) { + throw new ArgumentNullException("value"); + } + // checked attribute is an explicit parameter so it takes precedence. + RouteValueDictionary attributes = htmlAttributes == null ? new RouteValueDictionary() : new RouteValueDictionary(htmlAttributes); + attributes.Remove("checked"); + return InputHelper(htmlHelper, InputType.Radio, name, value, false, isChecked, true, true /* isExplicitValue */, attributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString RadioButtonFor(this HtmlHelper htmlHelper, Expression> expression, object value) { + return RadioButtonFor(htmlHelper, expression, value, null /* htmlAttributes */); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString RadioButtonFor(this HtmlHelper htmlHelper, Expression> expression, object value, object htmlAttributes) { + return RadioButtonFor(htmlHelper, expression, value, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString RadioButtonFor(this HtmlHelper htmlHelper, Expression> expression, object value, IDictionary htmlAttributes) { + return RadioButtonHelper(htmlHelper, + ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model, + ExpressionHelper.GetExpressionText(expression), + value, + null /* isChecked */, + htmlAttributes); + } + + private static MvcHtmlString RadioButtonHelper(HtmlHelper htmlHelper, object model, string name, object value, bool? isChecked, IDictionary htmlAttributes) { + if (value == null) { + throw new ArgumentNullException("value"); + } + + RouteValueDictionary attributes = + htmlAttributes == null ? new RouteValueDictionary() + : new RouteValueDictionary(htmlAttributes); + + bool explicitValue = isChecked.HasValue; + if (explicitValue) { + attributes.Remove("checked"); // Explicit value must override dictionary + } + else { + string valueString = Convert.ToString(value, CultureInfo.CurrentCulture); + isChecked = model != null && + !String.IsNullOrEmpty(name) && + String.Equals(model.ToString(), valueString, StringComparison.OrdinalIgnoreCase); + } + + return InputHelper(htmlHelper, InputType.Radio, name, value, false /* useViewData */, isChecked ?? false, true /* setId */, true /* isExplicitValue */, attributes); + } + + // TextBox + + public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name) { + return TextBox(htmlHelper, name, null /* value */); + } + + public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value) { + return TextBox(htmlHelper, name, value, (object)null /* htmlAttributes */); + } + + public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) { + return TextBox(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString TextBox(this HtmlHelper htmlHelper, string name, object value, IDictionary htmlAttributes) { + return InputHelper(htmlHelper, InputType.Text, name, value, (value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression> expression) { + return htmlHelper.TextBoxFor(expression, (IDictionary)null); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes) { + return htmlHelper.TextBoxFor(expression, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString TextBoxFor(this HtmlHelper htmlHelper, Expression> expression, IDictionary htmlAttributes) { + return TextBoxHelper(htmlHelper, + ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model, + ExpressionHelper.GetExpressionText(expression), + htmlAttributes); + } + + private static MvcHtmlString TextBoxHelper(this HtmlHelper htmlHelper, object model, string expression, IDictionary htmlAttributes) { + return InputHelper(htmlHelper, InputType.Text, expression, model, false /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes); + } + + // Helper methods + + private static MvcHtmlString InputHelper(HtmlHelper htmlHelper, InputType inputType, string name, object value, bool useViewData, bool isChecked, bool setId, bool isExplicitValue, IDictionary htmlAttributes) { + name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); + if (String.IsNullOrEmpty(name)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name"); + } + + TagBuilder tagBuilder = new TagBuilder("input"); + tagBuilder.MergeAttributes(htmlAttributes); + tagBuilder.MergeAttribute("type", HtmlHelper.GetInputTypeString(inputType)); + tagBuilder.MergeAttribute("name", name, true); + + string valueParameter = Convert.ToString(value, CultureInfo.CurrentCulture); + bool usedModelState = false; + + switch (inputType) { + case InputType.CheckBox: + bool? modelStateWasChecked = htmlHelper.GetModelStateValue(name, typeof(bool)) as bool?; + if (modelStateWasChecked.HasValue) { + isChecked = modelStateWasChecked.Value; + usedModelState = true; + } + goto case InputType.Radio; + case InputType.Radio: + if (!usedModelState) { + string modelStateValue = htmlHelper.GetModelStateValue(name, typeof(string)) as string; + if (modelStateValue != null) { + isChecked = String.Equals(modelStateValue, valueParameter, StringComparison.Ordinal); + usedModelState = true; + } + } + if (!usedModelState && useViewData) { + isChecked = htmlHelper.EvalBoolean(name); + } + if (isChecked) { + tagBuilder.MergeAttribute("checked", "checked"); + } + tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue); + break; + case InputType.Password: + if (value != null) { + tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue); + } + break; + default: + string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string)); + tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue); + break; + } + + if (setId) { + tagBuilder.GenerateId(name); + } + + // If there are any errors for a named field, we add the css attribute. + ModelState modelState; + if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState)) { + if (modelState.Errors.Count > 0) { + tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); + } + } + + if (inputType == InputType.CheckBox) { + // Render an additional for checkboxes. This + // addresses scenarios where unchecked checkboxes are not sent in the request. + // Sending a hidden input makes it possible to know that the checkbox was present + // on the page when the request was submitted. + StringBuilder inputItemBuilder = new StringBuilder(); + inputItemBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing)); + + TagBuilder hiddenInput = new TagBuilder("input"); + hiddenInput.MergeAttribute("type", HtmlHelper.GetInputTypeString(InputType.Hidden)); + hiddenInput.MergeAttribute("name", name); + hiddenInput.MergeAttribute("value", "false"); + inputItemBuilder.Append(hiddenInput.ToString(TagRenderMode.SelfClosing)); + return MvcHtmlString.Create(inputItemBuilder.ToString()); + } + + return tagBuilder.ToMvcHtmlString(TagRenderMode.SelfClosing); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LabelExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LabelExtensions.cs new file mode 100644 index 00000000000..4af88eaafd3 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LabelExtensions.cs @@ -0,0 +1,49 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.Diagnostics.CodeAnalysis; + using System.Linq; + using System.Linq.Expressions; + + public static class LabelExtensions { + public static MvcHtmlString Label(this HtmlHelper html, string expression) { + return LabelHelper(html, + ModelMetadata.FromStringExpression(expression, html.ViewData), + expression); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString LabelFor(this HtmlHelper html, Expression> expression) { + return LabelHelper(html, + ModelMetadata.FromLambdaExpression(expression, html.ViewData), + ExpressionHelper.GetExpressionText(expression)); + } + + public static MvcHtmlString LabelForModel(this HtmlHelper html) { + return LabelHelper(html, html.ViewData.ModelMetadata, String.Empty); + } + + internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName) { + string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last(); + if (String.IsNullOrEmpty(labelText)) { + return MvcHtmlString.Empty; + } + + TagBuilder tag = new TagBuilder("label"); + tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName)); + tag.SetInnerText(labelText); + return tag.ToMvcHtmlString(TagRenderMode.Normal); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LinkExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LinkExtensions.cs new file mode 100644 index 00000000000..8250ff341c4 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/LinkExtensions.cs @@ -0,0 +1,116 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.Collections.Generic; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public static class LinkExtensions { + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName) { + return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(), new RouteValueDictionary()); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues) { + return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(routeValues), new RouteValueDictionary()); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, object routeValues, object htmlAttributes) { + return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues) { + return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, routeValues, new RouteValueDictionary()); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, RouteValueDictionary routeValues, IDictionary htmlAttributes) { + return ActionLink(htmlHelper, linkText, actionName, null /* controllerName */, routeValues, htmlAttributes); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName) { + return ActionLink(htmlHelper, linkText, actionName, controllerName, new RouteValueDictionary(), new RouteValueDictionary()); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes) { + return ActionLink(htmlHelper, linkText, actionName, controllerName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, RouteValueDictionary routeValues, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null/* routeName */, actionName, controllerName, routeValues, htmlAttributes)); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes) { + return ActionLink(htmlHelper, linkText, actionName, controllerName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null /* routeName */, actionName, controllerName, protocol, hostName, fragment, routeValues, htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, object routeValues) { + return RouteLink(htmlHelper, linkText, new RouteValueDictionary(routeValues)); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues) { + return RouteLink(htmlHelper, linkText, routeValues, new RouteValueDictionary()); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName) { + return RouteLink(htmlHelper, linkText, routeName, (object)null /* routeValues */ ); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues) { + return RouteLink(htmlHelper, linkText, routeName, new RouteValueDictionary(routeValues)); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, RouteValueDictionary routeValues) { + return RouteLink(htmlHelper, linkText, routeName, routeValues, new RouteValueDictionary()); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, object routeValues, object htmlAttributes) { + return RouteLink(htmlHelper, linkText, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, RouteValueDictionary routeValues, IDictionary htmlAttributes) { + return RouteLink(htmlHelper, linkText, null /* routeName */, routeValues, htmlAttributes); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, object routeValues, object htmlAttributes) { + return RouteLink(htmlHelper, linkText, routeName, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, RouteValueDictionary routeValues, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + return MvcHtmlString.Create(HtmlHelper.GenerateRouteLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, routeName, routeValues, htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, string protocol, string hostName, string fragment, object routeValues, object htmlAttributes) { + return RouteLink(htmlHelper, linkText, routeName, protocol, hostName, fragment, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString RouteLink(this HtmlHelper htmlHelper, string linkText, string routeName, string protocol, string hostName, string fragment, RouteValueDictionary routeValues, IDictionary htmlAttributes) { + if (String.IsNullOrEmpty(linkText)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "linkText"); + } + return MvcHtmlString.Create(HtmlHelper.GenerateRouteLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, routeName, protocol, hostName, fragment, routeValues, htmlAttributes)); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/MvcForm.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/MvcForm.cs new file mode 100644 index 00000000000..6aa1d992b3d --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/MvcForm.cs @@ -0,0 +1,69 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System; + using System.IO; + + public class MvcForm : IDisposable { + + private bool _disposed; + private readonly FormContext _originalFormContext; + private readonly ViewContext _viewContext; + private readonly TextWriter _writer; + + [Obsolete("The recommended alternative is the constructor MvcForm(ViewContext viewContext).", true /* error */)] + public MvcForm(HttpResponseBase httpResponse) { + if (httpResponse == null) { + throw new ArgumentNullException("httpResponse"); + } + + _writer = httpResponse.Output; + } + + public MvcForm(ViewContext viewContext) { + if (viewContext == null) { + throw new ArgumentNullException("viewContext"); + } + + _viewContext = viewContext; + _writer = viewContext.Writer; + + // push the new FormContext + _originalFormContext = viewContext.FormContext; + viewContext.FormContext = new FormContext(); + } + + public void Dispose() { + Dispose(true /* disposing */); + GC.SuppressFinalize(this); + } + + protected virtual void Dispose(bool disposing) { + if (!_disposed) { + _disposed = true; + _writer.Write(""); + + // output client validation and restore the original form context + if (_viewContext != null) { + _viewContext.OutputClientValidation(); + _viewContext.FormContext = _originalFormContext; + } + } + } + + public void EndForm() { + Dispose(true); + } + + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/PartialExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/PartialExtensions.cs new file mode 100644 index 00000000000..8f488c6331b --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/PartialExtensions.cs @@ -0,0 +1,36 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System.Globalization; + using System.IO; + + public static class PartialExtensions { + public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName) { + return Partial(htmlHelper, partialViewName, null /* model */, htmlHelper.ViewData); + } + + public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData) { + return Partial(htmlHelper, partialViewName, null /* model */, viewData); + } + + public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model) { + return Partial(htmlHelper, partialViewName, model, htmlHelper.ViewData); + } + + public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData) { + StringWriter writer = new StringWriter(CultureInfo.CurrentCulture); + htmlHelper.RenderPartialInternal(partialViewName, viewData, model, writer, ViewEngines.Engines); + return MvcHtmlString.Create(writer.ToString()); + } + } +} diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/RenderPartialExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/RenderPartialExtensions.cs new file mode 100644 index 00000000000..3d25070aae9 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/RenderPartialExtensions.cs @@ -0,0 +1,35 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + public static class RenderPartialExtensions { + // Renders the partial view with the parent's view data and model + public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName) { + htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines); + } + + // Renders the partial view with the given view data and, implicitly, the given view data's model + public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData) { + htmlHelper.RenderPartialInternal(partialViewName, viewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines); + } + + // Renders the partial view with an empty view data and the given model + public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model) { + htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines); + } + + // Renders the partial view with a copy of the given view data plus the given model + public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData) { + htmlHelper.RenderPartialInternal(partialViewName, viewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines); + } + } +} \ No newline at end of file diff --git a/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/SelectExtensions.cs b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/SelectExtensions.cs new file mode 100644 index 00000000000..e3cf48b7e27 --- /dev/null +++ b/mcs/class/System.Web.Mvc2/System.Web.Mvc/Html/SelectExtensions.cs @@ -0,0 +1,256 @@ +/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. All rights reserved. + * + * This software is subject to the Microsoft Public License (Ms-PL). + * A copy of the license can be found in the license.htm file included + * in this distribution. + * + * You must not remove this notice, or any other, from this software. + * + * ***************************************************************************/ + +namespace System.Web.Mvc.Html { + using System.Collections; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Globalization; + using System.Linq; + using System.Linq.Expressions; + using System.Text; + using System.Web; + using System.Web.Mvc.Resources; + using System.Web.Routing; + + public static class SelectExtensions { + + // DropDownList + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name) { + return DropDownList(htmlHelper, name, null /* selectList */, null /* optionLabel */, null /* htmlAttributes */); + } + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string optionLabel) { + return DropDownList(htmlHelper, name, null /* selectList */, optionLabel, null /* htmlAttributes */); + } + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList) { + return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, null /* htmlAttributes */); + } + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, object htmlAttributes) { + return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, IDictionary htmlAttributes) { + return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, htmlAttributes); + } + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, string optionLabel) { + return DropDownList(htmlHelper, name, selectList, optionLabel, null /* htmlAttributes */); + } + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, string optionLabel, object htmlAttributes) { + return DropDownList(htmlHelper, name, selectList, optionLabel, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, string optionLabel, IDictionary htmlAttributes) { + return DropDownListHelper(htmlHelper, name, selectList, optionLabel, htmlAttributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList) { + return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, null /* htmlAttributes */); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, object htmlAttributes) { + return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, IDictionary htmlAttributes) { + return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, htmlAttributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, string optionLabel) { + return DropDownListFor(htmlHelper, expression, selectList, optionLabel, null /* htmlAttributes */); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, string optionLabel, object htmlAttributes) { + return DropDownListFor(htmlHelper, expression, selectList, optionLabel, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, string optionLabel, IDictionary htmlAttributes) { + if (expression == null) { + throw new ArgumentNullException("expression"); + } + + return DropDownListHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, optionLabel, htmlAttributes); + } + + private static MvcHtmlString DropDownListHelper(HtmlHelper htmlHelper, string expression, IEnumerable selectList, string optionLabel, IDictionary htmlAttributes) { + return SelectInternal(htmlHelper, optionLabel, expression, selectList, false /* allowMultiple */, htmlAttributes); + } + + // ListBox + + public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name) { + return ListBox(htmlHelper, name, null /* selectList */, null /* htmlAttributes */); + } + + public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable selectList) { + return ListBox(htmlHelper, name, selectList, (IDictionary)null); + } + + public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable selectList, object htmlAttributes) { + return ListBox(htmlHelper, name, selectList, new RouteValueDictionary(htmlAttributes)); + } + + public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable selectList, IDictionary htmlAttributes) { + return ListBoxHelper(htmlHelper, name, selectList, htmlAttributes); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString ListBoxFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList) { + return ListBoxFor(htmlHelper, expression, selectList, null /* htmlAttributes */); + } + + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString ListBoxFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, object htmlAttributes) { + return ListBoxFor(htmlHelper, expression, selectList, new RouteValueDictionary(htmlAttributes)); + } + + [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")] + [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")] + public static MvcHtmlString ListBoxFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, IDictionary htmlAttributes) { + if (expression == null) { + throw new ArgumentNullException("expression"); + } + + return ListBoxHelper(htmlHelper, + ExpressionHelper.GetExpressionText(expression), + selectList, + htmlAttributes); + } + + private static MvcHtmlString ListBoxHelper(HtmlHelper htmlHelper, string name, IEnumerable selectList, IDictionary htmlAttributes) { + return SelectInternal(htmlHelper, null /* optionLabel */, name, selectList, true /* allowMultiple */, htmlAttributes); + } + + // Helper methods + + private static IEnumerable GetSelectData(this HtmlHelper htmlHelper, string name) { + object o = null; + if (htmlHelper.ViewData != null) { + o = htmlHelper.ViewData.Eval(name); + } + if (o == null) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.HtmlHelper_MissingSelectData, + name, + "IEnumerable")); + } + IEnumerable selectList = o as IEnumerable; + if (selectList == null) { + throw new InvalidOperationException( + String.Format( + CultureInfo.CurrentUICulture, + MvcResources.HtmlHelper_WrongSelectDataType, + name, + o.GetType().FullName, + "IEnumerable")); + } + return selectList; + } + + internal static string ListItemToOption(SelectListItem item) { + TagBuilder builder = new TagBuilder("option") { + InnerHtml = HttpUtility.HtmlEncode(item.Text) + }; + if (item.Value != null) { + builder.Attributes["value"] = item.Value; + } + if (item.Selected) { + builder.Attributes["selected"] = "selected"; + } + return builder.ToString(TagRenderMode.Normal); + } + + private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable selectList, bool allowMultiple, IDictionary htmlAttributes) { + name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); + if (String.IsNullOrEmpty(name)) { + throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name"); + } + + bool usedViewData = false; + + // If we got a null selectList, try to use ViewData to get the list of items. + if (selectList == null) { + selectList = htmlHelper.GetSelectData(name); + usedViewData = true; + } + + object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(name, typeof(string[])) : htmlHelper.GetModelStateValue(name, typeof(string)); + + // If we haven't already used ViewData to get the entire list of items then we need to + // use the ViewData-supplied value before using the parameter-supplied value. + if (!usedViewData) { + if (defaultValue == null) { + defaultValue = htmlHelper.ViewData.Eval(name); + } + } + + if (defaultValue != null) { + IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue }; + IEnumerable values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture); + HashSet selectedValues = new HashSet(values, StringComparer.OrdinalIgnoreCase); + List newSelectList = new List(); + + foreach (SelectListItem item in selectList) { + item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text); + newSelectList.Add(item); + } + selectList = newSelectList; + } + + // Convert each ListItem to an