Compare commits
1087 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c250fa560e | |||
| b017e8690a | |||
| 8a9680e75c | |||
| 36c66e676a | |||
| ba530061a0 | |||
| 89ae3bc143 | |||
| 3951f59d09 | |||
| cd8c998ebf | |||
| 2cb544591b | |||
| 1b1b5c047c | |||
| fa5b9e5689 | |||
| c26df8da6f | |||
| 1e02d85fca | |||
| d1dc2331f8 | |||
| d503deb8c5 | |||
| 0859b92aaf | |||
| 695d26434c | |||
| a19de645e4 | |||
| de9a27db10 | |||
| b6d5b7d603 | |||
| 93d7cf4dc3 | |||
| 0c42596dc8 | |||
| 8cf9c1ba97 | |||
| 7a47d63b48 | |||
| 4648a8c103 | |||
| 87947871d1 | |||
| 87fee572ff | |||
| 89f7a3ec63 | |||
| 7092a9ccbb | |||
| e9ea9b5e1b | |||
| fd1efb29ec | |||
| cf4781153e | |||
| ebed142cd5 | |||
| d162aba14a | |||
| ec075f5807 | |||
| dca90e6316 | |||
| df31fafec5 | |||
| 828dc64035 | |||
| 0b74164a8e | |||
| 62be1b1267 | |||
| 85ae7e764f | |||
| 3daa624627 | |||
| d8af1aaf7b | |||
| f2d105d8b9 | |||
| 5b0a8c0668 | |||
| c3ccf3a609 | |||
| 60bbede408 | |||
| 1d0299af89 | |||
| c2d0e255df | |||
| 005d3e7d64 | |||
| 12f8638223 | |||
| e3f9e8c842 | |||
| a475f72d50 | |||
| a559ef9f90 | |||
| be83302b14 | |||
| 83d7ea9ef1 | |||
| 95024442de | |||
| 69f54b5f22 | |||
| 3404f95b2e | |||
| e56738481b | |||
| cb59dc353b | |||
| d1b75eac08 | |||
| 8fabd4e4ed | |||
| 564d92bed7 | |||
| 95f103ccc2 | |||
| 0ace2fdae7 | |||
| 5da3541584 | |||
| ef86d2f1f1 | |||
| a10a6d1af8 | |||
| 6d87174cc1 | |||
| 9af9c3fe77 | |||
| 9cedf5da4c | |||
| 906d675dca | |||
| f1b3105202 | |||
| 3ebb213916 | |||
| a65ca205de | |||
| 3e1120612b | |||
| 8d06d39a62 | |||
| da7fea47c6 | |||
| f2442b25f6 | |||
| 300d3ff09b | |||
| e6337b8f14 | |||
| 2be785ace3 | |||
| 5e2d991fab | |||
| 536cb4caf1 | |||
| 27745ea141 | |||
| 5289c55740 | |||
| 791773fc8a | |||
| 1da27e6c2b | |||
| a909b7904e | |||
| 1b1abce7da | |||
| fbc10be381 | |||
| 61f2647b62 | |||
| a5bea7fc59 | |||
| b9be5c2561 | |||
| 97556de447 | |||
| d5bde0d8df | |||
| cc5ca0b5fe | |||
| 0cb9cc6840 | |||
| d38d7b1ff4 | |||
| 2d87f933d5 | |||
| a734a0cff7 | |||
| d0ace55d03 | |||
| 3fda0308ac | |||
| d796b2afc1 | |||
| f95cfc2ee0 | |||
| c5d1439422 | |||
| 5e9f4559b6 | |||
| 4bbb0441a6 | |||
| 4cf1d7d9a4 | |||
| a6a3ddca75 | |||
| 27cfa85d3a | |||
| a9e1e7b634 | |||
| 9f5f920c81 | |||
| f9a0d91299 | |||
| 82c2560822 | |||
| f467b8cb6c | |||
| aea1a03453 | |||
| 1568e5f19c | |||
| 8dff47db78 | |||
| 987e48733a | |||
| ac5142443a | |||
| 44360d83aa | |||
| 021cb817d4 | |||
| f4f91fba78 | |||
| dec5e8ad6c | |||
| a6b2196c10 | |||
| 4321c8d24e | |||
| 4cff3a3c28 | |||
| 5458c9a310 | |||
| 0045ec353f | |||
| 716d3e95f1 | |||
| beeb28f390 | |||
| 080e8816a5 | |||
| f7eb323bd5 | |||
| 0f484fdf49 | |||
| d779422bf4 | |||
| 11ea698969 | |||
| 0e0e6b5c41 | |||
| 4c218621c6 | |||
| c150a91e50 | |||
| 7be9a0a987 | |||
| 50589c0911 | |||
| e61ae618e8 | |||
| 930e6a0989 | |||
| 7c50b32684 | |||
| 0f7daf7ebd | |||
| 12cbc2a9c5 | |||
| 959d263619 | |||
| 6a1fb52b25 | |||
| 18cd043421 | |||
| ddb2f82aba | |||
| 6c99e7951f | |||
| e44e745761 | |||
| 30c11439e4 | |||
| 0883f621f6 | |||
| 2d0784d1e5 | |||
| af0011f32a | |||
| ab6c5ac21a | |||
| 227a38fb98 | |||
| 06f9dee649 | |||
| 75680192bb | |||
| a53efb394f | |||
| 98ed32c8cf | |||
| df10ebebca | |||
| 88dc73cd66 | |||
| cd0919aeeb | |||
| ce6711b587 | |||
| 6cb3fcf9ad | |||
| e5878554bd | |||
| 44c8c4b5b8 | |||
| c0b5525dd7 | |||
| 36f8a8e1dd | |||
| 16f73b56ab | |||
| 47dc2e6214 | |||
| c6483f0380 | |||
| 168b38b2a3 | |||
| 70ca4ac913 | |||
| 72099192b5 | |||
| ea48128869 | |||
| f0b22146c8 | |||
| fe0d94687a | |||
| 238c3d38e8 | |||
| 6af4f1f2c6 | |||
| e215fb056f | |||
| e6178efcfb | |||
| 30cf0e2040 | |||
| 48d620cdb0 | |||
| 3bd487d092 | |||
| 6c8c37256b | |||
| 37b1fcbaf0 | |||
| dc111768e3 | |||
| 6589d5d5d3 | |||
| e6975a71d5 | |||
| 33b497e5f4 | |||
| c5e7c81c19 | |||
| 47d1fe7082 | |||
| 735bd574ff | |||
| 5c0d9785e0 | |||
| db14868324 | |||
| 06952833ef | |||
| 2a90e93a6f | |||
| 0d94ddb96e | |||
| c7645b55ba | |||
| 208806c027 | |||
| 8024610364 | |||
| 8e4644568b | |||
| e0a71830fa | |||
| 5b0057c258 | |||
| fb61c55fa7 | |||
| a70ef52964 | |||
| 51204ee401 | |||
| 657f165ffb | |||
| 3bd98d851a | |||
| 9eea46b19b | |||
| 76fb5d260f | |||
| 267cd46ea0 | |||
| 96f6a0161f | |||
| 7bc53adc67 | |||
| 8ecff73c18 | |||
| 35e65ad18c | |||
| 8def8eaa86 | |||
| c0774ad9b9 | |||
| f306cbe457 | |||
| 577b989c4c | |||
| e6b162f4f6 | |||
| b40cc1879f | |||
| 8a7c7bf77d | |||
| 38a1179de5 | |||
| f263b4d92b | |||
| c612727116 | |||
| ab9c9df7d6 | |||
| c607e50433 | |||
| df5555bdf1 | |||
| 9506339e6f | |||
| 68605a7560 | |||
| 839dd7315a | |||
| f1314628d7 | |||
| e23ed30b0c | |||
| 55cb46927e | |||
| 654c3b7403 | |||
| 4195754b0c | |||
| 96a6f17bd7 | |||
| 61d99c4061 | |||
| 0a6e91a2f9 | |||
| cf9e786e45 | |||
| ba1d3fd3e6 | |||
| ac01fd48fa | |||
| f53fb694be | |||
| 1ecd8fa87d | |||
| ce1c9d697b | |||
| c67a76fb03 | |||
| 3d72a4497c | |||
| 30cc8e0861 | |||
| 30ca3f6df9 | |||
| cccfed6efe | |||
| 82c148e997 | |||
| c50a3e7a27 | |||
| 811cbe2339 | |||
| a8bf881ae1 | |||
| c446be734c | |||
| f0f7f6af55 | |||
| 19bd8ae193 | |||
| 81d8f74e0d | |||
| 0011d568c6 | |||
| 159718bf4f | |||
| b9ff3ca729 | |||
| 4f3ac36d7f | |||
| a9257ad366 | |||
| 2218459877 | |||
| 8f5e2946d6 | |||
| 19c3b251a0 | |||
| ce4c855f00 | |||
| 48c45447e4 | |||
| 4683144987 | |||
| 238a237cb5 | |||
| cde1ca9f83 | |||
| 93e2d8d822 | |||
| 8609389bdb | |||
| 48f985b70a | |||
| b02afb3af8 | |||
| b9d814c3fb | |||
| 1b54ce1d48 | |||
| e3efc0d19b | |||
| 3ba9e09164 | |||
| d148c10c66 | |||
| 2b573b9070 | |||
| 4cb03ab36c | |||
| 3ebbcc77e9 | |||
| 8be97295dc | |||
| 3dd411f159 | |||
| 8b141dc51a | |||
| 278aa3f820 | |||
| a7a38478db | |||
| b2e004b825 | |||
| 10df6e878c | |||
| eac11c1b80 | |||
| 0ad5da67ea | |||
| 3fb9ffca5b | |||
| 8e7fe5ee55 | |||
| 9554c6a1c6 | |||
| 8597876c92 | |||
| 3df7d81bde | |||
| f82ae4fdda | |||
| 4a981225b3 | |||
| 0cd115c268 | |||
| 291b0582e4 | |||
| f4e48872a2 | |||
| 9e320700e2 | |||
| 7f0ff70ca9 | |||
| 65e3b7f951 | |||
| 156f145c69 | |||
| a0c941dac2 | |||
| 33eb9d40f3 | |||
| cf8186653c | |||
| 75403d3b94 | |||
| 083bab0528 | |||
| ee3e3787a8 | |||
| a3895ab149 | |||
| c590c6a265 | |||
| 6c1bf4b85f | |||
| 3632d6b0c6 | |||
| bf95792524 | |||
| 885b421201 | |||
| b11143e2c4 | |||
| 00a625fb7f | |||
| e9ae11ff2b | |||
| bd4e6eaa62 | |||
| b2e4489e66 | |||
| d27e32e918 | |||
| 3a6dae9d0d | |||
| 9f95c48242 | |||
| e2934bb036 | |||
| 664a0ff4ec | |||
| 715f0ddac1 | |||
| 4d5f142a30 | |||
| f4dc045561 | |||
| ca55372f89 | |||
| 29c96c2c64 | |||
| 1a969d76e1 | |||
| fba31a0a6a | |||
| 5132d66924 | |||
| 36f367f9d6 | |||
| 67d9e578f5 | |||
| 306f0f9679 | |||
| b9d53ceac8 | |||
| 1bceb746fa | |||
| d390a4c0a9 | |||
| e4f8b5c586 | |||
| 869915f991 | |||
| 0cb4a9ad9c | |||
| 8c7dbd7207 | |||
| 0110cf01f2 | |||
| fee1a0dd9e | |||
| 315e8b27a0 | |||
| fb0c9c3fbb | |||
| 0df1ebb83e | |||
| 204d7a79aa | |||
| e68629b8bc | |||
| f80fa2f373 | |||
| 55ac779bf2 | |||
| f8732cd70b | |||
| ff5c5c8a03 | |||
| 7df9921441 | |||
| 329431e6df | |||
| 292ded852e | |||
| a4a9b26d93 | |||
| e4d4aa935a | |||
| b337f4e5e4 | |||
| 6f5689004d | |||
| ed5a0be20e | |||
| 4e82d282bf | |||
| fe003edd02 | |||
| 17f326dc89 | |||
| 2c38f7ce7f | |||
| 3ba31cc82c | |||
| e502ce4ff9 | |||
| 8fff66dcb7 | |||
| bc47e0c4a6 | |||
| 85c110bad5 | |||
| 8866607582 | |||
| 0db6c2cc11 | |||
| 84858bea65 | |||
| c3795d7e5a | |||
| 36eea348ba | |||
| be3f95610b | |||
| f9aa4b28af | |||
| 232c2292cb | |||
| 80dca1e3f2 | |||
| 47b6f7f4d5 | |||
| 03af54b1d5 | |||
| bbd62f20a9 | |||
| 9738227189 | |||
| 6bf3a7a74a | |||
| 07f8f79620 | |||
| f0690ec55f | |||
| e4bfccf974 | |||
| 51d08a353c | |||
| 982825dd56 | |||
| c8c4e2437b | |||
| 1970b20eb9 | |||
| a5499cff26 | |||
| d9c37a03b9 | |||
| e17b93bcfe | |||
| 6ffc231be0 | |||
| 99d8aca0c5 | |||
| 3c2ac0e90e | |||
| 7af10e3b67 | |||
| 62a48df421 | |||
| f146b8f6af | |||
| 946f905885 | |||
| 707eca930f | |||
| e4a002c976 | |||
| e731afadc9 | |||
| a006a480f7 | |||
| 674923468d | |||
| afafcfbb7a | |||
| c489d910b8 | |||
| 6e226ef995 | |||
| 0b1c479428 | |||
| 3f2ca8a823 | |||
| 78d57e89d5 | |||
| d9049864f3 | |||
| 21632d2ffc | |||
| da3d20a5bb | |||
| c0f0dcca3a | |||
| 22f7d8797c | |||
| 25da44825e | |||
| 55d4a7e367 | |||
| 33e73ab965 | |||
| 05db49c66d | |||
| 4cf2035039 | |||
| 27f059bf58 | |||
| aee8730315 | |||
| b517d59bee | |||
| e4f3081da2 | |||
| 5cca506d20 | |||
| e3f9375fd2 | |||
| cbd8085675 | |||
| a9d6c7872a | |||
| d4d4272b1b | |||
| e9aef79747 | |||
| 3b5a1ddcdd | |||
| 14ad9f571c | |||
| 243633365e | |||
| 258d19df22 | |||
| 8261fa2aea | |||
| c434790b2f | |||
| 4397319ac3 | |||
| 7309c7c02f | |||
| 12e9ab050a | |||
| d0fd7c1374 | |||
| f7ccad4269 | |||
| 1bf20b9c97 | |||
| f03d861942 | |||
| c0eb3e256b | |||
| 41d7571e29 | |||
| c2f420be7a | |||
| b0e083e8fc | |||
| 04197a5900 | |||
| d2fd02315a | |||
| f654c67540 | |||
| 9b28214c3e | |||
| 6a665efd7e | |||
| 5aee883bd2 | |||
| c0f7493e70 | |||
| 7d8524dd55 | |||
| 4c667a6a3e | |||
| ce06a30e64 | |||
| 1be891d05f | |||
| e85f594b84 | |||
| a3278be3fe | |||
| 90aa8c3b5a | |||
| ea217edaae | |||
| 3cf9a45724 | |||
| 38fc6c980d | |||
| cc34208871 | |||
| 6f778c26d1 | |||
| 29b978c1cd | |||
| 346a2d4fc9 | |||
| 02cc7e69ec | |||
| acb66f45ac | |||
| 487fdea34e | |||
| 0e0c4fcb1f | |||
| f7868b2cf1 | |||
| 0368f2846e | |||
| ee94652a0c | |||
| a1da12f033 | |||
| ea406d2d7c | |||
| 093a33e495 | |||
| 7a4ccc825d | |||
| a22efcdb2b | |||
| 1b71c66256 | |||
| dc7e18b97b | |||
| f6c51205fc | |||
| d45b5a3139 | |||
| 15dd774229 | |||
| b248604c0f | |||
| f01a195369 | |||
| 75af1e9d7c | |||
| d3c553c945 | |||
| 689fe2a44f | |||
| 06519ab238 | |||
| 65d5bc9155 | |||
| 05fc15d164 | |||
| a3b87a1d8b | |||
| b6f7d99039 | |||
| c1aa60c1ac | |||
| a2988a30c0 | |||
| 23f2382947 | |||
| 4d94909782 | |||
| 422a2a685c | |||
| c4f1235f0b | |||
| ce4828d678 | |||
| 8e914e751c | |||
| 7fefde4c8a | |||
| 29614d6b03 | |||
| 16b47539b4 | |||
| 83c53333c6 | |||
| 77db6cad01 | |||
| a10daaab52 | |||
| 3ddb9785c7 | |||
| 585eea1c6b | |||
| 10095a4ee7 | |||
| 8f4ccc53d5 | |||
| f04db8c52c | |||
| e2283c2310 | |||
| 635f09fb75 | |||
| 9022894d23 | |||
| 747675816d | |||
| 2833a8c5c7 | |||
| 75a686bc07 | |||
| 76a521dd8b | |||
| 8fa36f3f22 | |||
| 18aef90017 | |||
| 82bb410f4f | |||
| caa937a4ef | |||
| d7103a3b83 | |||
| e555520ddf | |||
| a71961c35b | |||
| ed3f715988 | |||
| 26aca92337 | |||
| 406e3663f6 | |||
| da8af696c5 | |||
| 12f5df33da | |||
| 775b2192ff | |||
| 458de6296e | |||
| b55ce96d85 | |||
| 8ae867389d | |||
| 5fc3d8e248 | |||
| 227d910722 | |||
| f184276ef8 | |||
| c72ab927a6 | |||
| a356552d2d | |||
| 5c6a595e48 | |||
| c1cfcaf9ea | |||
| 40a413cd70 | |||
| c7c10b8ab6 | |||
| 2da0728b78 | |||
| a71f3f8412 | |||
| b21423efe2 | |||
| 5895858e6e | |||
| cd38123fbd | |||
| 842d7120e6 | |||
| cae2183ab4 | |||
| 07e75dab15 | |||
| 7bc2375a77 | |||
| 5cebbd8a91 | |||
| db59b08f58 | |||
| 392fbb836f | |||
| 0cb8603c80 | |||
| 20fc02053a | |||
| e389dc39a7 | |||
| fbd4669da8 | |||
| 2b2c75f5e4 | |||
| 8c7b06fe2b | |||
| 540db7137a | |||
| 079aae7e63 | |||
| 6183e01642 | |||
| cf91933791 | |||
| d10c3a960f | |||
| 4d6d89dbe7 | |||
| c138c6643a | |||
| a2b876608f | |||
| 9e113564fa | |||
| f8848086fd | |||
| 261a6af60a | |||
| c66d70fbd8 | |||
| e8c7af8b25 | |||
| 8804d912f2 | |||
| 54e5140d6a | |||
| c0102f1c71 | |||
| 831d1966dc | |||
| ef5525e67f | |||
| f3e04ac871 | |||
| ba98f587b2 | |||
| 2753dbe5b4 | |||
| 56c93891a8 | |||
| 6bd005775d | |||
| 73c79e8528 | |||
| 827d4dd6c0 | |||
| ffd14c839b | |||
| f8d8b767b8 | |||
| 4f011e0390 | |||
| 053df24640 | |||
| 45c335702d | |||
| bc04d4f8da | |||
| be5076783f | |||
| 5c20f4f6ec | |||
| 42da98e020 | |||
| eeb305c740 | |||
| c19541cb11 | |||
| dea22f22cb | |||
| 656c61d1e2 | |||
| bac038b82d | |||
| dd6d0e380e | |||
| c95c1a7038 | |||
| 9e1c5e71e4 | |||
| aba68720bb | |||
| 1b1722c875 | |||
| 248af2eaa2 | |||
| 0709174560 | |||
| b0c0ed050d | |||
| e3a085774c | |||
| 6f0ddc37a0 | |||
| d3eb5ceabe | |||
| 1bffb7395c | |||
| e636a42744 | |||
| d3927a1265 | |||
| d6fc106588 | |||
| 68fc833280 | |||
| 5a8443fe72 | |||
| 153fb4a248 | |||
| 72ef5b01d2 | |||
| 0854fee4ee | |||
| e122d40fb9 | |||
| b696aa4340 | |||
| e32dd303e3 | |||
| 7c524abb84 | |||
| 993bac8a29 | |||
| b40dbf73ca | |||
| 0808665342 | |||
| 7623746f64 | |||
| 3152427ff7 | |||
| 85e88e5640 | |||
| ea3d2f893f | |||
| 3cddc5e4dc | |||
| 8cd49749ec | |||
| e45bf57632 | |||
| 3e99dd0d55 | |||
| be2ed3762b | |||
| e3abd49276 | |||
| d76f6c1cdb | |||
| 840109dc58 | |||
| 1aebce7ad6 | |||
| 11fd6553e9 | |||
| 690c4a165c | |||
| 8fb159ddc2 | |||
| b3ca264af1 | |||
| 34e71027b3 | |||
| 926427ff68 | |||
| abe4944843 | |||
| 5f12767f48 | |||
| 04e0b35c7d | |||
| d82cbfccc5 | |||
| 3ed1b4c77d | |||
| 6c4869f931 | |||
| b0e336e01f | |||
| 05bdd42567 | |||
| d8c2a71531 | |||
| a469e3dbe3 | |||
| b8b951f094 | |||
| c409cfa421 | |||
| 9f7814591e | |||
| 2c995f7fa7 | |||
| 7e5db90b3b | |||
| f7f83bc057 | |||
| 530e7ae44e | |||
| 126044cd48 | |||
| f76e90990f | |||
| 587542ace7 | |||
| d3676b376d | |||
| 53a3ad24e6 | |||
| 05add96294 | |||
| 9b5fd3d67b | |||
| 5ece0b5af0 | |||
| 332b42aa49 | |||
| 97472c6ce6 | |||
| 48a3a920d2 | |||
| 7b7e3b82f1 | |||
| 0b7f04ab37 | |||
| 083b18139a | |||
| 1bc3943f33 | |||
| 449613de3e | |||
| 7d8ec2678c | |||
| 12c0ce258b | |||
| 42317ec207 | |||
| 343c14db48 | |||
| 2fcb9d7b30 | |||
| ccbcb991b1 | |||
| 33f4da875a | |||
| 0549e39a00 | |||
| 6fb0fc643b | |||
| 8824579dac | |||
| 94b6a9df8d | |||
| cb8a8b997f | |||
| fe99c22022 | |||
| 0225047a52 | |||
| d89a24d96b | |||
| c5535ddbc2 | |||
| 3a21d48dbc | |||
| ea8ff709c2 | |||
| eb9937c33a | |||
| 777c7dd683 | |||
| 10963fe3c4 | |||
| 3e5d684333 | |||
| 6a9b2b260b | |||
| 7a38d7f845 | |||
| 745707dc4b | |||
| 1f4ceaa75c | |||
| a16f28eb26 | |||
| fa36ff3662 | |||
| ae4cb00bbc | |||
| fd166389c4 | |||
| a48b996571 | |||
| 6e4929b84d | |||
| f912d465c5 | |||
| 3e292b77ad | |||
| dc000ea33c | |||
| aaa8cafd0b | |||
| ce0923cfc6 | |||
| 7473557580 | |||
| 982ba0f4b0 | |||
| 278c1fefaa | |||
| 71b2137513 | |||
| 2952992ffe | |||
| 0dbd214b00 | |||
| 90ca566e53 | |||
| aa633bbbb2 | |||
| 2c204d9d9e | |||
| 8307da1a87 | |||
| d339f74e95 | |||
| 59fe173933 | |||
| 51769847ad | |||
| 918e7ad682 | |||
| ca55579982 | |||
| b5099c37c7 | |||
| 2826fbd807 | |||
| b5d209677e | |||
| b15d03a54d | |||
| 247aa08d57 | |||
| 394078d470 | |||
| 91834e8f53 | |||
| 201bc2d1ab | |||
| 29ed7bf8ae | |||
| 26f32bab8e | |||
| 1566b16f0f | |||
| 0a8b1cc784 | |||
| c441887a96 | |||
| 32d76cc143 | |||
| 4340df53fd | |||
| f6c6f4f0c0 | |||
| 18713fe513 | |||
| a1edad4e08 | |||
| 1c040912f6 | |||
| 458f1d3b8f | |||
| 9e5f2f3c9a | |||
| f6022c8dda | |||
| 0ed15db408 | |||
| c742c6c249 | |||
| b06a4d2e13 | |||
| 89cd2772dc | |||
| 48c69b9335 | |||
| e8d6f694e7 | |||
| 253b58aafb | |||
| a864fc1fe8 | |||
| 8a5cd21603 | |||
| f2a7b3b255 | |||
| d5ca5e32b4 | |||
| 37969909ca | |||
| fe92947d72 | |||
| b9165a8b70 | |||
| 27bcea78d2 | |||
| ce9be79ec6 | |||
| d83887e314 | |||
| 59fa733156 | |||
| 534c28046a | |||
| 4056b47d32 | |||
| 5e9d791523 | |||
| 9127061194 | |||
| 9563526108 | |||
| 61d7dba2c0 | |||
| 8081d1d97b | |||
| 36c6dbb6be | |||
| 56b7f8d98b | |||
| bba5e6a59a | |||
| 4dc181b4de | |||
| 792860a7bb | |||
| c3747d70ce | |||
| 2fc0fe574b | |||
| a293f53438 | |||
| 85b7574f43 | |||
| c961eb368c | |||
| 529c52844d | |||
| 6949178f4b | |||
| 30ec9406de | |||
| 04f49d42cf | |||
| f0148ae833 | |||
| 4ced9cf8b2 | |||
| d0ab7e505d | |||
| b511ae3a1a | |||
| 85d7d5e7cf | |||
| 05ebc8d2f9 | |||
| b86d513aff | |||
| c251c9f0d3 | |||
| 7be4480254 | |||
| 3cd1592abc | |||
| bc3a5122dd | |||
| 4d2b145369 | |||
| 32350fd35a | |||
| a922272c67 | |||
| 3c7b5d7522 | |||
| 33c07a2390 | |||
| d2210e9985 | |||
| 48e8e12877 | |||
| 2b248e621c | |||
| edfe6ed547 | |||
| 6cffa06bd6 | |||
| d08946c822 | |||
| 6892c1afb8 | |||
| 7cecb01ffd | |||
| 38d3d6b575 | |||
| 528b06f692 | |||
| 92602e3480 | |||
| f18e59575f | |||
| 64c9d97e53 | |||
| 71fd352ea5 | |||
| fbd20fd4b1 | |||
| b0f77a38f0 | |||
| bf5c3bf5ae | |||
| e9e598d32c | |||
| b2eeb6a70d | |||
| 9e4cf35370 | |||
| ebd87e0eaa | |||
| d369567f3f | |||
| ba0b0ea52d | |||
| f36a88384d | |||
| 7fb89da4db | |||
| 19f7ba1ef4 | |||
| 23532b0ec8 | |||
| 47042ed3d3 | |||
| 0c57e0e6eb | |||
| ace18acd7e | |||
| b91fa1a8f2 | |||
| 7a84761810 | |||
| 18200aa997 | |||
| bd0ebeb092 | |||
| 358610655b | |||
| fa3f79c0e4 | |||
| d25fae730d | |||
| 5b150c74ac | |||
| 83fcdcfd86 | |||
| bd058d649a | |||
| ec638b9c3e | |||
| 7b4bf6e502 | |||
| d7f8214d24 | |||
| 22c0350a4a | |||
| 3222d39808 | |||
| 33c339a724 | |||
| e9c793cede | |||
| 1cbd355a2a | |||
| bee73cce12 | |||
| f5d258b42d | |||
| c1278674c3 | |||
| 605e66c159 | |||
| b86bbb0e82 | |||
| 930dd74edb | |||
| d30b5b0b2c | |||
| 8e785cc215 | |||
| efe0970245 | |||
| 15264d36f0 | |||
| 298e06974e | |||
| 91acf40b3b | |||
| 085f4a4fcf | |||
| 3e2510cbda | |||
| 2775d9bedc | |||
| 7afbc8e7bf | |||
| 3a2ed918de | |||
| 847b3523a8 | |||
| 72ac3532d2 | |||
| e24e3af955 | |||
| 3180b5c5b6 | |||
| 480f73dba7 | |||
| 56a13c5e0c | |||
| 7175860ae0 | |||
| 9177257952 | |||
| 3da387591d | |||
| 5213d6de5c | |||
| bd5182792e | |||
| b057b6d68a | |||
| 0bc1234a4e | |||
| 8b76f2a893 | |||
| 943e53f655 | |||
| 9846d6dc4d | |||
| 4e9f9b77f4 | |||
| 91e9392992 | |||
| 6093e4ff5e | |||
| 2f4a18087d | |||
| f52ae8c46b | |||
| ce53f400a8 | |||
| b9b24990b6 | |||
| b596b3584e | |||
| 05f8778e40 | |||
| ed4de4465f | |||
| 766a834f53 | |||
| 546b53f9b0 | |||
| e2274b7892 | |||
| c11bc9559c | |||
| d95b688a7f | |||
| d329123cda | |||
| aceb5b0203 | |||
| 524244d1ec | |||
| ad291265f3 | |||
| d2ac9158c6 | |||
| f6e59e0264 | |||
| 8afa6298e0 | |||
| f6436d2eee | |||
| 813fcf5903 | |||
| c522ad6e30 | |||
| a858712bcc | |||
| e131011667 | |||
| 3415554142 | |||
| 61c4a9e68d | |||
| 7280dbc66e | |||
| 67e921f862 | |||
| e75aebc4fd | |||
| 2e5db72a09 | |||
| 739de3ef78 | |||
| 626b9ceefa | |||
| 4111298b00 | |||
| cd56882845 | |||
| 37ddb9223f | |||
| 44a15900c7 | |||
| ccd56f5594 | |||
| a989ea77ff | |||
| 9e611ba8f4 | |||
| 6f8b016728 | |||
| d92d309c61 | |||
| 872ef1fadc | |||
| 9b8d40ee2d | |||
| d9eb8b426c | |||
| ef0d7821eb | |||
| b68bcba85e | |||
| fbf94bbf01 | |||
| 19205f1435 | |||
| 1e271455e8 | |||
| 1ad7abcd69 | |||
| 7a93c108fb | |||
| c8ac04228e | |||
| 11a6b2a31f | |||
| 58dec4774d | |||
| 7235141f02 | |||
| 32bef227b7 | |||
| 082378815f | |||
| f8bdb42a63 | |||
| 86be51f7ce | |||
| 5e720ec965 | |||
| 7a274bf429 | |||
| a539fd2554 | |||
| 8a192a0065 | |||
| 923f4f517f | |||
| d644b44d80 | |||
| 2115146fdb | |||
| 646e96ab15 | |||
| 4049a77332 | |||
| cabe37014b | |||
| 20fada8fd4 | |||
| dff3905e85 | |||
| c2ee1e63bb | |||
| d4806895a9 | |||
| bee357ffdc | |||
| a0a99e8f12 | |||
| ddc2619511 | |||
| 69b3645e9c | |||
| 4e1e7fe657 | |||
| 2481a8df98 | |||
| 76c99d3f47 | |||
| 2fd8d17be9 | |||
| 5b8057f063 | |||
| c9a4b708aa | |||
| 2537925350 | |||
| 5a3534bc52 | |||
| 5da0445c32 | |||
| 352d817fc1 | |||
| e55e688dc7 | |||
| ec22d985ef | |||
| 3b6508e534 | |||
| 60ec172d37 | |||
| 95451e99a7 | |||
| 1aa70c4bb8 | |||
| 750f5b18d3 | |||
| b7cea05f18 | |||
| b226be4939 | |||
| 16127a378a | |||
| b09422ed5e | |||
| b186d5f8e4 | |||
| c4d578442b | |||
| 83f76ed4a4 | |||
| 74dd444506 | |||
| 573c5a3387 | |||
| 872fb9d8f3 | |||
| da0217d330 | |||
| 507b6ab773 | |||
| 960dd52750 | |||
| 5576f65ef0 | |||
| 1823cce4f6 | |||
| 09a68f9376 | |||
| 58fbe9f4ab | |||
| 92f983a569 | |||
| 8082abc27a | |||
| 373fdd324b | |||
| dbe43a0918 | |||
| a6b9aca45a | |||
| 1731ad45f5 | |||
| 32e8a1a5dc | |||
| 466d871ede | |||
| 25037ed9c8 | |||
| 53f6577b32 | |||
| a78b5f50dd | |||
| 15c5b5de57 | |||
| 62d6db935d | |||
| fec2e0eb6e | |||
| 0eefbdc610 | |||
| fe87f6b89f | |||
| a08c698c77 | |||
| 6b4fff176a | |||
| 514326adfe | |||
| ef0f8b5282 | |||
| 135bfc6d94 | |||
| 5fcd8b1d52 | |||
| 82ca2609ec | |||
| fdcc81003d | |||
| c51267136c | |||
| 9f60e49a32 | |||
| 74b8b4f147 | |||
| 3546b3e954 | |||
| 533cc91a68 | |||
| 5fbf4379cc | |||
| d9faea49ec | |||
| 36e3857643 | |||
| fa469416a2 | |||
| c60abf747c | |||
| be51bfa67f | |||
| 8f278bcaa5 | |||
| 6c872e8a65 | |||
| 1b9e226f61 | |||
| 25b06a88ab | |||
| f2c084feda | |||
| f83ae489db | |||
| 00c18fe764 | |||
| ce90e114df | |||
| c205197683 | |||
| b13c16ddc2 | |||
| 8c9e19c0b7 | |||
| 14dd4fcd68 | |||
| d82bb9bff1 | |||
| 4b819c081e | |||
| c91ef375ba | |||
| 82d8e2854a | |||
| 7e5f4c20bf | |||
| 6e459a3afb | |||
| 2e8ab316fe | |||
| c4760e0593 | |||
| 0f8797096d | |||
| 9a1935e6ea | |||
| 25bd7b8ad7 | |||
| 7ca29b87f3 | |||
| 9679d0f6df | |||
| 62f4db0b76 | |||
| 8046a778bd | |||
| 23b2899101 | |||
| 6c8d72576c | |||
| 10f2d9b3ed | |||
| dfe512ead8 | |||
| ddbde6e15f | |||
| 96cc9a1f35 | |||
| 21203b8070 |
@@ -2,7 +2,6 @@
|
||||
syntax: glob
|
||||
|
||||
*.obj
|
||||
*.exe
|
||||
*.pdb
|
||||
*.user
|
||||
*.aps
|
||||
@@ -27,12 +26,17 @@ umbraco\presentation\usercontrols\*
|
||||
umbraco\presentation\scripts\*
|
||||
umbraco\presentation\fonts\*
|
||||
umbraco\presentation\css\*
|
||||
glob:*App_Code\*
|
||||
glob:*App_Data\*
|
||||
glob:*media\*
|
||||
glob:*masterpages\*
|
||||
glob:*macroScripts\*
|
||||
glob:*xslt\*
|
||||
|
||||
src\Umbraco.Web.UI\css\*
|
||||
src\Umbraco.Web.UI\App_Code\*
|
||||
src\Umbraco.Web.UI\App_Data\*
|
||||
src\Umbraco.Tests\App_Data\*
|
||||
src\Umbraco.Web.UI\media\*
|
||||
src\Umbraco.Web.UI\masterpages\*
|
||||
src\Umbraco.Web.UI\macroScripts\*
|
||||
src\Umbraco.Web.UI\xslt\*
|
||||
src\Umbraco.Web.UI\images\*
|
||||
src\Umbraco.Web.UI\scripts\*
|
||||
|
||||
umbraco\presentation\umbraco\plugins\uComponents\uComponentsInstaller.ascx
|
||||
umbraco\presentation\packages\uComponents\MultiNodePicker\CustomTreeService.asmx
|
||||
@@ -41,7 +45,18 @@ _BuildOutput/*
|
||||
build/UmbracoCms.AllBinaries.zip
|
||||
build/UmbracoCms.WebPI.zip
|
||||
build/UmbracoCms.zip
|
||||
build/*.nupkg
|
||||
src/Umbraco.Tests/config/applications.config
|
||||
src/Umbraco.Tests/config/trees.config
|
||||
src/Umbraco.Web.UI/web.config
|
||||
*.orig
|
||||
src/Umbraco.Tests/config/404handlers.config
|
||||
src/Umbraco.Web.UI/Views/*.cshtml
|
||||
src/Umbraco.Web.UI/Views/*.vbhtml
|
||||
src/Umbraco.Tests/config/umbracoSettings.config
|
||||
src/Umbraco.Web.UI/App_Plugins/*
|
||||
src/Umbraco.Web.UI/Views/*
|
||||
|
||||
src\Umbraco.Web.UI\[W]eb.config
|
||||
src/packages/
|
||||
build/*.zip
|
||||
|
||||
@@ -10,3 +10,20 @@ d03fcffb8834a9583a56813bb44b6abbd9f042cc Release-4.6.0
|
||||
096f20bb0575d6199f20fcb3147b63554e765a74 Release-4.8.0
|
||||
8f8a203857886b373148af29edd57460a42940be Release-4.8.1
|
||||
de73e687ddf6086ed52b6554676c1632865d07f2 Release-4.9.0
|
||||
8d7d8609e2e4b971da99cd97f72132ce85ce3333 Release-4.9.1
|
||||
f6da531fbb4c251ff61d314e2a7effb13c71e74a Release-4.10.0
|
||||
20e4dff821d8ac2527a5353618fa1a23ea1d8b34 Release-4.11.0
|
||||
7f827760cb49d749616859f528d19dde64807947 Release-4.11.1
|
||||
7f827760cb49d749616859f528d19dde64807947 Release-4.11.1
|
||||
6eb5f2fb5a88aa29ea544499df9160a1b31b5638 Release-4.11.1
|
||||
73711b806a4044dbf0d7d7c095ddfdda23b09932 4.11.2
|
||||
73711b806a4044dbf0d7d7c095ddfdda23b09932 4.11.2
|
||||
0000000000000000000000000000000000000000 4.11.2
|
||||
73711b806a4044dbf0d7d7c095ddfdda23b09932 Release-4.11.2
|
||||
77db220b89e166b3c0736ed321ecfd6416cddbcd Release-4.11.2.1
|
||||
54cde33b809dcb3a1f7e7ae0d5375f6dd0d89c8d Release-4.11.2.2
|
||||
baa44b79cf90a60631e38e11f771c200b08a4583 Release-4.11.3
|
||||
e4d0c7e740555d8707ba71f55a623a3f96da8e65 Release-4.11.3.1
|
||||
e4d0c7e740555d8707ba71f55a623a3f96da8e65 Release-4.11.3.1
|
||||
0000000000000000000000000000000000000000 Release-4.11.3.1
|
||||
e02f5aebb87e3f07d27376647756caa9762931d8 Release-4.11.4
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec
|
||||
NuGet.exe pack NuSpecs\UmbracoCms.nuspec
|
||||
REM pause
|
||||
+25
-2
@@ -1,2 +1,25 @@
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj"
|
||||
REM pause
|
||||
@ECHO OFF
|
||||
set version=4.11.5
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%version%
|
||||
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Code\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Data\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\App_Plugins\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\css\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\macroScripts\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\masterpages\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\media\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\scripts\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\usercontrols\dummy.txt
|
||||
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\xslt\dummy.txt
|
||||
|
||||
NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
|
||||
NuGet.exe pack NuSpecs\UmbracoCms.nuspec -Version %version%
|
||||
|
||||
|
||||
if ERRORLEVEL 1 goto :showerror
|
||||
|
||||
goto :EOF
|
||||
|
||||
:showerror
|
||||
pause
|
||||
+13
-4
@@ -24,6 +24,9 @@
|
||||
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildConfiguration>Release</BuildConfiguration>
|
||||
@@ -46,10 +49,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<SystemFolders Include="$(WebAppFolder)App_Code" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Plugins" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Code" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data\ClientDependency" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data\ExamineIndexes" />
|
||||
<SystemFolders Include="$(WebAppFolder)media" />
|
||||
<SystemFolders Include="$(WebAppFolder)masterpages" />
|
||||
<SystemFolders Include="$(WebAppFolder)scripts" />
|
||||
@@ -161,7 +163,7 @@
|
||||
<Message Text="Finished offsetting timestamps" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects">
|
||||
<Target Name="CompileProjects" DependsOnTargets="SetVersionNumber">
|
||||
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
|
||||
@@ -233,6 +235,13 @@
|
||||
<Message Text="Finished compiling projects" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\GlobalSettings.cs"
|
||||
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?(-([a-zA-Z]+))?"
|
||||
ReplacementText="$(BUILD_RELEASE)"/>
|
||||
</Target>
|
||||
|
||||
<Target Name="AfterBuild">
|
||||
<Message Text="Hi" />
|
||||
</Target>
|
||||
|
||||
@@ -1,370 +0,0 @@
|
||||
<?xml version="1.0" ?>
|
||||
<project name="umbraco" default="test" basedir=".">
|
||||
<description>Build the umbraco 4.6 alpha Application for asp.net 3.5</description>
|
||||
|
||||
<property name="nant.settings.currentframework" value="net-2.0" />
|
||||
|
||||
<!-- filenames and directories, generally won't change -->
|
||||
|
||||
<property name="web.dir" value="D:\inetpub\wwwroot\v4.umbraco.org" />
|
||||
<property name="public.dir" value="D:\inetpub\wwwroot\nightlies\umbraco 4.6 for asp.net 3.5" />
|
||||
<property name="root.dir" value="${directory::get-current-directory()}" />
|
||||
<property name="source.dir" value="${root.dir}\umbraco\presentation" />
|
||||
<property name="build.dir" value="${root.dir}\build" />
|
||||
<property name="dlls.dir" value="${root.dir}\foreign dlls" />
|
||||
|
||||
<property name="build.version" value="4.6 Alpha"/>
|
||||
|
||||
<property name="docs.dir" value="${root.dir}\docs" />
|
||||
|
||||
<property name="win.dir" value="c:\WINDOWS" />
|
||||
<property name="Webdeploy.dir" value="C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0" />
|
||||
|
||||
<!-- YUI -->
|
||||
<property name="YUICompressor.dir" value="D:\inetpub\wwwroot\ccnet\buildTools\YUI" />
|
||||
|
||||
|
||||
|
||||
<target name="build" depends="init">
|
||||
<!-- set everything to writable-->
|
||||
<attrib normal="true" readonly="false">
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</attrib>
|
||||
|
||||
<!-- Remove those damn DLR dlls that might be left behind by careless devs...-->
|
||||
<!-- They will get added again after build is completed, no worries no dependencies during build-->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${source.dir}\bin\IronPython.dll" />
|
||||
<include name="${source.dir}\bin\IronPython.Modules.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.Libraries.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.Libraries.Yaml.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Dynamic.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.ScriptinG.Core.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.Debugging.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.ExtensionAttribute.dll" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v4.0.30319\msbuild.exe">
|
||||
<arg value="${root.dir}\umbraco.sln" />
|
||||
<arg value="/v:n" />
|
||||
<arg value="/p:WarningLevel=0" />
|
||||
<arg value="/p:ToolsVersion=3.5" />
|
||||
</exec>
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v2.0.50727\aspnet_compiler.exe" commandline="-f -u -p umbraco/presentation -v / "${build.dir}""/>
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<!-- Directories and files -->
|
||||
<target name="directories" depends="build">
|
||||
|
||||
<!-- setup docs files -->
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- asp.net 2.0 SP1 DLR dlls -->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}\bin\Microsoft.Scripting.*" />
|
||||
<include name="${build.dir}\bin\Microsoft.Dynamic.*" />
|
||||
<include name="${build.dir}\bin\IronPython.*" />
|
||||
<include name="${build.dir}\bin\IronRuby.*" />
|
||||
</fileset>
|
||||
</delete>
|
||||
<copy todir="${build.dir}\bin">
|
||||
<fileset basedir="${dlls.dir}\DLR 2.0 SP1">
|
||||
<include name="*.dll" />
|
||||
<exclude name="Microsoft.Scripting.ExtensionAttribute.dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!--standard web.config-->
|
||||
<copy file="${root.dir}\aspnet35.config" tofile="${build.dir}\web.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!--standard /config files-->
|
||||
<copy file="${root.dir}\config templates\config\404handlers.config" tofile="${build.dir}\config\404handlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\dashboard.config" tofile="${build.dir}\config\dashboard.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\formhandlers.config" tofile="${build.dir}\config\formhandlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\metablogconfig.config" tofile="${build.dir}\config\metablogconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\restextensions.config" tofile="${build.dir}\config\restextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\xsltextensions.config" tofile="${build.dir}\config\xsltextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\tinymceconfig.config" tofile="${build.dir}\config\tinymceconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\umbracosettings.config" tofile="${build.dir}\config\umbracosettings.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\urlrewriting.config" tofile="${build.dir}\config\urlrewriting.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\applications.config" tofile="${build.dir}\config\applications.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\trees.config" tofile="${build.dir}\config\trees.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- new 4.1 files -->
|
||||
<copy file="${root.dir}\config templates\config\ClientDependency.config" tofile="${build.dir}\config\ClientDependency.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\ExamineSettings.config" tofile="${build.dir}\config\ExamineSettings.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\ExamineIndex.config" tofile="${build.dir}\config\ExamineIndex.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\scripting.config" tofile="${build.dir}\config\scripting.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
|
||||
<!--standard /data/packages files-->
|
||||
<copy file="${root.dir}\config templates\packages\installedPackages.config" tofile="${build.dir}\data\packages\installed\installedPackages.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\packages\createdPackages.config" tofile="${build.dir}\data\packages\created\createdPackages.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard access.xml file-->
|
||||
<copy file="${root.dir}\config templates\access.xml" tofile="${build.dir}\data\access.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard create UI.xml-->
|
||||
<copy file="${root.dir}\config templates\config\UI.xml" tofile="${build.dir}\umbraco\config\create\UI.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard empty cache file -->
|
||||
<copy file="${root.dir}\config templates\umbraco.config" tofile="${build.dir}\umbraco\data\umbraco.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Baseline Language file for translation tool -->
|
||||
<copy file="${build.dir}\umbraco\config\lang\en.xml" tofile="${web.dir}\usercontrols\translation\langs\en.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- LINQ2UMB dll-->
|
||||
<copy file="${root.dir}\LinqToUmbraco\src\umbraco.Linq\Core\bin\Debug - Fixed Version\umbraco.Linq.Core.dll" tofile="${build.dir}\bin\umbraco.Linq.Core.dll" failonerror="false" overwrite="true"/>
|
||||
|
||||
|
||||
<delete dir="${build.dir}\webservices" />
|
||||
<delete dir="${build.dir}\umbracoBase" />
|
||||
<delete dir="${build.dir}\Web References" />
|
||||
<delete dir="${build.dir}\obj" />
|
||||
<delete dir="${build.dir}\properties" />
|
||||
|
||||
<delete dir="${build.dir}\css" />
|
||||
<delete dir="${build.dir}\masterpages" />
|
||||
<delete dir="${build.dir}\scripts" />
|
||||
<delete dir="${build.dir}\python" />
|
||||
<delete dir="${build.dir}\xslt" />
|
||||
<delete dir="${build.dir}\usercontrols" />
|
||||
|
||||
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}/**/*.build" />
|
||||
<include name="${build.dir}/**/*.csproj" />
|
||||
<include name="${build.dir}/**/*.vspscc" />
|
||||
<include name="${build.dir}/**/*.scc" />
|
||||
<include name="${build.dir}/**/*.sln" />
|
||||
<include name="${build.dir}/**/*.compiled" />
|
||||
<include name="${build.dir}/**/*.resx" />
|
||||
<include name="${build.dir}/**/*.user" />
|
||||
<include name="${build.dir}/**/*.pdb" />
|
||||
|
||||
<include name="${build.dir}/PrecompiledApp.config" />
|
||||
<include name="${build.dir}/web.config.template" />
|
||||
<include name="${build.dir}/*.xslt" />
|
||||
<include name="${build.dir}/web.STANDARD.config" />
|
||||
<include name="${build.dir}/site.py" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<!-- standard folders -->
|
||||
<mkdir dir="${build.dir}\App_Code" />
|
||||
<mkdir dir="${build.dir}\App_Data" />
|
||||
<mkdir dir="${build.dir}\App_Data\ClientDependency" />
|
||||
<mkdir dir="${build.dir}\App_Data\ExamineIndexes" />
|
||||
|
||||
<mkdir dir="${build.dir}\media" />
|
||||
<mkdir dir="${build.dir}\masterpages" />
|
||||
<mkdir dir="${build.dir}\scripts" />
|
||||
<mkdir dir="${build.dir}\css" />
|
||||
<mkdir dir="${build.dir}\python" />
|
||||
<mkdir dir="${build.dir}\xslt" />
|
||||
<mkdir dir="${build.dir}\usercontrols" />
|
||||
</target>
|
||||
|
||||
<!-- Minify -->
|
||||
<target name="minify" description="minify JS files" depends="directories">
|
||||
<fileset basedir="${build.dir}" id="jsFileSet">
|
||||
<include name="umbraco/css/*.css"/>
|
||||
<include name="umbraco/js/**/*.js"/>
|
||||
|
||||
<include name="umbraco_client/**/*.js"/>
|
||||
<include name="umbraco_client/**/*.css"/>
|
||||
</fileset>
|
||||
|
||||
<property name="js_files" value=""/>
|
||||
<foreach item="File" property="file">
|
||||
<in>
|
||||
<items refid="jsFileSet"/>
|
||||
</in>
|
||||
<do>
|
||||
<exec program="java" workingdir="${YUICompressor.dir}" failonerror="false">
|
||||
<arg value="-jar" />
|
||||
<arg value="yuicompressor.jar" />
|
||||
<arg value="-o" />
|
||||
<arg value="${file}.min" />
|
||||
<arg value="${file}" />
|
||||
</exec>
|
||||
<move file="${file}.min" tofile="${file}" overwrite="true" failonerror="false"/>
|
||||
</do>
|
||||
</foreach>
|
||||
</target>
|
||||
|
||||
<!-- Documentation -->
|
||||
<target name="documentation" depends="directories">
|
||||
<!-- Transformations -->
|
||||
<property name="sandcastle.addfriendlyfilenames.xsl" value="${sandcastle.dir}\ProductionTransforms\AddFriendlyFilenames.xsl" />
|
||||
<property name="sandcastle.reflectiontomanifest.xsl" value="${sandcastle.dir}\ProductionTransforms\ReflectionToManifest.xsl" />
|
||||
|
||||
<property name="sandcastle.buildassembler.config" value="${sandcastle.dir}\Presentation\wiki\configuration\sandcastle.config" />
|
||||
|
||||
<!-- Create a doc dir and move vs comment files to it-->
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Create or Cleanup Working Directory -->
|
||||
<mkdir dir="${sandcastle.workingdir}" if="${not directory::exists(sandcastle.workingdir)}" />
|
||||
<delete>
|
||||
<fileset basedir="${sandcastle.workingdir}">
|
||||
<include name="**\*" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<copy file="${sandcastle.buildassembler.config}" tofile="${sandcastle.workingdir}\Sandcastle.config">
|
||||
<filterchain>
|
||||
<replacestring from="%DXROOT%\" to="${sandcastle.dir}" />
|
||||
<replacestring from=".\comments.xml" to="${docs.dir}\*.xml" />
|
||||
</filterchain>
|
||||
</copy>
|
||||
|
||||
<!-- Run MRefBuilder (introspection on assemblies) to create basic Reflection XML -->
|
||||
<exec program="${sandcastle.mrefbuilder}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value=""${build.dir}\bin\businesslogic.dll" " />
|
||||
<arg value=""${build.dir}\bin\cms.dll" " />
|
||||
<arg value=""${build.dir}\bin\controls.dll" " />
|
||||
<arg value=""${build.dir}\bin\interfaces.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.datalayer.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.editorcontrols.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.providers.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.webservices.dll" " />
|
||||
<arg value="/out:reflection.org" />
|
||||
</exec>
|
||||
|
||||
<!-- Regroup overloads -->
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.addfriendlyfilenames.xsl}"" />
|
||||
<arg value="/out:reflection.xml" />
|
||||
</exec>
|
||||
|
||||
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.reflectiontomanifest.xsl}"" />
|
||||
<arg value="/out:manifest.xml" />
|
||||
</exec>
|
||||
|
||||
<exec program="${sandcastle.buildassembler}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="/config:Sandcastle.config" />
|
||||
<arg value="manifest.xml" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- do the full release with docs, minify and nightly file distribution -->
|
||||
<target name="release" depends="zip,minify">
|
||||
<property name="assembly.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<mkdir dir="${public.dir}\${build.version}" />
|
||||
<copy file="${release.filename}" tofile="${public.dir}\${build.version}\${assembly.name}.zip" />
|
||||
</target>
|
||||
|
||||
<!-- do the full release with docs, minify and nightly file distribution -->
|
||||
<target name="zip" depends="directories">
|
||||
<property name="assembly.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<zip zipfile="${release.filename}" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="build/*" />
|
||||
<include name="build/**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<!-- do a nightly build without the minification and docs -->
|
||||
<target name="nightly" depends="zip">
|
||||
<property name="assembly.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<mkdir dir="${public.dir}\${build.version}" />
|
||||
<copy file="${release.filename}" tofile="${public.dir}\${build.version}\${assembly.name}.zip" />
|
||||
</target>
|
||||
|
||||
<!-- will produce the a clean /build folder and nothing else-->
|
||||
<target name="test" depends="directories">
|
||||
|
||||
</target>
|
||||
|
||||
<target name="webPIRelease" depends="release,webPiFile">
|
||||
<copy file="${root.dir}\webPi_sha.txt" tofile="${public.dir}\${build.version}\webPi_sha.txt" />
|
||||
<copy file="${root.dir}\Umbraco_${build.version}_WebDeploy.zip" tofile="${public.dir}\${build.version}\Umbraco_${build.version}_WebDeploy.zip" />
|
||||
</target>
|
||||
|
||||
<!-- do the webdeploy release for web PI-->
|
||||
<target name="webPiFile" depends="directories">
|
||||
|
||||
<property name="webpi.dir" value="${root.dir}\deploy" />
|
||||
|
||||
<delete dir="${webpi.dir}\umbraco" />
|
||||
|
||||
<mkdir dir="${webpi.dir}" />
|
||||
<mkdir dir="${webpi.dir}\umbraco" />
|
||||
|
||||
<copy todir="${webpi.dir}\umbraco" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="build/*" />
|
||||
<include name="build/**/*" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy file="d:\webpiAssets\installSQL.sql" tofile="${webpi.dir}\installSQL.sql" failonerror="false"/>
|
||||
<copy file="d:\webpiAssets\manifest.xml" tofile="${webpi.dir}\manifest.xml" failonerror="false"/>
|
||||
<copy file="d:\webpiAssets\parameters.xml" tofile="${webpi.dir}\parameters.xml" failonerror="false"/>
|
||||
|
||||
<property name="webpi.filename" value="${root.dir}\Umbraco_${build.version}_WebDeploy.zip" />
|
||||
<zip zipfile="${webpi.filename}" includeemptydirs="true" >
|
||||
<fileset basedir="${webpi.dir}">
|
||||
<include name="*" />
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
|
||||
<exec program="${win.dir}\hashMyFiles.exe">
|
||||
<arg value="/file "${webpi.filename}"" />
|
||||
<arg value="/stext "${root.dir}\webPi_sha.txt"" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="init" description="init tasks for the build">
|
||||
|
||||
<!-- Clean the plugins dir any leftovers, only tinyMCE belongs in here -->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}\umbraco\plugins\*" />
|
||||
<exclude name="${build.dir}\umbraco\plugins\tinymce3" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<delete dir="${build.dir}" />
|
||||
<mkdir dir="${build.dir}" />
|
||||
</target>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -1,229 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections >
|
||||
<section name="urlrewritingnet" restartOnExternalChanges="true" requirePermission="false" type="UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter" />
|
||||
<section name="microsoft.scripting" type="Microsoft.Scripting.Hosting.Configuration.Section, Microsoft.Scripting, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" />
|
||||
|
||||
<!-- ASPNETAJAX -->
|
||||
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
|
||||
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
|
||||
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
|
||||
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
|
||||
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
|
||||
</sectionGroup>
|
||||
</sectionGroup>
|
||||
</sectionGroup>
|
||||
|
||||
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<section name="umbraco.presentation.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
|
||||
<section name="clientDependency" type="ClientDependency.Core.Config.ClientDependencySection, ClientDependency.Core" requirePermission="false"/>
|
||||
<section name="Examine" type="Examine.Config.ExamineSettings, Examine" requirePermission="false"/>
|
||||
<section name="ExamineLuceneIndexSets" type="UmbracoExamine.Config.ExamineLuceneIndexes, UmbracoExamine" requirePermission="false"/>
|
||||
</configSections>
|
||||
|
||||
<urlrewritingnet configSource="config\UrlRewriting.config" />
|
||||
<microsoft.scripting configSource="config\scripting.config" />
|
||||
<clientDependency configSource="config\ClientDependency.config" />
|
||||
<Examine configSource="config\ExamineSettings.config" />
|
||||
<ExamineLuceneIndexSets configSource="config\ExamineIndex.config" />
|
||||
|
||||
<appSettings>
|
||||
<add key="umbracoDbDSN" value="server=.\SQLEXPRESS;database=DATABASE;user id=USER;password=PASS" />
|
||||
<add key="umbracoConfigurationStatus" value="" />
|
||||
<add key="umbracoReservedUrls" value="~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd" />
|
||||
<add key="umbracoReservedPaths" value="~/umbraco,~/install/" />
|
||||
<add key="umbracoContentXML" value="~/App_Data/umbraco.config" />
|
||||
<add key="umbracoStorageDirectory" value="~/App_Data" />
|
||||
<add key="umbracoPath" value="~/umbraco" />
|
||||
<add key="umbracoEnableStat" value="false" />
|
||||
<add key="umbracoHideTopLevelNodeFromPath" value="true" />
|
||||
<add key="umbracoEditXhtmlMode" value="true" />
|
||||
<add key="umbracoUseDirectoryUrls" value="false" />
|
||||
<add key="umbracoDebugMode" value="true" />
|
||||
<add key="umbracoTimeOutInMinutes" value="20" />
|
||||
<add key="umbracoVersionCheckPeriod" value="7" />
|
||||
<add key="umbracoDisableXsltExtensions" value="true" />
|
||||
<add key="umbracoDefaultUILanguage" value="en" />
|
||||
<add key="umbracoProfileUrl" value="profiler" />
|
||||
<add key="umbracoUseSSL" value="false" />
|
||||
<add key="umbracoUseMediumTrust" value="false" />
|
||||
<add key="umbracoContentXMLUseLocalTemp" value="false" />
|
||||
</appSettings>
|
||||
<system.net>
|
||||
<mailSettings>
|
||||
<smtp>
|
||||
<network host="127.0.0.1" userName="username" password="password" />
|
||||
</smtp>
|
||||
</mailSettings>
|
||||
</system.net>
|
||||
<!-- REMOVE FOR BETA -->
|
||||
<!-- added by NH to test foreign membership providers-->
|
||||
<connectionStrings>
|
||||
<remove name="LocalSqlServer" />
|
||||
<!--<add name="LocalSqlServer" connectionString="server=.\sqlexpress;database=aspnetdb;user id=DBUSER;password=DBPASSWORD" providerName="System.Data.SqlClient"/>-->
|
||||
</connectionStrings>
|
||||
<system.web>
|
||||
<!-- <trust level="Medium" originUrl=".*" /> -->
|
||||
<customErrors mode="Off" />
|
||||
<trace enabled="true" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
|
||||
<sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="false" timeout="20" />
|
||||
<globalization requestEncoding="UTF-8" responseEncoding="UTF-8" />
|
||||
<xhtmlConformance mode="Strict" />
|
||||
|
||||
<pages enableEventValidation="false">
|
||||
<!-- ASPNETAJAX -->
|
||||
<controls>
|
||||
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<add tagPrefix="umbraco" namespace="umbraco.presentation.templateControls" assembly="umbraco" />
|
||||
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
</controls>
|
||||
</pages>
|
||||
|
||||
<httpModules>
|
||||
<!-- URL REWRTIER -->
|
||||
<add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter" />
|
||||
<add name="umbracoRequestModule" type="umbraco.presentation.requestModule" />
|
||||
|
||||
<!-- UMBRACO -->
|
||||
<add name="viewstateMoverModule" type="umbraco.presentation.viewstateMoverModule, umbraco" />
|
||||
<add name="umbracoBaseRequestModule" type="umbraco.presentation.umbracobase.requestModule, umbraco" />
|
||||
|
||||
<!-- ASPNETAJAX -->
|
||||
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
|
||||
<!-- CLIENT DEPENDENCY -->
|
||||
<add name="ClientDependencyModule" type="ClientDependency.Core.Module.ClientDependencyModule, ClientDependency.Core"/>
|
||||
</httpModules>
|
||||
|
||||
<httpHandlers>
|
||||
<remove verb="*" path="*.asmx"/>
|
||||
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
|
||||
|
||||
<!-- UMBRACO CHANNELS -->
|
||||
<add verb="*" path="umbraco/channels.aspx" type="umbraco.presentation.channels.api, umbraco" />
|
||||
<add verb="*" path="umbraco/channels/word.aspx" type="umbraco.presentation.channels.wordApi, umbraco" />
|
||||
|
||||
<!-- CLIENT DEPENDENCY -->
|
||||
<add verb="*" path="DependencyHandler.axd" type="ClientDependency.Core.CompositeFiles.CompositeDependencyHandler, ClientDependency.Core "/>
|
||||
|
||||
<!-- SPELL CHECKER -->
|
||||
<add verb="GET,HEAD,POST" path="GoogleSpellChecker.ashx" type="umbraco.presentation.umbraco_client.tinymce3.plugins.spellchecker.GoogleSpellChecker,umbraco" />
|
||||
</httpHandlers>
|
||||
|
||||
<compilation defaultLanguage="c#" debug="false" batch="false">
|
||||
<assemblies>
|
||||
<!-- ASPNETAJAX -->
|
||||
<add assembly="System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
|
||||
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
|
||||
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
|
||||
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
|
||||
<add assembly="System.Web.Extensions.Design, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
|
||||
</assemblies>
|
||||
</compilation>
|
||||
|
||||
<authentication mode="Forms">
|
||||
<forms name="yourAuthCookie" loginUrl="login.aspx" protection="All" path="/" />
|
||||
</authentication>
|
||||
|
||||
<authorization>
|
||||
<allow users="?" />
|
||||
</authorization>
|
||||
|
||||
<!-- Membership Provider -->
|
||||
<membership defaultProvider="UmbracoMembershipProvider" userIsOnlineTimeWindow="15">
|
||||
<providers>
|
||||
<clear />
|
||||
<add name="UmbracoMembershipProvider" type="umbraco.providers.members.UmbracoMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" defaultMemberTypeAlias="Another Type" passwordFormat="Hashed" />
|
||||
<add name="UsersMembershipProvider" type="umbraco.providers.UsersMembershipProvider" enablePasswordRetrieval="false" enablePasswordReset="false" requiresQuestionAndAnswer="false" passwordFormat="Hashed" />
|
||||
</providers>
|
||||
</membership>
|
||||
|
||||
<!-- added by NH to support membership providers in access layer -->
|
||||
<roleManager enabled="true" defaultProvider="UmbracoRoleProvider">
|
||||
<providers>
|
||||
<clear />
|
||||
<add name="UmbracoRoleProvider" type="umbraco.providers.members.UmbracoRoleProvider" />
|
||||
</providers>
|
||||
</roleManager>
|
||||
|
||||
<!-- Sitemap provider-->
|
||||
<siteMap defaultProvider="UmbracoSiteMapProvider" enabled="true">
|
||||
<providers>
|
||||
<clear />
|
||||
<add name="UmbracoSiteMapProvider" type="umbraco.presentation.nodeFactory.UmbracoSiteMapProvider" defaultDescriptionAlias="description" securityTrimmingEnabled="true" />
|
||||
</providers>
|
||||
</siteMap>
|
||||
</system.web>
|
||||
|
||||
|
||||
<system.webServer>
|
||||
<validation validateIntegratedModeConfiguration="false" />
|
||||
<modules>
|
||||
<remove name="ScriptModule" />
|
||||
<remove name="UrlRewriteModule" />
|
||||
<remove name="umbracoRequestModule" />
|
||||
<remove name="viewstateMoverModule" />
|
||||
<remove name="umbracoBaseRequestModule" />
|
||||
<remove name="ClientDependencyModule" />
|
||||
|
||||
<add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter" />
|
||||
<add name="umbracoRequestModule" type="umbraco.presentation.requestModule" />
|
||||
<add name="viewstateMoverModule" type="umbraco.presentation.viewstateMoverModule" />
|
||||
<add name="umbracoBaseRequestModule" type="umbraco.presentation.umbracobase.requestModule" />
|
||||
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<add name="ClientDependencyModule" type="ClientDependency.Core.Module.ClientDependencyModule, ClientDependency.Core"/>
|
||||
</modules>
|
||||
|
||||
<handlers accessPolicy="Read, Write, Script, Execute">
|
||||
<remove name="WebServiceHandlerFactory-Integrated" />
|
||||
<remove name="ScriptHandlerFactory" />
|
||||
<remove name="ScriptHandlerFactoryAppServices" />
|
||||
<remove name="ScriptResource" />
|
||||
<remove name="Channels" />
|
||||
<remove name="Channels_Word" />
|
||||
<remove name="ClientDependency" />
|
||||
<remove name="SpellChecker" />
|
||||
|
||||
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
<add name="ScriptResource" verb="GET,HEAD" path="ScriptResource.axd" preCondition="integratedMode" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
|
||||
|
||||
<add verb="*" name="Channels" preCondition="integratedMode" path="umbraco/channels.aspx" type="umbraco.presentation.channels.api, umbraco" />
|
||||
<add verb="*" name="Channels_Word" preCondition="integratedMode" path="umbraco/channels/word.aspx" type="umbraco.presentation.channels.wordApi, umbraco" />
|
||||
<add verb="*" name="ClientDependency" preCondition="integratedMode" path="DependencyHandler.axd" type="ClientDependency.Core.CompositeFiles.CompositeDependencyHandler, ClientDependency.Core "/>
|
||||
<add verb="GET,HEAD,POST" preCondition="integratedMode" name="SpellChecker" path="GoogleSpellChecker.ashx" type="umbraco.presentation.umbraco_client.tinymce3.plugins.spellchecker.GoogleSpellChecker,umbraco"/>
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
|
||||
<system.codedom>
|
||||
<compilers>
|
||||
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CSharp.CSharpCodeProvider,System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" warningLevel="4">
|
||||
<providerOption name="CompilerVersion" value="v3.5" />
|
||||
<providerOption name="WarnAsError" value="false" />
|
||||
</compiler>
|
||||
</compilers>
|
||||
</system.codedom>
|
||||
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
</configuration>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<build>
|
||||
<version>4.0 Beta 2</version>
|
||||
<assembly>@assembly@</assembly>
|
||||
<date>@date@</date>
|
||||
</build>
|
||||
@@ -1,495 +0,0 @@
|
||||
<?xml version="1.0" ?>
|
||||
<project name="umbraco" default="test" basedir=".">
|
||||
<description>Build the umbraco 4.5 Application</description>
|
||||
|
||||
<!-- global properties, generally won't change -->
|
||||
<!--
|
||||
<property name="nant.settings.currentframework" value="net-2.0" />
|
||||
-->
|
||||
<property name="nant.settings.currentframework" value="net-4.0" />,
|
||||
|
||||
<property name="build.version" value="4.8.0"/>
|
||||
<property name="build.configuration" value="Debug"/>
|
||||
|
||||
|
||||
<!-- filenames and directories, generally won't change -->
|
||||
|
||||
<property name="web.dir" value="D:\inetpub\wwwroot\v4.umbraco.org" />
|
||||
<property name="public.dir" value="C:\inetpub\wwwroot\_Live Sites\nightly.umbraco.org\umbraco 4.7.2" />
|
||||
<property name="root.dir" value="${directory::get-current-directory()}" />
|
||||
<property name="source.dir" value="${root.dir}\umbraco\presentation" />
|
||||
|
||||
<property name="build.dir" value="${root.dir}\build" />
|
||||
<property name="build.symbolFiles.dir" value="${root.dir}\SymbolFiles" />
|
||||
<property name="build.macroEnginesIron.dir" value="${root.dir}\umbraco.macroEngines.Iron_build" />
|
||||
|
||||
<property name="dlls.dir" value="${root.dir}\foreign dlls" />
|
||||
|
||||
<property name="WebPiAssets.dir" value="${root.dir}\config templates\WebPi" />
|
||||
|
||||
|
||||
|
||||
<property name="docs.dir" value="${root.dir}\docs" />
|
||||
|
||||
<property name="win.dir" value="c:\WINDOWS" />
|
||||
<property name="Webdeploy.dir" value="C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0" />
|
||||
|
||||
<!-- Sandcastle Directories -->
|
||||
<property name="sandcastle.dir" value="c:\Program Files\Sandcastle" />
|
||||
<property name="sandcastle.workingdir" value="${root.dir}\docs\SandcastleWorkingDir" />
|
||||
<property name="sandcastle.output.dir" value="${sandcastle.workingdir}\Output" />
|
||||
|
||||
<!-- Sandcastle -->
|
||||
<property name="sandcastle.mrefbuilder" value="${sandcastle.dir}\productiontools\mrefbuilder.exe" />
|
||||
<property name="sandcastle.buildassembler" value="${sandcastle.dir}\productiontools\buildassembler.exe" />
|
||||
<property name="sandcastle.xsltransform" value="${sandcastle.dir}\productiontools\xsltransform.exe" />
|
||||
|
||||
<!-- YUI -->
|
||||
<property name="YUICompressor.dir" value="D:\inetpub\wwwroot\ccnet\buildTools\YUI" />
|
||||
|
||||
<!-- Build source -->
|
||||
<target name="build" depends="init">
|
||||
|
||||
<!-- set everything to writable-->
|
||||
<attrib normal="true" readonly="false">
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</attrib>
|
||||
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${source.dir}\bin\IronPython.dll" />
|
||||
<include name="${source.dir}\bin\IronPython.Modules.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.Libraries.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.Libraries.Yaml.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Dynamic.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.ScriptinG.Core.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.Debugging.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.ExtensionAttribute.dll" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v4.0.30319\msbuild.exe">
|
||||
<arg value="${root.dir}\umbraco.MacroEngines.Juno\umbraco.MacroEngines.csproj" />
|
||||
<arg value="/v:n" />
|
||||
<arg value="/p:WarningLevel=0" />
|
||||
<arg value="/p:ToolsVersion=4.0" />
|
||||
<arg value="/p:Configuration=${build.configuration}" />
|
||||
</exec>
|
||||
|
||||
|
||||
<copy file="${root.dir}\umbraco.MacroEngines.Juno\bin\${build.configuration}\umbraco.MacroEngines.dll" tofile="${source.dir}\bin\umbraco.MacroEngines.dll" failonerror="false" overwrite="true"/>
|
||||
|
||||
<copy todir="${source.dir}\bin" overwrite="true">
|
||||
<fileset basedir="${dlls.dir}\WebPages">
|
||||
<include name="*.dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v4.0.30319\msbuild.exe">
|
||||
<arg value="${root.dir}\umbraco.sln" />
|
||||
<arg value="/v:n" />
|
||||
<arg value="/p:WarningLevel=0" />
|
||||
<arg value="/p:ToolsVersion=4.0" />
|
||||
<arg value="/p:Configuration=${build.configuration}" />
|
||||
</exec>
|
||||
<exec program="${win.dir}\microsoft.net\framework\v4.0.30319\aspnet_compiler.exe" commandline="-f -u -p umbraco/presentation -v / "${build.dir}""/>
|
||||
|
||||
|
||||
<call target="buildMacroEnginesIron" />
|
||||
|
||||
<call target="buildSymbolFiles" />
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<target name="buildMacroEnginesIron">
|
||||
|
||||
<mkdir dir="${build.macroEnginesIron.dir}" />
|
||||
<mkdir dir="${build.macroEnginesIron.dir}\bin" />
|
||||
|
||||
<copy todir="${build.macroEnginesIron.dir}\bin" overwrite="true">
|
||||
<fileset basedir="${dlls.dir}\DLR 4.0">
|
||||
<include name="*.dll" />
|
||||
<exclude name="Microsoft.Scripting.ExtensionAttribute.dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy file="${root.dir}\umbraco.MacroEngines.Iron\bin\${build.configuration}\umbraco.MacroEngines.Iron.dll" tofile="${build.macroEnginesIron.dir}\bin\umbraco.MacroEngines.Iron.dll" failonerror="false" overwrite="true"/>
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<target name="buildSymbolFiles">
|
||||
|
||||
<!-- setup symbol files -->
|
||||
<mkdir dir="${build.symbolFiles.dir}" />
|
||||
|
||||
<copy todir="${build.symbolFiles.dir}" flatten="true">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
<include name="*.pdb" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy todir="${build.symbolFiles.dir}" flatten="true">
|
||||
<fileset basedir="${root.dir}" >
|
||||
<include name="**/*.pdb" />
|
||||
<include name="**/bin/*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy todir="${build.symbolFiles.dir}" flatten="true">
|
||||
<fileset basedir="${docs.dir}">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<!-- Directories and files -->
|
||||
<target name="directories" depends="build">
|
||||
|
||||
<!-- setup docs files -->
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- DLR FILES -->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}\bin\Microsoft.Scripting.*" />
|
||||
<include name="${build.dir}\bin\Microsoft.Dynamic.*" />
|
||||
<include name="${build.dir}\bin\IronPython.*" />
|
||||
<include name="${build.dir}\bin\IronRuby.*" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<!--
|
||||
<copy todir="${build.dir}\bin" overwrite="true">
|
||||
<fileset basedir="${dlls.dir}\DLR 4.0">
|
||||
<include name="*.dll" />
|
||||
<exclude name="Microsoft.Scripting.ExtensionAttribute.dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
-->
|
||||
|
||||
<!--standard web.config-->
|
||||
<copy file="${root.dir}\config templates\web.config" tofile="${build.dir}\web.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!--standard /config files-->
|
||||
<copy file="${root.dir}\config templates\config\404handlers.config" tofile="${build.dir}\config\404handlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\dashboard.config" tofile="${build.dir}\config\dashboard.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\formhandlers.config" tofile="${build.dir}\config\formhandlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\metablogconfig.config" tofile="${build.dir}\config\metablogconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\restextensions.config" tofile="${build.dir}\config\restextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\xsltextensions.config" tofile="${build.dir}\config\xsltextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\tinymceconfig.config" tofile="${build.dir}\config\tinymceconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\umbracosettings.config" tofile="${build.dir}\config\umbracosettings.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\urlrewriting.config" tofile="${build.dir}\config\urlrewriting.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\applications.config" tofile="${build.dir}\config\applications.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\trees.config" tofile="${build.dir}\config\trees.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- new 4.5 files -->
|
||||
<copy file="${root.dir}\config templates\config\ClientDependency.config" tofile="${build.dir}\config\ClientDependency.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\ExamineSettings.config" tofile="${build.dir}\config\ExamineSettings.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\ExamineIndex.config" tofile="${build.dir}\config\ExamineIndex.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<copy file="${root.dir}\config templates\config\scripting.config" tofile="${build.dir}\config\scripting.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
|
||||
<!-- Macro engines files + razor Files -->
|
||||
<copy file="${root.dir}\umbraco.MacroEngines.Juno\bin\${build.configuration}\umbraco.MacroEngines.dll" tofile="${build.dir}\bin\umbraco.MacroEngines.dll" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\umbraco.MacroEngines.Juno\bin\${build.configuration}\umbraco.MacroEngines.pdb" tofile="${build.dir}\bin\umbraco.MacroEngines.pdb" failonerror="false" overwrite="true"/>
|
||||
<copy todir="${build.dir}\bin" overwrite="true">
|
||||
<fileset basedir="${dlls.dir}\WebPages">
|
||||
<include name="*.dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
|
||||
<!--
|
||||
<copy file="${root.dir}\foreign dlls\System.Web.Razor.dll" tofile="${build.dir}\bin\System.Web.Razor.dll" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\foreign dlls\RazorEngine.Core.dll" tofile="${build.dir}\bin\RazorEngine.Core.dll" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\foreign dlls\RazorEngine.Templates.dll" tofile="${build.dir}\bin\RazorEngine.Templates.dll" failonerror="false" overwrite="true"/>
|
||||
-->
|
||||
|
||||
<!--standard /data/packages files-->
|
||||
<mkdir dir="${build.dir}\App_Data" />
|
||||
<copy file="${root.dir}\config templates\packages\installedPackages.config" tofile="${build.dir}\app_data\packages\installed\installedPackages.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\packages\createdPackages.config" tofile="${build.dir}\app_data\packages\created\createdPackages.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard access.xml file-->
|
||||
<copy file="${root.dir}\config templates\access.xml" tofile="${build.dir}\app_data\access.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard create UI.xml-->
|
||||
<copy file="${root.dir}\config templates\config\UI.xml" tofile="${build.dir}\umbraco\config\create\UI.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard empty cache file -->
|
||||
<copy file="${root.dir}\config templates\umbraco.config" tofile="${build.dir}\umbraco\app_data\umbraco.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Baseline Language file for translation tool -->
|
||||
<copy file="${build.dir}\umbraco\config\lang\en.xml" tofile="${web.dir}\usercontrols\translation\langs\en.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- LINQ2UMB dll-->
|
||||
<copy file="${root.dir}\LinqToUmbraco\src\umbraco.Linq\Core\bin\${build.configuration}\umbraco.Linq.Core.dll" tofile="${build.dir}\bin\umbraco.Linq.Core.dll" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\LinqToUmbraco\src\umbraco.Linq\Core\bin\${build.configuration}\umbraco.Linq.Core.pdb" tofile="${build.dir}\bin\umbraco.Linq.Core.pdb" failonerror="false" overwrite="true"/>
|
||||
|
||||
<delete dir="${build.dir}\webservices" />
|
||||
<delete dir="${build.dir}\umbracoBase" />
|
||||
<delete dir="${build.dir}\Web References" />
|
||||
<delete dir="${build.dir}\obj" />
|
||||
<delete dir="${build.dir}\properties" />
|
||||
|
||||
<delete dir="${build.dir}\css" />
|
||||
<delete dir="${build.dir}\masterpages" />
|
||||
<delete dir="${build.dir}\scripts" />
|
||||
<delete dir="${build.dir}\python" />
|
||||
<delete dir="${build.dir}\macroScripts" />
|
||||
<delete dir="${build.dir}\xslt" />
|
||||
<delete dir="${build.dir}\usercontrols" />
|
||||
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}/**/*.build" />
|
||||
<include name="${build.dir}/**/*.csproj" />
|
||||
<include name="${build.dir}/**/*.vspscc" />
|
||||
<include name="${build.dir}/**/*.scc" />
|
||||
<include name="${build.dir}/**/*.sln" />
|
||||
<include name="${build.dir}/**/*.compiled" />
|
||||
<include name="${build.dir}/**/*.resx" />
|
||||
<include name="${build.dir}/**/*.user" />
|
||||
<include name="${build.dir}/**/*.bak" />
|
||||
|
||||
<include name="${build.dir}/**/*.orig" />
|
||||
|
||||
<include name="${build.dir}/PrecompiledApp.config" />
|
||||
<include name="${build.dir}/web.config.template" />
|
||||
<include name="${build.dir}/*.xslt" />
|
||||
<include name="${build.dir}/web.*.config" />
|
||||
<include name="${build.dir}/site.py" />
|
||||
<include name="${build.dir}/bin/umbraco.MacroEngines.Legacy.*" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<if test="${build.configuration=='Release'}">
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}/**/*.pdb" />
|
||||
<include name="${build.dir}/bin/*.xml" />
|
||||
</fileset>
|
||||
</delete>
|
||||
</if>
|
||||
|
||||
<!-- standard folders -->
|
||||
<mkdir dir="${build.dir}\App_Code" />
|
||||
<mkdir dir="${build.dir}\App_Data\ClientDependency" />
|
||||
<mkdir dir="${build.dir}\App_Data\ExamineIndexes" />
|
||||
|
||||
<mkdir dir="${build.dir}\media" />
|
||||
<mkdir dir="${build.dir}\masterpages" />
|
||||
<mkdir dir="${build.dir}\scripts" />
|
||||
<mkdir dir="${build.dir}\css" />
|
||||
<mkdir dir="${build.dir}\macroScripts" />
|
||||
<mkdir dir="${build.dir}\xslt" />
|
||||
<mkdir dir="${build.dir}\usercontrols" />
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<!-- Documentation -->
|
||||
<target name="documentation" depends="directories">
|
||||
<!-- Transformations -->
|
||||
<property name="sandcastle.addfriendlyfilenames.xsl" value="${sandcastle.dir}\ProductionTransforms\AddFriendlyFilenames.xsl" />
|
||||
<property name="sandcastle.reflectiontomanifest.xsl" value="${sandcastle.dir}\ProductionTransforms\ReflectionToManifest.xsl" />
|
||||
|
||||
<property name="sandcastle.buildassembler.config" value="${sandcastle.dir}\Presentation\wiki\configuration\sandcastle.config" />
|
||||
|
||||
<!-- Create a doc dir and move vs comment files to it-->
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Create or Cleanup Working Directory -->
|
||||
<mkdir dir="${sandcastle.workingdir}" if="${not directory::exists(sandcastle.workingdir)}" />
|
||||
<delete>
|
||||
<fileset basedir="${sandcastle.workingdir}">
|
||||
<include name="**\*" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<copy file="${sandcastle.buildassembler.config}" tofile="${sandcastle.workingdir}\Sandcastle.config">
|
||||
<filterchain>
|
||||
<replacestring from="%DXROOT%\" to="${sandcastle.dir}" />
|
||||
<replacestring from=".\comments.xml" to="${docs.dir}\*.xml" />
|
||||
</filterchain>
|
||||
</copy>
|
||||
|
||||
<!-- Run MRefBuilder (introspection on assemblies) to create basic Reflection XML -->
|
||||
<exec program="${sandcastle.mrefbuilder}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value=""${build.dir}\bin\businesslogic.dll" " />
|
||||
<arg value=""${build.dir}\bin\cms.dll" " />
|
||||
<arg value=""${build.dir}\bin\controls.dll" " />
|
||||
<arg value=""${build.dir}\bin\interfaces.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.datalayer.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.editorcontrols.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.providers.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.webservices.dll" " />
|
||||
<arg value="/out:reflection.org" />
|
||||
</exec>
|
||||
|
||||
<!-- Regroup overloads -->
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.addfriendlyfilenames.xsl}"" />
|
||||
<arg value="/out:reflection.xml" />
|
||||
</exec>
|
||||
|
||||
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.reflectiontomanifest.xsl}"" />
|
||||
<arg value="/out:manifest.xml" />
|
||||
</exec>
|
||||
|
||||
<exec program="${sandcastle.buildassembler}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="/config:Sandcastle.config" />
|
||||
<arg value="manifest.xml" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- do the full release with docs, minify and nightly file distribution -->
|
||||
<target name="release" depends="zip">
|
||||
<property name="assembly.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<mkdir dir="${public.dir}\${build.version}" />
|
||||
<copy file="${release.filename}" tofile="${public.dir}\${build.version}\${assembly.name}.zip" />
|
||||
</target>
|
||||
|
||||
<!-- do the full release with docs, minify and nightly file distribution -->
|
||||
<target name="zip" depends="directories">
|
||||
<property name="assembly.name" value="${build.number}"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<zip zipfile="${release.filename}" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="build/*" />
|
||||
<include name="build/**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
|
||||
<zip zipfile="${root.dir}\SymbolFiles.zip" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="SymbolFiles/*" />
|
||||
<include name="SymbolFiles/**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
|
||||
<zip zipfile="${root.dir}\Umbraco.MacroEngines.Iron.zip" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="umbraco.macroEngines.Iron_build/*" />
|
||||
<include name="umbraco.macroEngines.Iron_build/**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- do a nightly build without the minification and docs -->
|
||||
<target name="nightly" depends="zip">
|
||||
<property name="assembly.name" value="${build.number}"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<mkdir dir="${public.dir}\${build.version}" />
|
||||
|
||||
<copy file="${release.filename}" tofile="${public.dir}\${build.version}\${assembly.name}.zip" />
|
||||
<copy file="${root.dir}\Umbraco.MacroEngines.Iron.zip" tofile="${public.dir}\${build.version}\Umbraco.MacroEngines.Iron.zip" />
|
||||
<copy file="${root.dir}\SymbolFiles.zip" tofile="${public.dir}\${build.version}\SymbolFiles.zip" />
|
||||
|
||||
</target>
|
||||
|
||||
<!-- will produce the a clean /build folder and nothing else-->
|
||||
<target name="test" depends="directories">
|
||||
|
||||
</target>
|
||||
|
||||
<target name="webPIRelease" depends="webPiFile">
|
||||
<copy file="${root.dir}\webPi_sha.txt" tofile="${public.dir}\${build.version}\Umbraco_${build.version}_WebDeploy_sha.txt" />
|
||||
<copy file="${root.dir}\Umbraco_${build.version}_WebDeploy.zip" tofile="${public.dir}\${build.version}\Umbraco_${build.version}_WebDeploy.zip" />
|
||||
</target>
|
||||
|
||||
<!-- do the webdeploy release for web PI-->
|
||||
<target name="webPiFile" depends="directories">
|
||||
|
||||
<property name="webpi.dir" value="${root.dir}\deploy" />
|
||||
|
||||
<delete dir="${webpi.dir}\umbraco" />
|
||||
|
||||
<mkdir dir="${webpi.dir}" />
|
||||
<mkdir dir="${webpi.dir}\umbraco" />
|
||||
|
||||
<copy todir="${webpi.dir}\umbraco" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}\build">
|
||||
<include name="*" />
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy todir="${webpi.dir}\umbraco\bin" includeemptydirs="true" >
|
||||
<fileset basedir="${dlls.dir}\SQLCE4">
|
||||
<include name="*" />
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy file="${root.dir}\components\SQLCE4Umbraco\bin\${build.configuration}\SQLCE4Umbraco.dll" tofile="${webpi.dir}\umbraco\bin\SQLCE4Umbraco.dll" failonerror="false" overwrite="true"/>
|
||||
|
||||
<copy file="${WebPiAssets.dir}\installSQL.sql" tofile="${webpi.dir}\installSQL.sql" failonerror="false"/>
|
||||
<copy file="${WebPiAssets.dir}\manifest.xml" tofile="${webpi.dir}\manifest.xml" failonerror="false"/>
|
||||
<copy file="${WebPiAssets.dir}\parameters.xml" tofile="${webpi.dir}\parameters.xml" failonerror="false"/>
|
||||
|
||||
<property name="webpi.filename" value="${root.dir}\Umbraco_${build.version}_WebDeploy.zip" />
|
||||
<zip zipfile="${webpi.filename}" includeemptydirs="true" >
|
||||
<fileset basedir="${webpi.dir}">
|
||||
<include name="*" />
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
|
||||
<exec program="${win.dir}\hashMyFiles.exe">
|
||||
<arg value="/file "${webpi.filename}"" />
|
||||
<arg value="/stext "${root.dir}\webPi_sha.txt"" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="init" description="init tasks for the build">
|
||||
|
||||
<!-- Clean the plugins dir any leftovers, only tinyMCE belongs in here -->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}\umbraco\plugins\*" />
|
||||
<exclude name="${build.dir}\umbraco\plugins\tinymce3" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<delete dir="${build.dir}" />
|
||||
<mkdir dir="${build.dir}" />
|
||||
</target>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -1,149 +0,0 @@
|
||||
<?xml version="1.0" ?>
|
||||
<project name="umbraco" default="test" basedir=".">
|
||||
<description>Build the umbraco 4.6 Application for asp.net 3.5</description>
|
||||
|
||||
<property name="nant.settings.currentframework" value="net-2.0" />
|
||||
|
||||
<!-- filenames and directories, generally won't change -->
|
||||
|
||||
<property name="public.dir" value="C:\Users\per\Documents\Projects\NugetServer\GalleryServer\src\Gallery.Server\App_Data\packages" />
|
||||
|
||||
|
||||
<property name="root.dir" value="${directory::get-current-directory()}" />
|
||||
<property name="source.dir" value="${root.dir}\umbraco\presentation" />
|
||||
<property name="build.dir" value="${root.dir}\build" />
|
||||
<property name="dlls.dir" value="${root.dir}\foreign dlls" />
|
||||
|
||||
<property name="nuget.dir" value="${root.dir}\nuget" />
|
||||
<property name="nuget.app" value="C:\Program Files (x86)\nuget\nuget.exe" />
|
||||
<property name="nuget.spec" value="${public.dir}\..\umbraco.nuspec" />
|
||||
|
||||
<property name="build.version" value="4.6.Beta"/>
|
||||
|
||||
<property name="win.dir" value="C:\windows" />
|
||||
|
||||
<target name="build" depends="init">
|
||||
<!-- set everything to writable-->
|
||||
<attrib normal="true" readonly="false">
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</attrib>
|
||||
|
||||
<!-- Remove those damn DLR dlls that might be left behind by careless devs...-->
|
||||
<!-- They will get added again after build is completed, no worries no dependencies during build-->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${source.dir}\bin\IronPython.dll" />
|
||||
<include name="${source.dir}\bin\IronPython.Modules.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.Libraries.dll" />
|
||||
<include name="${source.dir}\bin\IronRuby.Libraries.Yaml.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Dynamic.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.ScriptinG.Core.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.Debugging.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.dll" />
|
||||
<include name="${source.dir}\bin\Microsoft.Scripting.ExtensionAttribute.dll" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<!-- build for 2.0 -->
|
||||
<exec program="${win.dir}\microsoft.net\framework\v4.0.30319\msbuild.exe">
|
||||
<arg value="${root.dir}\umbraco.sln" />
|
||||
<arg value="/v:n" />
|
||||
<arg value="/p:WarningLevel=0" />
|
||||
<arg value="/p:ToolsVersion=3.5" />
|
||||
</exec>
|
||||
<exec program="${win.dir}\microsoft.net\framework\v2.0.50727\aspnet_compiler.exe" commandline="-f -u -p umbraco/presentation -v / "${build.dir}\Net20""/>
|
||||
|
||||
|
||||
<!-- build for 4.0 -->
|
||||
<exec program="${win.dir}\microsoft.net\framework\v4.0.30319\msbuild.exe">
|
||||
<arg value="${root.dir}\umbraco.sln" />
|
||||
<arg value="/v:n" />
|
||||
<arg value="/p:WarningLevel=0" />
|
||||
<arg value="/p:ToolsVersion=4.0" />
|
||||
</exec>
|
||||
<exec program="${win.dir}\microsoft.net\framework\v2.0.50727\aspnet_compiler.exe" commandline="-f -u -p umbraco/presentation -v / "${build.dir}\Net40""/>
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
<!-- Directories and files -->
|
||||
<target name="directories" depends="build">
|
||||
<!-- asp.net 2.0 SP1 DLR dlls -->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}\**\*" />
|
||||
|
||||
<exclude name="${build.dir}\**\businesslogic.dll" />
|
||||
<exclude name="${build.dir}\**\cms.dll" />
|
||||
<exclude name="${build.dir}\**\controls.dll" />
|
||||
<exclude name="${build.dir}\**\Examine.dll" />
|
||||
|
||||
<exclude name="${build.dir}\**\interfaces.dll" />
|
||||
<exclude name="${build.dir}\**\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<exclude name="${build.dir}\**\umbraco.DataLayer.dll" />
|
||||
<exclude name="${build.dir}\**\umbraco.dll" />
|
||||
<exclude name="${build.dir}\**\umbraco.editorcontrols.dll" />
|
||||
<exclude name="${build.dir}\**\umbraco.linq.core.dll" />
|
||||
<exclude name="${build.dir}\**\umbraco.macrorenderings.dll" />
|
||||
<exclude name="${build.dir}\**\umbraco.providers.dll" />
|
||||
<exclude name="${build.dir}\**\UmbracoExamine.dll" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<copy todir="${nuget.dir}\lib\Net20">
|
||||
<fileset basedir="${build.dir}\Net20\bin">
|
||||
<include name="*.dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy todir="${nuget.dir}\lib\Net40">
|
||||
<fileset basedir="${build.dir}\Net40\bin">
|
||||
<include name="*.dll" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy file="${nuget.spec}" tofile="${nuget.dir}\umbraco.nuspec" failonerror="false" overwrite="true"/>
|
||||
|
||||
<xmlpoke
|
||||
file="${nuget.dir}\umbraco.nuspec"
|
||||
xpath="/package/metadata/version"
|
||||
value="${build.version}" />
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<!-- will produce the a clean /build folder and nothing else-->
|
||||
<target name="nuget" depends="directories">
|
||||
<exec program="${nuget.app}" commandline="pack "${nuget.dir}\umbraco.nuspec" /o "${public.dir}""/>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="test">
|
||||
<exec program="${nuget.app}" commandline="pack "${nuget.dir}\umbraco.nuspec" /o "${public.dir}""/>
|
||||
</target>
|
||||
|
||||
<target name="init" description="init tasks for the build">
|
||||
|
||||
<!-- Clean the plugins dir any leftovers, only tinyMCE belongs in here -->
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}\umbraco\plugins\*" />
|
||||
<exclude name="${build.dir}\umbraco\plugins\tinymce3" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<delete dir="${build.dir}" />
|
||||
<mkdir dir="${build.dir}" />
|
||||
|
||||
<delete dir="${nuget.dir}" />
|
||||
<mkdir dir="${nuget.dir}" />
|
||||
<mkdir dir="${nuget.dir}\lib\Net20" />
|
||||
<mkdir dir="${nuget.dir}\lib\Net40" />
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -1,310 +0,0 @@
|
||||
<?xml version="1.0" ?>
|
||||
<project name="umbraco" default="test" basedir=".">
|
||||
<description>Build the umbraco 3.1.x Application</description>
|
||||
|
||||
<!-- global properties, generally won't change -->
|
||||
|
||||
<property name="nant.settings.currentframework" value="net-2.0" />
|
||||
|
||||
<!-- filenames and directories, generally won't change -->
|
||||
|
||||
<property name="web.dir" value="D:\inetpub\wwwroot\v4.umbraco.org" />
|
||||
<property name="public.dir" value="D:\inetpub\wwwroot\nightlies\umbraco 4.1" />
|
||||
<property name="root.dir" value="${directory::get-current-directory()}" />
|
||||
<property name="source.dir" value="${root.dir}\umbraco\presentation" />
|
||||
<property name="build.dir" value="${root.dir}\build" />
|
||||
<property name="dlls.dir" value="${root.dir}\foreign dlls" />
|
||||
|
||||
<property name="build.version" value="4.1"/>
|
||||
|
||||
<property name="docs.dir" value="${root.dir}\docs" />
|
||||
|
||||
<property name="win.dir" value="c:\WINDOWS" />
|
||||
<property name="Webdeploy.dir" value="C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0" />
|
||||
|
||||
<!-- Sandcastle Directories -->
|
||||
<property name="sandcastle.dir" value="c:\Program Files\Sandcastle" />
|
||||
<property name="sandcastle.workingdir" value="${root.dir}\docs\SandcastleWorkingDir" />
|
||||
<property name="sandcastle.output.dir" value="${sandcastle.workingdir}\Output" />
|
||||
|
||||
<!-- Sandcastle -->
|
||||
<property name="sandcastle.mrefbuilder" value="${sandcastle.dir}\productiontools\mrefbuilder.exe" />
|
||||
<property name="sandcastle.buildassembler" value="${sandcastle.dir}\productiontools\buildassembler.exe" />
|
||||
<property name="sandcastle.xsltransform" value="${sandcastle.dir}\productiontools\xsltransform.exe" />
|
||||
|
||||
<!-- YUI -->
|
||||
<property name="YUICompressor.dir" value="D:\inetpub\wwwroot\ccnet\buildTools\YUI" />
|
||||
|
||||
|
||||
<!-- Build source -->
|
||||
<target name="build" depends="init">
|
||||
<attrib normal="true" readonly="false">
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</attrib>
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v3.5\msbuild.exe">
|
||||
<arg value="${root.dir}\umbraco.sln" />
|
||||
</exec>
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v2.0.50727\aspnet_compiler.exe" commandline="-f -u -p umbraco/presentation -v / "${build.dir}""/>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- Directories and files -->
|
||||
<target name="directories" depends="build">
|
||||
|
||||
<!-- setup docs files -->
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!--standard web.config-->
|
||||
<copy file="${root.dir}\config templates\web.config" tofile="${build.dir}\web.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!--standard /config files-->
|
||||
<copy file="${root.dir}\config templates\config\404handlers.config" tofile="${build.dir}\config\404handlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\dashboard.config" tofile="${build.dir}\config\dashboard.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\formhandlers.config" tofile="${build.dir}\config\formhandlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\metablogconfig.config" tofile="${build.dir}\config\metablogconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\restextensions.config" tofile="${build.dir}\config\restextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\xsltextensions.config" tofile="${build.dir}\config\xsltextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\tinymceconfig.config" tofile="${build.dir}\config\tinymceconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\umbracosettings.config" tofile="${build.dir}\config\umbracosettings.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\urlrewriting.config" tofile="${build.dir}\config\urlrewriting.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\applications.config" tofile="${build.dir}\config\applications.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\trees.config" tofile="${build.dir}\config\trees.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!--standard /data/packages files-->
|
||||
<copy file="${root.dir}\config templates\packages\installedPackages.config" tofile="${build.dir}\data\packages\installed\installedPackages.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\packages\createdPackages.config" tofile="${build.dir}\data\packages\created\createdPackages.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard access.xml file-->
|
||||
<copy file="${root.dir}\config templates\access.xml" tofile="${build.dir}\data\access.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard create UI.xml-->
|
||||
<copy file="${root.dir}\config templates\config\UI.xml" tofile="${build.dir}\umbraco\config\create\UI.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard empty cache file -->
|
||||
<copy file="${root.dir}\config templates\umbraco.config" tofile="${build.dir}\umbraco\data\umbraco.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Baseline Language file for translation tool -->
|
||||
<copy file="${build.dir}\umbraco\config\lang\en.xml" tofile="${web.dir}\usercontrols\translation\langs\en.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
|
||||
<!-- standard folders -->
|
||||
<mkdir dir="${build.dir}\App_Code" />
|
||||
<mkdir dir="${build.dir}\App_Data" />
|
||||
|
||||
<mkdir dir="${build.dir}\media" />
|
||||
<mkdir dir="${build.dir}\masterpages" />
|
||||
<mkdir dir="${build.dir}\scripts" />
|
||||
<mkdir dir="${build.dir}\css" />
|
||||
<mkdir dir="${build.dir}\python" />
|
||||
<mkdir dir="${build.dir}\xslt" />
|
||||
<mkdir dir="${build.dir}\usercontrols" />
|
||||
|
||||
<delete dir="${build.dir}\webservices" />
|
||||
<delete dir="${build.dir}\umbracoBase" />
|
||||
<delete dir="${build.dir}\Web References" />
|
||||
<delete dir="${build.dir}\obj" />
|
||||
<delete dir="${build.dir}\properties" />
|
||||
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}/**/*.build" />
|
||||
<include name="${build.dir}/**/*.csproj" />
|
||||
<include name="${build.dir}/**/*.vspscc" />
|
||||
<include name="${build.dir}/**/*.scc" />
|
||||
<include name="${build.dir}/**/*.sln" />
|
||||
<include name="${build.dir}/**/*.compiled" />
|
||||
<include name="${build.dir}/**/*.resx" />
|
||||
<include name="${build.dir}/PrecompiledApp.config" />
|
||||
<include name="${build.dir}/web.config.template" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
</target>
|
||||
|
||||
<!-- Minify -->
|
||||
<target name="minify" description="minify JS files" depends="directories">
|
||||
<fileset basedir="${build.dir}" id="jsFileSet">
|
||||
<include name="umbraco/css/*.css"/>
|
||||
<include name="umbraco/js/**/*.js"/>
|
||||
|
||||
<include name="umbraco_client/**/*.js"/>
|
||||
<include name="umbraco_client/**/*.css"/>
|
||||
</fileset>
|
||||
|
||||
<property name="js_files" value=""/>
|
||||
<foreach item="File" property="file">
|
||||
<in>
|
||||
<items refid="jsFileSet"/>
|
||||
</in>
|
||||
<do>
|
||||
<exec program="java" workingdir="${YUICompressor.dir}" failonerror="false">
|
||||
<arg value="-jar" />
|
||||
<arg value="yuicompressor.jar" />
|
||||
<arg value="-o" />
|
||||
<arg value="${file}.min" />
|
||||
<arg value="${file}" />
|
||||
</exec>
|
||||
<move file="${file}.min" tofile="${file}" overwrite="true" failonerror="false"/>
|
||||
</do>
|
||||
</foreach>
|
||||
</target>
|
||||
|
||||
<!-- Documentation -->
|
||||
<target name="documentation" depends="directories">
|
||||
<!-- Transformations -->
|
||||
<property name="sandcastle.addfriendlyfilenames.xsl" value="${sandcastle.dir}\ProductionTransforms\AddFriendlyFilenames.xsl" />
|
||||
<property name="sandcastle.reflectiontomanifest.xsl" value="${sandcastle.dir}\ProductionTransforms\ReflectionToManifest.xsl" />
|
||||
|
||||
<property name="sandcastle.buildassembler.config" value="${sandcastle.dir}\Presentation\wiki\configuration\sandcastle.config" />
|
||||
|
||||
<!-- Create a doc dir and move vs comment files to it-->
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Create or Cleanup Working Directory -->
|
||||
<mkdir dir="${sandcastle.workingdir}" if="${not directory::exists(sandcastle.workingdir)}" />
|
||||
<delete>
|
||||
<fileset basedir="${sandcastle.workingdir}">
|
||||
<include name="**\*" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<copy file="${sandcastle.buildassembler.config}" tofile="${sandcastle.workingdir}\Sandcastle.config">
|
||||
<filterchain>
|
||||
<replacestring from="%DXROOT%\" to="${sandcastle.dir}" />
|
||||
<replacestring from=".\comments.xml" to="${docs.dir}\*.xml" />
|
||||
</filterchain>
|
||||
</copy>
|
||||
|
||||
<!-- Run MRefBuilder (introspection on assemblies) to create basic Reflection XML -->
|
||||
<exec program="${sandcastle.mrefbuilder}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value=""${build.dir}\bin\businesslogic.dll" " />
|
||||
<arg value=""${build.dir}\bin\cms.dll" " />
|
||||
<arg value=""${build.dir}\bin\controls.dll" " />
|
||||
<arg value=""${build.dir}\bin\interfaces.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.datalayer.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.editorcontrols.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.providers.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.webservices.dll" " />
|
||||
<arg value="/out:reflection.org" />
|
||||
</exec>
|
||||
|
||||
<!-- Regroup overloads -->
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.addfriendlyfilenames.xsl}"" />
|
||||
<arg value="/out:reflection.xml" />
|
||||
</exec>
|
||||
|
||||
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.reflectiontomanifest.xsl}"" />
|
||||
<arg value="/out:manifest.xml" />
|
||||
</exec>
|
||||
|
||||
<exec program="${sandcastle.buildassembler}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="/config:Sandcastle.config" />
|
||||
<arg value="manifest.xml" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<!-- do the full release with docs, minify and nightly file distribution -->
|
||||
<target name="release" depends="zip,minify">
|
||||
<property name="assembly.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<mkdir dir="${public.dir}\${build.version}" />
|
||||
<copy file="${release.filename}" tofile="${public.dir}\${build.version}\${assembly.name}.zip" />
|
||||
</target>
|
||||
|
||||
<!-- do the full release with docs, minify and nightly file distribution -->
|
||||
<target name="zip" depends="directories">
|
||||
<property name="assembly.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<zip zipfile="${release.filename}" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="build/*" />
|
||||
<include name="build/**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
</target>
|
||||
|
||||
<!-- do a nightly build without the minification and docs -->
|
||||
<target name="nightly" depends="zip">
|
||||
<property name="assembly.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
<property name="release.filename" value="${root.dir}\build_${build.version}_${assembly.name}.zip" />
|
||||
|
||||
<mkdir dir="${public.dir}\${build.version}" />
|
||||
<copy file="${release.filename}" tofile="${public.dir}\${build.version}\${assembly.name}.zip" />
|
||||
</target>
|
||||
|
||||
<!-- will produce the a clean /build folder and nothing else-->
|
||||
<target name="test" depends="directories">
|
||||
|
||||
</target>
|
||||
|
||||
<target name="webPIRelease" depends="release,webPiFile">
|
||||
<copy file="${root.dir}\webPi_sha.txt" tofile="${public.dir}\${build.version}\webPi_sha.txt" />
|
||||
<copy file="${root.dir}\Umbraco_${build.version}_WebDeploy.zip" tofile="${public.dir}\${build.version}\Umbraco_${build.version}_WebDeploy.zip" />
|
||||
</target>
|
||||
|
||||
<!-- do the webdeploy release for web PI-->
|
||||
<target name="webPiFile" depends="directories">
|
||||
|
||||
<property name="webpi.dir" value="${root.dir}\deploy" />
|
||||
|
||||
<delete dir="${webpi.dir}\umbraco" />
|
||||
|
||||
<mkdir dir="${webpi.dir}" />
|
||||
<mkdir dir="${webpi.dir}\umbraco" />
|
||||
|
||||
<copy todir="${webpi.dir}\umbraco" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="build/*" />
|
||||
<include name="build/**/*" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<copy file="d:\webpiAssets\installSQL.sql" tofile="${webpi.dir}\installSQL.sql" failonerror="false"/>
|
||||
<copy file="d:\webpiAssets\manifest.xml" tofile="${webpi.dir}\manifest.xml" failonerror="false"/>
|
||||
<copy file="d:\webpiAssets\parameters.xml" tofile="${webpi.dir}\parameters.xml" failonerror="false"/>
|
||||
|
||||
<property name="webpi.filename" value="${root.dir}\Umbraco_${build.version}_WebDeploy.zip" />
|
||||
<zip zipfile="${webpi.filename}" includeemptydirs="true" >
|
||||
<fileset basedir="${webpi.dir}">
|
||||
<include name="*" />
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
|
||||
<exec program="${win.dir}\hashMyFiles.exe">
|
||||
<arg value="/file "${webpi.filename}"" />
|
||||
<arg value="/stext "${root.dir}\webPi_sha.txt"" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="init" description="init tasks for the build">
|
||||
<delete dir="${build.dir}" />
|
||||
<mkdir dir="${build.dir}" />
|
||||
</target>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -1,248 +0,0 @@
|
||||
<?xml version="1.0" ?>
|
||||
<project name="umbraco" default="compile" basedir=".">
|
||||
<description>Build the umbraco 3.1.x Application</description>
|
||||
|
||||
<!-- global properties, generally won't change -->
|
||||
|
||||
<property name="nant.settings.currentframework" value="net-2.0" />
|
||||
|
||||
<!-- filenames and directories, generally won't change -->
|
||||
|
||||
<property name="web.dir" value="D:\inetpub\wwwroot\v4.umbraco.org" />
|
||||
<property name="public.dir" value="D:\inetpub\wwwroot\nightlies\umbraco 4.0" />
|
||||
<property name="root.dir" value="${directory::get-current-directory()}" />
|
||||
<property name="source.dir" value="${root.dir}\umbraco\presentation" />
|
||||
<property name="build.dir" value="${root.dir}\build" />
|
||||
<property name="dlls.dir" value="${root.dir}\foreign dlls" />
|
||||
|
||||
<property name="build.major" value="4"/>
|
||||
<property name="build.minor" value="0"/>
|
||||
<property name="build.build" value="0"/>
|
||||
<property name="build.revision" value="0"/>
|
||||
|
||||
<property name="docs.dir" value="${root.dir}\docs" />
|
||||
|
||||
<property name="win.dir" value="c:\WINDOWS" />
|
||||
<property name="cc.dir" value="C:\Program Files\CruiseControl.NET\server" />
|
||||
<property name="Webdeploy.dir" value="C:\Program Files\MSBuild\Microsoft\WebDeployment\v8.0" />
|
||||
|
||||
<!-- Sandcastle Directories -->
|
||||
<property name="sandcastle.dir" value="c:\Program Files\Sandcastle" />
|
||||
<property name="sandcastle.workingdir" value="${root.dir}\docs\SandcastleWorkingDir" />
|
||||
<property name="sandcastle.output.dir" value="${sandcastle.workingdir}\Output" />
|
||||
<!-- Sandcastle Executables -->
|
||||
<property name="sandcastle.mrefbuilder" value="${sandcastle.dir}\productiontools\mrefbuilder.exe" />
|
||||
<property name="sandcastle.buildassembler" value="${sandcastle.dir}\productiontools\buildassembler.exe" />
|
||||
<property name="sandcastle.xsltransform" value="${sandcastle.dir}\productiontools\xsltransform.exe" />
|
||||
<!-- Transformations -->
|
||||
<property name="sandcastle.ApplyVSDocModel.xsl" value="${sandcastle.dir}\ProductionTransforms\ApplyVSDocModel.xsl" />
|
||||
<property name="sandcastle.addguidfilenames.xsl" value="${sandcastle.dir}\ProductionTransforms\AddGuidFilenames.xsl" />
|
||||
<property name="sandcastle.addfriendlyfilenames.xsl" value="${sandcastle.dir}\ProductionTransforms\AddFriendlyFilenames.xsl" />
|
||||
<property name="sandcastle.reflectiontomanifest.xsl" value="${sandcastle.dir}\ProductionTransforms\ReflectionToManifest.xsl" />
|
||||
<property name="sandcastle.reflectiontochmproject.xsl" value="${sandcastle.dir}\ProductionTransforms\ReflectionToChmProject.xsl" />
|
||||
<property name="sandcastle.reflectiontochmcontents.xsl" value="${sandcastle.dir}\ProductionTransforms\ReflectionToChmContents.xsl" />
|
||||
<property name="sandcastle.reflectiontochmindex.xsl" value="${sandcastle.dir}\ProductionTransforms\ReflectionToChmIndex.xsl" />
|
||||
|
||||
<property name="sandcastle.buildassembler.config" value="${sandcastle.dir}\Presentation\wiki\configuration\sandcastle.config" />
|
||||
|
||||
<target name="compile" depends="init">
|
||||
|
||||
<attrib normal="true" readonly="false">
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="**/*" />
|
||||
</fileset>
|
||||
</attrib>
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v3.5\msbuild.exe">
|
||||
<arg value="${root.dir}\umbraco.sln" />
|
||||
</exec>
|
||||
|
||||
<exec program="${win.dir}\microsoft.net\framework\v2.0.50727\aspnet_compiler.exe" commandline="-f -u -p umbraco/presentation -v / "${build.dir}""/>
|
||||
|
||||
<!-- Moves stuff around and zips the distribution-->
|
||||
<call target="zip"/>
|
||||
|
||||
<!-- Handles documentation
|
||||
<call target="docs" />
|
||||
-->
|
||||
|
||||
</target>
|
||||
|
||||
|
||||
<target name="clean" description="remove generated files">
|
||||
|
||||
|
||||
</target>
|
||||
|
||||
<target name="docs" description="generates documents">
|
||||
|
||||
<!-- Create a doc dir and move vs comment files to it-->
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
<!-- Create or Cleanup Working Directory -->
|
||||
<mkdir dir="${sandcastle.workingdir}" if="${not directory::exists(sandcastle.workingdir)}" />
|
||||
<delete>
|
||||
<fileset basedir="${sandcastle.workingdir}">
|
||||
<include name="**\*" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
<copy file="${sandcastle.buildassembler.config}" tofile="${sandcastle.workingdir}\Sandcastle.config">
|
||||
<filterchain>
|
||||
<replacestring from="%DXROOT%\" to="${sandcastle.dir}" />
|
||||
<replacestring from=".\comments.xml" to="${docs.dir}\*.xml" />
|
||||
</filterchain>
|
||||
</copy>
|
||||
|
||||
<!-- Run MRefBuilder (introspection on assemblies) to create basic Reflection XML -->
|
||||
<exec program="${sandcastle.mrefbuilder}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value=""${build.dir}\bin\businesslogic.dll" " />
|
||||
<arg value=""${build.dir}\bin\cms.dll" " />
|
||||
<arg value=""${build.dir}\bin\controls.dll" " />
|
||||
<arg value=""${build.dir}\bin\interfaces.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.datalayer.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.editorcontrols.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.providers.dll" " />
|
||||
<arg value=""${build.dir}\bin\umbraco.webservices.dll" " />
|
||||
<arg value="/out:reflection.org" />
|
||||
</exec>
|
||||
|
||||
<!-- Regroup overloads -->
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.addfriendlyfilenames.xsl}"" />
|
||||
<arg value="/out:reflection.xml" />
|
||||
</exec>
|
||||
|
||||
|
||||
<exec program="${sandcastle.xsltransform}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="reflection.org" />
|
||||
<arg value="/xsl:"${sandcastle.reflectiontomanifest.xsl}"" />
|
||||
<arg value="/out:manifest.xml" />
|
||||
</exec>
|
||||
|
||||
<exec program="${sandcastle.buildassembler}" workingdir="${sandcastle.workingdir}">
|
||||
<arg value="/config:Sandcastle.config" />
|
||||
<arg value="manifest.xml" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="zip" description="zip the release">
|
||||
|
||||
<mkdir dir="${docs.dir}" />
|
||||
<copy todir="${docs.dir}">
|
||||
<fileset basedir="${build.dir}\bin">
|
||||
<include name="*.xml" />
|
||||
</fileset>
|
||||
</copy>
|
||||
|
||||
|
||||
<!--standard web.config-->
|
||||
<copy file="${root.dir}\config templates\web.config" tofile="${build.dir}\web.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!--standard /config files-->
|
||||
<copy file="${root.dir}\config templates\config\404handlers.config" tofile="${build.dir}\config\404handlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\dashboard.config" tofile="${build.dir}\config\dashboard.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\formhandlers.config" tofile="${build.dir}\config\formhandlers.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\metablogconfig.config" tofile="${build.dir}\config\metablogconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\restextensions.config" tofile="${build.dir}\config\restextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\xsltextensions.config" tofile="${build.dir}\config\xsltextensions.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\tinymceconfig.config" tofile="${build.dir}\config\tinymceconfig.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\umbracosettings.config" tofile="${build.dir}\config\umbracosettings.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\urlrewriting.config" tofile="${build.dir}\config\urlrewriting.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\applications.config" tofile="${build.dir}\config\applications.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\config\trees.config" tofile="${build.dir}\config\trees.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!--standard /data/packages files-->
|
||||
<copy file="${root.dir}\config templates\packages\installedPackages.config" tofile="${build.dir}\data\packages\installed\installedPackages.config" failonerror="false" overwrite="true"/>
|
||||
<copy file="${root.dir}\config templates\packages\createdPackages.config" tofile="${build.dir}\data\packages\created\createdPackages.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard access.xml file-->
|
||||
<copy file="${root.dir}\config templates\access.xml" tofile="${build.dir}\data\access.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard create UI.xml-->
|
||||
<copy file="${root.dir}\config templates\config\UI.xml" tofile="${build.dir}\umbraco\config\create\UI.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Standard empty cache file -->
|
||||
<copy file="${root.dir}\config templates\umbraco.config" tofile="${build.dir}\umbraco\data\umbraco.config" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!-- Baseline Language file for translation tool -->
|
||||
<copy file="${build.dir}\umbraco\config\lang\en.xml" tofile="${web.dir}\usercontrols\translation\langs\en.xml" failonerror="false" overwrite="true"/>
|
||||
|
||||
<!--
|
||||
<delete dir="${build.dir}\umbraco\webservices\api" />
|
||||
<mkdir dir="${build.dir}\umbraco\webservices\api" />
|
||||
|
||||
<copy todir="${build.dir}\umbraco\webservices\api">
|
||||
<fileset basedir="${root.dir}\components\umbraco.webservices}">
|
||||
<include name="*.asmx" />
|
||||
</fileset>
|
||||
</copy>
|
||||
-->
|
||||
|
||||
<!-- standard folders -->
|
||||
<mkdir dir="${build.dir}\App_Code" />
|
||||
<mkdir dir="${build.dir}\media" />
|
||||
<mkdir dir="${build.dir}\masterpages" />
|
||||
<mkdir dir="${build.dir}\scripts" />
|
||||
<mkdir dir="${build.dir}\css" />
|
||||
<mkdir dir="${build.dir}\python" />
|
||||
<mkdir dir="${build.dir}\xslt" />
|
||||
<mkdir dir="${build.dir}\usercontrols" />
|
||||
|
||||
<delete dir="${build.dir}\webservices" />
|
||||
<delete dir="${build.dir}\umbracoBase" />
|
||||
<delete dir="${build.dir}\Web References" />
|
||||
<delete dir="${build.dir}\obj" />
|
||||
<delete dir="${build.dir}\properties" />
|
||||
<delete>
|
||||
<fileset>
|
||||
<include name="${build.dir}/**/*.build" />
|
||||
<include name="${build.dir}/**/*.csproj" />
|
||||
<include name="${build.dir}/**/*.vspscc" />
|
||||
<include name="${build.dir}/**/*.scc" />
|
||||
<include name="${build.dir}/**/*.sln" />
|
||||
<include name="${build.dir}/**/*.compiled" />
|
||||
<include name="${build.dir}/**/*.resx" />
|
||||
<include name="${build.dir}/PrecompiledApp.config" />
|
||||
<include name="${build.dir}/web.config.template" />
|
||||
</fileset>
|
||||
</delete>
|
||||
|
||||
|
||||
<property name="dist.name" value="${ assemblyname::get-version( assemblyname::get-assembly-name('umbraco/presentation/bin/umbraco.dll') ) }"/>
|
||||
|
||||
|
||||
<zip zipfile="${web.dir}\nightly\umbraco40.zip" includeemptydirs="true" >
|
||||
<fileset basedir="${root.dir}">
|
||||
<include name="build/*" />
|
||||
<include name="build/**/*" />
|
||||
</fileset>
|
||||
</zip>
|
||||
|
||||
<copy file="${web.dir}\nightly\umbraco40.zip" tofile="${public.dir}\${dist.name}_${datetime::get-ticks(datetime::now())}.zip" />
|
||||
|
||||
<copy file="${root.dir}\build.xml" tofile="${web.dir}\nightly\build.xml">
|
||||
<filterchain>
|
||||
<replacetokens>
|
||||
<token key="assembly" value="${dist.name}" />
|
||||
<token key="date" value="${datetime::now()}" />
|
||||
</replacetokens>
|
||||
</filterchain>
|
||||
</copy>
|
||||
|
||||
</target>
|
||||
|
||||
<target name="init" description="init tasks for the build">
|
||||
<delete dir="${build.dir}" />
|
||||
<mkdir dir="${build.dir}" />
|
||||
</target>
|
||||
|
||||
|
||||
</project>
|
||||
@@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>4.9.0</version>
|
||||
<version>$version$</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
@@ -26,6 +26,7 @@
|
||||
<file src="..\_BuildOutput\WebApp\bin\ICSharpCode.SharpZipLib.dll" target="lib\ICSharpCode.SharpZipLib.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Lucene.Net.dll" target="lib\Lucene.Net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.Web.Helpers.dll" target="lib\Microsoft.Web.Helpers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.Web.Infrastructure.dll" target="lib\Microsoft.Web.Infrastructure.dll" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms</id>
|
||||
<version>4.9.0</version>
|
||||
<version>$version$</version>
|
||||
<title>Umbraco Cms</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
@@ -15,7 +15,7 @@
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="UmbracoCms.Core" version="4.9.0" />
|
||||
<dependency id="UmbracoCms.Core" version="[$version$]" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -27,16 +27,19 @@
|
||||
<file src="..\_BuildOutput\WebApp\scripts\**" target="Content\scripts" />
|
||||
<file src="..\_BuildOutput\WebApp\usercontrols\**" target="Content\usercontrols" />
|
||||
<file src="..\_BuildOutput\WebApp\xslt\**" target="Content\xslt" />
|
||||
<file src="..\_BuildOutput\WebApp\Views\**" target="Content\Views" />
|
||||
<file src="..\_BuildOutput\WebApp\default.aspx" target="Content\default.aspx" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="Content\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Browsers\**" target="UmbracoFiles\App_Browsers" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Code\**" target="UmbracoFiles\App_Code" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Data\**" target="UmbracoFiles\App_Data" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\config\**" target="UmbracoFiles\config" />
|
||||
<file src="..\_BuildOutput\WebApp\install\**" target="UmbracoFiles\install" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="UmbracoFiles\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\Global.asax" target="UmbracoFiles\Global.asax" />
|
||||
<file src="tools\install.ps1" target="tools\install.ps1" />
|
||||
<file src="tools\Readme.txt" target="tools\Readme.txt" />
|
||||
</files>
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
@ECHO OFF
|
||||
|
||||
:choice
|
||||
set /P c=WARNING! Are you sure you want to continue, this will remove all package files, view files, sqlce database, etc... Press 'Y' to auto-remove all files/folders, 'N' to cancel or 'C' to prompt for each folder removal?
|
||||
if /I "%c%" EQU "C" goto :prompt
|
||||
if /I "%c%" EQU "Y" goto :auto
|
||||
if /I "%c%" EQU "N" goto :exit
|
||||
goto :choice
|
||||
|
||||
|
||||
:prompt
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Removing sqlce database
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Umbraco.sdf
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*
|
||||
|
||||
echo Removing cache files and examine index
|
||||
del ..\src\Umbraco.Web.UI\App_Data\TEMP\*.*
|
||||
|
||||
echo Removing log files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Logs\*.*
|
||||
|
||||
echo Removing packages
|
||||
del ..\src\Umbraco.Web.UI\App_Data\packages\*.*
|
||||
|
||||
echo Removing previews
|
||||
del ..\src\Umbraco.Web.UI\App_Data\preview\*.*
|
||||
|
||||
echo Removing app code files (typically added by starterkits)
|
||||
del ..\src\Umbraco.Web.UI\App_Code\*.*
|
||||
|
||||
echo Removing xslt files
|
||||
del ..\src\Umbraco.Web.UI\xslt\*.*
|
||||
|
||||
echo Removing user control files
|
||||
del ..\src\Umbraco.Web.UI\UserControls\*.*
|
||||
|
||||
echo Removing masterpage files
|
||||
del ..\src\Umbraco.Web.UI\masterpages\*.*
|
||||
|
||||
echo Removing view files
|
||||
del ..\src\Umbraco.Web.UI\Views\*.*
|
||||
|
||||
echo Removing razor files
|
||||
del ..\src\Umbraco.Web.UI\macroScripts\*.*
|
||||
|
||||
echo Removing media files
|
||||
del ..\src\Umbraco.Web.UI\media\*.*
|
||||
|
||||
echo Removing script files
|
||||
del ..\src\Umbraco.Web.UI\scripts\*.*
|
||||
|
||||
echo Removing css files
|
||||
del ..\src\Umbraco.Web.UI\css\*.*
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:auto
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Removing sqlce database
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Umbraco.sdf
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*) DO DEL %%A
|
||||
|
||||
echo Removing cache files and examine index
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\*.*) DO DEL %%A
|
||||
|
||||
echo Removing log files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\Logs\*.*) DO DEL %%A
|
||||
|
||||
echo Removing packages
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\packages\*.*) DO DEL %%A
|
||||
|
||||
echo Removing previews
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\preview\*.*) DO DEL %%A
|
||||
|
||||
echo Removing app code files (typically added by starterkits)
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Code\*.*) DO DEL %%A
|
||||
|
||||
echo Removing xslt files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\xslt\*.*) DO DEL %%A
|
||||
|
||||
echo Removing masterpage files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\masterpages\*.*) DO DEL %%A
|
||||
|
||||
echo Removing user control files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\usercontrols\*.*) DO DEL %%A
|
||||
|
||||
echo Removing view files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Views\*.*) DO DEL %%A
|
||||
|
||||
echo Removing razor files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\macroScripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing media files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\media\*.*) DO DEL %%A
|
||||
|
||||
echo Removing script files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\scripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing css files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\css\*.*) DO DEL %%A
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:exit
|
||||
exit
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<solution>
|
||||
<add key="disableSourceControlIntegration" value="true" />
|
||||
</solution>
|
||||
</configuration>
|
||||
Binary file not shown.
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
||||
|
||||
<!-- Enable the restore command to run before builds -->
|
||||
<RestorePackages Condition=" '$(RestorePackages)' == '' ">false</RestorePackages>
|
||||
|
||||
<!-- Property that enables building a package from a project -->
|
||||
<BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
|
||||
|
||||
<!-- Determines if package restore consent is required to restore packages -->
|
||||
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
|
||||
|
||||
<!-- Download NuGet.exe if it does not already exist -->
|
||||
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(PackageSources)' == '' ">
|
||||
<!-- Package sources used to restore packages. By default will used the registered sources under %APPDATA%\NuGet\NuGet.Config -->
|
||||
<!--
|
||||
<PackageSource Include="https://nuget.org/api/v2/" />
|
||||
<PackageSource Include="https://my-nuget-source/nuget/" />
|
||||
-->
|
||||
<PackageSource Include="https://nuget.org/api/v2/" />
|
||||
<PackageSource Include="http://www.myget.org/F/umbracocore/" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
|
||||
<!-- Windows specific commands -->
|
||||
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
|
||||
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
|
||||
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
|
||||
<NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
|
||||
<PackagesConfig>packages.config</PackagesConfig>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- NuGet command -->
|
||||
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\nuget.exe</NuGetExePath>
|
||||
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
|
||||
|
||||
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
|
||||
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
|
||||
|
||||
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
|
||||
|
||||
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
|
||||
<!-- Commands -->
|
||||
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(RequireConsentSwitch) -solutionDir "$(SolutionDir) "</RestoreCommand>
|
||||
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols</BuildCommand>
|
||||
|
||||
<!-- We need to ensure packages are restored prior to assembly resolve -->
|
||||
<ResolveReferencesDependsOn Condition="$(RestorePackages) == 'true'">
|
||||
RestorePackages;
|
||||
$(ResolveReferencesDependsOn);
|
||||
</ResolveReferencesDependsOn>
|
||||
|
||||
<!-- Make the build depend on restore packages -->
|
||||
<BuildDependsOn Condition="$(BuildPackage) == 'true'">
|
||||
$(BuildDependsOn);
|
||||
BuildPackage;
|
||||
</BuildDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="CheckPrerequisites">
|
||||
<!-- Raise an error if we're unable to locate nuget.exe -->
|
||||
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
|
||||
<SetEnvironmentVariable EnvKey="VisualStudioVersion" EnvValue="$(VisualStudioVersion)" Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' " />
|
||||
<!--
|
||||
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
|
||||
This effectively acts as a lock that makes sure that the download operation will only happen once and all
|
||||
parallel builds will have to wait for it to complete.
|
||||
-->
|
||||
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_DownloadNuGet">
|
||||
<DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
|
||||
<Exec Command="$(RestoreCommand)"
|
||||
Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
||||
|
||||
<Exec Command="$(RestoreCommand)"
|
||||
LogStandardErrorAsError="true"
|
||||
Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
|
||||
<Exec Command="$(BuildCommand)"
|
||||
Condition=" '$(OS)' != 'Windows_NT' " />
|
||||
|
||||
<Exec Command="$(BuildCommand)"
|
||||
LogStandardErrorAsError="true"
|
||||
Condition=" '$(OS)' == 'Windows_NT' " />
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<OutputFilename ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Reference Include="System.Core" />
|
||||
<Using Namespace="System" />
|
||||
<Using Namespace="System.IO" />
|
||||
<Using Namespace="System.Net" />
|
||||
<Using Namespace="Microsoft.Build.Framework" />
|
||||
<Using Namespace="Microsoft.Build.Utilities" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
try {
|
||||
OutputFilename = Path.GetFullPath(OutputFilename);
|
||||
|
||||
Log.LogMessage("Downloading latest version of NuGet.exe...");
|
||||
WebClient webClient = new WebClient();
|
||||
webClient.DownloadFile("https://nuget.org/nuget.exe", OutputFilename);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Log.LogErrorFromException(ex);
|
||||
return false;
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
|
||||
<UsingTask TaskName="SetEnvironmentVariable" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<EnvKey ParameterType="System.String" Required="true" />
|
||||
<EnvValue ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Using Namespace="System" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
try {
|
||||
Environment.SetEnvironmentVariable(EnvKey, EnvValue, System.EnvironmentVariableTarget.Process);
|
||||
}
|
||||
catch {
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
</Project>
|
||||
@@ -146,7 +146,8 @@ CREATE TABLE [cmsContentType]
|
||||
[pk] [int] NOT NULL IDENTITY(1, 1),
|
||||
[nodeId] [int] NOT NULL,
|
||||
[alias] [nvarchar] (255) NULL,
|
||||
[icon] [nvarchar] (255) NULL
|
||||
[icon] [nvarchar] (255) NULL,
|
||||
[thumbnail] nvarchar(255) NOT NULL CONSTRAINT [DF_cmsContentType_thumbnail] DEFAULT ('folder.png')
|
||||
)
|
||||
|
||||
;
|
||||
@@ -657,9 +658,9 @@ ALTER TABLE [umbracoNode] DROP CONSTRAINT [FK_umbracoNode_umbracoNode]
|
||||
|SET IDENTITY_INSERT [umbracoNode] OFF
|
||||
;
|
||||
!!!SET IDENTITY_INSERT [cmsContentType] ON
|
||||
|INSERT INTO [cmsContentType] ([pk], [nodeId], [alias], [icon]) VALUES (532, 1031, N'Folder', N'folder.gif')
|
||||
|INSERT INTO [cmsContentType] ([pk], [nodeId], [alias], [icon]) VALUES (533, 1032, N'Image', N'mediaPhoto.gif')
|
||||
|INSERT INTO [cmsContentType] ([pk], [nodeId], [alias], [icon]) VALUES (534, 1033, N'File', N'mediaFile.gif')
|
||||
|INSERT INTO [cmsContentType] ([pk], [nodeId], [alias], [icon], [thumbnail]) VALUES (532, 1031, N'Folder', N'folder.gif', N'folder.png')
|
||||
|INSERT INTO [cmsContentType] ([pk], [nodeId], [alias], [icon], [thumbnail]) VALUES (533, 1032, N'Image', N'mediaPhoto.gif', N'mediaPhoto.png')
|
||||
|INSERT INTO [cmsContentType] ([pk], [nodeId], [alias], [icon], [thumbnail]) VALUES (534, 1033, N'File', N'mediaFile.gif', N'mediaFile.png')
|
||||
|SET IDENTITY_INSERT [cmsContentType] OFF
|
||||
;
|
||||
!!!SET IDENTITY_INSERT [umbracoUser] ON
|
||||
@@ -863,10 +864,10 @@ INSERT INTO [umbracoAppTree]([treeSilent], [treeInitialize], [treeSortOrder], [a
|
||||
INSERT INTO [umbracoAppTree]([treeSilent], [treeInitialize], [treeSortOrder], [appAlias], [treeAlias], [treeTitle], [treeIconClosed], [treeIconOpen], [treeHandlerAssembly], [treeHandlerType]) VALUES(0, 1, 2, 'settings', 'scripts', 'Scripts', 'folder.gif', 'folder_o.gif', 'umbraco', 'loadScripts')
|
||||
;
|
||||
*/
|
||||
alter TABLE [cmsContentType]
|
||||
/*alter TABLE [cmsContentType]
|
||||
add [thumbnail] nvarchar(255) NOT NULL CONSTRAINT
|
||||
[DF_cmsContentType_thumbnail] DEFAULT ('folder.png')
|
||||
;
|
||||
;*/
|
||||
alter TABLE [cmsContentType]
|
||||
add [description] nvarchar(1500) NULL
|
||||
;
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
<EmbeddedResource Include="SqlCEResources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>SqlCEResources1.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace SqlCE4Umbraco
|
||||
internal void ClearDatabase()
|
||||
{
|
||||
var localConnection = new SqlCeConnection(ConnectionString);
|
||||
if (!System.IO.File.Exists(ReplaceDataDirectory(localConnection.Database)))
|
||||
if (System.IO.File.Exists(ReplaceDataDirectory(localConnection.Database)))
|
||||
{
|
||||
var tables = new List<string>();
|
||||
using (var reader = ExecuteReader("select table_name from information_schema.tables where TABLE_TYPE <> 'VIEW'"))
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.17626
|
||||
// Runtime Version:4.0.30319.18010
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
@@ -73,11 +73,11 @@ namespace SQLCE4Umbraco {
|
||||
///
|
||||
///IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT IMPORTANT
|
||||
///
|
||||
/// Database version: 4.8.0.2
|
||||
/// Database version: 4.10.0.0
|
||||
///
|
||||
/// Please increment this version number if ANY change is made to this script,
|
||||
/// so compatibility with scripts for other database systems can be verified easily.
|
||||
/// The first 3 digits depict the Umbraco [rest of string was truncated]";.
|
||||
/// The first 3 digits depict the Umbraco [rest of string was truncated]";.
|
||||
/// </summary>
|
||||
internal static string Total {
|
||||
get {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all IAction objects
|
||||
/// </summary>
|
||||
internal sealed class ActionsResolver : LazyManyObjectsResolverBase<ActionsResolver, IAction>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="packageActions"></param>
|
||||
internal ActionsResolver(Func<IEnumerable<Type>> packageActions)
|
||||
: base(packageActions)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPackageAction"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IAction> Actions
|
||||
{
|
||||
get
|
||||
{
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<IAction> CreateInstances()
|
||||
{
|
||||
var actions = new List<IAction>();
|
||||
var foundIActions = InstanceTypes;
|
||||
foreach (var type in foundIActions)
|
||||
{
|
||||
IAction typeInstance;
|
||||
var instance = type.GetProperty("Instance", BindingFlags.Public | BindingFlags.Static);
|
||||
//if the singletone initializer is not found, try simply creating an instance of the IAction if it supports public constructors
|
||||
if (instance == null)
|
||||
typeInstance = PluginManager.Current.CreateInstance<IAction>(type);
|
||||
else
|
||||
typeInstance = instance.GetValue(null, null) as IAction;
|
||||
|
||||
if (typeInstance != null)
|
||||
{
|
||||
actions.Add(typeInstance);
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper methods for Activation
|
||||
/// </summary>
|
||||
internal static class ActivatorHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates an instance of a type using that type's default constructor.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T CreateInstance<T>() where T : class, new()
|
||||
{
|
||||
return Activator.CreateInstance(typeof(T)) as T;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// the Umbraco Application context
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// one per AppDomain, represents the global Umbraco application
|
||||
/// </remarks>
|
||||
public class ApplicationContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
internal ApplicationContext()
|
||||
{
|
||||
//create a new application cache from the HttpRuntime.Cache
|
||||
ApplicationCache = HttpRuntime.Cache == null
|
||||
? new CacheHelper(new Cache())
|
||||
: new CacheHelper(HttpRuntime.Cache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
public static ApplicationContext Current { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the application wide cache accessor
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Any caching that is done in the application (app wide) should be done through this property
|
||||
/// </remarks>
|
||||
public CacheHelper ApplicationCache { get; private set; }
|
||||
|
||||
// IsReady is set to true by the boot manager once it has successfully booted
|
||||
// note - the original umbraco module checks on content.Instance in umbraco.dll
|
||||
// now, the boot task that setup the content store ensures that it is ready
|
||||
bool _isReady = false;
|
||||
readonly System.Threading.ManualResetEventSlim _isReadyEvent = new System.Threading.ManualResetEventSlim(false);
|
||||
public bool IsReady
|
||||
{
|
||||
get
|
||||
{
|
||||
return _isReady;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
AssertIsNotReady();
|
||||
_isReady = value;
|
||||
_isReadyEvent.Set();
|
||||
}
|
||||
}
|
||||
|
||||
public bool WaitForReady(int timeout)
|
||||
{
|
||||
return _isReadyEvent.WaitHandle.WaitOne(timeout);
|
||||
}
|
||||
|
||||
|
||||
// notes
|
||||
// GlobalSettings.ConfigurationStatus returns the value that's in the web.config, so it's the "configured version"
|
||||
// GlobalSettings.CurrentVersion returns the hard-coded "current version"
|
||||
// the system is configured if they match
|
||||
// if they don't, install runs, updates web.config (presumably) and updates GlobalSettings.ConfiguredStatus
|
||||
//
|
||||
// then there is Application["umbracoNeedConfiguration"] which makes no sense... getting rid of it...
|
||||
//
|
||||
public bool IsConfigured
|
||||
{
|
||||
// fixme - let's do this for the time being
|
||||
get
|
||||
{
|
||||
return Configured;
|
||||
}
|
||||
}
|
||||
|
||||
private bool Configured
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
string configStatus = ConfigurationStatus;
|
||||
string currentVersion = GlobalSettings.CurrentVersion;
|
||||
|
||||
|
||||
if (currentVersion != configStatus)
|
||||
{
|
||||
LogHelper.Info<ApplicationContext>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
|
||||
}
|
||||
|
||||
|
||||
return (configStatus == currentVersion);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string ConfigurationStatus
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConfigurationManager.AppSettings["umbracoConfigurationStatus"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void AssertIsReady()
|
||||
{
|
||||
if (!this.IsReady)
|
||||
throw new Exception("ApplicationContext is not ready yet.");
|
||||
}
|
||||
|
||||
private void AssertIsNotReady()
|
||||
{
|
||||
if (this.IsReady)
|
||||
throw new Exception("ApplicationContext has already been initialized.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal static class AssemblyExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the file used to load the assembly
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
public static FileInfo GetAssemblyFile(this Assembly assembly)
|
||||
{
|
||||
var codeBase = assembly.CodeBase;
|
||||
var uri = new Uri(codeBase);
|
||||
var path = uri.LocalPath;
|
||||
return new FileInfo(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the file used to load the assembly
|
||||
/// </summary>
|
||||
/// <param name="assemblyName"></param>
|
||||
/// <returns></returns>
|
||||
public static FileInfo GetAssemblyFile(this AssemblyName assemblyName)
|
||||
{
|
||||
var codeBase = assemblyName.CodeBase;
|
||||
var uri = new Uri(codeBase);
|
||||
var path = uri.LocalPath;
|
||||
return new FileInfo(path);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the result of an operation attempt
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <remarks></remarks>
|
||||
[Serializable]
|
||||
public struct Attempt<T>
|
||||
{
|
||||
private readonly bool _success;
|
||||
private readonly T _result;
|
||||
private readonly Exception _error;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="Attempt{T}"/> represents a successful operation.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
public bool Success
|
||||
{
|
||||
get { return _success; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the error associated with an unsuccessful attempt.
|
||||
/// </summary>
|
||||
/// <value>The error.</value>
|
||||
public Exception Error { get { return _error; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parse result.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
public T Result
|
||||
{
|
||||
get { return _result; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an unsuccessful parse operation
|
||||
/// </summary>
|
||||
public static readonly Attempt<T> False = new Attempt<T>(false, default(T));
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Attempt{T}"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="success">If set to <c>true</c> this tuple represents a successful parse result.</param>
|
||||
/// <param name="result">The parse result.</param>
|
||||
/// <remarks></remarks>
|
||||
public Attempt(bool success, T result)
|
||||
{
|
||||
_success = success;
|
||||
_result = result;
|
||||
_error = null;
|
||||
}
|
||||
|
||||
public Attempt(Exception error)
|
||||
{
|
||||
_success = false;
|
||||
_result = default(T);
|
||||
_error = error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Class that is exposed by the ApplicationContext for application wide caching purposes
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class may be opened publicly at some point but needs a review of what is absoletely necessary.
|
||||
/// </remarks>
|
||||
public class CacheHelper
|
||||
{
|
||||
private readonly Cache _cache;
|
||||
|
||||
public CacheHelper(System.Web.Caching.Cache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything in umbraco's runtime cache, which means that not only
|
||||
/// umbraco content is removed, but also other cache items from pages running in
|
||||
/// the same application / website. Use with care :-)
|
||||
/// </summary>
|
||||
public void ClearAllCache()
|
||||
{
|
||||
var cacheEnumerator = _cache.GetEnumerator();
|
||||
while (cacheEnumerator.MoveNext())
|
||||
{
|
||||
_cache.Remove(cacheEnumerator.Key.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's runtime cache with the given key
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
public void ClearCacheItem(string key)
|
||||
{
|
||||
// NH 10 jan 2012
|
||||
// Patch by the always wonderful Stéphane Gay to avoid cache null refs
|
||||
lock (Locker)
|
||||
{
|
||||
if (_cache[key] == null) return;
|
||||
_cache.Remove(key);;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type name as the
|
||||
/// input parameter. (using [object].GetType())
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
|
||||
public void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
foreach (var c in from DictionaryEntry c in _cache where _cache[c.Key.ToString()] != null && _cache[c.Key.ToString()].GetType().ToString() == typeName select c)
|
||||
{
|
||||
_cache.Remove(c.Key.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that starts with the key passed.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
public void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
foreach (var c in from DictionaryEntry c in _cache where c.Key is string && ((string)c.Key).StartsWith(keyStartsWith) select c)
|
||||
{
|
||||
ClearCacheItem((string)c.Key);
|
||||
}
|
||||
}
|
||||
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
TimeSpan timeout, Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is used only for legacy purposes as I did not want to change all of the locking to one lock found on this object,
|
||||
/// however, the reason this is used for legacy purposes is because I see zero reason to use different sync locks, just the one
|
||||
/// lock (Locker) on this class should be sufficient.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <param name="syncLock"></param>
|
||||
/// <returns></returns>
|
||||
internal TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency, TimeSpan timeout, Func<TT> getCacheItem, object syncLock)
|
||||
{
|
||||
var result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
result = getCacheItem();
|
||||
if (result != null)
|
||||
{
|
||||
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
|
||||
_cache.Insert(cacheKey, result, cacheDependency, DateTime.Now.Add(timeout), TimeSpan.Zero, priority, refreshAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (TT)result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A resolver to return all ICacheRefresher objects
|
||||
/// </summary>
|
||||
internal sealed class CacheRefreshersResolver : LegacyTransientObjectsResolver<CacheRefreshersResolver, ICacheRefresher>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="refreshers"></param>
|
||||
internal CacheRefreshersResolver(Func<IEnumerable<Type>> refreshers)
|
||||
: base(refreshers)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ICacheRefresher"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<ICacheRefresher> CacheResolvers
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureIdsAreTracked();
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
protected override Guid GetUniqueIdentifier(ICacheRefresher obj)
|
||||
{
|
||||
return obj.UniqueIdentifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks the program elements that Umbraco is experimenting with and could become public.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Indicates that Umbraco is experimenting with code that potentially could become
|
||||
/// public, but we're not sure, and the code is not stable and can be refactored at any time.</para>
|
||||
/// <para>The issue tracker should contain more details, discussion, and planning.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
|
||||
internal sealed class UmbracoExperimentalFeatureAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoExperimentalFeatureAttribute"/> class with a description.
|
||||
/// </summary>
|
||||
/// <param name="description">The text string that describes what is intended.</param>
|
||||
public UmbracoExperimentalFeatureAttribute(string description)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoExperimentalFeatureAttribute"/> class with a tracker url and a description.
|
||||
/// </summary>
|
||||
/// <param name="trackerUrl">The url of a tracker issue containing more details, discussion, and planning.</param>
|
||||
/// <param name="description">The text string that describes what is intended.</param>
|
||||
public UmbracoExperimentalFeatureAttribute(string trackerUrl, string description)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks the program elements that Umbraco is considering making public.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Indicates that Umbraco considers making the (currently internal) program element public
|
||||
/// at some point in the future, but the decision is not fully made yet and is still pending reviews.</para>
|
||||
/// <para>Note that it is not a commitment to make the program element public. It may not ever become public.</para>
|
||||
/// <para>The issue tracker should contain more details, discussion, and planning.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple=false, Inherited=false)]
|
||||
internal sealed class UmbracoProposedPublicAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoProposedPublicAttribute"/> class with a description.
|
||||
/// </summary>
|
||||
/// <param name="description">The text string that describes what is intended.</param>
|
||||
public UmbracoProposedPublicAttribute(string description)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoProposedPublicAttribute"/> class with a tracker url and a description.
|
||||
/// </summary>
|
||||
/// <param name="trackerUrl">The url of a tracker issue containing more details, discussion, and planning.</param>
|
||||
/// <param name="description">The text string that describes what is intended.</param>
|
||||
public UmbracoProposedPublicAttribute(string trackerUrl, string description)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Marks the program elements that Umbraco will obsolete.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Indicates that Umbraco will obsolete the program element at some point in the future, but we do not want to
|
||||
/// explicitely mark it [Obsolete] yet to avoid warning messages showing when developers compile Umbraco.
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
|
||||
internal sealed class UmbracoWillObsoleteAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoWillObsoleteAttribute"/> class with a description.
|
||||
/// </summary>
|
||||
/// <param name="description">The text string that describes what is intended.</param>
|
||||
public UmbracoWillObsoleteAttribute(string description)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoWillObsoleteAttribute"/> class with a tracker url and a description.
|
||||
/// </summary>
|
||||
/// <param name="trackerUrl">The url of a tracker issue containing more details, discussion, and planning.</param>
|
||||
/// <param name="description">The text string that describes what is intended.</param>
|
||||
public UmbracoWillObsoleteAttribute(string trackerUrl, string description)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Routing;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
//NOTE: Do not expose this class ever until we cleanup all configuration including removal of static classes, etc...
|
||||
// we have this two tasks logged:
|
||||
// http://issues.umbraco.org/issue/U4-58
|
||||
// http://issues.umbraco.org/issue/U4-115
|
||||
|
||||
//TODO: Re-enable Logging!!!!
|
||||
|
||||
//TODO: Remove checks for if HttpContext is null, why are we doing this? we should be checking if the config setting
|
||||
// can be read and if not then return the default.
|
||||
// http://issues.umbraco.org/issue/U4-115
|
||||
|
||||
//TODO: Replace checking for if the app settings exist and returning an empty string, instead return the defaults!
|
||||
|
||||
/// <summary>
|
||||
/// The GlobalSettings Class contains general settings information for the entire Umbraco instance based on information from web.config appsettings
|
||||
@@ -25,45 +25,34 @@ namespace Umbraco.Core.Configuration
|
||||
internal class GlobalSettings
|
||||
{
|
||||
|
||||
private static HttpContextBase _customHttpContext;
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets the HttpContext object, this is generally used for unit testing. By default this will
|
||||
/// use the HttpContext.Current
|
||||
/// </summary>
|
||||
internal static HttpContextBase HttpContext
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_customHttpContext == null && System.Web.HttpContext.Current != null)
|
||||
{
|
||||
//return the current HttpContxt, do NOT store this in the _customHttpContext field
|
||||
//as it will persist across reqeusts!
|
||||
return new HttpContextWrapper(System.Web.HttpContext.Current);
|
||||
}
|
||||
|
||||
if (_customHttpContext == null && System.Web.HttpContext.Current == null)
|
||||
{
|
||||
//throw new NullReferenceException("The HttpContext property has not been set or the object execution is not running inside of an HttpContext");
|
||||
//NOTE: We should throw an exception here but the legacy code checks for null so we need to stick witht he legacy code for now.
|
||||
return null;
|
||||
}
|
||||
return _customHttpContext;
|
||||
}
|
||||
set { _customHttpContext = value; }
|
||||
}
|
||||
|
||||
#region Private static fields
|
||||
|
||||
// CURRENT UMBRACO VERSION ID
|
||||
private const string CurrentUmbracoVersion = "4.9.0";
|
||||
private const string CurrentUmbracoVersion = "4.11.5";
|
||||
|
||||
private static string _reservedUrlsCache;
|
||||
private static readonly object Locker = new object();
|
||||
//make this volatile so that we can ensure thread safety with a double check lock
|
||||
private static volatile string _reservedUrlsCache;
|
||||
private static string _reservedPathsCache;
|
||||
private static StartsWithContainer _reservedList = new StartsWithContainer();
|
||||
private static string _reservedPaths;
|
||||
private static string _reservedUrls;
|
||||
//ensure the built on (non-changeable) reserved paths are there at all times
|
||||
private const string StaticReservedPaths = "~/app_plugins/,~/install/,";
|
||||
private const string StaticReservedUrls = "~/config/splashes/booting.aspx,~/install/default.aspx,~/config/splashes/noNodes.aspx,~/VSEnterpriseHelper.axd,";
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// used for unit tests
|
||||
/// </summary>
|
||||
internal static void ResetCache()
|
||||
{
|
||||
_reservedUrlsCache = null;
|
||||
_reservedPaths = null;
|
||||
_reservedUrls = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reserved urls from web.config.
|
||||
/// </summary>
|
||||
@@ -71,11 +60,19 @@ namespace Umbraco.Core.Configuration
|
||||
public static string ReservedUrls
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoReservedUrls"];
|
||||
return String.Empty;
|
||||
{
|
||||
if (_reservedUrls == null)
|
||||
{
|
||||
var urls = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedUrls")
|
||||
? ConfigurationManager.AppSettings["umbracoReservedUrls"]
|
||||
: string.Empty;
|
||||
|
||||
//ensure the built on (non-changeable) reserved paths are there at all times
|
||||
_reservedUrls = StaticReservedUrls + urls;
|
||||
}
|
||||
return _reservedUrls;
|
||||
}
|
||||
internal set { _reservedUrls = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -86,28 +83,38 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoReservedPaths"];
|
||||
return String.Empty;
|
||||
if (_reservedPaths == null)
|
||||
{
|
||||
var reservedPaths = StaticReservedPaths;
|
||||
//always add the umbraco path to the list
|
||||
if (ConfigurationManager.AppSettings.ContainsKey("umbracoPath")
|
||||
&& !ConfigurationManager.AppSettings["umbracoPath"].IsNullOrWhiteSpace())
|
||||
{
|
||||
reservedPaths += ConfigurationManager.AppSettings["umbracoPath"].EnsureEndsWith(',');
|
||||
}
|
||||
|
||||
var allPaths = ConfigurationManager.AppSettings.ContainsKey("umbracoReservedPaths")
|
||||
? ConfigurationManager.AppSettings["umbracoReservedPaths"]
|
||||
: string.Empty;
|
||||
|
||||
_reservedPaths = reservedPaths + allPaths;
|
||||
}
|
||||
return _reservedPaths;
|
||||
}
|
||||
internal set { _reservedPaths = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the content XML file.
|
||||
/// </summary>
|
||||
/// <value>The content XML.</value>
|
||||
public static string ContentXml
|
||||
public static string ContentXmlFile
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConfigurationManager.AppSettings["umbracoContentXML"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
{
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoContentXML")
|
||||
? ConfigurationManager.AppSettings["umbracoContentXML"]
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,14 +126,9 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConfigurationManager.AppSettings["umbracoStorageDirectory"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoStorageDirectory")
|
||||
? ConfigurationManager.AppSettings["umbracoStorageDirectory"]
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,18 +140,35 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
return IOHelper.ResolveUrl(ConfigurationManager.AppSettings["umbracoPath"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoPath")
|
||||
? IOHelper.ResolveUrl(ConfigurationManager.AppSettings["umbracoPath"])
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This returns the string of the MVC Area route.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// THIS IS TEMPORARY AND SHOULD BE REMOVED WHEN WE MIGRATE/UPDATE THE CONFIG SETTINGS TO BE A REAL CONFIG SECTION
|
||||
/// AND SHOULD PROBABLY BE HANDLED IN A MORE ROBUST WAY.
|
||||
///
|
||||
/// This will return the MVC area that we will route all custom routes through like surface controllers, etc...
|
||||
/// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin
|
||||
/// we will convert the '/' to '-' and use that as the path. its a bit lame but will work.
|
||||
/// </remarks>
|
||||
internal static string UmbracoMvcArea
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Path.IsNullOrWhiteSpace())
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified");
|
||||
}
|
||||
return Path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to umbraco's client directory (/umbraco_client by default).
|
||||
/// This is a relative path to the Umbraco Path as it always must exist beside the 'umbraco'
|
||||
@@ -172,14 +191,9 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConfigurationManager.AppSettings["umbracoDbDSN"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoDbDSN")
|
||||
? ConfigurationManager.AppSettings["umbracoDbDSN"]
|
||||
: string.Empty;
|
||||
}
|
||||
set
|
||||
{
|
||||
@@ -198,45 +212,16 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return ConfigurationManager.AppSettings["umbracoConfigurationStatus"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoConfigurationStatus")
|
||||
? ConfigurationManager.AppSettings["umbracoConfigurationStatus"]
|
||||
: string.Empty;
|
||||
}
|
||||
set
|
||||
{
|
||||
SaveSetting("umbracoConfigurationStatus", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Forces umbraco to be medium trust compatible
|
||||
/// </summary>
|
||||
/// <value>If true, umbraco will be medium-trust compatible, no matter what Permission level the server is on.</value>
|
||||
public static bool UseMediumTrust
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var trustLevel = SystemUtilities.GetCurrentTrustLevel();
|
||||
if (trustLevel == AspNetHostingPermissionLevel.High || trustLevel == AspNetHostingPermissionLevel.Unrestricted)
|
||||
return false;
|
||||
else
|
||||
return bool.Parse(ConfigurationManager.AppSettings["umbracoUseMediumTrust"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves a setting into the configuration file.
|
||||
/// </summary>
|
||||
@@ -246,21 +231,27 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
var webConfig = new WebConfigurationFileMap();
|
||||
var vDirs = webConfig.VirtualDirectories;
|
||||
var vDir = FullpathToRoot;
|
||||
var physicalPathToRoot = FullpathToRoot;
|
||||
foreach (VirtualDirectoryMapping v in webConfig.VirtualDirectories)
|
||||
{
|
||||
if (v.IsAppRoot)
|
||||
{
|
||||
vDir = v.PhysicalDirectory;
|
||||
physicalPathToRoot = v.PhysicalDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
var doc = new XmlDocument();
|
||||
doc.Load(String.Concat(vDir, "web.config"));
|
||||
var root = doc.DocumentElement;
|
||||
var setting = doc.SelectSingleNode(String.Concat("//appSettings/add[@key='", key, "']"));
|
||||
setting.Attributes["value"].InnerText = value;
|
||||
doc.Save(String.Concat(vDir, "web.config"));
|
||||
|
||||
string fileName = System.IO.Path.Combine(physicalPathToRoot, "web.config");
|
||||
var xml = XDocument.Load(fileName);
|
||||
var appSettings = xml.Root.Descendants("appSettings").Single();
|
||||
|
||||
// Update appSetting if it exists, or else create a new appSetting for the given key and value
|
||||
var setting = appSettings.Descendants("add").Where(s => s.Attribute("key").Value == key).FirstOrDefault();
|
||||
if (setting == null)
|
||||
appSettings.Add(new XElement("add", new XAttribute("key", key), new XAttribute("value", value)));
|
||||
else
|
||||
setting.Attribute("value").Value = value;
|
||||
|
||||
xml.Save(fileName);
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
}
|
||||
|
||||
@@ -270,7 +261,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <value>The fullpath to root.</value>
|
||||
public static string FullpathToRoot
|
||||
{
|
||||
get { return HttpRuntime.AppDomainAppPath; }
|
||||
get { return IOHelper.GetRootDirectorySafe(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -308,9 +299,7 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
if (currentVersion != configStatus)
|
||||
{
|
||||
//Log.Add(LogTypes.Debug, User.GetUser(0), -1,
|
||||
// "CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus +
|
||||
// "'");
|
||||
LogHelper.Debug<GlobalSettings>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
|
||||
}
|
||||
|
||||
|
||||
@@ -369,69 +358,17 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
int versionCheckPeriod = 7;
|
||||
if (HttpContext != null)
|
||||
{
|
||||
if (int.TryParse(ConfigurationManager.AppSettings["umbracoVersionCheckPeriod"], out versionCheckPeriod))
|
||||
return versionCheckPeriod;
|
||||
|
||||
}
|
||||
return versionCheckPeriod;
|
||||
try
|
||||
{
|
||||
return int.Parse(ConfigurationManager.AppSettings["umbracoVersionCheckPeriod"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL forbitten characters.
|
||||
/// </summary>
|
||||
/// <value>The URL forbitten characters.</value>
|
||||
public static string UrlForbittenCharacters
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoUrlForbittenCharacters"];
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL space character.
|
||||
/// </summary>
|
||||
/// <value>The URL space character.</value>
|
||||
public static string UrlSpaceCharacter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoUrlSpaceCharacter"];
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SMTP server IP-address or hostname.
|
||||
/// </summary>
|
||||
/// <value>The SMTP server.</value>
|
||||
public static string SmtpServer
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var mailSettings = ConfigurationManager.GetSection("system.net/mailSettings") as System.Net.Configuration.MailSettingsSectionGroup;
|
||||
|
||||
if (mailSettings != null)
|
||||
return mailSettings.Smtp.Network.Host;
|
||||
else
|
||||
return ConfigurationManager.AppSettings["umbracoSmtpServer"];
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string value to determine if umbraco should disbable xslt extensions
|
||||
/// </summary>
|
||||
@@ -440,9 +377,9 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoDisableXsltExtensions"];
|
||||
return "";
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoDisableXsltExtensions")
|
||||
? ConfigurationManager.AppSettings["umbracoDisableXsltExtensions"]
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,9 +391,9 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoEditXhtmlMode"];
|
||||
return "";
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoEditXhtmlMode")
|
||||
? ConfigurationManager.AppSettings["umbracoEditXhtmlMode"]
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,9 +405,9 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoDefaultUILanguage"];
|
||||
return "";
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoDefaultUILanguage")
|
||||
? ConfigurationManager.AppSettings["umbracoDefaultUILanguage"]
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,9 +419,9 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return ConfigurationManager.AppSettings["umbracoProfileUrl"];
|
||||
return "";
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoProfileUrl")
|
||||
? ConfigurationManager.AppSettings["umbracoProfileUrl"]
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,9 +435,14 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
return bool.Parse(ConfigurationManager.AppSettings["umbracoHideTopLevelNodeFromPath"]);
|
||||
return false;
|
||||
try
|
||||
{
|
||||
return bool.Parse(ConfigurationManager.AppSettings["umbracoHideTopLevelNodeFromPath"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,74 +559,60 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
string license =
|
||||
"<A href=\"http://umbraco.org/redir/license\" target=\"_blank\">the open source license MIT</A>. The umbraco UI is freeware licensed under the umbraco license.";
|
||||
if (HttpContext != null)
|
||||
{
|
||||
var versionDoc = new XmlDocument();
|
||||
var versionReader = new XmlTextReader(IOHelper.MapPath(SystemDirectories.Umbraco + "/version.xml"));
|
||||
versionDoc.Load(versionReader);
|
||||
versionReader.Close();
|
||||
|
||||
// check for license
|
||||
try
|
||||
{
|
||||
string licenseUrl =
|
||||
versionDoc.SelectSingleNode("/version/licensing/licenseUrl").FirstChild.Value;
|
||||
string licenseValidation =
|
||||
versionDoc.SelectSingleNode("/version/licensing/licenseValidation").FirstChild.Value;
|
||||
string licensedTo =
|
||||
versionDoc.SelectSingleNode("/version/licensing/licensedTo").FirstChild.Value;
|
||||
var versionDoc = new XmlDocument();
|
||||
var versionReader = new XmlTextReader(IOHelper.MapPath(SystemDirectories.Umbraco + "/version.xml"));
|
||||
versionDoc.Load(versionReader);
|
||||
versionReader.Close();
|
||||
|
||||
// check for license
|
||||
try
|
||||
{
|
||||
string licenseUrl =
|
||||
versionDoc.SelectSingleNode("/version/licensing/licenseUrl").FirstChild.Value;
|
||||
string licenseValidation =
|
||||
versionDoc.SelectSingleNode("/version/licensing/licenseValidation").FirstChild.Value;
|
||||
string licensedTo =
|
||||
versionDoc.SelectSingleNode("/version/licensing/licensedTo").FirstChild.Value;
|
||||
|
||||
if (licensedTo != "" && licenseUrl != "")
|
||||
{
|
||||
license = "umbraco Commercial License<br/><b>Registered to:</b><br/>" +
|
||||
licensedTo.Replace("\n", "<br/>") + "<br/><b>For use with domain:</b><br/>" +
|
||||
licenseUrl;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
if (licensedTo != "" && licenseUrl != "")
|
||||
{
|
||||
license = "umbraco Commercial License<br/><b>Registered to:</b><br/>" +
|
||||
licensedTo.Replace("\n", "<br/>") + "<br/><b>For use with domain:</b><br/>" +
|
||||
licenseUrl;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
return license;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current request is reserved based on the route table and
|
||||
/// whether the specified URL is reserved or is inside a reserved path.
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="httpContext"></param>
|
||||
/// <param name="routes">The route collection to lookup the request in</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsReservedPathOrUrl(string url, HttpContextBase httpContext, RouteCollection routes)
|
||||
{
|
||||
if (httpContext == null) throw new ArgumentNullException("httpContext");
|
||||
if (routes == null) throw new ArgumentNullException("routes");
|
||||
|
||||
/// <summary>
|
||||
/// Developer method to test if configuration settings are loaded properly.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if succesfull; otherwise, <c>false</c>.</value>
|
||||
internal static bool Test
|
||||
{
|
||||
get
|
||||
{
|
||||
if (HttpContext != null)
|
||||
{
|
||||
HttpContext.Response.Write("ContentXML :" + ContentXml + "\n");
|
||||
HttpContext.Response.Write("DbDSN :" + DbDsn + "\n");
|
||||
HttpContext.Response.Write("DebugMode :" + DebugMode + "\n");
|
||||
HttpContext.Response.Write("DefaultUILanguage :" + DefaultUILanguage + "\n");
|
||||
HttpContext.Response.Write("VersionCheckPeriod :" + VersionCheckPeriod + "\n");
|
||||
HttpContext.Response.Write("DisableXsltExtensions :" + DisableXsltExtensions + "\n");
|
||||
HttpContext.Response.Write("EditXhtmlMode :" + EditXhtmlMode + "\n");
|
||||
HttpContext.Response.Write("HideTopLevelNodeFromPath :" + HideTopLevelNodeFromPath + "\n");
|
||||
HttpContext.Response.Write("Path :" + Path + "\n");
|
||||
HttpContext.Response.Write("ProfileUrl :" + ProfileUrl + "\n");
|
||||
HttpContext.Response.Write("ReservedPaths :" + ReservedPaths + "\n");
|
||||
HttpContext.Response.Write("ReservedUrls :" + ReservedUrls + "\n");
|
||||
HttpContext.Response.Write("StorageDirectory :" + StorageDirectory + "\n");
|
||||
HttpContext.Response.Write("TimeOutInMinutes :" + TimeOutInMinutes + "\n");
|
||||
HttpContext.Response.Write("UrlForbittenCharacters :" + UrlForbittenCharacters + "\n");
|
||||
HttpContext.Response.Write("UrlSpaceCharacter :" + UrlSpaceCharacter + "\n");
|
||||
HttpContext.Response.Write("UseDirectoryUrls :" + UseDirectoryUrls + "\n");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//check if the current request matches a route, if so then it is reserved.
|
||||
var route = routes.GetRouteData(httpContext);
|
||||
if (route != null)
|
||||
return true;
|
||||
|
||||
//continue with the standard ignore routine
|
||||
return IsReservedPathOrUrl(url);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Determines whether the specified URL is reserved or is inside a reserved path.
|
||||
/// </summary>
|
||||
/// <param name="url">The URL to check.</param>
|
||||
@@ -692,49 +620,56 @@ namespace Umbraco.Core.Configuration
|
||||
/// <c>true</c> if the specified URL is reserved; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public static bool IsReservedPathOrUrl(string url)
|
||||
{
|
||||
// check if GlobalSettings.ReservedPaths and GlobalSettings.ReservedUrls are unchanged
|
||||
if (!object.ReferenceEquals(_reservedPathsCache, GlobalSettings.ReservedPaths)
|
||||
|| !object.ReferenceEquals(_reservedUrlsCache, GlobalSettings.ReservedUrls))
|
||||
{
|
||||
if (_reservedUrlsCache == null)
|
||||
{
|
||||
// store references to strings to determine changes
|
||||
_reservedPathsCache = GlobalSettings.ReservedPaths;
|
||||
_reservedUrlsCache = GlobalSettings.ReservedUrls;
|
||||
|
||||
string _root = SystemDirectories.Root.Trim().ToLower();
|
||||
|
||||
// add URLs and paths to a new list
|
||||
StartsWithContainer _newReservedList = new StartsWithContainer();
|
||||
foreach (string reservedUrl in _reservedUrlsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
lock (Locker)
|
||||
{
|
||||
//resolves the url to support tilde chars
|
||||
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl).Trim().ToLower();
|
||||
if (reservedUrlTrimmed.Length > 0)
|
||||
_newReservedList.Add(reservedUrlTrimmed);
|
||||
if (_reservedUrlsCache == null)
|
||||
{
|
||||
// store references to strings to determine changes
|
||||
_reservedPathsCache = GlobalSettings.ReservedPaths;
|
||||
_reservedUrlsCache = GlobalSettings.ReservedUrls;
|
||||
|
||||
string _root = SystemDirectories.Root.Trim().ToLower();
|
||||
|
||||
// add URLs and paths to a new list
|
||||
StartsWithContainer _newReservedList = new StartsWithContainer();
|
||||
foreach (string reservedUrl in _reservedUrlsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
//resolves the url to support tilde chars
|
||||
string reservedUrlTrimmed = IOHelper.ResolveUrl(reservedUrl).Trim().ToLower();
|
||||
if (reservedUrlTrimmed.Length > 0)
|
||||
_newReservedList.Add(reservedUrlTrimmed);
|
||||
}
|
||||
|
||||
foreach (string reservedPath in _reservedPathsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
bool trimEnd = !reservedPath.EndsWith("/");
|
||||
//resolves the url to support tilde chars
|
||||
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath).Trim().ToLower();
|
||||
|
||||
if (reservedPathTrimmed.Length > 0)
|
||||
_newReservedList.Add(reservedPathTrimmed + (reservedPathTrimmed.EndsWith("/") ? "" : "/"));
|
||||
}
|
||||
|
||||
// use the new list from now on
|
||||
_reservedList = _newReservedList;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string reservedPath in _reservedPathsCache.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
bool trimEnd = !reservedPath.EndsWith("/");
|
||||
//resolves the url to support tilde chars
|
||||
string reservedPathTrimmed = IOHelper.ResolveUrl(reservedPath).Trim().ToLower();
|
||||
|
||||
if (reservedPathTrimmed.Length > 0)
|
||||
_newReservedList.Add(reservedPathTrimmed + (reservedPathTrimmed.EndsWith("/") ? "" : "/"));
|
||||
}
|
||||
|
||||
// use the new list from now on
|
||||
_reservedList = _newReservedList;
|
||||
}
|
||||
|
||||
string res = "";
|
||||
foreach (string st in _reservedList._list.Keys)
|
||||
res += st + ",";
|
||||
|
||||
Debug.Write("reserverd urls: '" + res + "'");
|
||||
//The url should be cleaned up before checking:
|
||||
// * If it doesn't contain an '.' in the path then we assume it is a path based URL, if that is the case we should add an trailing '/' because all of our reservedPaths use a trailing '/'
|
||||
// * We shouldn't be comparing the query at all
|
||||
var pathPart = url.Split('?')[0];
|
||||
if (!pathPart.Contains(".") && !pathPart.EndsWith("/"))
|
||||
{
|
||||
pathPart += "/";
|
||||
}
|
||||
|
||||
// return true if url starts with an element of the reserved list
|
||||
return _reservedList.StartsWith(url.ToLower());
|
||||
return _reservedList.StartsWith(pathPart.ToLowerInvariant());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -809,14 +744,11 @@ namespace Umbraco.Core.Configuration
|
||||
if (part == null || whole == null || part.Length >= whole.Length)
|
||||
return _stringComparer.Compare(part, whole);
|
||||
|
||||
// Reverted changeset 4d5a20d6124d because it will match with
|
||||
// anything starting with install and umbraco see issue U4-741
|
||||
|
||||
////trim the end '/' of each
|
||||
//part = part.TrimEnd('/');
|
||||
//whole = whole.TrimEnd('/');
|
||||
//if (part.Length >= whole.Length)
|
||||
// return _stringComparer.Compare(part, whole);
|
||||
////ensure both have a / on the end
|
||||
//part = part.EndsWith("/") ? part : part + "/";
|
||||
//whole = whole.EndsWith("/") ? whole : whole + "/";
|
||||
//if (part.Length >= whole.Length)
|
||||
// return _stringComparer.Compare(part, whole);
|
||||
|
||||
// loop through all characters that part and whole have in common
|
||||
int pos = 0;
|
||||
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
//NOTE: I'm not sure what this does or what it is used for, have emailed Gareth about it as the name really means nothing to me
|
||||
// and don't know where this class actually belongs.
|
||||
|
||||
//NOTE: This is used in the old DynamicNode for performing value conversions/mappings for certain data types.
|
||||
// it has been obsoleted because we've replaced this with the PropertyEditorValueConvertersResolver which can
|
||||
// have converters registered in code so we don't have to rely on even more config sections.
|
||||
// These things probably won't need to be created all that often and in code is much easier to do.
|
||||
|
||||
internal class RazorDataTypeModelStaticMappingItem
|
||||
{
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A bootstrapper for the Umbraco application which initializes all objects for the Core of the application
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does not provide any startup functionality relating to web objects
|
||||
/// </remarks>
|
||||
internal class CoreBootManager : IBootManager
|
||||
{
|
||||
|
||||
private DisposableTimer _timer;
|
||||
private bool _isInitialized = false;
|
||||
private bool _isStarted = false;
|
||||
private bool _isComplete = false;
|
||||
|
||||
protected ApplicationContext ApplicationContext { get; private set; }
|
||||
|
||||
public virtual IBootManager Initialize()
|
||||
{
|
||||
if (_isInitialized)
|
||||
throw new InvalidOperationException("The boot manager has already been initialized");
|
||||
|
||||
LogHelper.Info<CoreBootManager>("Umbraco application starting");
|
||||
_timer = DisposableTimer.Start(x => LogHelper.Info<CoreBootManager>("Umbraco application startup complete" + " (took " + x + "ms)"));
|
||||
|
||||
//create the ApplicationContext
|
||||
ApplicationContext = ApplicationContext.Current = new ApplicationContext();
|
||||
|
||||
InitializeResolvers();
|
||||
|
||||
_isInitialized = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires after initialization and calls the callback to allow for customizations to occur
|
||||
/// </summary>
|
||||
/// <param name="afterStartup"></param>
|
||||
/// <returns></returns>
|
||||
public virtual IBootManager Startup(Action<ApplicationContext> afterStartup)
|
||||
{
|
||||
if (_isStarted)
|
||||
throw new InvalidOperationException("The boot manager has already been initialized");
|
||||
|
||||
if (afterStartup != null)
|
||||
{
|
||||
afterStartup(ApplicationContext.Current);
|
||||
}
|
||||
|
||||
_isStarted = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires after startup and calls the callback once customizations are locked
|
||||
/// </summary>
|
||||
/// <param name="afterComplete"></param>
|
||||
/// <returns></returns>
|
||||
public virtual IBootManager Complete(Action<ApplicationContext> afterComplete)
|
||||
{
|
||||
if (_isComplete)
|
||||
throw new InvalidOperationException("The boot manager has already been completed");
|
||||
|
||||
//freeze resolution to not allow Resolvers to be modified
|
||||
Resolution.Freeze();
|
||||
|
||||
//stop the timer and log the output
|
||||
_timer.Dispose();
|
||||
|
||||
if (afterComplete != null)
|
||||
{
|
||||
afterComplete(ApplicationContext.Current);
|
||||
}
|
||||
|
||||
_isComplete = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the resolvers
|
||||
/// </summary>
|
||||
protected virtual void InitializeResolvers()
|
||||
{
|
||||
CacheRefreshersResolver.Current = new CacheRefreshersResolver(
|
||||
() => PluginManager.Current.ResolveCacheRefreshers());
|
||||
|
||||
DataTypesResolver.Current = new DataTypesResolver(
|
||||
() => PluginManager.Current.ResolveDataTypes());
|
||||
|
||||
MacroFieldEditorsResolver.Current = new MacroFieldEditorsResolver(
|
||||
() => PluginManager.Current.ResolveMacroRenderings());
|
||||
|
||||
PackageActionsResolver.Current = new PackageActionsResolver(
|
||||
() => PluginManager.Current.ResolvePackageActions());
|
||||
|
||||
ActionsResolver.Current = new ActionsResolver(
|
||||
() => PluginManager.Current.ResolveActions());
|
||||
|
||||
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
|
||||
PluginManager.Current.ResolvePropertyEditorValueConverters());
|
||||
//add the internal ones, these are not public currently so need to add them manually
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<DatePickerPropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<TinyMcePropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<YesNoPropertyEditorValueConverter>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows for converting string representations of 0 and 1 to boolean
|
||||
/// </summary>
|
||||
internal class CustomBooleanTypeConverter : BooleanConverter
|
||||
{
|
||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||
{
|
||||
if (sourceType == typeof(string))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return base.CanConvertFrom(context, sourceType);
|
||||
}
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
|
||||
{
|
||||
if (value is string)
|
||||
{
|
||||
var str = (string)value;
|
||||
if (str == "1") return true;
|
||||
if (str == "0" || str == "") return false;
|
||||
}
|
||||
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Static and extension methods for the DataTable object
|
||||
/// </summary>
|
||||
internal static class DataTableExtensions
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a DataTable with the specified alias and columns and uses a callback to populate the headers.
|
||||
/// </summary>
|
||||
/// <param name="tableAlias"></param>
|
||||
/// <param name="getHeaders"></param>
|
||||
/// <param name="rowData"> </param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This has been migrated from the Node class and uses proper locking now. It is now used by the Node class and the
|
||||
/// DynamicPublishedContent extensions for legacy reasons.
|
||||
/// </remarks>
|
||||
public static DataTable GenerateDataTable(
|
||||
string tableAlias,
|
||||
Func<string, IEnumerable<KeyValuePair<string, string>>> getHeaders,
|
||||
Func<IEnumerable<Tuple<IEnumerable<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>>>> rowData)
|
||||
{
|
||||
var dt = new DataTable(tableAlias);
|
||||
|
||||
//get all row data
|
||||
var tableData = rowData().ToArray();
|
||||
|
||||
//get all headers
|
||||
var propertyHeaders = GetPropertyHeaders(tableAlias, getHeaders);
|
||||
foreach(var h in propertyHeaders)
|
||||
{
|
||||
dt.Columns.Add(new DataColumn(h.Value));
|
||||
}
|
||||
|
||||
//add row data
|
||||
foreach(var r in tableData)
|
||||
{
|
||||
dt.PopulateRow(
|
||||
propertyHeaders,
|
||||
r.Item1,
|
||||
r.Item2);
|
||||
}
|
||||
|
||||
return dt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to return this ugly object
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is for legacy code, I didn't want to go creating custom classes for these
|
||||
/// </remarks>
|
||||
internal static List<System.Tuple<IEnumerable<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>>> CreateTableData()
|
||||
{
|
||||
return new List<System.Tuple<IEnumerable<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method to deal with these ugly objects
|
||||
/// </summary>
|
||||
/// <param name="rowData"></param>
|
||||
/// <param name="standardVals"></param>
|
||||
/// <param name="userVals"></param>
|
||||
/// <remarks>
|
||||
/// This is for legacy code, I didn't want to go creating custom classes for these
|
||||
/// </remarks>
|
||||
internal static void AddRowData(
|
||||
List<System.Tuple<IEnumerable<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>>> rowData,
|
||||
IEnumerable<KeyValuePair<string, object>> standardVals,
|
||||
IEnumerable<KeyValuePair<string, object>> userVals)
|
||||
{
|
||||
rowData.Add(new System.Tuple<IEnumerable<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>>(
|
||||
standardVals,
|
||||
userVals
|
||||
));
|
||||
}
|
||||
|
||||
private static IDictionary<string, string> GetPropertyHeaders(string alias, Func<string, IEnumerable<KeyValuePair<string, string>>> getHeaders)
|
||||
{
|
||||
var headers = getHeaders(alias);
|
||||
var def = headers.ToDictionary(pt => pt.Key, pt => pt.Value);
|
||||
return def;
|
||||
}
|
||||
|
||||
private static void PopulateRow(
|
||||
this DataTable dt,
|
||||
IDictionary<string, string> aliasesToNames,
|
||||
IEnumerable<KeyValuePair<string, object>> standardVals,
|
||||
IEnumerable<KeyValuePair<string, object>> userPropertyVals)
|
||||
{
|
||||
var dr = dt.NewRow();
|
||||
foreach (var r in standardVals)
|
||||
{
|
||||
dr[r.Key] = r.Value;
|
||||
}
|
||||
foreach (var p in userPropertyVals.Where(p => p.Value != null))
|
||||
{
|
||||
dr[aliasesToNames[p.Key]] = p.Value;
|
||||
}
|
||||
dt.Rows.Add(dr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all IDataType objects
|
||||
/// </summary>
|
||||
internal sealed class DataTypesResolver : LegacyTransientObjectsResolver<DataTypesResolver, IDataType>
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dataTypes"></param>
|
||||
internal DataTypesResolver(Func<IEnumerable<Type>> dataTypes)
|
||||
: base(dataTypes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ICacheRefresher"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IDataType> DataTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureIdsAreTracked();
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
protected override Guid GetUniqueIdentifier(IDataType obj)
|
||||
{
|
||||
return obj.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Dictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves the current CultureDictionaryFactory
|
||||
/// </summary>
|
||||
internal sealed class CultureDictionaryFactoryResolver : SingleObjectResolverBase<CultureDictionaryFactoryResolver, ICultureDictionaryFactory>
|
||||
{
|
||||
internal CultureDictionaryFactoryResolver(ICultureDictionaryFactory factory)
|
||||
: base(factory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can be used by developers at runtime to set their ICultureDictionaryFactory at app startup
|
||||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
public void SetContentStore(ICultureDictionaryFactory factory)
|
||||
{
|
||||
Value = factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ICultureDictionaryFactory
|
||||
/// </summary>
|
||||
public ICultureDictionaryFactory Factory
|
||||
{
|
||||
get { return Value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Umbraco.Core.Dictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a dictionary based on a specific culture
|
||||
/// </summary>
|
||||
internal interface ICultureDictionary
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the dictionary value based on the key supplied
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
string this[string key] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current culture
|
||||
/// </summary>
|
||||
CultureInfo Culture { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Umbraco.Core.Dictionary
|
||||
{
|
||||
internal interface ICultureDictionaryFactory
|
||||
{
|
||||
ICultureDictionary CreateDictionary();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
///<summary>
|
||||
/// Extension methods for dictionary
|
||||
///</summary>
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts a dictionary to another type by only using direct casting
|
||||
/// </summary>
|
||||
/// <typeparam name="TKeyOut"></typeparam>
|
||||
/// <typeparam name="TValOut"></typeparam>
|
||||
/// <param name="d"></param>
|
||||
/// <returns></returns>
|
||||
public static IDictionary<TKeyOut, TValOut> ConvertTo<TKeyOut, TValOut>(this IDictionary d)
|
||||
{
|
||||
var result = new Dictionary<TKeyOut, TValOut>();
|
||||
foreach (DictionaryEntry v in d)
|
||||
{
|
||||
result.Add((TKeyOut)v.Key, (TValOut)v.Value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a dictionary to another type using the specified converters
|
||||
/// </summary>
|
||||
/// <typeparam name="TKeyOut"></typeparam>
|
||||
/// <typeparam name="TValOut"></typeparam>
|
||||
/// <param name="d"></param>
|
||||
/// <param name="keyConverter"></param>
|
||||
/// <param name="valConverter"></param>
|
||||
/// <returns></returns>
|
||||
public static IDictionary<TKeyOut, TValOut> ConvertTo<TKeyOut, TValOut>(this IDictionary d, Func<object, TKeyOut> keyConverter, Func<object, TValOut> valConverter)
|
||||
{
|
||||
var result = new Dictionary<TKeyOut, TValOut>();
|
||||
foreach (DictionaryEntry v in d)
|
||||
{
|
||||
result.Add(keyConverter(v.Key), valConverter(v.Value));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a dictionary to a NameValueCollection
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
/// <returns></returns>
|
||||
public static NameValueCollection ToNameValueCollection(this IDictionary<string, string> d)
|
||||
{
|
||||
var n = new NameValueCollection();
|
||||
foreach (var i in d)
|
||||
{
|
||||
n.Add(i.Key, i.Value);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a dictionary to a FormCollection
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
/// <returns></returns>
|
||||
public static FormCollection ToFormCollection(this IDictionary<string, object> d)
|
||||
{
|
||||
var n = new FormCollection();
|
||||
foreach (var i in d)
|
||||
{
|
||||
n.Add(i.Key, Convert.ToString(i.Value));
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new dictionary of this ... others merged leftward.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TK"></typeparam>
|
||||
/// <typeparam name="TV"></typeparam>
|
||||
/// <param name="me"></param>
|
||||
/// <param name="others"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// Reference: http://stackoverflow.com/questions/294138/merging-dictionaries-in-c
|
||||
/// </remarks>
|
||||
public static T MergeLeft<T, TK, TV>(this T me, params IDictionary<TK, TV>[] others)
|
||||
where T : IDictionary<TK, TV>, new()
|
||||
{
|
||||
var newMap = new T();
|
||||
foreach (var p in (new List<IDictionary<TK, TV>> { me }).Concat(others).SelectMany(src => src))
|
||||
{
|
||||
newMap[p.Key] = p.Value;
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of the key value based on the key, if the key is not found, a null value is returned
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">The type of the key.</typeparam>
|
||||
/// <typeparam name="TVal">The type of the val.</typeparam>
|
||||
/// <param name="d">The d.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
/// <returns></returns>
|
||||
public static TVal GetValue<TKey, TVal>(this IDictionary<TKey, TVal> d, TKey key, TVal defaultValue = default(TVal))
|
||||
{
|
||||
if (d.ContainsKey(key))
|
||||
{
|
||||
return d[key];
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of the key value based on the key as it's string value, if the key is not found, then an empty string is returned
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetValueAsString<TKey, TVal>(this IDictionary<TKey, TVal> d, TKey key)
|
||||
{
|
||||
if (d.ContainsKey(key))
|
||||
{
|
||||
return d[key].ToString();
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
/// <summary>contains key ignore case.</summary>
|
||||
/// <param name="dictionary">The dictionary.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <typeparam name="TValue">Value Type</typeparam>
|
||||
/// <returns>The contains key ignore case.</returns>
|
||||
public static bool ContainsKeyIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key)
|
||||
{
|
||||
return dictionary.Keys.Any(i => i.Equals(key, StringComparison.CurrentCultureIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a dictionary object to a query string representation such as:
|
||||
/// firstname=shannon&lastname=deminick
|
||||
/// </summary>
|
||||
/// <param name="d"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToQueryString(this IDictionary<string, object> d)
|
||||
{
|
||||
if (!d.Any()) return "";
|
||||
|
||||
var builder = new StringBuilder();
|
||||
foreach (var i in d)
|
||||
{
|
||||
builder.Append(String.Format("{0}={1}&", HttpUtility.UrlEncode(i.Key), i.Value == null ? string.Empty : HttpUtility.UrlEncode(i.Value.ToString())));
|
||||
}
|
||||
return builder.ToString().TrimEnd('&');
|
||||
}
|
||||
|
||||
/// <summary>The get entry ignore case.</summary>
|
||||
/// <param name="dictionary">The dictionary.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <typeparam name="TValue">The type</typeparam>
|
||||
/// <returns>The entry</returns>
|
||||
public static TValue GetEntryIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key)
|
||||
{
|
||||
return dictionary.GetEntryIgnoreCase(key, default(TValue));
|
||||
}
|
||||
|
||||
/// <summary>The get entry ignore case.</summary>
|
||||
/// <param name="dictionary">The dictionary.</param>
|
||||
/// <param name="key">The key.</param>
|
||||
/// <param name="defaultValue">The default value.</param>
|
||||
/// <typeparam name="TValue">The type</typeparam>
|
||||
/// <returns>The entry</returns>
|
||||
public static TValue GetEntryIgnoreCase<TValue>(this IDictionary<string, TValue> dictionary, string key, TValue defaultValue)
|
||||
{
|
||||
key = dictionary.Keys.Where(i => i.Equals(key, StringComparison.CurrentCultureIgnoreCase)).FirstOrDefault();
|
||||
|
||||
return !key.IsNullOrWhiteSpace()
|
||||
? dictionary[key]
|
||||
: defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract implementation of logic commonly required to safely handle disposable unmanaged resources.
|
||||
/// </summary>
|
||||
public abstract class DisposableObject : IDisposable
|
||||
{
|
||||
private bool _disposed;
|
||||
private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is disposed.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if this instance is disposed; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsDisposed
|
||||
{
|
||||
get { return _disposed; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
// Use SupressFinalize in case a subclass of this type implements a finalizer.
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~DisposableObject()
|
||||
{
|
||||
// Run dispose but let the class know it was due to the finalizer running.
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
// Only operate if we haven't already disposed
|
||||
if (IsDisposed || !disposing) return;
|
||||
|
||||
using (new WriteLock(_disposalLocker))
|
||||
{
|
||||
// Check again now we're inside the lock
|
||||
if (IsDisposed) return;
|
||||
|
||||
// Call to actually release resources. This method is only
|
||||
// kept separate so that the entire disposal logic can be used as a VS snippet
|
||||
DisposeResources();
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
|
||||
/// </summary>
|
||||
protected abstract void DisposeResources();
|
||||
|
||||
protected virtual void DisposeUnmanagedResources()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Starts the timer and invokes a callback upon disposal. Provides a simple way of timing an operation by wrapping it in a <code>using</code> (C#) statement.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// Console.WriteLine("Testing Stopwatchdisposable, should be 567:");
|
||||
// using (var timer = new DisposableTimer(result => Console.WriteLine("Took {0}ms", result)))
|
||||
// {
|
||||
// Thread.Sleep(567);
|
||||
// }
|
||||
/// </code>
|
||||
/// </example>
|
||||
public class DisposableTimer : DisposableObject
|
||||
{
|
||||
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();
|
||||
private readonly Action<long> _callback;
|
||||
|
||||
protected DisposableTimer(Action<long> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
public Stopwatch Stopwatch
|
||||
{
|
||||
get { return _stopwatch; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the timer and invokes the specified callback upon disposal.
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback.</param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer Start(Action<long> callback)
|
||||
{
|
||||
return new DisposableTimer(callback);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Info and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Info(loggerType, () => startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, () => startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a start and end log entry as Debug and tracks how long it takes until disposed.
|
||||
/// </summary>
|
||||
/// <param name="loggerType"></param>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
return new DisposableTimer(x => LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the disposal of resources. Derived from abstract class <see cref="DisposableObject"/> which handles common required locking logic.
|
||||
/// </summary>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal class DynamicWrapper
|
||||
{
|
||||
public class DynamicWrapperBase
|
||||
{
|
||||
internal protected object RealObject;
|
||||
}
|
||||
|
||||
private static readonly ModuleBuilder _moduleBuilder;
|
||||
|
||||
static DynamicWrapper()
|
||||
{
|
||||
var name = Assembly.GetExecutingAssembly().GetName();
|
||||
var assembly = Thread.GetDomain().DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
|
||||
_moduleBuilder = assembly.DefineDynamicModule("DynamicWrapperModule", false);
|
||||
}
|
||||
|
||||
private static readonly WrapperDictionary _wrapperDictionary = new WrapperDictionary();
|
||||
|
||||
public static Type GetWrapper(Type interfaceType, Type realObjectType)
|
||||
{
|
||||
Type wrapperType = _wrapperDictionary.GetType(interfaceType, realObjectType);
|
||||
|
||||
if (wrapperType == null)
|
||||
{
|
||||
wrapperType = GenerateWrapperType(interfaceType, realObjectType);
|
||||
_wrapperDictionary.SetType(interfaceType, realObjectType, wrapperType);
|
||||
}
|
||||
|
||||
return wrapperType;
|
||||
}
|
||||
|
||||
private static Type GenerateWrapperType(Type InterfaceType, Type RealObjectType)
|
||||
{
|
||||
var wrapperName = string.Format("{0}_{1}_Wrapper", InterfaceType.Name, RealObjectType.Name);
|
||||
|
||||
TypeBuilder wrapperBuilder = _moduleBuilder.DefineType(
|
||||
wrapperName,
|
||||
TypeAttributes.NotPublic | TypeAttributes.Sealed,
|
||||
typeof(DynamicWrapperBase),
|
||||
new[] { InterfaceType });
|
||||
|
||||
var wrapperMethod = new WrapperMethodBuilder(RealObjectType, wrapperBuilder);
|
||||
|
||||
foreach (MethodInfo method in InterfaceType.AllMethods())
|
||||
{
|
||||
wrapperMethod.Generate(method);
|
||||
}
|
||||
|
||||
return wrapperBuilder.CreateType();
|
||||
}
|
||||
|
||||
public static T CreateWrapper<T>(object realObject) where T : class
|
||||
{
|
||||
var dynamicType = GetWrapper(typeof(T), realObject.GetType());
|
||||
var dynamicWrapper = (DynamicWrapperBase)Activator.CreateInstance(dynamicType);
|
||||
|
||||
dynamicWrapper.RealObject = realObject;
|
||||
|
||||
return dynamicWrapper as T;
|
||||
}
|
||||
}
|
||||
|
||||
internal class WrapperMethodBuilder
|
||||
{
|
||||
private readonly Type _realObjectType;
|
||||
private readonly TypeBuilder _wrapperBuilder;
|
||||
|
||||
public WrapperMethodBuilder(Type realObjectType, TypeBuilder proxyBuilder)
|
||||
{
|
||||
_realObjectType = realObjectType;
|
||||
_wrapperBuilder = proxyBuilder;
|
||||
}
|
||||
|
||||
public void Generate(MethodInfo newMethod)
|
||||
{
|
||||
if (newMethod.IsGenericMethod)
|
||||
newMethod = newMethod.GetGenericMethodDefinition();
|
||||
|
||||
FieldInfo srcField = typeof(DynamicWrapper.DynamicWrapperBase).GetField("RealObject", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
var parameters = newMethod.GetParameters();
|
||||
var parameterTypes = parameters.Select(parameter => parameter.ParameterType).ToArray();
|
||||
|
||||
var methodBuilder = _wrapperBuilder.DefineMethod(
|
||||
newMethod.Name,
|
||||
MethodAttributes.Public | MethodAttributes.Virtual,
|
||||
newMethod.ReturnType,
|
||||
parameterTypes);
|
||||
|
||||
if (newMethod.IsGenericMethod)
|
||||
{
|
||||
methodBuilder.DefineGenericParameters(
|
||||
newMethod.GetGenericArguments().Select(arg => arg.Name).ToArray());
|
||||
}
|
||||
|
||||
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
|
||||
|
||||
LoadRealObject(ilGenerator, srcField);
|
||||
PushParameters(parameters, ilGenerator);
|
||||
ExecuteMethod(newMethod, parameterTypes, ilGenerator);
|
||||
Return(ilGenerator);
|
||||
}
|
||||
|
||||
private static void Return(ILGenerator ilGenerator)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
private void ExecuteMethod(MethodBase newMethod, Type[] parameterTypes, ILGenerator ilGenerator)
|
||||
{
|
||||
MethodInfo srcMethod = GetMethod(newMethod, parameterTypes);
|
||||
|
||||
if (srcMethod == null) throw new MissingMethodException("Unable to find method " + newMethod.Name + " in " + _realObjectType.FullName);
|
||||
|
||||
ilGenerator.Emit(OpCodes.Call, srcMethod);
|
||||
}
|
||||
|
||||
private MethodInfo GetMethod(MethodBase realMethod, Type[] parameterTypes)
|
||||
{
|
||||
if (realMethod.IsGenericMethod)
|
||||
return _realObjectType.GetGenericMethod(realMethod.Name, parameterTypes);
|
||||
|
||||
return _realObjectType.GetMethod(realMethod.Name, parameterTypes);
|
||||
}
|
||||
|
||||
private static void PushParameters(ICollection<ParameterInfo> parameters, ILGenerator ilGenerator)
|
||||
{
|
||||
for (int i = 1; i < parameters.Count + 1; i++)
|
||||
ilGenerator.Emit(OpCodes.Ldarg, i);
|
||||
}
|
||||
|
||||
private static void LoadRealObject(ILGenerator ilGenerator, FieldInfo srcField)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldarg_0);
|
||||
ilGenerator.Emit(OpCodes.Ldfld, srcField);
|
||||
}
|
||||
}
|
||||
|
||||
internal class WrapperDictionary
|
||||
{
|
||||
private readonly Dictionary<string, Type> _wrapperTypes = new Dictionary<string, Type>();
|
||||
|
||||
private static string GenerateKey(Type interfaceType, Type realObjectType)
|
||||
{
|
||||
return interfaceType.Name + "->" + realObjectType.Name;
|
||||
}
|
||||
|
||||
public Type GetType(Type interfaceType, Type realObjectType)
|
||||
{
|
||||
string key = GenerateKey(interfaceType, realObjectType);
|
||||
|
||||
if (_wrapperTypes.ContainsKey(key))
|
||||
return _wrapperTypes[key];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetType(Type interfaceType, Type realObjectType, Type wrapperType)
|
||||
{
|
||||
string key = GenerateKey(interfaceType, realObjectType);
|
||||
|
||||
if (_wrapperTypes.ContainsKey(key))
|
||||
_wrapperTypes[key] = wrapperType;
|
||||
else
|
||||
_wrapperTypes.Add(key, wrapperType);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal class ClassFactory
|
||||
{
|
||||
public static readonly ClassFactory Instance = new ClassFactory();
|
||||
|
||||
static ClassFactory() { } // Trigger lazy initialization of static fields
|
||||
|
||||
ModuleBuilder module;
|
||||
Dictionary<Signature, Type> classes;
|
||||
int classCount;
|
||||
ReaderWriterLock rwLock;
|
||||
|
||||
protected ClassFactory()
|
||||
{
|
||||
AssemblyName name = new AssemblyName("DynamicClasses");
|
||||
AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
|
||||
#if ENABLE_LINQ_PARTIAL_TRUST
|
||||
new ReflectionPermission(PermissionState.Unrestricted).Assert();
|
||||
#endif
|
||||
try
|
||||
{
|
||||
module = assembly.DefineDynamicModule("Module");
|
||||
}
|
||||
finally
|
||||
{
|
||||
#if ENABLE_LINQ_PARTIAL_TRUST
|
||||
PermissionSet.RevertAssert();
|
||||
#endif
|
||||
}
|
||||
classes = new Dictionary<Signature, Type>();
|
||||
rwLock = new ReaderWriterLock();
|
||||
}
|
||||
|
||||
public Type GetDynamicClass(IEnumerable<DynamicProperty> properties)
|
||||
{
|
||||
rwLock.AcquireReaderLock(Timeout.Infinite);
|
||||
try
|
||||
{
|
||||
Signature signature = new Signature(properties);
|
||||
Type type;
|
||||
if (!classes.TryGetValue(signature, out type))
|
||||
{
|
||||
type = CreateDynamicClass(signature.Properties);
|
||||
classes.Add(signature, type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
finally
|
||||
{
|
||||
rwLock.ReleaseReaderLock();
|
||||
}
|
||||
}
|
||||
|
||||
Type CreateDynamicClass(DynamicProperty[] properties)
|
||||
{
|
||||
LockCookie cookie = rwLock.UpgradeToWriterLock(Timeout.Infinite);
|
||||
try
|
||||
{
|
||||
string typeName = "DynamicClass" + (classCount + 1);
|
||||
#if ENABLE_LINQ_PARTIAL_TRUST
|
||||
new ReflectionPermission(PermissionState.Unrestricted).Assert();
|
||||
#endif
|
||||
try
|
||||
{
|
||||
TypeBuilder tb = this.module.DefineType(typeName, TypeAttributes.Class |
|
||||
TypeAttributes.Public, typeof(DynamicClass));
|
||||
FieldInfo[] fields = GenerateProperties(tb, properties);
|
||||
GenerateEquals(tb, fields);
|
||||
GenerateGetHashCode(tb, fields);
|
||||
Type result = tb.CreateType();
|
||||
classCount++;
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
#if ENABLE_LINQ_PARTIAL_TRUST
|
||||
PermissionSet.RevertAssert();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
rwLock.DowngradeFromWriterLock(ref cookie);
|
||||
}
|
||||
}
|
||||
|
||||
FieldInfo[] GenerateProperties(TypeBuilder tb, DynamicProperty[] properties)
|
||||
{
|
||||
FieldInfo[] fields = new FieldBuilder[properties.Length];
|
||||
for (int i = 0; i < properties.Length; i++)
|
||||
{
|
||||
DynamicProperty dp = properties[i];
|
||||
FieldBuilder fb = tb.DefineField("_" + dp.Name, dp.Type, FieldAttributes.Private);
|
||||
PropertyBuilder pb = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, null);
|
||||
MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name,
|
||||
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
|
||||
dp.Type, Type.EmptyTypes);
|
||||
ILGenerator genGet = mbGet.GetILGenerator();
|
||||
genGet.Emit(OpCodes.Ldarg_0);
|
||||
genGet.Emit(OpCodes.Ldfld, fb);
|
||||
genGet.Emit(OpCodes.Ret);
|
||||
MethodBuilder mbSet = tb.DefineMethod("set_" + dp.Name,
|
||||
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
|
||||
null, new Type[] { dp.Type });
|
||||
ILGenerator genSet = mbSet.GetILGenerator();
|
||||
genSet.Emit(OpCodes.Ldarg_0);
|
||||
genSet.Emit(OpCodes.Ldarg_1);
|
||||
genSet.Emit(OpCodes.Stfld, fb);
|
||||
genSet.Emit(OpCodes.Ret);
|
||||
pb.SetGetMethod(mbGet);
|
||||
pb.SetSetMethod(mbSet);
|
||||
fields[i] = fb;
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
void GenerateEquals(TypeBuilder tb, FieldInfo[] fields)
|
||||
{
|
||||
MethodBuilder mb = tb.DefineMethod("Equals",
|
||||
MethodAttributes.Public | MethodAttributes.ReuseSlot |
|
||||
MethodAttributes.Virtual | MethodAttributes.HideBySig,
|
||||
typeof(bool), new Type[] { typeof(object) });
|
||||
ILGenerator gen = mb.GetILGenerator();
|
||||
LocalBuilder other = gen.DeclareLocal(tb);
|
||||
Label next = gen.DefineLabel();
|
||||
gen.Emit(OpCodes.Ldarg_1);
|
||||
gen.Emit(OpCodes.Isinst, tb);
|
||||
gen.Emit(OpCodes.Stloc, other);
|
||||
gen.Emit(OpCodes.Ldloc, other);
|
||||
gen.Emit(OpCodes.Brtrue_S, next);
|
||||
gen.Emit(OpCodes.Ldc_I4_0);
|
||||
gen.Emit(OpCodes.Ret);
|
||||
gen.MarkLabel(next);
|
||||
foreach (FieldInfo field in fields)
|
||||
{
|
||||
Type ft = field.FieldType;
|
||||
Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);
|
||||
next = gen.DefineLabel();
|
||||
gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);
|
||||
gen.Emit(OpCodes.Ldarg_0);
|
||||
gen.Emit(OpCodes.Ldfld, field);
|
||||
gen.Emit(OpCodes.Ldloc, other);
|
||||
gen.Emit(OpCodes.Ldfld, field);
|
||||
gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", new Type[] { ft, ft }), null);
|
||||
gen.Emit(OpCodes.Brtrue_S, next);
|
||||
gen.Emit(OpCodes.Ldc_I4_0);
|
||||
gen.Emit(OpCodes.Ret);
|
||||
gen.MarkLabel(next);
|
||||
}
|
||||
gen.Emit(OpCodes.Ldc_I4_1);
|
||||
gen.Emit(OpCodes.Ret);
|
||||
}
|
||||
|
||||
void GenerateGetHashCode(TypeBuilder tb, FieldInfo[] fields)
|
||||
{
|
||||
MethodBuilder mb = tb.DefineMethod("GetHashCode",
|
||||
MethodAttributes.Public | MethodAttributes.ReuseSlot |
|
||||
MethodAttributes.Virtual | MethodAttributes.HideBySig,
|
||||
typeof(int), Type.EmptyTypes);
|
||||
ILGenerator gen = mb.GetILGenerator();
|
||||
gen.Emit(OpCodes.Ldc_I4_0);
|
||||
foreach (FieldInfo field in fields)
|
||||
{
|
||||
Type ft = field.FieldType;
|
||||
Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);
|
||||
gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);
|
||||
gen.Emit(OpCodes.Ldarg_0);
|
||||
gen.Emit(OpCodes.Ldfld, field);
|
||||
gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", new Type[] { ft }), null);
|
||||
gen.Emit(OpCodes.Xor);
|
||||
}
|
||||
gen.Emit(OpCodes.Ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
public abstract class DynamicClass
|
||||
{
|
||||
public override string ToString()
|
||||
{
|
||||
PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("{");
|
||||
for (int i = 0; i < props.Length; i++)
|
||||
{
|
||||
if (i > 0) sb.Append(", ");
|
||||
sb.Append(props[i].Name);
|
||||
sb.Append("=");
|
||||
sb.Append(props[i].GetValue(this, null));
|
||||
}
|
||||
sb.Append("}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
public class DynamicDictionary : DynamicObject
|
||||
{
|
||||
internal readonly Dictionary<string, object> SourceItems;
|
||||
|
||||
public DynamicDictionary(Dictionary<string, object> sourceItems)
|
||||
{
|
||||
SourceItems = sourceItems;
|
||||
}
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
if (SourceItems.ContainsKey(binder.Name))
|
||||
{
|
||||
SourceItems[binder.Name.ToLower()] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
SourceItems.Add(binder.Name.ToLower(), value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
if (SourceItems != null)
|
||||
{
|
||||
if (SourceItems.TryGetValue(binder.Name.ToLower(), out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class to try invoke members, find properties, etc...
|
||||
/// </summary>
|
||||
internal class DynamicInstanceHelper
|
||||
{
|
||||
|
||||
internal class TryInvokeMemberResult
|
||||
{
|
||||
public object ObjectResult { get; private set; }
|
||||
public TryInvokeMemberSuccessReason Reason { get; private set; }
|
||||
|
||||
public TryInvokeMemberResult(object result, TryInvokeMemberSuccessReason reason)
|
||||
{
|
||||
ObjectResult = result;
|
||||
Reason = reason;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum TryInvokeMemberSuccessReason
|
||||
{
|
||||
FoundProperty,
|
||||
FoundMethod,
|
||||
FoundExtensionMethod
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to invoke a member based on the dynamic instance
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="thisObject">The object instance to invoke the extension method for</param>
|
||||
/// <param name="binder"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// First tries to find a property with the binder name, if that fails it will try to find a static or instance method
|
||||
/// on the object that matches the binder name
|
||||
/// </remarks>
|
||||
public static Attempt<TryInvokeMemberResult> TryInvokeMember<T>(T thisObject, InvokeMemberBinder binder, object[] args)
|
||||
{
|
||||
return TryInvokeMember<T>(thisObject, binder, args, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to invoke a member based on the dynamic instance
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="thisObject">The object instance to invoke the extension method for</param>
|
||||
/// <param name="binder"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <param name="findExtensionMethodsOnTypes">The types to scan for extension methods </param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// First tries to find a property with the binder name, if that fails it will try to find a static or instance method
|
||||
/// on the object that matches the binder name, if that fails it will then attempt to invoke an extension method
|
||||
/// based on the binder name and the extension method types to scan.
|
||||
/// </remarks>
|
||||
public static Attempt<TryInvokeMemberResult> TryInvokeMember<T>(T thisObject,
|
||||
InvokeMemberBinder binder,
|
||||
object[] args,
|
||||
IEnumerable<Type> findExtensionMethodsOnTypes)
|
||||
{
|
||||
//TODO: We MUST cache the result here, it is very expensive to keep finding extension methods!
|
||||
object result;
|
||||
try
|
||||
{
|
||||
//Property?
|
||||
result = typeof(T).InvokeMember(binder.Name,
|
||||
System.Reflection.BindingFlags.Instance |
|
||||
System.Reflection.BindingFlags.Public |
|
||||
System.Reflection.BindingFlags.GetProperty,
|
||||
null,
|
||||
thisObject,
|
||||
args);
|
||||
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundProperty));
|
||||
}
|
||||
catch (MissingMethodException)
|
||||
{
|
||||
try
|
||||
{
|
||||
//Static or Instance Method?
|
||||
result = typeof(T).InvokeMember(binder.Name,
|
||||
System.Reflection.BindingFlags.Instance |
|
||||
System.Reflection.BindingFlags.Public |
|
||||
System.Reflection.BindingFlags.Static |
|
||||
System.Reflection.BindingFlags.InvokeMethod,
|
||||
null,
|
||||
thisObject,
|
||||
args);
|
||||
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundMethod));
|
||||
}
|
||||
catch (MissingMethodException)
|
||||
{
|
||||
if (findExtensionMethodsOnTypes != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = FindAndExecuteExtensionMethod(thisObject, args, binder.Name, findExtensionMethodsOnTypes);
|
||||
return new Attempt<TryInvokeMemberResult>(true, new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundExtensionMethod));
|
||||
}
|
||||
catch (TargetInvocationException ext)
|
||||
{
|
||||
//don't log here, we return this exception because the caller may need to do something specific when
|
||||
//this exception occurs.
|
||||
return new Attempt<TryInvokeMemberResult>(ext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var sb = new StringBuilder("An error occurred finding an executing an extension method for type ");
|
||||
sb.Append(typeof (T));
|
||||
sb.Append("Types searched for extension methods were ");
|
||||
foreach(var t in findExtensionMethodsOnTypes)
|
||||
{
|
||||
sb.Append(t + ",");
|
||||
}
|
||||
LogHelper.Error<DynamicInstanceHelper>(sb.ToString(), ex);
|
||||
return new Attempt<TryInvokeMemberResult>(ex);
|
||||
}
|
||||
}
|
||||
return Attempt<TryInvokeMemberResult>.False;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<DynamicInstanceHelper>("An unhandled exception occurred in method TryInvokeMember", ex);
|
||||
return new Attempt<TryInvokeMemberResult>(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to find an extension method that matches the name and arguments based on scanning the Type's passed in
|
||||
/// to the findMethodsOnTypes parameter
|
||||
/// </summary>
|
||||
/// <param name="thisObject">The instance object to execute the extension method for</param>
|
||||
/// <param name="args"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="findMethodsOnTypes"></param>
|
||||
/// <returns></returns>
|
||||
internal static object FindAndExecuteExtensionMethod<T>(T thisObject,
|
||||
object[] args,
|
||||
string name,
|
||||
IEnumerable<Type> findMethodsOnTypes)
|
||||
{
|
||||
object result = null;
|
||||
|
||||
//find known extension methods that match the first type in the list
|
||||
MethodInfo toExecute = null;
|
||||
foreach (var t in findMethodsOnTypes)
|
||||
{
|
||||
toExecute = ExtensionMethodFinder.FindExtensionMethod(t, args, name, false);
|
||||
if (toExecute != null)
|
||||
break;
|
||||
}
|
||||
|
||||
if (toExecute != null)
|
||||
{
|
||||
var genericArgs = (new[] { (object)thisObject }).Concat(args);
|
||||
result = toExecute.Invoke(null, genericArgs.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MissingMethodException();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections;
|
||||
using System.Dynamic;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
//This type is used as a return type when TryGetMember fails on a DynamicNode
|
||||
//.Where explicitly checks for this type, to indicate that nothing was returned
|
||||
//Because it's IEnumerable, if the user is actually trying @Model.TextPages or similar
|
||||
//it will still return an enumerable object (assuming the call actually failed because there were no children of that type)
|
||||
//but in .Where, if they use a property that doesn't exist, the lambda will bypass this and return false
|
||||
public class DynamicNull : DynamicObject, IEnumerable, IHtmlString
|
||||
{
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return (new List<DynamicNull>()).GetEnumerator();
|
||||
}
|
||||
public DynamicNull Where(string predicate, params object[] values)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
public DynamicNull OrderBy(string orderBy)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
public int Count()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
result = this;
|
||||
return true;
|
||||
}
|
||||
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
|
||||
{
|
||||
result = this;
|
||||
return true;
|
||||
}
|
||||
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
|
||||
{
|
||||
result = this;
|
||||
return true;
|
||||
}
|
||||
public bool IsNull()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
public bool HasValue()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator bool(DynamicNull n)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public static implicit operator DateTime(DynamicNull n)
|
||||
{
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
public static implicit operator int(DynamicNull n)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public static implicit operator string(DynamicNull n)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public string ToHtmlString()
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal class DynamicOrdering
|
||||
{
|
||||
public Expression Selector;
|
||||
public bool Ascending;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal class DynamicProperty
|
||||
{
|
||||
readonly string _name;
|
||||
readonly Type _type;
|
||||
|
||||
public DynamicProperty(string name, Type type)
|
||||
{
|
||||
if (name == null) throw new ArgumentNullException("name");
|
||||
if (type == null) throw new ArgumentNullException("type");
|
||||
this._name = name;
|
||||
this._type = type;
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
}
|
||||
|
||||
public Type Type
|
||||
{
|
||||
get { return _type; }
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-5
@@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Dynamic;
|
||||
|
||||
namespace umbraco.MacroEngines
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
public class DynamicQueryableGetMemberBinder : GetMemberBinder
|
||||
internal class DynamicQueryableGetMemberBinder : GetMemberBinder
|
||||
{
|
||||
public DynamicQueryableGetMemberBinder(string name, bool ignoreCase) : base(name, ignoreCase) { }
|
||||
|
||||
@@ -0,0 +1,735 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Dynamic;
|
||||
using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
public class DynamicXml : DynamicObject, IEnumerable<DynamicXml>, IEnumerable<XElement>
|
||||
{
|
||||
public XElement BaseElement { get; set; }
|
||||
|
||||
public DynamicXml(XElement baseElement)
|
||||
{
|
||||
this.BaseElement = baseElement;
|
||||
}
|
||||
public DynamicXml(string xml)
|
||||
{
|
||||
var baseElement = XElement.Parse(xml);
|
||||
this.BaseElement = baseElement;
|
||||
}
|
||||
public DynamicXml(XPathNodeIterator xpni)
|
||||
{
|
||||
if (xpni != null)
|
||||
{
|
||||
if (xpni.Current != null)
|
||||
{
|
||||
var xml = xpni.Current.OuterXml;
|
||||
var baseElement = XElement.Parse(xml);
|
||||
this.BaseElement = baseElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
public string InnerText
|
||||
{
|
||||
get
|
||||
{
|
||||
return BaseElement.Value;
|
||||
}
|
||||
}
|
||||
public string ToXml()
|
||||
{
|
||||
return BaseElement.ToString(SaveOptions.DisableFormatting);
|
||||
}
|
||||
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
|
||||
{
|
||||
int index = 0;
|
||||
if (indexes.Length > 0)
|
||||
{
|
||||
index = (int)indexes[0];
|
||||
result = new DynamicXml(this.BaseElement.Elements().ToList()[index]);
|
||||
return true;
|
||||
}
|
||||
return base.TryGetIndex(binder, indexes, out result);
|
||||
}
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
|
||||
{
|
||||
if (args.Length == 0 && binder.Name == "ToXml")
|
||||
{
|
||||
result = this.BaseElement.ToString();
|
||||
return true;
|
||||
}
|
||||
if (args.Length == 1 && binder.Name == "XPath")
|
||||
{
|
||||
var elements = this.BaseElement.XPathSelectElements(args[0].ToString());
|
||||
HandleIEnumerableXElement(elements, out result);
|
||||
return true; //anyway
|
||||
}
|
||||
|
||||
//ok, now lets try to match by member, property, extensino method
|
||||
var attempt = DynamicInstanceHelper.TryInvokeMember(this, binder, args, new[]
|
||||
{
|
||||
typeof (IEnumerable<DynamicXml>),
|
||||
typeof (IEnumerable<XElement>),
|
||||
typeof (DynamicXml)
|
||||
});
|
||||
|
||||
if (attempt.Success)
|
||||
{
|
||||
result = attempt.Result.ObjectResult;
|
||||
|
||||
//need to check the return type and possibly cast if result is from an extension method found
|
||||
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod)
|
||||
{
|
||||
//if the result is already a DynamicXml instance, then we do not need to cast
|
||||
if (attempt.Result.ObjectResult != null && !(attempt.Result.ObjectResult is DynamicXml))
|
||||
{
|
||||
if (attempt.Result.ObjectResult is XElement)
|
||||
{
|
||||
result = new DynamicXml((XElement)attempt.Result.ObjectResult);
|
||||
}
|
||||
else if (attempt.Result.ObjectResult is IEnumerable<XElement>)
|
||||
{
|
||||
result = ((IEnumerable<XElement>)attempt.Result.ObjectResult).Select(x => new DynamicXml(x));
|
||||
}
|
||||
else if (attempt.Result.ObjectResult is IEnumerable<DynamicXml>)
|
||||
{
|
||||
result = ((IEnumerable<DynamicXml>)attempt.Result.ObjectResult).Select(x => new DynamicXml(x.BaseElement));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//this is the result of an extension method execution gone wrong so we return dynamic null
|
||||
if (attempt.Result.Reason == DynamicInstanceHelper.TryInvokeMemberSuccessReason.FoundExtensionMethod
|
||||
&& attempt.Error != null && attempt.Error is TargetInvocationException)
|
||||
{
|
||||
result = new DynamicNull();
|
||||
return true;
|
||||
}
|
||||
|
||||
result = null;
|
||||
return false;
|
||||
|
||||
}
|
||||
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
||||
{
|
||||
if (BaseElement == null || binder == null)
|
||||
{
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
//Go ahead and try to fetch all of the elements matching the member name, and wrap them
|
||||
var elements = BaseElement.Elements(binder.Name);
|
||||
if (!elements.Any() && BaseElement.Name == "root" && BaseElement.Elements().Count() == 1)
|
||||
{
|
||||
//no elements matched, lets try first child
|
||||
elements = BaseElement.Elements().ElementAt(0).Elements(binder.Name);
|
||||
}
|
||||
if (HandleIEnumerableXElement(elements, out result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
//Ok, so no elements matched, so lets try attributes
|
||||
IEnumerable<string> attributes = BaseElement.Attributes(binder.Name).Select(attr => attr.Value);
|
||||
int count = attributes.Count();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
if (count > 1)
|
||||
result = attributes; //more than one attribute matched, lets return the collection
|
||||
else
|
||||
result = attributes.FirstOrDefault(); //only one attribute matched, lets just return it
|
||||
|
||||
return true; // return true because we matched
|
||||
}
|
||||
else
|
||||
{
|
||||
//no attributes matched, lets try first child
|
||||
if (BaseElement.Name == "root" && BaseElement.Elements().Count() == 1)
|
||||
{
|
||||
attributes = BaseElement.Elements().ElementAt(0).Attributes(binder.Name).Select(attr => attr.Value);
|
||||
count = attributes.Count();
|
||||
if (count > 1)
|
||||
result = attributes; //more than one attribute matched, lets return the collection
|
||||
else
|
||||
result = attributes.FirstOrDefault(); //only one attribute matched, lets just return it
|
||||
|
||||
return true; // return true because we matched
|
||||
}
|
||||
}
|
||||
}
|
||||
return base.TryGetMember(binder, out result);
|
||||
}
|
||||
|
||||
private bool HandleIEnumerableXElement(IEnumerable<XElement> elements, out object result)
|
||||
{
|
||||
//Get the count now, so we don't have to call it twice
|
||||
int count = elements.Count();
|
||||
if (count > 0)
|
||||
{
|
||||
var firstElement = elements.FirstOrDefault();
|
||||
//we have a single element, does it have any children?
|
||||
if (firstElement != null && firstElement.Elements().Count() == 0 && !firstElement.HasAttributes)
|
||||
{
|
||||
//no, return the text
|
||||
result = firstElement.Value;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//We have more than one matching element, so let's return the collection
|
||||
//elements is IEnumerable<DynamicXml>
|
||||
//but we want to be able to re-enter this code
|
||||
XElement root = new XElement(XName.Get("root"));
|
||||
root.Add(elements);
|
||||
result = new DynamicXml(root);
|
||||
|
||||
//From here, you'll either end up back here (because you have <root><node><node>)
|
||||
//or you use [] indexing and you end up with a single element
|
||||
return true;
|
||||
}
|
||||
}
|
||||
result = null;
|
||||
return false;
|
||||
}
|
||||
public DynamicXml XPath(string expression)
|
||||
{
|
||||
var matched = this.BaseElement.XPathSelectElements(expression);
|
||||
DynamicXml root = new DynamicXml("<results/>");
|
||||
foreach (var element in matched)
|
||||
{
|
||||
root.BaseElement.Add(element);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
public IHtmlString ToHtml()
|
||||
{
|
||||
return new HtmlString(this.ToXml());
|
||||
}
|
||||
public DynamicXml Find(string expression)
|
||||
{
|
||||
return new DynamicXml(this.BaseElement.XPathSelectElements(expression).FirstOrDefault());
|
||||
}
|
||||
|
||||
public DynamicXml Find(string attributeName, object value)
|
||||
{
|
||||
string expression = string.Format("//*[{0}='{1}']", attributeName, value);
|
||||
return new DynamicXml(this.BaseElement.XPathSelectElements(expression).FirstOrDefault());
|
||||
}
|
||||
|
||||
IEnumerator<XElement> IEnumerable<XElement>.GetEnumerator()
|
||||
{
|
||||
return this.BaseElement.Elements().GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerator<DynamicXml> GetEnumerator()
|
||||
{
|
||||
return this.BaseElement.Elements().Select(e => new DynamicXml(e)).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public int Count()
|
||||
{
|
||||
return ((IEnumerable<XElement>)this).Count();
|
||||
}
|
||||
|
||||
public bool Any()
|
||||
{
|
||||
return ((IEnumerable<XElement>)this).Any();
|
||||
}
|
||||
|
||||
public IEnumerable<DynamicXml> Take(int count)
|
||||
{
|
||||
return ((IEnumerable<DynamicXml>)this).Take(count);
|
||||
}
|
||||
|
||||
public IEnumerable<DynamicXml> Skip(int count)
|
||||
{
|
||||
return ((IEnumerable<DynamicXml>)this).Skip(count);
|
||||
}
|
||||
|
||||
public bool IsNull()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
public bool HasValue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsFirst()
|
||||
{
|
||||
return IsHelper(n => n.Index() == 0);
|
||||
}
|
||||
public HtmlString IsFirst(string valueIfTrue)
|
||||
{
|
||||
return IsHelper(n => n.Index() == 0, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return IsHelper(n => n.Index() == 0, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsNotFirst()
|
||||
{
|
||||
return !IsHelper(n => n.Index() == 0);
|
||||
}
|
||||
public HtmlString IsNotFirst(string valueIfTrue)
|
||||
{
|
||||
return IsHelper(n => n.Index() != 0, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsNotFirst(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return IsHelper(n => n.Index() != 0, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsPosition(int index)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return IsHelper(n => n.Index() == index);
|
||||
}
|
||||
public HtmlString IsPosition(int index, string valueIfTrue)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(string.Empty);
|
||||
}
|
||||
return IsHelper(n => n.Index() == index, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsPosition(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(valueIfFalse);
|
||||
}
|
||||
return IsHelper(n => n.Index() == index, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsModZero(int modulus)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return IsHelper(n => n.Index() % modulus == 0);
|
||||
}
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(string.Empty);
|
||||
}
|
||||
return IsHelper(n => n.Index() % modulus == 0, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(valueIfFalse);
|
||||
}
|
||||
return IsHelper(n => n.Index() % modulus == 0, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
|
||||
public bool IsNotModZero(int modulus)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return IsHelper(n => n.Index() % modulus != 0);
|
||||
}
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(string.Empty);
|
||||
}
|
||||
return IsHelper(n => n.Index() % modulus != 0, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsNotModZero(int modulus, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(valueIfFalse);
|
||||
}
|
||||
return IsHelper(n => n.Index() % modulus != 0, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsNotPosition(int index)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return !IsHelper(n => n.Index() == index);
|
||||
}
|
||||
public HtmlString IsNotPosition(int index, string valueIfTrue)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(string.Empty);
|
||||
}
|
||||
return IsHelper(n => n.Index() != index, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsNotPosition(int index, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(valueIfFalse);
|
||||
}
|
||||
return IsHelper(n => n.Index() != index, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsLast()
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int count = this.BaseElement.Parent.Elements().Count();
|
||||
return IsHelper(n => n.Index() == count - 1);
|
||||
}
|
||||
public HtmlString IsLast(string valueIfTrue)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(string.Empty);
|
||||
}
|
||||
int count = this.BaseElement.Parent.Elements().Count();
|
||||
return IsHelper(n => n.Index() == count - 1, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(valueIfFalse);
|
||||
}
|
||||
int count = this.BaseElement.Parent.Elements().Count();
|
||||
return IsHelper(n => n.Index() == count - 1, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsNotLast()
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int count = this.BaseElement.Parent.Elements().Count();
|
||||
return !IsHelper(n => n.Index() == count - 1);
|
||||
}
|
||||
public HtmlString IsNotLast(string valueIfTrue)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(string.Empty);
|
||||
}
|
||||
int count = this.BaseElement.Parent.Elements().Count();
|
||||
return IsHelper(n => n.Index() != count - 1, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsNotLast(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
if (this.BaseElement == null || this.BaseElement.Parent == null)
|
||||
{
|
||||
return new HtmlString(valueIfFalse);
|
||||
}
|
||||
int count = this.BaseElement.Parent.Elements().Count();
|
||||
return IsHelper(n => n.Index() != count - 1, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsEven()
|
||||
{
|
||||
return IsHelper(n => n.Index() % 2 == 0);
|
||||
}
|
||||
public HtmlString IsEven(string valueIfTrue)
|
||||
{
|
||||
return IsHelper(n => n.Index() % 2 == 0, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsEven(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return IsHelper(n => n.Index() % 2 == 0, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsOdd()
|
||||
{
|
||||
return IsHelper(n => n.Index() % 2 == 1);
|
||||
}
|
||||
public HtmlString IsOdd(string valueIfTrue)
|
||||
{
|
||||
return IsHelper(n => n.Index() % 2 == 1, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsOdd(string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return IsHelper(n => n.Index() % 2 == 1, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsEqual(DynamicXml other)
|
||||
{
|
||||
return IsHelper(n => n.BaseElement == other.BaseElement);
|
||||
}
|
||||
public HtmlString IsEqual(DynamicXml other, string valueIfTrue)
|
||||
{
|
||||
return IsHelper(n => n.BaseElement == other.BaseElement, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsEqual(DynamicXml other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return IsHelper(n => n.BaseElement == other.BaseElement, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsNotEqual(DynamicXml other)
|
||||
{
|
||||
return IsHelper(n => n.BaseElement != other.BaseElement);
|
||||
}
|
||||
public HtmlString IsNotEqual(DynamicXml other, string valueIfTrue)
|
||||
{
|
||||
return IsHelper(n => n.BaseElement != other.BaseElement, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsNotEqual(DynamicXml other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return IsHelper(n => n.BaseElement != other.BaseElement, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsDescendant(DynamicXml other)
|
||||
{
|
||||
var ancestors = this.Ancestors();
|
||||
return IsHelper(n => ancestors.FirstOrDefault(ancestor => ancestor.BaseElement == other.BaseElement) != null);
|
||||
}
|
||||
public HtmlString IsDescendant(DynamicXml other, string valueIfTrue)
|
||||
{
|
||||
var ancestors = this.Ancestors();
|
||||
return IsHelper(n => ancestors.FirstOrDefault(ancestor => ancestor.BaseElement == other.BaseElement) != null, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsDescendant(DynamicXml other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
var ancestors = this.Ancestors();
|
||||
return IsHelper(n => ancestors.FirstOrDefault(ancestor => ancestor.BaseElement == other.BaseElement) != null, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsDescendantOrSelf(DynamicXml other)
|
||||
{
|
||||
var ancestors = this.AncestorsOrSelf();
|
||||
return IsHelper(n => ancestors.FirstOrDefault(ancestor => ancestor.BaseElement == other.BaseElement) != null);
|
||||
}
|
||||
public HtmlString IsDescendantOrSelf(DynamicXml other, string valueIfTrue)
|
||||
{
|
||||
var ancestors = this.AncestorsOrSelf();
|
||||
return IsHelper(n => ancestors.FirstOrDefault(ancestor => ancestor.BaseElement == other.BaseElement) != null, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsDescendantOrSelf(DynamicXml other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
var ancestors = this.AncestorsOrSelf();
|
||||
return IsHelper(n => ancestors.FirstOrDefault(ancestor => ancestor.BaseElement == other.BaseElement) != null, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsAncestor(DynamicXml other)
|
||||
{
|
||||
var descendants = this.Descendants();
|
||||
return IsHelper(n => descendants.FirstOrDefault(descendant => descendant.BaseElement == other.BaseElement) != null);
|
||||
}
|
||||
public HtmlString IsAncestor(DynamicXml other, string valueIfTrue)
|
||||
{
|
||||
var descendants = this.Descendants();
|
||||
return IsHelper(n => descendants.FirstOrDefault(descendant => descendant.BaseElement == other.BaseElement) != null, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsAncestor(DynamicXml other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
var descendants = this.Descendants();
|
||||
return IsHelper(n => descendants.FirstOrDefault(descendant => descendant.BaseElement == other.BaseElement) != null, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public bool IsAncestorOrSelf(DynamicXml other)
|
||||
{
|
||||
var descendants = this.DescendantsOrSelf();
|
||||
return IsHelper(n => descendants.FirstOrDefault(descendant => descendant.BaseElement == other.BaseElement) != null);
|
||||
}
|
||||
public HtmlString IsAncestorOrSelf(DynamicXml other, string valueIfTrue)
|
||||
{
|
||||
var descendants = this.DescendantsOrSelf();
|
||||
return IsHelper(n => descendants.FirstOrDefault(descendant => descendant.BaseElement == other.BaseElement) != null, valueIfTrue);
|
||||
}
|
||||
public HtmlString IsAncestorOrSelf(DynamicXml other, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
var descendants = this.DescendantsOrSelf();
|
||||
return IsHelper(n => descendants.FirstOrDefault(descendant => descendant.BaseElement == other.BaseElement) != null, valueIfTrue, valueIfFalse);
|
||||
}
|
||||
public IEnumerable<DynamicXml> Descendants()
|
||||
{
|
||||
return Descendants(n => true);
|
||||
}
|
||||
public IEnumerable<DynamicXml> Descendants(Func<XElement, bool> func)
|
||||
{
|
||||
var flattenedNodes = this.BaseElement.Elements().Map(func, (XElement n) => { return n.Elements(); });
|
||||
return flattenedNodes.ToList().ConvertAll(n => new DynamicXml(n));
|
||||
}
|
||||
public IEnumerable<DynamicXml> DescendantsOrSelf()
|
||||
{
|
||||
return DescendantsOrSelf(n => true);
|
||||
}
|
||||
public IEnumerable<DynamicXml> DescendantsOrSelf(Func<XElement, bool> func)
|
||||
{
|
||||
var flattenedNodes = this.BaseElement.Elements().Map(func, (XElement n) => { return n.Elements(); });
|
||||
var list = new List<DynamicXml>();
|
||||
list.Add(this);
|
||||
list.AddRange(flattenedNodes.ToList().ConvertAll(n => new DynamicXml(n)));
|
||||
return list;
|
||||
}
|
||||
public IEnumerable<DynamicXml> Ancestors()
|
||||
{
|
||||
return Ancestors(item => true);
|
||||
}
|
||||
public IEnumerable<DynamicXml> Ancestors(Func<XElement, bool> func)
|
||||
{
|
||||
var ancestorList = new List<XElement>();
|
||||
var node = this.BaseElement;
|
||||
while (node != null)
|
||||
{
|
||||
if (node.Parent == null) break;
|
||||
XElement parent = node.Parent;
|
||||
if (parent != null)
|
||||
{
|
||||
if (this.BaseElement != parent)
|
||||
{
|
||||
node = parent;
|
||||
if (func(node))
|
||||
{
|
||||
ancestorList.Add(node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
ancestorList.Reverse();
|
||||
return ancestorList.ConvertAll(item => new DynamicXml(item));
|
||||
}
|
||||
public IEnumerable<DynamicXml> AncestorsOrSelf()
|
||||
{
|
||||
return AncestorsOrSelf(item => true);
|
||||
}
|
||||
public IEnumerable<DynamicXml> AncestorsOrSelf(Func<XElement, bool> func)
|
||||
{
|
||||
List<XElement> ancestorList = new List<XElement>();
|
||||
var node = this.BaseElement;
|
||||
ancestorList.Add(node);
|
||||
while (node != null)
|
||||
{
|
||||
if (node.Parent == null) break;
|
||||
XElement parent = node.Parent;
|
||||
if (parent != null)
|
||||
{
|
||||
if (this.BaseElement != parent)
|
||||
{
|
||||
node = parent;
|
||||
if (func(node))
|
||||
{
|
||||
ancestorList.Add(node);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
ancestorList.Reverse();
|
||||
return ancestorList.ConvertAll(item => new DynamicXml(item));
|
||||
}
|
||||
|
||||
public int Index()
|
||||
{
|
||||
if (this.BaseElement != null && this.BaseElement.Parent != null)
|
||||
{
|
||||
var elements = this.BaseElement.Parent.Elements();
|
||||
int index = 0;
|
||||
foreach (var element in elements)
|
||||
{
|
||||
if (element == this.BaseElement) break;
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool IsHelper(Func<DynamicXml, bool> test)
|
||||
{
|
||||
return test(this);
|
||||
}
|
||||
public HtmlString IsHelper(Func<DynamicXml, bool> test, string valueIfTrue)
|
||||
{
|
||||
return IsHelper(test, valueIfTrue, string.Empty);
|
||||
}
|
||||
public HtmlString IsHelper(Func<DynamicXml, bool> test, string valueIfTrue, string valueIfFalse)
|
||||
{
|
||||
return test(this) ? new HtmlString(valueIfTrue) : new HtmlString(valueIfFalse);
|
||||
}
|
||||
|
||||
public static string StripDashesInElementOrAttributeNames(string xml)
|
||||
{
|
||||
using (MemoryStream outputms = new MemoryStream())
|
||||
{
|
||||
using (TextWriter outputtw = new StreamWriter(outputms))
|
||||
{
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
using (TextWriter tw = new StreamWriter(ms))
|
||||
{
|
||||
tw.Write(xml);
|
||||
tw.Flush();
|
||||
ms.Position = 0;
|
||||
using (TextReader tr = new StreamReader(ms))
|
||||
{
|
||||
bool IsInsideElement = false, IsInsideQuotes = false;
|
||||
int ic = 0;
|
||||
while ((ic = tr.Read()) != -1)
|
||||
{
|
||||
if (ic == (int)'<' && !IsInsideQuotes)
|
||||
{
|
||||
if (tr.Peek() != (int)'!')
|
||||
{
|
||||
IsInsideElement = true;
|
||||
}
|
||||
}
|
||||
if (ic == (int)'>' && !IsInsideQuotes)
|
||||
{
|
||||
IsInsideElement = false;
|
||||
}
|
||||
if (ic == (int)'"')
|
||||
{
|
||||
IsInsideQuotes = !IsInsideQuotes;
|
||||
}
|
||||
if (!IsInsideElement || ic != (int)'-' || IsInsideQuotes)
|
||||
{
|
||||
outputtw.Write((char)ic);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
outputtw.Flush();
|
||||
outputms.Position = 0;
|
||||
using (TextReader outputtr = new StreamReader(outputms))
|
||||
{
|
||||
return outputtr.ReadToEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web.Compilation;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Collections;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class for finding extension methods on a type to execute
|
||||
/// </summary>
|
||||
internal static class ExtensionMethodFinder
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns all extension methods found matching the definition
|
||||
/// </summary>
|
||||
/// <param name="thisType"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="argumentCount"></param>
|
||||
/// <param name="argsContainsThis"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// TODO: NOTE: This will be an intensive method to call!! Results should be cached!
|
||||
/// </remarks>
|
||||
private static IEnumerable<MethodInfo> GetAllExtensionMethods(Type thisType, string name, int argumentCount, bool argsContainsThis)
|
||||
{
|
||||
//only scan assemblies we know to contain extension methods (user assemblies)
|
||||
var assembliesToScan = TypeFinder.GetAssembliesWithKnownExclusions();
|
||||
|
||||
//get extension methods from runtime
|
||||
var candidates = (
|
||||
from assembly in assembliesToScan
|
||||
where assembly.IsDefined(typeof(ExtensionAttribute), false)
|
||||
from type in assembly.GetTypes()
|
||||
where (type.IsDefined(typeof(ExtensionAttribute), false)
|
||||
&& type.IsSealed && !type.IsGenericType && !type.IsNested)
|
||||
from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public)
|
||||
// this filters extension methods
|
||||
where method.IsDefined(typeof(ExtensionAttribute), false)
|
||||
select method
|
||||
);
|
||||
|
||||
//add the extension methods defined in IEnumerable
|
||||
candidates = candidates.Concat(typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public));
|
||||
|
||||
//filter by name
|
||||
var methodsByName = candidates.Where(m => m.Name == name);
|
||||
|
||||
var isGenericAndRightParamCount = methodsByName.Where(m => m.GetParameters().Length == argumentCount + (argsContainsThis ? 0 : 1));
|
||||
|
||||
//find the right overload that can take genericParameterType
|
||||
//which will be either DynamicNodeList or List<DynamicNode> which is IEnumerable`
|
||||
|
||||
var withGenericParameterType = isGenericAndRightParamCount.Select(m => new { m, t = FirstParameterType(m) });
|
||||
|
||||
var methodsWhereArgZeroIsTargetType = (from method in withGenericParameterType
|
||||
where
|
||||
method.t != null && MethodArgZeroHasCorrectTargetType(method.m, method.t, thisType)
|
||||
select method);
|
||||
|
||||
return methodsWhereArgZeroIsTargetType.Select(mt => mt.m);
|
||||
}
|
||||
|
||||
private static bool MethodArgZeroHasCorrectTargetType(MethodInfo method, Type firstArgumentType, Type thisType)
|
||||
{
|
||||
//This is done with seperate method calls because you can't debug/watch lamdas - if you're trying to figure
|
||||
//out why the wrong method is returned, it helps to be able to see each boolean result
|
||||
|
||||
return
|
||||
|
||||
// is it defined on me?
|
||||
MethodArgZeroHasCorrectTargetTypeTypeMatchesExactly(method, firstArgumentType, thisType) ||
|
||||
|
||||
// or on any of my interfaces?
|
||||
MethodArgZeroHasCorrectTargetTypeAnInterfaceMatches(method, firstArgumentType, thisType) ||
|
||||
|
||||
// or on any of my base types?
|
||||
MethodArgZeroHasCorrectTargetTypeIsASubclassOf(method, firstArgumentType, thisType) ||
|
||||
|
||||
//share a common interface (e.g. IEnumerable)
|
||||
MethodArgZeroHasCorrectTargetTypeShareACommonInterface(method, firstArgumentType, thisType);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static bool MethodArgZeroHasCorrectTargetTypeShareACommonInterface(MethodInfo method, Type firstArgumentType, Type thisType)
|
||||
{
|
||||
Type[] interfaces = firstArgumentType.GetInterfaces();
|
||||
if (interfaces.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
bool result = interfaces.All(i => thisType.GetInterfaces().Contains(i));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool MethodArgZeroHasCorrectTargetTypeIsASubclassOf(MethodInfo method, Type firstArgumentType, Type thisType)
|
||||
{
|
||||
bool result = thisType.IsSubclassOf(firstArgumentType);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool MethodArgZeroHasCorrectTargetTypeAnInterfaceMatches(MethodInfo method, Type firstArgumentType, Type thisType)
|
||||
{
|
||||
bool result = thisType.GetInterfaces().Contains(firstArgumentType);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool MethodArgZeroHasCorrectTargetTypeTypeMatchesExactly(MethodInfo method, Type firstArgumentType, Type thisType)
|
||||
{
|
||||
bool result = (thisType == firstArgumentType);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Type FirstParameterType(MethodInfo m)
|
||||
{
|
||||
ParameterInfo[] p = m.GetParameters();
|
||||
if (p.Any())
|
||||
{
|
||||
return p.First().ParameterType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MethodInfo DetermineMethodFromParams(IEnumerable<MethodInfo> methods, Type genericType, IEnumerable<object> args)
|
||||
{
|
||||
if (!methods.Any())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
MethodInfo methodToExecute = null;
|
||||
if (methods.Count() > 1)
|
||||
{
|
||||
//Given the args, lets get the types and compare the type sequence to try and find the correct overload
|
||||
var argTypes = args.ToList().ConvertAll(o =>
|
||||
{
|
||||
var oe = (o as Expression);
|
||||
if (oe != null)
|
||||
{
|
||||
return oe.Type.FullName;
|
||||
}
|
||||
return o.GetType().FullName;
|
||||
});
|
||||
var methodsWithArgTypes = methods.Select(method => new { method, types = method.GetParameters().Select(pi => pi.ParameterType.FullName) });
|
||||
var firstMatchingOverload = methodsWithArgTypes.FirstOrDefault(m => m.types.SequenceEqual(argTypes));
|
||||
if (firstMatchingOverload != null)
|
||||
{
|
||||
methodToExecute = firstMatchingOverload.method;
|
||||
}
|
||||
}
|
||||
|
||||
if (methodToExecute == null)
|
||||
{
|
||||
var firstMethod = methods.FirstOrDefault();
|
||||
// NH: this is to ensure that it's always the correct one being chosen when using the LINQ extension methods
|
||||
if (methods.Count() > 1)
|
||||
{
|
||||
var firstGenericMethod = methods.FirstOrDefault(x => x.IsGenericMethodDefinition);
|
||||
if (firstGenericMethod != null)
|
||||
{
|
||||
firstMethod = firstGenericMethod;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMethod != null)
|
||||
{
|
||||
if (firstMethod.IsGenericMethodDefinition)
|
||||
{
|
||||
if (genericType != null)
|
||||
{
|
||||
methodToExecute = firstMethod.MakeGenericMethod(genericType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
methodToExecute = firstMethod;
|
||||
}
|
||||
}
|
||||
}
|
||||
return methodToExecute;
|
||||
}
|
||||
|
||||
public static MethodInfo FindExtensionMethod(Type thisType, object[] args, string name, bool argsContainsThis)
|
||||
{
|
||||
Type genericType = null;
|
||||
if (thisType.IsGenericType)
|
||||
{
|
||||
genericType = thisType.GetGenericArguments()[0];
|
||||
}
|
||||
|
||||
var methods = GetAllExtensionMethods(thisType, name, args.Length, argsContainsThis).ToArray();
|
||||
return DetermineMethodFromParams(methods, genericType, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal static class ExtensionMethods
|
||||
{
|
||||
public static IEnumerable<TSource> Map<TSource>(
|
||||
this IEnumerable<TSource> source,
|
||||
Func<TSource, bool> selectorFunction,
|
||||
Func<TSource, IEnumerable<TSource>> getChildrenFunction)
|
||||
{
|
||||
if (!source.Any())
|
||||
{
|
||||
return source;
|
||||
}
|
||||
// Add what we have to the stack
|
||||
var flattenedList = source.Where(selectorFunction);
|
||||
// Go through the input enumerable looking for children,
|
||||
// and add those if we have them
|
||||
foreach (TSource element in source)
|
||||
{
|
||||
var secondInner = getChildrenFunction(element);
|
||||
if (secondInner.Any())
|
||||
{
|
||||
secondInner = secondInner.Map(selectorFunction, getChildrenFunction);
|
||||
}
|
||||
flattenedList = flattenedList.Concat(secondInner);
|
||||
}
|
||||
return flattenedList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static bool ContainsAny(this string haystack, IEnumerable<string> needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
if (!string.IsNullOrEmpty(haystack) || needles.Any())
|
||||
{
|
||||
return needles.Any(haystack.Contains);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool ContainsAny(this string haystack, params string[] needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
if (!string.IsNullOrEmpty(haystack) || needles.Length > 0)
|
||||
{
|
||||
return needles.Any(haystack.Contains);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool ContainsAny(this string haystack, StringComparison comparison, IEnumerable<string> needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
if (!string.IsNullOrEmpty(haystack) || needles.Any())
|
||||
{
|
||||
return needles.Any(value => haystack.IndexOf(value, comparison) >= 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool ContainsAny(this string haystack, StringComparison comparison, params string[] needles)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
if (!string.IsNullOrEmpty(haystack) || needles.Length > 0)
|
||||
{
|
||||
return needles.Any(value => haystack.IndexOf(value, comparison) >= 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static bool ContainsInsensitive(this string haystack, string needle)
|
||||
{
|
||||
if (haystack == null) throw new ArgumentNullException("haystack");
|
||||
return haystack.IndexOf(needle, StringComparison.CurrentCultureIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
public static bool HasValue(this string s)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(s);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal sealed class ParseException : Exception
|
||||
{
|
||||
readonly int _position;
|
||||
|
||||
public ParseException(string message, int position)
|
||||
: base(message)
|
||||
{
|
||||
this._position = position;
|
||||
}
|
||||
|
||||
public int Position
|
||||
{
|
||||
get { return _position; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(Res.ParseExceptionFormat, Message, _position);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using umbraco.interfaces;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal class PropertyResult : IPublishedContentProperty, IHtmlString
|
||||
{
|
||||
internal PropertyResult(IPublishedContentProperty source, PropertyResultType type)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException("source");
|
||||
|
||||
Alias = source.Alias;
|
||||
Value = source.Value;
|
||||
Version = source.Version;
|
||||
PropertyType = type;
|
||||
}
|
||||
internal PropertyResult(string alias, object value, Guid version, PropertyResultType type)
|
||||
{
|
||||
if (alias == null) throw new ArgumentNullException("alias");
|
||||
if (value == null) throw new ArgumentNullException("value");
|
||||
|
||||
Alias = alias;
|
||||
Value = value;
|
||||
Version = version;
|
||||
PropertyType = type;
|
||||
}
|
||||
|
||||
internal PropertyResultType PropertyType { get; private set; }
|
||||
|
||||
public string Alias { get; private set; }
|
||||
|
||||
public object Value { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value as a string output, this is used in the final rendering process of a property
|
||||
/// </summary>
|
||||
internal string ValueAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
return Value == null ? "" : Convert.ToString(Value);
|
||||
}
|
||||
}
|
||||
|
||||
public Guid Version { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The Id of the document for which this property belongs to
|
||||
/// </summary>
|
||||
public int DocumentId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The alias of the document type alias for which this property belongs to
|
||||
/// </summary>
|
||||
public string DocumentTypeAlias { get; set; }
|
||||
|
||||
public string ToHtmlString()
|
||||
{
|
||||
return ValueAsString;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
/// <summary>
|
||||
/// Currently just used for informational purposes as to where a PropertyResult object was created from.
|
||||
/// </summary>
|
||||
internal enum PropertyResultType
|
||||
{
|
||||
/// <summary>
|
||||
/// The property resolved was a normal document property
|
||||
/// </summary>
|
||||
UserProperty,
|
||||
|
||||
/// <summary>
|
||||
/// The property resolved was a property defined as a member on the document object (IPublishedContent) itself
|
||||
/// </summary>
|
||||
ReflectedProperty,
|
||||
|
||||
/// <summary>
|
||||
/// The property was created manually for a custom purpose
|
||||
/// </summary>
|
||||
CustomProperty
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal static class Res
|
||||
{
|
||||
public const string DuplicateIdentifier = "The identifier '{0}' was defined more than once";
|
||||
public const string ExpressionTypeMismatch = "Expression of type '{0}' expected";
|
||||
public const string ExpressionExpected = "Expression expected";
|
||||
public const string InvalidCharacterLiteral = "Character literal must contain exactly one character";
|
||||
public const string InvalidIntegerLiteral = "Invalid integer literal '{0}'";
|
||||
public const string InvalidRealLiteral = "Invalid real literal '{0}'";
|
||||
public const string UnknownIdentifier = "Unknown identifier '{0}'";
|
||||
public const string NoItInScope = "No 'it' is in scope";
|
||||
public const string IifRequiresThreeArgs = "The 'iif' function requires three arguments";
|
||||
public const string FirstExprMustBeBool = "The first expression must be of type 'Boolean'";
|
||||
public const string BothTypesConvertToOther = "Both of the types '{0}' and '{1}' convert to the other";
|
||||
public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other";
|
||||
public const string MissingAsClause = "Expression is missing an 'as' clause";
|
||||
public const string ArgsIncompatibleWithLambda = "Argument list incompatible with lambda expression";
|
||||
public const string TypeHasNoNullableForm = "Type '{0}' has no nullable form";
|
||||
public const string NoMatchingConstructor = "No matching constructor in type '{0}'";
|
||||
public const string AmbiguousConstructorInvocation = "Ambiguous invocation of '{0}' constructor";
|
||||
public const string CannotConvertValue = "A value of type '{0}' cannot be converted to type '{1}'";
|
||||
public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'";
|
||||
public const string MethodsAreInaccessible = "Methods on type '{0}' are not accessible";
|
||||
public const string MethodIsVoid = "Method '{0}' in type '{1}' does not return a value";
|
||||
public const string AmbiguousMethodInvocation = "Ambiguous invocation of method '{0}' in type '{1}'";
|
||||
public const string UnknownPropertyOrField = "No property or field '{0}' exists in type '{1}'";
|
||||
public const string NoApplicableAggregate = "No applicable aggregate method '{0}' exists";
|
||||
public const string CannotIndexMultiDimArray = "Indexing of multi-dimensional arrays is not supported";
|
||||
public const string InvalidIndex = "Array index must be an integer expression";
|
||||
public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'";
|
||||
public const string AmbiguousIndexerInvocation = "Ambiguous invocation of indexer in type '{0}'";
|
||||
public const string IncompatibleOperand = "Operator '{0}' incompatible with operand type '{1}'";
|
||||
public const string IncompatibleOperands = "Operator '{0}' incompatible with operand types '{1}' and '{2}'";
|
||||
public const string UnterminatedStringLiteral = "Unterminated string literal";
|
||||
public const string InvalidCharacter = "Syntax error '{0}'";
|
||||
public const string DigitExpected = "Digit expected";
|
||||
public const string SyntaxError = "Syntax error";
|
||||
public const string TokenExpected = "{0} expected";
|
||||
public const string ParseExceptionFormat = "{0} (at index {1})";
|
||||
public const string ColonExpected = "':' expected";
|
||||
public const string OpenParenExpected = "'(' expected";
|
||||
public const string CloseParenOrOperatorExpected = "')' or operator expected";
|
||||
public const string CloseParenOrCommaExpected = "')' or ',' expected";
|
||||
public const string DotOrOpenParenExpected = "'.' or '(' expected";
|
||||
public const string OpenBracketExpected = "'[' expected";
|
||||
public const string CloseBracketOrCommaExpected = "']' or ',' expected";
|
||||
public const string IdentifierExpected = "Identifier expected";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
internal class Signature : IEquatable<Signature>
|
||||
{
|
||||
public DynamicProperty[] Properties { get; set; }
|
||||
public int HashCode { get; set; }
|
||||
|
||||
public Signature(IEnumerable<DynamicProperty> properties)
|
||||
{
|
||||
this.Properties = properties.ToArray();
|
||||
HashCode = 0;
|
||||
foreach (DynamicProperty p in this.Properties)
|
||||
{
|
||||
HashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Signature && Equals((Signature)obj);
|
||||
}
|
||||
|
||||
public bool Equals(Signature other)
|
||||
{
|
||||
if (Properties.Length != other.Properties.Length) return false;
|
||||
for (int i = 0; i < Properties.Length; i++)
|
||||
{
|
||||
if (Properties[i].Name != other.Properties[i].Name ||
|
||||
Properties[i].Type != other.Properties[i].Type) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A very useful class for parsing, enumerating and querying Enum objects
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <remarks>
|
||||
/// Taken from http://damieng.com/blog/2010/10/17/enums-better-syntax-improved-performance-and-tryparse-in-net-3-5
|
||||
/// </remarks>
|
||||
internal static class Enum<T> where T : struct
|
||||
{
|
||||
private static readonly IEnumerable<T> All = Enum.GetValues(typeof(T)).Cast<T>();
|
||||
private static readonly Dictionary<string, T> InsensitiveNames = All.ToDictionary(k => Enum.GetName(typeof(T), k).ToLowerInvariant());
|
||||
private static readonly Dictionary<string, T> SensitiveNames = All.ToDictionary(k => Enum.GetName(typeof(T), k));
|
||||
private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k));
|
||||
private static readonly Dictionary<T, string> Names = All.ToDictionary(k => k, v => v.ToString());
|
||||
|
||||
public static bool IsDefined(T value)
|
||||
{
|
||||
return Names.Keys.Contains(value);
|
||||
}
|
||||
|
||||
public static bool IsDefined(string value)
|
||||
{
|
||||
return SensitiveNames.Keys.Contains(value);
|
||||
}
|
||||
|
||||
public static bool IsDefined(int value)
|
||||
{
|
||||
return Values.Keys.Contains(value);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> GetValues()
|
||||
{
|
||||
return All;
|
||||
}
|
||||
|
||||
public static string[] GetNames()
|
||||
{
|
||||
return Names.Values.ToArray();
|
||||
}
|
||||
|
||||
public static string GetName(T value)
|
||||
{
|
||||
string name;
|
||||
Names.TryGetValue(value, out name);
|
||||
return name;
|
||||
}
|
||||
|
||||
public static T Parse(string value)
|
||||
{
|
||||
T parsed = default(T);
|
||||
if (!SensitiveNames.TryGetValue(value, out parsed))
|
||||
throw new ArgumentException("Value is not one of the named constants defined for the enumeration", "value");
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public static T Parse(string value, bool ignoreCase)
|
||||
{
|
||||
if (!ignoreCase)
|
||||
return Parse(value);
|
||||
|
||||
T parsed = default(T);
|
||||
if (!InsensitiveNames.TryGetValue(value.ToLowerInvariant(), out parsed))
|
||||
throw new ArgumentException("Value is not one of the named constants defined for the enumeration", "value");
|
||||
return parsed;
|
||||
}
|
||||
|
||||
public static bool TryParse(string value, out T returnValue)
|
||||
{
|
||||
return SensitiveNames.TryGetValue(value, out returnValue);
|
||||
}
|
||||
|
||||
public static bool TryParse(string value, bool ignoreCase, out T returnValue)
|
||||
{
|
||||
if (!ignoreCase)
|
||||
return TryParse(value, out returnValue);
|
||||
|
||||
return InsensitiveNames.TryGetValue(value.ToLowerInvariant(), out returnValue);
|
||||
}
|
||||
|
||||
public static T? ParseOrNull(string value)
|
||||
{
|
||||
if (String.IsNullOrEmpty(value))
|
||||
return null;
|
||||
|
||||
T foundValue;
|
||||
if (InsensitiveNames.TryGetValue(value.ToLowerInvariant(), out foundValue))
|
||||
return foundValue;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static T? CastOrNull(int value)
|
||||
{
|
||||
T foundValue;
|
||||
if (Values.TryGetValue(value, out foundValue))
|
||||
return foundValue;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal static class ExpressionExtensions
|
||||
{
|
||||
public static Expression<Func<T, bool>> True<T>() { return f => true; }
|
||||
public static Expression<Func<T, bool>> False<T>() { return f => false; }
|
||||
|
||||
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left,
|
||||
Expression<Func<T, bool>> right)
|
||||
{
|
||||
var invokedExpr = Expression.Invoke(right, left.Parameters.Cast<Expression>());
|
||||
return Expression.Lambda<Func<T, bool>>
|
||||
(Expression.OrElse(left.Body, invokedExpr), left.Parameters);
|
||||
}
|
||||
|
||||
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left,
|
||||
Expression<Func<T, bool>> right)
|
||||
{
|
||||
var invokedExpr = Expression.Invoke(right, left.Parameters.Cast<Expression>());
|
||||
return Expression.Lambda<Func<T, bool>>
|
||||
(Expression.AndAlso(left.Body, invokedExpr), left.Parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A set of helper methods for dealing with expressions
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
internal static class ExpressionHelper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<LambdaExpressionCacheKey, PropertyInfo> PropertyInfoCache = new ConcurrentDictionary<LambdaExpressionCacheKey, PropertyInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="PropertyInfo"/> object from an expression.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The type of the source.</typeparam>
|
||||
/// <typeparam name="TProperty">The type of the property.</typeparam>
|
||||
/// <param name="source">The source.</param>
|
||||
/// <param name="propertyLambda">The property lambda.</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public static PropertyInfo GetPropertyInfo<TSource, TProperty>(this TSource source, Expression<Func<TSource, TProperty>> propertyLambda)
|
||||
{
|
||||
return GetPropertyInfo(propertyLambda);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="PropertyInfo"/> object from an expression.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The type of the source.</typeparam>
|
||||
/// <typeparam name="TProperty">The type of the property.</typeparam>
|
||||
/// <param name="propertyLambda">The property lambda.</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public static PropertyInfo GetPropertyInfo<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertyLambda)
|
||||
{
|
||||
return PropertyInfoCache.GetOrAdd(
|
||||
new LambdaExpressionCacheKey(propertyLambda),
|
||||
x =>
|
||||
{
|
||||
var type = typeof(TSource);
|
||||
|
||||
var member = propertyLambda.Body as MemberExpression;
|
||||
if (member == null)
|
||||
{
|
||||
if (propertyLambda.Body.GetType().Name == "UnaryExpression")
|
||||
{
|
||||
// The expression might be for some boxing, e.g. representing a value type like HiveId as an object
|
||||
// in which case the expression will be Convert(x.MyProperty)
|
||||
var unary = propertyLambda.Body as UnaryExpression;
|
||||
if (unary != null)
|
||||
{
|
||||
var boxedMember = unary.Operand as MemberExpression;
|
||||
if (boxedMember == null)
|
||||
throw new ArgumentException("The type of property could not be infered, try specifying the type parameters explicitly. This can happen if you have tried to access PropertyInfo where the property's return type is a value type, but the expression is trying to convert it to an object");
|
||||
else member = boxedMember;
|
||||
}
|
||||
}
|
||||
else throw new ArgumentException(string.Format("Expression '{0}' refers to a method, not a property.", propertyLambda));
|
||||
}
|
||||
|
||||
|
||||
var propInfo = member.Member as PropertyInfo;
|
||||
if (propInfo == null)
|
||||
throw new ArgumentException(string.Format(
|
||||
"Expression '{0}' refers to a field, not a property.",
|
||||
propertyLambda));
|
||||
|
||||
if (type != propInfo.ReflectedType &&
|
||||
!type.IsSubclassOf(propInfo.ReflectedType))
|
||||
throw new ArgumentException(string.Format(
|
||||
"Expresion '{0}' refers to a property that is not from type {1}.",
|
||||
propertyLambda,
|
||||
type));
|
||||
|
||||
return propInfo;
|
||||
});
|
||||
}
|
||||
|
||||
public static IDictionary<string, object> GetMethodParams<T1, T2>(Expression<Func<T1, T2>> fromExpression)
|
||||
{
|
||||
if (fromExpression == null) return null;
|
||||
var body = fromExpression.Body as MethodCallExpression;
|
||||
if (body == null)
|
||||
return new Dictionary<string, object>();
|
||||
|
||||
var rVal = new Dictionary<string, object>();
|
||||
var parameters = body.Method.GetParameters().Select(x => x.Name).ToArray();
|
||||
var i = 0;
|
||||
foreach (var argument in body.Arguments)
|
||||
{
|
||||
var lambda = Expression.Lambda(argument, fromExpression.Parameters);
|
||||
var d = lambda.Compile();
|
||||
var value = d.DynamicInvoke(new object[1]);
|
||||
rVal.Add(parameters[i], value);
|
||||
i++;
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="MethodInfo"/> from an <see cref="Expression{Action{T}}"/> provided it refers to a method call.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="fromExpression">From expression.</param>
|
||||
/// <returns>The <see cref="MethodInfo"/> or null if <paramref name="fromExpression"/> is null or cannot be converted to <see cref="MethodCallExpression"/>.</returns>
|
||||
/// <remarks></remarks>
|
||||
public static MethodInfo GetMethodInfo<T>(Expression<Action<T>> fromExpression)
|
||||
{
|
||||
if (fromExpression == null) return null;
|
||||
var body = fromExpression.Body as MethodCallExpression;
|
||||
return body != null ? body.Method : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the method info.
|
||||
/// </summary>
|
||||
/// <typeparam name="TReturn">The return type of the method.</typeparam>
|
||||
/// <param name="fromExpression">From expression.</param>
|
||||
/// <returns></returns>
|
||||
public static MethodInfo GetMethodInfo<TReturn>(Expression<Func<TReturn>> fromExpression)
|
||||
{
|
||||
if (fromExpression == null) return null;
|
||||
var body = fromExpression.Body as MethodCallExpression;
|
||||
return body != null ? body.Method : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the method info.
|
||||
/// </summary>
|
||||
/// <typeparam name="T1">The type of the 1.</typeparam>
|
||||
/// <typeparam name="T2">The type of the 2.</typeparam>
|
||||
/// <param name="fromExpression">From expression.</param>
|
||||
/// <returns></returns>
|
||||
public static MethodInfo GetMethodInfo<T1, T2>(Expression<Func<T1, T2>> fromExpression)
|
||||
{
|
||||
if (fromExpression == null) return null;
|
||||
var body = fromExpression.Body as MethodCallExpression;
|
||||
return body != null ? body.Method : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="MethodInfo"/> from an <see cref="Expression"/> provided it refers to a method call.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression.</param>
|
||||
/// <returns>The <see cref="MethodInfo"/> or null if <paramref name="expression"/> cannot be converted to <see cref="MethodCallExpression"/>.</returns>
|
||||
/// <remarks></remarks>
|
||||
public static MethodInfo GetMethod(Expression expression)
|
||||
{
|
||||
if (expression == null) return null;
|
||||
return IsMethod(expression) ? (((MethodCallExpression)expression).Method) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="MemberInfo"/> from an <see cref="Expression{Func{T, TReturn}}"/> provided it refers to member access.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TReturn">The type of the return.</typeparam>
|
||||
/// <param name="fromExpression">From expression.</param>
|
||||
/// <returns>The <see cref="MemberInfo"/> or null if <paramref name="fromExpression"/> cannot be converted to <see cref="MemberExpression"/>.</returns>
|
||||
/// <remarks></remarks>
|
||||
public static MemberInfo GetMemberInfo<T, TReturn>(Expression<Func<T, TReturn>> fromExpression)
|
||||
{
|
||||
if (fromExpression == null) return null;
|
||||
var body = fromExpression.Body as MemberExpression;
|
||||
return body != null ? body.Member : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the MethodInfo is the same based on signature, not based on the equality operator or HashCode.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is method signature equal to] [the specified left]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// This is useful for comparing Expression methods that may contain different generic types
|
||||
/// </remarks>
|
||||
public static bool IsMethodSignatureEqualTo(this MethodInfo left, MethodInfo right)
|
||||
{
|
||||
if (left.Equals(right))
|
||||
return true;
|
||||
if (left.DeclaringType != right.DeclaringType)
|
||||
return false;
|
||||
if (left.Name != right.Name)
|
||||
return false;
|
||||
var leftParams = left.GetParameters();
|
||||
var rightParams = right.GetParameters();
|
||||
if (leftParams.Length != rightParams.Length)
|
||||
return false;
|
||||
for (int i = 0; i < leftParams.Length; i++)
|
||||
{
|
||||
//if they are delegate parameters, then assume they match as they could be anything
|
||||
if (typeof(Delegate).IsAssignableFrom(leftParams[i].ParameterType) && typeof(Delegate).IsAssignableFrom(rightParams[i].ParameterType))
|
||||
continue;
|
||||
//if they are not delegates, then compare the types
|
||||
if (leftParams[i].ParameterType != rightParams[i].ParameterType)
|
||||
return false;
|
||||
}
|
||||
if (left.ReturnType != right.ReturnType)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="MemberInfo"/> from an <see cref="Expression"/> provided it refers to member access.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression.</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public static MemberInfo GetMember(Expression expression)
|
||||
{
|
||||
if (expression == null) return null;
|
||||
return IsMember(expression) ? (((MemberExpression)expression).Member) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="MethodInfo"/> from a <see cref="Delegate"/>
|
||||
/// </summary>
|
||||
/// <param name="fromMethodGroup">From method group.</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public static MethodInfo GetStaticMethodInfo(Delegate fromMethodGroup)
|
||||
{
|
||||
if (fromMethodGroup == null) throw new ArgumentNullException("fromMethodGroup");
|
||||
|
||||
|
||||
return fromMethodGroup.Method;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Formats an unhandled item for representing the expression as a string.
|
||||
///// </summary>
|
||||
///// <typeparam name="T"></typeparam>
|
||||
///// <param name="unhandledItem">The unhandled item.</param>
|
||||
///// <returns></returns>
|
||||
///// <remarks></remarks>
|
||||
//public static string FormatUnhandledItem<T>(T unhandledItem) where T : class
|
||||
//{
|
||||
// if (unhandledItem == null) throw new ArgumentNullException("unhandledItem");
|
||||
|
||||
|
||||
// var itemAsExpression = unhandledItem as Expression;
|
||||
// return itemAsExpression != null
|
||||
// ? FormattingExpressionTreeVisitor.Format(itemAsExpression)
|
||||
// : unhandledItem.ToString();
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified expression is a method.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression.</param>
|
||||
/// <returns><c>true</c> if the specified expression is method; otherwise, <c>false</c>.</returns>
|
||||
/// <remarks></remarks>
|
||||
public static bool IsMethod(Expression expression)
|
||||
{
|
||||
return expression != null && typeof(MethodCallExpression).IsAssignableFrom(expression.GetType());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified expression is a member.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression.</param>
|
||||
/// <returns><c>true</c> if the specified expression is member; otherwise, <c>false</c>.</returns>
|
||||
/// <remarks></remarks>
|
||||
public static bool IsMember(Expression expression)
|
||||
{
|
||||
return expression != null && typeof(MemberExpression).IsAssignableFrom(expression.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified expression is a constant.
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression.</param>
|
||||
/// <returns><c>true</c> if the specified expression is constant; otherwise, <c>false</c>.</returns>
|
||||
/// <remarks></remarks>
|
||||
public static bool IsConstant(Expression expression)
|
||||
{
|
||||
return expression != null && typeof(ConstantExpression).IsAssignableFrom(expression.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the first value from the supplied arguments of an expression, for those arguments that can be cast to <see cref="ConstantExpression"/>.
|
||||
/// </summary>
|
||||
/// <param name="arguments">The arguments.</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
public static object GetFirstValueFromArguments(IEnumerable<Expression> arguments)
|
||||
{
|
||||
if (arguments == null) return false;
|
||||
return
|
||||
arguments.Where(x => typeof(ConstantExpression).IsAssignableFrom(x.GetType())).Cast
|
||||
<ConstantExpression>().Select(x => x.Value).DefaultIfEmpty(null).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to create a hash code from multiple objects.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// .Net has a class the same as this: System.Web.Util.HashCodeCombiner and of course it works for all sorts of things
|
||||
/// which we've not included here as we just need a quick easy class for this in order to create a unique
|
||||
/// hash of directories/files to see if they have changed.
|
||||
/// </remarks>
|
||||
internal class HashCodeCombiner
|
||||
{
|
||||
private long _combinedHash = 5381L;
|
||||
|
||||
internal void AddInt(int i)
|
||||
{
|
||||
_combinedHash = ((_combinedHash << 5) + _combinedHash) ^ i;
|
||||
}
|
||||
|
||||
internal void AddObject(object o)
|
||||
{
|
||||
AddInt(o.GetHashCode());
|
||||
}
|
||||
|
||||
internal void AddDateTime(DateTime d)
|
||||
{
|
||||
AddInt(d.GetHashCode());
|
||||
}
|
||||
|
||||
internal void AddCaseInsensitiveString(string s)
|
||||
{
|
||||
if (s != null)
|
||||
AddInt((StringComparer.InvariantCultureIgnoreCase).GetHashCode(s));
|
||||
}
|
||||
|
||||
internal void AddFileSystemItem(FileSystemInfo f)
|
||||
{
|
||||
//if it doesn't exist, don't proceed.
|
||||
if (!f.Exists)
|
||||
return;
|
||||
|
||||
AddCaseInsensitiveString(f.FullName);
|
||||
AddDateTime(f.CreationTimeUtc);
|
||||
AddDateTime(f.LastWriteTimeUtc);
|
||||
|
||||
//check if it is a file or folder
|
||||
var fileInfo = f as FileInfo;
|
||||
if (fileInfo != null)
|
||||
{
|
||||
AddInt(fileInfo.Length.GetHashCode());
|
||||
}
|
||||
|
||||
var dirInfo = f as DirectoryInfo;
|
||||
if (dirInfo != null)
|
||||
{
|
||||
foreach (var d in dirInfo.GetFiles())
|
||||
{
|
||||
AddFile(d);
|
||||
}
|
||||
foreach (var s in dirInfo.GetDirectories())
|
||||
{
|
||||
AddFolder(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddFile(FileInfo f)
|
||||
{
|
||||
AddFileSystemItem(f);
|
||||
}
|
||||
|
||||
internal void AddFolder(DirectoryInfo d)
|
||||
{
|
||||
AddFileSystemItem(d);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hex code of the combined hash code
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal string GetCombinedHashCode()
|
||||
{
|
||||
return _combinedHash.ToString("x", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A bootstrapper interface for the Umbraco application
|
||||
/// </summary>
|
||||
internal interface IBootManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Fires first in the application startup process before any customizations can occur
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IBootManager Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Fires after initialization and calls the callback to allow for customizations to occur
|
||||
/// </summary>
|
||||
/// <param name="afterStartup"></param>
|
||||
/// <returns></returns>
|
||||
IBootManager Startup(Action<ApplicationContext> afterStartup);
|
||||
|
||||
/// <summary>
|
||||
/// Fires after startup and calls the callback once customizations are locked
|
||||
/// </summary>
|
||||
/// <param name="afterComplete"></param>
|
||||
/// <returns></returns>
|
||||
IBootManager Complete(Action<ApplicationContext> afterComplete);
|
||||
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -2,11 +2,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
public static class IFileSystemExtensions
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
public static class FileSystemExtensions
|
||||
{
|
||||
[UmbracoExperimentalFeature("", "Will be declared public after 4.10")]
|
||||
internal static long GetSize(this IFileSystem fs, string path)
|
||||
{
|
||||
var s = fs.OpenFile(path);
|
||||
@@ -16,6 +19,7 @@ namespace Umbraco.Core.IO
|
||||
return size;
|
||||
}
|
||||
|
||||
[UmbracoExperimentalFeature("", "Will be declared public after 4.10")]
|
||||
internal static void CopyFile(this IFileSystem fs, string path, string newPath)
|
||||
{
|
||||
fs.AddFile(newPath, fs.OpenFile(path));
|
||||
@@ -2,9 +2,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProvider
|
||||
{
|
||||
public const string Media = "media";
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal class FileSystemProviderAttribute : Attribute
|
||||
{
|
||||
public string Alias { get; set; }
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[UmbracoExperimentalFeature("http://issues.umbraco.org/issue/U4-1156", "Will be declared public after 4.10")]
|
||||
internal class FileSystemProviderManager
|
||||
{
|
||||
private readonly FileSystemProvidersSection _config;
|
||||
@@ -31,44 +35,85 @@ namespace Umbraco.Core.IO
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// used to cache the lookup of how to construct this object so we don't have to reflect each time.
|
||||
/// </summary>
|
||||
private class ProviderConstructionInfo
|
||||
{
|
||||
public object[] Parameters { get; set; }
|
||||
public ConstructorInfo Constructor { get; set; }
|
||||
public string ProviderAlias { get; set; }
|
||||
}
|
||||
|
||||
private readonly ConcurrentDictionary<string, ProviderConstructionInfo> _providerLookup = new ConcurrentDictionary<string, ProviderConstructionInfo>();
|
||||
private readonly ConcurrentDictionary<Type, string> _wrappedProviderLookup = new ConcurrentDictionary<Type, string>();
|
||||
|
||||
public IFileSystem GetFileSystemProvider(string alias)
|
||||
{
|
||||
var providerConfig = _config.Providers[alias];
|
||||
if(providerConfig == null)
|
||||
throw new ArgumentException(string.Format("No provider found with the alias '{0}'", alias));
|
||||
//either get the constructor info from cache or create it and add to cache
|
||||
var ctorInfo = _providerLookup.GetOrAdd(alias, s =>
|
||||
{
|
||||
var providerConfig = _config.Providers[s];
|
||||
if (providerConfig == null)
|
||||
throw new ArgumentException(string.Format("No provider found with the alias '{0}'", s));
|
||||
|
||||
var providerType = Type.GetType(providerConfig.Type);
|
||||
if(providerType == null)
|
||||
throw new InvalidOperationException(string.Format("Could not find type '{0}'", providerConfig.Type));
|
||||
var providerType = Type.GetType(providerConfig.Type);
|
||||
if (providerType == null)
|
||||
throw new InvalidOperationException(string.Format("Could not find type '{0}'", providerConfig.Type));
|
||||
|
||||
if (providerType.IsAssignableFrom(typeof(IFileSystem)))
|
||||
throw new InvalidOperationException(string.Format("The type '{0}' does not implement IFileSystem", providerConfig.Type));
|
||||
if (providerType.IsAssignableFrom(typeof (IFileSystem)))
|
||||
throw new InvalidOperationException(string.Format("The type '{0}' does not implement IFileSystem", providerConfig.Type));
|
||||
|
||||
var paramCount = providerConfig.Parameters != null ? providerConfig.Parameters.Count : 0;
|
||||
var constructor = providerType.GetConstructors()
|
||||
.SingleOrDefault(x => x.GetParameters().Count() == paramCount
|
||||
&& x.GetParameters().All(y => providerConfig.Parameters.AllKeys.Contains(y.Name)));
|
||||
if(constructor == null)
|
||||
throw new InvalidOperationException(string.Format("Could not find constructor for type '{0}' which accepts {1} parameters", providerConfig.Type, paramCount));
|
||||
var paramCount = providerConfig.Parameters != null ? providerConfig.Parameters.Count : 0;
|
||||
var constructor = providerType.GetConstructors()
|
||||
.SingleOrDefault(x => x.GetParameters().Count() == paramCount
|
||||
&& x.GetParameters().All(y => providerConfig.Parameters.AllKeys.Contains(y.Name)));
|
||||
if (constructor == null)
|
||||
throw new InvalidOperationException(string.Format("Could not find constructor for type '{0}' which accepts {1} parameters", providerConfig.Type, paramCount));
|
||||
|
||||
var parameters = new object[paramCount];
|
||||
for(var i = 0; i < paramCount; i++)
|
||||
parameters[i] = providerConfig.Parameters[providerConfig.Parameters.AllKeys[i]].Value;
|
||||
var parameters = new object[paramCount];
|
||||
for (var i = 0; i < paramCount; i++)
|
||||
parameters[i] = providerConfig.Parameters[providerConfig.Parameters.AllKeys[i]].Value;
|
||||
|
||||
return (IFileSystem) constructor.Invoke(parameters);
|
||||
//return the new constructor info class to cache so we don't have to do this again.
|
||||
return new ProviderConstructionInfo()
|
||||
{
|
||||
Constructor = constructor,
|
||||
Parameters = parameters,
|
||||
ProviderAlias = s
|
||||
};
|
||||
});
|
||||
|
||||
var fs = (IFileSystem)ctorInfo.Constructor.Invoke(ctorInfo.Parameters);
|
||||
return fs;
|
||||
}
|
||||
|
||||
public TProviderTypeFilter GetFileSystemProvider<TProviderTypeFilter>()
|
||||
where TProviderTypeFilter : class, IFileSystem
|
||||
where TProviderTypeFilter : FileSystemWrapper
|
||||
{
|
||||
var attr =
|
||||
(FileSystemProviderAttribute)typeof(TProviderTypeFilter).GetCustomAttributes(typeof(FileSystemProviderAttribute), false).
|
||||
SingleOrDefault();
|
||||
//get the alias for the type from cache or look it up and add it to the cache, then we don't have to reflect each time
|
||||
var alias = _wrappedProviderLookup.GetOrAdd(typeof (TProviderTypeFilter), fsType =>
|
||||
{
|
||||
//validate the ctor
|
||||
var constructor = fsType.GetConstructors()
|
||||
.SingleOrDefault(x =>
|
||||
x.GetParameters().Count() == 1 && TypeHelper.IsTypeAssignableFrom<IFileSystem>(x.GetParameters().Single().ParameterType));
|
||||
if (constructor == null)
|
||||
throw new InvalidOperationException("The type of " + fsType + " must inherit from FileSystemWrapper and must have a constructor that accepts one parameter of type " + typeof(IFileSystem));
|
||||
|
||||
if (attr == null)
|
||||
throw new InvalidOperationException(string.Format("The provider type filter '{0}' is missing the required FileSystemProviderAttribute", typeof(FileSystemProviderAttribute).FullName));
|
||||
var attr =
|
||||
(FileSystemProviderAttribute)fsType.GetCustomAttributes(typeof(FileSystemProviderAttribute), false).
|
||||
SingleOrDefault();
|
||||
|
||||
return GetFileSystemProvider(attr.Alias).As<TProviderTypeFilter>();
|
||||
if (attr == null)
|
||||
throw new InvalidOperationException(string.Format("The provider type filter '{0}' is missing the required FileSystemProviderAttribute", typeof(FileSystemProviderAttribute).FullName));
|
||||
|
||||
return attr.Alias;
|
||||
});
|
||||
|
||||
var innerFs = GetFileSystemProvider(alias);
|
||||
var outputFs = Activator.CreateInstance(typeof (TProviderTypeFilter), innerFs);
|
||||
return (TProviderTypeFilter)outputFs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// All custom file systems that are based upon another IFileSystem should inherit from FileSystemWrapper
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// An IFileSystem is generally used as a base file system, for example like a PhysicalFileSystem or an S3FileSystem.
|
||||
/// Then, other custom file systems are wrapped upon these files systems like MediaFileSystem, etc... All of the custom
|
||||
/// file systems must inherit from FileSystemWrapper.
|
||||
///
|
||||
/// This abstract class just wraps the 'real' IFileSystem object passed in to its constructor.
|
||||
/// </remarks>
|
||||
public abstract class FileSystemWrapper : IFileSystem
|
||||
{
|
||||
private readonly IFileSystem _wrapped;
|
||||
|
||||
protected FileSystemWrapper(IFileSystem wrapped)
|
||||
{
|
||||
_wrapped = wrapped;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetDirectories(string path)
|
||||
{
|
||||
return _wrapped.GetDirectories(path);
|
||||
}
|
||||
|
||||
public void DeleteDirectory(string path)
|
||||
{
|
||||
_wrapped.DeleteDirectory(path);
|
||||
}
|
||||
|
||||
public void DeleteDirectory(string path, bool recursive)
|
||||
{
|
||||
_wrapped.DeleteDirectory(path, recursive);
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
{
|
||||
return _wrapped.DirectoryExists(path);
|
||||
}
|
||||
|
||||
public void AddFile(string path, Stream stream)
|
||||
{
|
||||
_wrapped.AddFile(path, stream);
|
||||
}
|
||||
|
||||
public void AddFile(string path, Stream stream, bool overrideIfExists)
|
||||
{
|
||||
_wrapped.AddFile(path, stream, overrideIfExists);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetFiles(string path)
|
||||
{
|
||||
return _wrapped.GetFiles(path);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetFiles(string path, string filter)
|
||||
{
|
||||
return _wrapped.GetFiles(path, filter);
|
||||
}
|
||||
|
||||
public Stream OpenFile(string path)
|
||||
{
|
||||
return _wrapped.OpenFile(path);
|
||||
}
|
||||
|
||||
public void DeleteFile(string path)
|
||||
{
|
||||
_wrapped.DeleteFile(path);
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
{
|
||||
return _wrapped.FileExists(path);
|
||||
}
|
||||
|
||||
public string GetRelativePath(string fullPathOrUrl)
|
||||
{
|
||||
return _wrapped.GetRelativePath(fullPathOrUrl);
|
||||
}
|
||||
|
||||
public string GetFullPath(string path)
|
||||
{
|
||||
return _wrapped.GetFullPath(path);
|
||||
}
|
||||
|
||||
public string GetUrl(string path)
|
||||
{
|
||||
return _wrapped.GetUrl(path);
|
||||
}
|
||||
|
||||
public DateTimeOffset GetLastModified(string path)
|
||||
{
|
||||
return _wrapped.GetLastModified(path);
|
||||
}
|
||||
|
||||
public DateTimeOffset GetCreated(string path)
|
||||
{
|
||||
return _wrapped.GetCreated(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
internal interface IFileSystem
|
||||
{
|
||||
public interface IFileSystem
|
||||
{
|
||||
IEnumerable<string> GetDirectories(string path);
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
[FileSystemProvider("media")]
|
||||
internal interface IMediaFileSystem : IFileSystem
|
||||
{ }
|
||||
}
|
||||
@@ -9,12 +9,14 @@ using System.Configuration;
|
||||
using System.Web;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
internal static class IOHelper
|
||||
public static class IOHelper
|
||||
{
|
||||
private static string _rootDir = "";
|
||||
|
||||
// static compiled regex for faster performance
|
||||
private readonly static Regex ResolveUrlPattern = new Regex("(=[\"\']?)(\\W?\\~(?:.(?![\"\']?\\s+(?:\\S+)=|[>\"\']))+.)[\"\']?", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
@@ -49,46 +51,33 @@ namespace Umbraco.Core.IO
|
||||
return VirtualPathUtility.ToAbsolute(virtualPath, SystemDirectories.Root);
|
||||
}
|
||||
|
||||
|
||||
public static string ResolveUrlsFromTextString(string text)
|
||||
[Obsolete("Use Umbraco.Web.Templates.TemplateUtilities.ResolveUrlsFromTextString instead, this method on this class will be removed in future versions")]
|
||||
internal static string ResolveUrlsFromTextString(string text)
|
||||
{
|
||||
if (UmbracoSettings.ResolveUrlsFromTextString)
|
||||
{
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
Debug.WriteLine("Start: " + sw.ElapsedMilliseconds);
|
||||
|
||||
// find all relative urls (ie. urls that contain ~)
|
||||
var tags =
|
||||
ResolveUrlPattern.Matches(text);
|
||||
Debug.WriteLine("After regex: " + sw.ElapsedMilliseconds);
|
||||
foreach (Match tag in tags)
|
||||
{
|
||||
Debug.WriteLine("-- inside regex: " + sw.ElapsedMilliseconds);
|
||||
string url = "";
|
||||
if (tag.Groups[1].Success)
|
||||
url = tag.Groups[1].Value;
|
||||
|
||||
// The richtext editor inserts a slash in front of the url. That's why we need this little fix
|
||||
// if (url.StartsWith("/"))
|
||||
// text = text.Replace(url, ResolveUrl(url.Substring(1)));
|
||||
// else
|
||||
if (!String.IsNullOrEmpty(url))
|
||||
{
|
||||
Debug.WriteLine("---- before resolve: " + sw.ElapsedMilliseconds);
|
||||
string resolvedUrl = (url.Substring(0, 1) == "/") ? ResolveUrl(url.Substring(1)) : ResolveUrl(url);
|
||||
Debug.WriteLine("---- after resolve: " + sw.ElapsedMilliseconds);
|
||||
Debug.WriteLine("---- before replace: " + sw.ElapsedMilliseconds);
|
||||
text = text.Replace(url, resolvedUrl);
|
||||
Debug.WriteLine("---- after replace: " + sw.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Debug.WriteLine("total: " + sw.ElapsedMilliseconds);
|
||||
sw.Stop();
|
||||
Debug.WriteLine("Resolve Urls", sw.ElapsedMilliseconds.ToString());
|
||||
{
|
||||
using (var timer = DisposableTimer.DebugDuration(typeof(IOHelper), "ResolveUrlsFromTextString starting", "ResolveUrlsFromTextString complete"))
|
||||
{
|
||||
// find all relative urls (ie. urls that contain ~)
|
||||
var tags = ResolveUrlPattern.Matches(text);
|
||||
LogHelper.Debug(typeof(IOHelper), "After regex: " + timer.Stopwatch.ElapsedMilliseconds + " matched: " + tags.Count);
|
||||
foreach (Match tag in tags)
|
||||
{
|
||||
string url = "";
|
||||
if (tag.Groups[1].Success)
|
||||
url = tag.Groups[1].Value;
|
||||
|
||||
// The richtext editor inserts a slash in front of the url. That's why we need this little fix
|
||||
// if (url.StartsWith("/"))
|
||||
// text = text.Replace(url, ResolveUrl(url.Substring(1)));
|
||||
// else
|
||||
if (!String.IsNullOrEmpty(url))
|
||||
{
|
||||
string resolvedUrl = (url.Substring(0, 1) == "/") ? ResolveUrl(url.Substring(1)) : ResolveUrl(url);
|
||||
text = text.Replace(url, resolvedUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
@@ -96,7 +85,7 @@ namespace Umbraco.Core.IO
|
||||
public static string MapPath(string path, bool useHttpContext)
|
||||
{
|
||||
// Check if the path is already mapped
|
||||
if (path.Length >= 2 && path[1] == Path.VolumeSeparatorChar)
|
||||
if ((path.Length >= 2 && path[1] == Path.VolumeSeparatorChar) || path.StartsWith("\\"))
|
||||
return path;
|
||||
|
||||
// Check that we even have an HttpContext! otherwise things will fail anyways
|
||||
@@ -128,7 +117,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
|
||||
//use a tilde character instead of the complete path
|
||||
public static string ReturnPath(string settingsKey, string standardPath, bool useTilde)
|
||||
internal static string ReturnPath(string settingsKey, string standardPath, bool useTilde)
|
||||
{
|
||||
string retval = ConfigurationManager.AppSettings[settingsKey];
|
||||
|
||||
@@ -138,21 +127,19 @@ namespace Umbraco.Core.IO
|
||||
return retval.TrimEnd('/');
|
||||
}
|
||||
|
||||
|
||||
public static string ReturnPath(string settingsKey, string standardPath)
|
||||
internal static string ReturnPath(string settingsKey, string standardPath)
|
||||
{
|
||||
return ReturnPath(settingsKey, standardPath, false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Validates if the current filepath matches a directory where the user is allowed to edit a file
|
||||
/// </summary>
|
||||
/// <param name="filePath">filepath </param>
|
||||
/// <param name="validDir"></param>
|
||||
/// <returns>true if valid, throws a FileSecurityException if not</returns>
|
||||
public static bool ValidateEditPath(string filePath, string validDir)
|
||||
internal static bool ValidateEditPath(string filePath, string validDir)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
filePath = MapPath(filePath);
|
||||
@@ -165,7 +152,24 @@ namespace Umbraco.Core.IO
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
|
||||
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
{
|
||||
foreach (var dir in validDirs)
|
||||
{
|
||||
var validDir = dir;
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
filePath = MapPath(filePath);
|
||||
if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
validDir = MapPath(validDir);
|
||||
|
||||
if (filePath.StartsWith(validDir))
|
||||
return true;
|
||||
}
|
||||
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
}
|
||||
|
||||
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
filePath = MapPath(filePath);
|
||||
@@ -202,5 +206,48 @@ namespace Umbraco.Core.IO
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check to see if filename passed has any special chars in it and strips them to create a safe filename. Used to overcome an issue when Umbraco is used in IE in an intranet environment.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filename passed to the file handler from the upload field.</param>
|
||||
/// <returns>A safe filename without any path specific chars.</returns>
|
||||
internal static string SafeFileName(string filePath)
|
||||
{
|
||||
if (String.IsNullOrEmpty(filePath))
|
||||
return String.Empty;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
foreach (var character in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
filePath = filePath.Replace(character, '-');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filePath = String.Empty;
|
||||
}
|
||||
|
||||
// Adapted from: http://stackoverflow.com/a/4827510/5018
|
||||
// Combined both Reserved Characters and Character Data
|
||||
// from http://en.wikipedia.org/wiki/Percent-encoding
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
const string reservedCharacters = "!*'();:@&=+$,/?%#[]-~{}\"<>\\^`| ";
|
||||
|
||||
foreach (var character in filePath)
|
||||
{
|
||||
if (reservedCharacters.IndexOf(character) == -1)
|
||||
stringBuilder.Append(character);
|
||||
else
|
||||
stringBuilder.Append("-");
|
||||
}
|
||||
|
||||
// Remove repeating dashes
|
||||
// From: http://stackoverflow.com/questions/5111967/regex-to-remove-a-specific-repeated-character
|
||||
var reducedString = Regex.Replace(stringBuilder.ToString(), "-+", "-");
|
||||
|
||||
return reducedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// A custom file system provider for media
|
||||
/// </summary>
|
||||
[FileSystemProvider("media")]
|
||||
public class MediaFileSystem : FileSystemWrapper
|
||||
{
|
||||
public MediaFileSystem(IFileSystem wrapped)
|
||||
: base(wrapped)
|
||||
{
|
||||
}
|
||||
|
||||
public string GetRelativePath(int propertyId, string fileName)
|
||||
{
|
||||
var seperator = UmbracoSettings.UploadAllowDirectories
|
||||
? Path.DirectorySeparatorChar
|
||||
: '-';
|
||||
|
||||
return propertyId.ToString() + seperator + fileName;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetThumbnails(string path)
|
||||
{
|
||||
var parentDirectory = System.IO.Path.GetDirectoryName(path);
|
||||
var extension = System.IO.Path.GetExtension(path);
|
||||
|
||||
return GetFiles(parentDirectory)
|
||||
.Where(x => x.StartsWith(path.TrimEnd(extension) + "_thumb"))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public void DeleteFile(string path, bool deleteThumbnails)
|
||||
{
|
||||
DeleteFile(path);
|
||||
|
||||
if (!deleteThumbnails)
|
||||
return;
|
||||
|
||||
DeleteThumbnails(path);
|
||||
}
|
||||
|
||||
public void DeleteThumbnails(string path)
|
||||
{
|
||||
GetThumbnails(path)
|
||||
.ForEach(DeleteFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
public static class MediaFileSystemExtensions
|
||||
{
|
||||
internal static string GetRelativePath(this IMediaFileSystem fs, int propertyId, string fileName)
|
||||
{
|
||||
var seperator = UmbracoSettings.UploadAllowDirectories
|
||||
? Path.DirectorySeparatorChar
|
||||
: '-';
|
||||
|
||||
return propertyId.ToString() + seperator + fileName;
|
||||
}
|
||||
|
||||
internal static IEnumerable<string> GetThumbnails(this IMediaFileSystem fs, string path)
|
||||
{
|
||||
var parentDirectory = System.IO.Path.GetDirectoryName(path);
|
||||
var extension = System.IO.Path.GetExtension(path);
|
||||
|
||||
return fs.GetFiles(parentDirectory)
|
||||
.Where(x => x.StartsWith(path.TrimEnd(extension) + "_thumb"))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
internal static void DeleteFile(this IMediaFileSystem fs, string path, bool deleteThumbnails)
|
||||
{
|
||||
fs.DeleteFile(path);
|
||||
|
||||
if(!deleteThumbnails)
|
||||
return;
|
||||
|
||||
fs.DeleteThumbnails(path);
|
||||
}
|
||||
|
||||
internal static void DeleteThumbnails(this IMediaFileSystem fs, string path)
|
||||
{
|
||||
fs.GetThumbnails(path)
|
||||
.ForEach(fs.DeleteFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
internal class PhysicalFileSystem : IFileSystem
|
||||
public class PhysicalFileSystem : IFileSystem
|
||||
{
|
||||
private readonly string _rootPath;
|
||||
private readonly string _rootUrl;
|
||||
|
||||
public PhysicalFileSystem(string virtualRoot)
|
||||
{
|
||||
_rootPath = System.Web.Hosting.HostingEnvironment.MapPath(virtualRoot);
|
||||
_rootUrl = VirtualPathUtility.ToAbsolute(virtualRoot);
|
||||
_rootPath = IOHelper.MapPath(virtualRoot);
|
||||
_rootUrl = IOHelper.ResolveUrl(virtualRoot);
|
||||
}
|
||||
|
||||
public PhysicalFileSystem(string rootPath, string rootUrl)
|
||||
@@ -40,9 +42,13 @@ namespace Umbraco.Core.IO
|
||||
return Directory.EnumerateDirectories(path).Select(GetRelativePath);
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{ }
|
||||
{
|
||||
LogHelper.Error<PhysicalFileSystem>("Not authorized to get directories", ex);
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{ }
|
||||
{
|
||||
LogHelper.Error<PhysicalFileSystem>("Directory not found", ex);
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
@@ -62,7 +68,9 @@ namespace Umbraco.Core.IO
|
||||
Directory.Delete(GetFullPath(path), recursive);
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{ }
|
||||
{
|
||||
LogHelper.Error<PhysicalFileSystem>("Directory not found", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public bool DirectoryExists(string path)
|
||||
@@ -77,9 +85,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
public void AddFile(string path, Stream stream, bool overrideIfExists)
|
||||
{
|
||||
if (FileExists(path) && !overrideIfExists)
|
||||
throw new InvalidOperationException(string.Format("A file at path '{0}' already exists",
|
||||
path));
|
||||
if (FileExists(path) && !overrideIfExists) throw new InvalidOperationException(string.Format("A file at path '{0}' already exists", path));
|
||||
|
||||
EnsureDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
@@ -105,9 +111,13 @@ namespace Umbraco.Core.IO
|
||||
return Directory.EnumerateFiles(path, filter).Select(GetRelativePath);
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{ }
|
||||
{
|
||||
LogHelper.Error<PhysicalFileSystem>("Not authorized to get directories", ex);
|
||||
}
|
||||
catch (DirectoryNotFoundException ex)
|
||||
{ }
|
||||
{
|
||||
LogHelper.Error<PhysicalFileSystem>("Directory not found", ex);
|
||||
}
|
||||
|
||||
return Enumerable.Empty<string>();
|
||||
}
|
||||
@@ -127,7 +137,9 @@ namespace Umbraco.Core.IO
|
||||
File.Delete(GetFullPath(path));
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{ }
|
||||
{
|
||||
LogHelper.Error<PhysicalFileSystem>("File not found", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FileExists(string path)
|
||||
@@ -185,7 +197,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
protected string EnsureTrailingSeparator(string path)
|
||||
{
|
||||
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
|
||||
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture), StringComparison.Ordinal))
|
||||
path = path + Path.DirectorySeparatorChar;
|
||||
|
||||
return path;
|
||||
|
||||
@@ -10,8 +10,9 @@ using System.IO;
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
//all paths has a starting but no trailing /
|
||||
internal class SystemDirectories
|
||||
public class SystemDirectories
|
||||
{
|
||||
//TODO: Why on earth is this even configurable? You cannot change the /Bin folder in ASP.Net
|
||||
public static string Bin
|
||||
{
|
||||
get
|
||||
@@ -68,6 +69,24 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
}
|
||||
|
||||
public static string AppPlugins
|
||||
{
|
||||
get
|
||||
{
|
||||
//NOTE: this is not configurable and shouldn't need to be
|
||||
return "~/App_Plugins";
|
||||
}
|
||||
}
|
||||
|
||||
public static string MvcViews
|
||||
{
|
||||
get
|
||||
{
|
||||
//NOTE: this is not configurable and shouldn't need to be
|
||||
return "~/Views";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static string Media
|
||||
{
|
||||
@@ -77,8 +96,9 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
}
|
||||
|
||||
//have changed to internal so nobody uses this anymore since this is a new class.
|
||||
[Obsolete("Please use MacroScripts instead!", true)]
|
||||
public static string Python
|
||||
internal static string Python
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@ using System.Web;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
internal class SystemFiles
|
||||
public class SystemFiles
|
||||
{
|
||||
|
||||
public static string AccessXml
|
||||
@@ -96,7 +96,7 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ContentCacheXmlIsEphemeral)
|
||||
if (ContentCacheXmlIsEphemeral && SystemUtilities.GetCurrentTrustLevel() == AspNetHostingPermissionLevel.Unrestricted)
|
||||
{
|
||||
return Path.Combine(HttpRuntime.CodegenDir, @"UmbracoData\umbraco.config");
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ContentCacheXmlIsEphemeral
|
||||
internal static bool ContentCacheXmlIsEphemeral
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal interface IThumbnailProvider
|
||||
{
|
||||
int Priority { get; }
|
||||
bool CanProvideThumbnail(string fileUrl);
|
||||
string GetThumbnailUrl(string fileUrl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static class IntExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Does something 'x' amount of times
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <param name="action"></param>
|
||||
public static void Times(this int n, Action<int> action)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
action(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user