Compare commits
950 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0695839717 | |||
| 12dba80553 | |||
| f1d26d0990 | |||
| 83d5eda63c | |||
| 2f80d5466d | |||
| e90766ad06 | |||
| 379c629e9c | |||
| 49417cbce4 | |||
| 6153c70ef6 | |||
| dffe09af58 | |||
| 07e9a3a4ea | |||
| e3973de880 | |||
| 8e114f1e8f | |||
| b21289a32f | |||
| 52cf5b5ec3 | |||
| 3fbf90e56d | |||
| f100d82e2c | |||
| 3890353ff5 | |||
| 60ce993c09 | |||
| c07021d2a0 | |||
| 744ee39904 | |||
| d669bf64c0 | |||
| ff277cd99c | |||
| 30cd303a13 | |||
| 60ce987507 | |||
| a231899052 | |||
| 7ddcccb0c5 | |||
| db824d8daf | |||
| a1a30240f6 | |||
| f285af8a4e | |||
| 7c4a189aa3 | |||
| 3b77c301c3 | |||
| 4ec66bc868 | |||
| fa8fe8ec66 | |||
| 61718f9450 | |||
| 115ba8dcb8 | |||
| a76ba9a0a7 | |||
| b804ff6107 | |||
| 9b086c7fdd | |||
| b788a6c642 | |||
| a94f7e6ec0 | |||
| 72046a6ab9 | |||
| ea2303c327 | |||
| 4c4117a052 | |||
| 521b8076d2 | |||
| 1def88d764 | |||
| 910c349f7c | |||
| 260ec800c2 | |||
| 9e223eb891 | |||
| 6cfb5bc678 | |||
| a3b5996372 | |||
| 31b4560daa | |||
| 2f2dd9c9b6 | |||
| 02599e1254 | |||
| ac7ff31a67 | |||
| bea7387459 | |||
| 009f071f48 | |||
| e0ecb3291d | |||
| dbaf7c0190 | |||
| 16e06b6d4d | |||
| 444a028e30 | |||
| 0e5a469577 | |||
| 9d8f33e98e | |||
| 2abb3177af | |||
| 43f99e11a5 | |||
| 99ff86aefb | |||
| 918bb761b2 | |||
| 031f70f529 | |||
| d1d9878ab6 | |||
| e9753c72a7 | |||
| 3b791c75f6 | |||
| 35cb4d5690 | |||
| adde7c2f50 | |||
| 25f9fecc16 | |||
| 76a10fc776 | |||
| 1d0b5f3251 | |||
| b01f8799ae | |||
| 62943d391f | |||
| 76fb595a55 | |||
| 0942eb839d | |||
| 21a4dfe33e | |||
| 8121fc42e5 | |||
| c356ed1df8 | |||
| 92f56ccedd | |||
| 7cbe2410e4 | |||
| 1dda3ce45d | |||
| 1e29a4a8ca | |||
| 01de0bd6a1 | |||
| fbb46c9ffe | |||
| 628f5b283f | |||
| 73c34fda9c | |||
| b442fecca7 | |||
| 4d0d29c004 | |||
| 741c2bb085 | |||
| 2c809857af | |||
| 236d6ee302 | |||
| 3094dea5d4 | |||
| 9e1d3220c2 | |||
| de7294335f | |||
| 416dcdf90f | |||
| 2cd5b252d5 | |||
| 64cbeb4c9d | |||
| f829b0b16c | |||
| a42526b890 | |||
| 3a36513307 | |||
| 0548a32405 | |||
| 433950dd59 | |||
| ad8926668e | |||
| 4ebc0fe4cf | |||
| 1b1455067e | |||
| 795de94a5f | |||
| d6699ab3b3 | |||
| d2deaf0375 | |||
| 95ff94c532 | |||
| d94b334375 | |||
| a4a49b1466 | |||
| 9f82ae1db7 | |||
| 2c92cd9ca9 | |||
| c34605937c | |||
| 11b5123bbb | |||
| 2a9d3df822 | |||
| 3b849987bf | |||
| d0dc5406cc | |||
| 3be1cd8b0d | |||
| 8443513b2b | |||
| fec9d066f0 | |||
| a69c7dd1fc | |||
| 4e6a3458d0 | |||
| a5bb8ba8ee | |||
| d4f3dbcfc0 | |||
| 6a0656fbb0 | |||
| 9dc0999ebd | |||
| 813f1a1f2d | |||
| e45b0a53b8 | |||
| 685635c568 | |||
| a3e37de1ad | |||
| 692a8f807e | |||
| f4bdcae411 | |||
| 3a726348d2 | |||
| d8b029eba6 | |||
| 7c01670caf | |||
| 3ce5ff882e | |||
| 6e7aa19073 | |||
| 1cac4ed075 | |||
| e358390211 | |||
| 2e6c643dde | |||
| d84b8aa675 | |||
| 41a0c1f491 | |||
| e8d4777d74 | |||
| e03ef76fcd | |||
| 781ca34e34 | |||
| d01e963365 | |||
| 821daa82c4 | |||
| a51dd93ffe | |||
| 7134373933 | |||
| 8299243129 | |||
| 4144590189 | |||
| e2a821c257 | |||
| ed54301914 | |||
| 6849274b98 | |||
| 8fa838e8fb | |||
| 2f9753cc12 | |||
| 66263a44a5 | |||
| 2f4ff6aaae | |||
| 425df19c5c | |||
| f9babe1882 | |||
| cd2f512284 | |||
| ab0e549c70 | |||
| be065b2fa3 | |||
| 624975b4c9 | |||
| 85cdc79fd2 | |||
| 374bbc0973 | |||
| f0dfd0dce2 | |||
| da579c91e1 | |||
| 550d690a31 | |||
| 40b75b7cf5 | |||
| 0b28a68678 | |||
| 5f27355247 | |||
| 356ea6824f | |||
| 7ffb73e467 | |||
| 57c3665d0f | |||
| 8037f929aa | |||
| fec3e57ed6 | |||
| 5106ffab97 | |||
| 9f569171c3 | |||
| d607041ca4 | |||
| b3daf7f55d | |||
| a77d3bc4ac | |||
| dc3e144493 | |||
| f20fed3ce8 | |||
| 5a3b97c669 | |||
| 570b71820f | |||
| 442160bb7a | |||
| c4aa87d73d | |||
| 57909489cb | |||
| f87764f9d5 | |||
| 9d4e0f1e3d | |||
| 800b8b5f7e | |||
| c10c1f8fac | |||
| dbd9240142 | |||
| c3ca651e4a | |||
| f2e319a01f | |||
| d6589960f2 | |||
| 2847a28e74 | |||
| c78b371965 | |||
| e29668a01b | |||
| 757108446d | |||
| 19715ef45f | |||
| a1c7352da1 | |||
| c525be3e44 | |||
| cc804bd3bd | |||
| 24dc8309f1 | |||
| ce81f9b1b1 | |||
| 3f70761d49 | |||
| dee45146a4 | |||
| b35397b464 | |||
| 147cc92ac5 | |||
| 3230fce76a | |||
| 1d22c1e81e | |||
| ece2e2359e | |||
| 8cbe53f49d | |||
| cac3ddc3c8 | |||
| 0eac50ceba | |||
| d5e735ac14 | |||
| 8d841d3537 | |||
| ae3c17073b | |||
| 5f175874b2 | |||
| fa053426c3 | |||
| 59dd6e0941 | |||
| a321d4d1b8 | |||
| 437e7f0ffc | |||
| afa6c35bb5 | |||
| 22ac571c7d | |||
| 8d00dbf648 | |||
| cd26a1ad21 | |||
| 40d3f2ffb9 | |||
| 437ab4aaf1 | |||
| 0c0802e964 | |||
| 2a6d5846d1 | |||
| a43847bc8b | |||
| df6bb36876 | |||
| d185f93c35 | |||
| df2ce2c133 | |||
| 5e90e74969 | |||
| 924ee5c413 | |||
| bceed10bd8 | |||
| dec7ef8f3f | |||
| f019900619 | |||
| ad92006f54 | |||
| 439935430a | |||
| 1de9dbf18c | |||
| 394cab5ab4 | |||
| 6efd14eff3 | |||
| e468492064 | |||
| 140d3c0268 | |||
| 349cb91e3a | |||
| abf70cd302 | |||
| 880c9cf679 | |||
| bf59510c68 | |||
| b67250c3d5 | |||
| 86833aa8bf | |||
| 4dcc4807ed | |||
| 90b562a0a1 | |||
| fc2b3d7fc7 | |||
| 4d50dcea61 | |||
| 1f9594eef4 | |||
| 5a88ff774c | |||
| b269760b21 | |||
| 3efd038906 | |||
| 2d72a66879 | |||
| 7dc50fda26 | |||
| ff602da0fa | |||
| 4b156ba27e | |||
| d9cf9cee88 | |||
| afa4c7b697 | |||
| a2a8c8fbd7 | |||
| 52c4d80cfc | |||
| 5d4d209030 | |||
| d9f453d860 | |||
| 8c51e8bad8 | |||
| d4b21243ca | |||
| 927add6f44 | |||
| 48317d7e61 | |||
| 93df2edec2 | |||
| 028ddfe290 | |||
| 051e9366e5 | |||
| 46c6503320 | |||
| 39a4f141d7 | |||
| 1cf2fc7870 | |||
| c350904219 | |||
| 3d09157091 | |||
| 040486c32b | |||
| cf1c38dcaa | |||
| 3b6d557dd4 | |||
| 73d7cd4856 | |||
| 74f4b60a21 | |||
| 1b87fd074c | |||
| 33f21e0528 | |||
| 0b5a2452c2 | |||
| cc8962f090 | |||
| f6b9fdba72 | |||
| e0effec3b4 | |||
| 76a2f433d9 | |||
| a2bfca4d3a | |||
| fb24becd0d | |||
| 58857c5d83 | |||
| 7a31d6cae3 | |||
| 021bb6d367 | |||
| 0742108ec1 | |||
| 1c3a7b95fc | |||
| 5464107a9a | |||
| 84345a7e37 | |||
| fda72b2acc | |||
| cd3191012f | |||
| ec742d1f66 | |||
| 4bdac1475f | |||
| 58ce04e26b | |||
| 4c3de920c6 | |||
| be37026587 | |||
| a73b7a5849 | |||
| b7436dc55f | |||
| bc068b201d | |||
| 912b01c9aa | |||
| a82035061c | |||
| ef9cc2da3a | |||
| 12fd5c642d | |||
| a9b71f8533 | |||
| c73749ea54 | |||
| e001ed93c1 | |||
| 0c107fd869 | |||
| 6419f301f7 | |||
| e775471013 | |||
| cc109d1ed0 | |||
| 9dfccd86fd | |||
| ffaf1f96b9 | |||
| 4e195543ea | |||
| 2c918a2015 | |||
| aa3c1d645b | |||
| c6b393f2e8 | |||
| 344d909e6b | |||
| e3925f18ef | |||
| 53a4d063e0 | |||
| 907e5e7ca4 | |||
| 94e281e951 | |||
| 03b60d4923 | |||
| 27e96d6d5b | |||
| d2b4345773 | |||
| c5bbf97921 | |||
| 8c4eba7837 | |||
| 08a2ec6883 | |||
| b02e0c0232 | |||
| 182d671e31 | |||
| fff0151b62 | |||
| f15301a7a0 | |||
| 90fdbb007e | |||
| 19e4fe5059 | |||
| 311d503d8b | |||
| f0fc3313e4 | |||
| dc7cb08824 | |||
| 3b2ae6bc4a | |||
| 5ddcf42bc3 | |||
| b714cbbd72 | |||
| 09afb93ec3 | |||
| ab4cb08c7d | |||
| 2e877aa446 | |||
| d3eff734aa | |||
| af112f6b20 | |||
| cbef51eaf0 | |||
| 85ba41dd06 | |||
| e5cf7b089c | |||
| 5fae61b196 | |||
| db5c204d8c | |||
| b9082cf390 | |||
| 9469b0b844 | |||
| 5737cdfbe2 | |||
| 1a082464e9 | |||
| e004ad31b5 | |||
| 6cf25f0043 | |||
| c0f50a4c1b | |||
| 00fbc6dfcb | |||
| 3a9ad91f8f | |||
| c2cfd26ee6 | |||
| c5f26c7c15 | |||
| f742c0a958 | |||
| 8cefe22bee | |||
| fad3599f50 | |||
| 37b219f6e1 | |||
| 4e9667a067 | |||
| 300a46f1b2 | |||
| 9aa5df43bf | |||
| 02b0e4dd6a | |||
| 9c1d3fabb8 | |||
| e9e84a7faa | |||
| 137d8553de | |||
| 7210c6cd95 | |||
| 6856f9f341 | |||
| d24ef3650e | |||
| 2feef247ed | |||
| 4974e2a2ce | |||
| 3eb0dac48a | |||
| a44b19da18 | |||
| 3ee4234968 | |||
| f06a468fb4 | |||
| 420c334af4 | |||
| 20b21c86ea | |||
| b52f234c02 | |||
| d2083673be | |||
| fe40b8fe99 | |||
| dd477a0cbe | |||
| 2834ccdc2b | |||
| b3f6f48834 | |||
| 4544520b66 | |||
| 5baaed19d0 | |||
| 183e7e5910 | |||
| 173392f26e | |||
| 017663833a | |||
| 9a5923771d | |||
| 0932c980e9 | |||
| 7e9261d4bc | |||
| 0ce503b369 | |||
| be26527b27 | |||
| 414374498f | |||
| 1443618857 | |||
| a7075422dc | |||
| 9213304161 | |||
| 46fdd605ae | |||
| 99598ec060 | |||
| 6d5d8fb39c | |||
| 9613772036 | |||
| 604779667d | |||
| 46212904ef | |||
| b7bb98d824 | |||
| f31d2ca7cf | |||
| 88ae95150e | |||
| 97a085d12b | |||
| 74d0ec949d | |||
| 9a042fbbdf | |||
| 834b780d8e | |||
| 8905878a87 | |||
| 36bed40db0 | |||
| f708a24401 | |||
| d32cf12c6f | |||
| 100485f748 | |||
| 56017a340c | |||
| 21c70462c9 | |||
| 9b254f8bf9 | |||
| 6dd63e8a01 | |||
| bac940d4ed | |||
| c1c090faab | |||
| 32bedfaa6a | |||
| b003c027e5 | |||
| 0295aaba3b | |||
| bb04f83a49 | |||
| 793ba42f9e | |||
| ded1def8e2 | |||
| 5a2a3c3b1e | |||
| 6f2fa2ed4d | |||
| 0ae1453fb1 | |||
| 7dad078af4 | |||
| 9a89b6048a | |||
| 8c13b89c79 | |||
| d54e09c40b | |||
| c0d6c511e4 | |||
| 2da3ec27db | |||
| 5f10ed99aa | |||
| 48fa60039b | |||
| 20ceceffe0 | |||
| b73c7fbb16 | |||
| c96b866f1d | |||
| b724a185b7 | |||
| f94d280e27 | |||
| f63e8d7aed | |||
| 5342d819d9 | |||
| b2399e97cc | |||
| 5580523c08 | |||
| 6670f7036b | |||
| ca20fb799d | |||
| c760a7c50d | |||
| 2a3019f1b4 | |||
| 896d7aa788 | |||
| b7eb81dc76 | |||
| a59dd32dd1 | |||
| ee78e3815b | |||
| 2acfd64706 | |||
| a72fae333a | |||
| 4eef90fe25 | |||
| 428df7ae4a | |||
| 1fd4995edc | |||
| 667a731164 | |||
| df3d8d3757 | |||
| a6f6a321f9 | |||
| 03b0133b58 | |||
| 25cfceadc0 | |||
| df5c5e78ff | |||
| 5579823b2d | |||
| 824212f6c9 | |||
| 03969fd687 | |||
| 7788452fb7 | |||
| c7778467e3 | |||
| 0600d5c463 | |||
| 15c36a63d3 | |||
| bcba12abc8 | |||
| c0dd32d1f9 | |||
| 2411271ae0 | |||
| c87d0a6430 | |||
| c0051ba8cd | |||
| 2cf590d9c9 | |||
| 2729da2c08 | |||
| 9046319dc9 | |||
| fa27a37207 | |||
| 80f81ce379 | |||
| 3022293565 | |||
| 34889c147a | |||
| 7d17aef953 | |||
| 8af8a6d411 | |||
| dd736dce3a | |||
| cd4c738c04 | |||
| ed383bdaeb | |||
| 4874a71e72 | |||
| 58b8aacff1 | |||
| 0c5acb7f32 | |||
| d4d5a355e3 | |||
| 24ef0dd961 | |||
| 0efb9b72e7 | |||
| dd680b6fd1 | |||
| 788ed68b5b | |||
| 470ccd1ffc | |||
| e12984af4c | |||
| 7a6a6409c4 | |||
| 7c0f8db31b | |||
| 89606d3a05 | |||
| 7091cb6012 | |||
| 77319301c6 | |||
| 227bd1cd7e | |||
| 4790dc59a9 | |||
| a721f6836f | |||
| 83840ba6dd | |||
| de53dbffd1 | |||
| 68ac167ec3 | |||
| c8087d1f68 | |||
| f87ba4f0d5 | |||
| fed5a14e1b | |||
| b681ca5e17 | |||
| cb853168c6 | |||
| c4c21b8b6e | |||
| c3640f2a3d | |||
| a7c134a375 | |||
| 9cdea752e8 | |||
| de3c836ac1 | |||
| 70b325a189 | |||
| 80b23f8fa7 | |||
| 6d08d9b7b0 | |||
| 2cdc89297f | |||
| 839a5b13b0 | |||
| 40cc4b90fc | |||
| ba54f96efd | |||
| f4a0bcfc96 | |||
| 6b0292db64 | |||
| b5696de71e | |||
| a4d4cbd99f | |||
| 08a2c0d082 | |||
| 1d80fc66af | |||
| 010e4edc83 | |||
| f037f8541c | |||
| 10990e50e6 | |||
| 9dad4c9573 | |||
| 6318b85449 | |||
| 9d313898d0 | |||
| 0380b04b03 | |||
| f32e47a363 | |||
| 3ea7f8a226 | |||
| 2617016e3b | |||
| 90b3bf59e0 | |||
| b7f2152535 | |||
| aadae6334b | |||
| 5f0dc4a58e | |||
| 5667256d2c | |||
| 0f7b902bba | |||
| b899ab6557 | |||
| c092d871c1 | |||
| e1e73f5e5f | |||
| 7c3ff7d746 | |||
| 23a8777cde | |||
| 0e2e47d4ee | |||
| dc8a37b489 | |||
| 47ec2572f5 | |||
| bff9dfedcc | |||
| 332a95a27a | |||
| 4482879fc6 | |||
| 1b161c8dbe | |||
| 5a76e380de | |||
| 199bf0ff6e | |||
| 24915163ff | |||
| 6a4966136d | |||
| 0a0e34d806 | |||
| 214db84f9d | |||
| 61fd3fc505 | |||
| 1289d3255c | |||
| dc40b73fef | |||
| c1cc8a3824 | |||
| 70789e3676 | |||
| a7de549e4f | |||
| efab275c99 | |||
| f8600725b2 | |||
| a5c1b0b2f2 | |||
| 9c8e6ab864 | |||
| bd5833ec5f | |||
| 070fc368b2 | |||
| 50ed207211 | |||
| 4ea0fa0a19 | |||
| b5dd742257 | |||
| 0f4185b6a5 | |||
| ccea64f0fa | |||
| b892f98834 | |||
| 2f86813a21 | |||
| 2cd92353ec | |||
| 42ad3af48b | |||
| afb0aa8099 | |||
| 9695ccea0a | |||
| e13e86b25f | |||
| 6b9930df6a | |||
| ae92c8219d | |||
| 512e59871e | |||
| 7545c0c1da | |||
| 3f8df66385 | |||
| bbcca7f3e5 | |||
| 44257e361a | |||
| 7b4a82eb8d | |||
| 8393465e8a | |||
| 9ced66f208 | |||
| 633f56a7aa | |||
| 12d51b292c | |||
| e94b6fa3a8 | |||
| 3621c20f80 | |||
| ef4d28299a | |||
| d4b718d615 | |||
| e85ef38218 | |||
| 4775b638a4 | |||
| 280826f3e8 | |||
| 0a0d845173 | |||
| db3b8a1acd | |||
| a999fca349 | |||
| 17906b505d | |||
| c853263894 | |||
| 16f63b7fd9 | |||
| d41035cb2d | |||
| 1cb0cd296c | |||
| 8f100a7e9f | |||
| ed95ccc18e | |||
| e88264d0f7 | |||
| d9d8bae376 | |||
| 6f76377a9e | |||
| 7a644b6681 | |||
| 3fdf13a8b1 | |||
| 23ea9e71fd | |||
| 19037ee1ba | |||
| 8abf6fc2b5 | |||
| 48c127fefd | |||
| 778d8e0afa | |||
| 5a6e63e8d4 | |||
| 23341d8c76 | |||
| 5cbfa7bd91 | |||
| b3a93e369a | |||
| 5d7902a9a7 | |||
| 59aa28bf3b | |||
| cea002fd61 | |||
| f8c1cc684b | |||
| c41c727e06 | |||
| 3663fd9f99 | |||
| 10aad7e048 | |||
| cc396c8b96 | |||
| 1a7fbf5927 | |||
| b28d719ee6 | |||
| d5c8430cd2 | |||
| e3acdbe85b | |||
| f8ed9e60f6 | |||
| 00895ff7a9 | |||
| da778e277f | |||
| ef2c46b6ab | |||
| 6fcfd49cf0 | |||
| b9398375f1 | |||
| 274819f75f | |||
| fb3b99a49a | |||
| ffd4e9507b | |||
| 6457a1a2ca | |||
| 7212015127 | |||
| 31a1ee9145 | |||
| 53fbb18f1c | |||
| 43cfabe9e7 | |||
| caf972cd0f | |||
| 5bef3593dd | |||
| 3f233ad4a4 | |||
| 9252dc222a | |||
| fafe056db0 | |||
| 9f30a9b0fc | |||
| 86f6c4a39d | |||
| 32470e9bd2 | |||
| 97c18980d8 | |||
| defc9d3bc2 | |||
| 4bbd278007 | |||
| f6677aa19e | |||
| a1bca2eba1 | |||
| 4c5cc93a67 | |||
| 77e672aec1 | |||
| 519b06fe30 | |||
| 7e1b20e600 | |||
| 023c7f3fe7 | |||
| 7590bd86dd | |||
| 6b25e5299f | |||
| 76ab09bfc8 | |||
| d6f47366d4 | |||
| dc846e7ff6 | |||
| 322bd4e41e | |||
| 282550f402 | |||
| 699713346c | |||
| d4f28fcd85 | |||
| 11e946d61c | |||
| 341239648d | |||
| f3b23a15c9 | |||
| cc61c34cdf | |||
| 91b599b213 | |||
| ce6eb3d939 | |||
| ec5ca9087e | |||
| 8cfdcbdd05 | |||
| 4a72e8c3df | |||
| d747d16b75 | |||
| 106873732c | |||
| 462467a7d8 | |||
| 89b8fe93b7 | |||
| f6cd597841 | |||
| fa48af02a1 | |||
| 8509aef99a | |||
| 46e939715a | |||
| ea12da99ea | |||
| 97a05008b3 | |||
| 69e1dd1c73 | |||
| 95f68b8bde | |||
| 485621b03a | |||
| 3f1b031789 | |||
| d0f125a51b | |||
| a4f7c49f50 | |||
| a378d0c202 | |||
| d235340ec6 | |||
| 93ca536b14 | |||
| dea78c5d13 | |||
| d06ff5f108 | |||
| d94fe7df68 | |||
| fec70fcf47 | |||
| 11b53a5dcc | |||
| d4c0ea9c48 | |||
| 459d9b34e7 | |||
| 2ad86ec83d | |||
| 70ddf646be | |||
| 4de31249fd | |||
| 26c3bb05d6 | |||
| b1fe15ed56 | |||
| 83f1613eb8 | |||
| e8e6f5f807 | |||
| 8a32f02781 | |||
| 573192c33f | |||
| 56f5789976 | |||
| f21265c7ae | |||
| eace046342 | |||
| 0a6a41e4c2 | |||
| b449973403 | |||
| 911e81e4af | |||
| 458e7dde94 | |||
| 0c7826b250 | |||
| ef0ad41c8e | |||
| fff1da2a12 | |||
| 920084b7c3 | |||
| ff2c71367f | |||
| 428efed7c3 | |||
| 7c59c71261 | |||
| a0c2914ce6 | |||
| dbb70a8646 | |||
| 6a423dd032 | |||
| 73e9ff04e8 | |||
| 201464cb44 | |||
| a68fed42ad | |||
| a427427564 | |||
| 2286c0899c | |||
| 55eea6e44f | |||
| f91f25e5c0 | |||
| ae257d0f50 | |||
| 3f35ca1e77 | |||
| 8c619e92d9 | |||
| 28a01d61a6 | |||
| bc776d787e | |||
| 2f74dfe5cb | |||
| 84d2caf5d8 | |||
| 456e7d9fdf | |||
| dae66ad2d0 | |||
| 69d254a198 | |||
| b30555f5a4 | |||
| d5b6428cdc | |||
| 7d5bce76c2 | |||
| d4d77611eb | |||
| 662ed03f0a | |||
| fdac0ede45 | |||
| 83aa30d2c5 | |||
| b8097219fb | |||
| 34b524aabb | |||
| 2e2ea57ba6 | |||
| 72004768cf | |||
| b8e98ae017 | |||
| e5ec935128 | |||
| 3ea16e66d4 | |||
| 3c01dcb30c | |||
| 938b236f54 | |||
| aa439cacda | |||
| e643f2a0ba | |||
| 5b9a98ad6a | |||
| 3323138232 | |||
| cd0aa5e342 | |||
| f63ec81c47 | |||
| 5b63a8e9d9 | |||
| 71244b9bcd | |||
| fd1e369b2a | |||
| c256266432 | |||
| db087a9e78 | |||
| 4e33552a5c | |||
| da25970f79 | |||
| 562367e9a2 | |||
| 0807597a3c | |||
| d564866b07 | |||
| 99a45d26ae | |||
| a32d38f7ea | |||
| 5bf9362c92 | |||
| d9925e3453 | |||
| e1106a9d67 | |||
| a8d7a1d01d | |||
| e62597521e | |||
| fa91321299 | |||
| 2d81691407 | |||
| 21f08ca491 | |||
| e202f21934 | |||
| 2936ff0bf9 | |||
| 55dbc82d75 | |||
| 8e4e575276 | |||
| 84752babc8 | |||
| e1ec49fd3c | |||
| 60a1116acd | |||
| a480d7bbe6 | |||
| 7316c5462a | |||
| 2a9960afb3 | |||
| ed899ec73d | |||
| 8f26f9385d | |||
| 599d367343 | |||
| 45241788b3 | |||
| a446cc224d | |||
| 8bfcd4ce3f | |||
| 07f9a9700d | |||
| 7e7acd0049 | |||
| 57985c26a2 | |||
| 504c1f7254 | |||
| 52ad36a6c2 | |||
| 01670e0832 | |||
| e1a93e9b3f | |||
| 2203db548a | |||
| ff66c90855 | |||
| b0779cb330 | |||
| e3f043794b | |||
| 25c021d0a9 | |||
| 8f35c8fb57 | |||
| 45e3b2acf4 | |||
| 082d116924 | |||
| 85ccea60ab | |||
| 49e5493d52 | |||
| a700258d92 | |||
| 712fb9f11a | |||
| c16a1c727d | |||
| 78bc12eb77 | |||
| 9c10145869 | |||
| 99c96bce86 | |||
| 70424183fa | |||
| da2bc6764b | |||
| d11a377f0f | |||
| d445f7cb0d | |||
| d02235b997 | |||
| 899d325ca1 | |||
| f1107b7a91 | |||
| a3f171e7b3 | |||
| 8b3e80a001 | |||
| 13a2d845c6 | |||
| c20c93e648 | |||
| 2c212cb16a | |||
| 848e8a6248 | |||
| 9dcba6a679 | |||
| accded4dfc | |||
| c8f80453b9 | |||
| d857743bf3 | |||
| 78bee017ca | |||
| f08320bd81 | |||
| a1fcdac896 | |||
| ae2d9e6c55 | |||
| 451be273a5 | |||
| bf7473145f | |||
| 01a309ef42 | |||
| bf4d0a8d01 | |||
| 3a919b67ea | |||
| 77fd2c9444 | |||
| 30042aae6d | |||
| 8bc9fb9242 | |||
| 482e90dbc0 | |||
| 0b61546633 | |||
| ca69e64846 | |||
| 6e60aa17dc | |||
| f60884e796 | |||
| d2dbd91b17 | |||
| 0a7bbfb1ca | |||
| 864994a56e | |||
| 3405c5001b | |||
| 4d8732d925 | |||
| 6751f108f0 | |||
| 0feb65c455 | |||
| 4eb9a54fa5 | |||
| d4fd58e038 | |||
| 2961370b83 | |||
| c71e00b3dc | |||
| 3b2a27dfb2 | |||
| ad66613011 | |||
| a1de100a93 | |||
| cbcbc128ff | |||
| 6555fd5791 | |||
| 641c7dfa04 | |||
| 95845c8f2e | |||
| c656bb632e | |||
| bf82a70744 | |||
| 520955a8db | |||
| 2b25815eee | |||
| 7cfcab4011 | |||
| 787e10bbe1 | |||
| 8328f09d6b | |||
| 04823c23a0 | |||
| 5af67facad | |||
| be9e4c9623 | |||
| e03988dd81 | |||
| 79990b6a6c | |||
| 71ca90d74b | |||
| fb42472f31 | |||
| 7f78aef05f | |||
| b6695b6953 | |||
| 8820fa1fdf | |||
| df3d427c0b | |||
| e558918432 | |||
| e6d1eb0ba0 | |||
| f32a46c546 | |||
| a4de37efb9 | |||
| ee386d06da |
+9
-9
@@ -1,9 +1,9 @@
|
||||
# The MIT License (MIT) #
|
||||
|
||||
Copyright (c) 2013 Umbraco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
# The MIT License (MIT) #
|
||||
|
||||
Copyright (c) 2013 Umbraco
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
+6
-17
@@ -23,14 +23,15 @@ ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %rel
|
||||
|
||||
ECHO Installing the Microsoft.Bcl.Build package before anything else, otherwise you'd have to run build.cmd twice
|
||||
SET nuGetFolder=%CD%\..\src\packages\
|
||||
..\src\.nuget\NuGet.exe sources Remove -Name MyGetUmbracoCore
|
||||
..\src\.nuget\NuGet.exe sources Remove -Name MyGetUmbracoCore >NUL
|
||||
..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
|
||||
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder%
|
||||
..\src\.nuget\NuGet.exe install ..\src\umbraco.businesslogic\packages.config -OutputDirectory %nuGetFolder%
|
||||
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Core\packages.config -OutputDirectory %nuGetFolder%
|
||||
|
||||
ECHO Removing the belle build folder to make sure everything is clean as a whistle
|
||||
ECHO Removing the belle build folder and bower_components folder to make sure everything is clean as a whistle
|
||||
RD ..\src\Umbraco.Web.UI.Client\build /Q /S
|
||||
RD ..\src\Umbraco.Web.UI.Client\bower_components /Q /S
|
||||
|
||||
ECHO Removing existing built files to make sure everything is clean as a whistle
|
||||
RMDIR /Q /S _BuildOutput
|
||||
@@ -44,28 +45,16 @@ CALL InstallGit.cmd
|
||||
ECHO Performing MSBuild and producing Umbraco binaries zip files
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment%
|
||||
|
||||
ECHO Adding dummy files to include in the NuGet package so that empty folders actually get created
|
||||
SET dummytext=This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete.
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\App_Code\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\App_Data\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\App_Plugins\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\css\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\masterpages\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\media\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\scripts\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\usercontrols\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\Views\Partials\dummy.txt
|
||||
ECHO %dummytext% > .\_BuildOutput\WebApp\Views\MacroPartials\dummy.txt
|
||||
ECHO Setting node_modules folder to hidden to prevent VS13 from crashing on it while loading the websites project
|
||||
attrib +h ..\src\Umbraco.Web.UI.Client\node_modules
|
||||
|
||||
ECHO Adding Web.config transform files to the NuGet package
|
||||
REN .\_BuildOutput\WebApp\MacroScripts\Web.config Web.config.transform
|
||||
REN .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
|
||||
REN .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
|
||||
|
||||
ECHO Packing the NuGet release files
|
||||
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
|
||||
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version% -Symbols
|
||||
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.nuspec -Version %version%
|
||||
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoExamine.PDF.nuspec
|
||||
|
||||
IF ERRORLEVEL 1 GOTO :showerror
|
||||
|
||||
|
||||
+92
-114
@@ -1,4 +1,3 @@
|
||||
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<!--
|
||||
@@ -14,18 +13,18 @@
|
||||
|
||||
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
|
||||
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
|
||||
|
||||
<UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
|
||||
<UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<InputFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
|
||||
<OutputFile ParameterType="System.String" Required="true" />
|
||||
<InputFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
|
||||
<OutputFile ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Using Namespace="System.IO" />
|
||||
<Using Namespace="System.Linq" />
|
||||
<Using Namespace="System.Security.Cryptography" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
<Using Namespace="System.IO" />
|
||||
<Using Namespace="System.Linq" />
|
||||
<Using Namespace="System.Security.Cryptography" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
foreach (var item in InputFiles)
|
||||
@@ -48,11 +47,11 @@
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
</UsingTask>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
****************************************************
|
||||
VARIABLES
|
||||
@@ -76,23 +75,19 @@
|
||||
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
|
||||
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
|
||||
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
|
||||
<BuildZipExaminePDFName>UmbracoExamine.PDF.0.6.0.zip</BuildZipExaminePDFName>
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
|
||||
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
|
||||
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
|
||||
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
|
||||
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
|
||||
<ConfigsFolder>$(BuildFolder)Configs\</ConfigsFolder>
|
||||
<ConfigsFolder>$(BuildFolder)Configs\</ConfigsFolder>
|
||||
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
|
||||
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
|
||||
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
|
||||
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
|
||||
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
|
||||
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
|
||||
<ExaminePDFPath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF\</ExaminePDFPath>
|
||||
<ExamineAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.Azure\</ExamineAzurePath>
|
||||
<ExaminePDFAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF.Azure\</ExaminePDFAzurePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -114,16 +109,16 @@
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
|
||||
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
|
||||
<Message Text="Build finished" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
|
||||
<ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
|
||||
<ItemGroup>
|
||||
<WebPiFile Include="$(BuildZipFileNameWebPi)" />
|
||||
</ItemGroup>
|
||||
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
|
||||
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
|
||||
</ItemGroup>
|
||||
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
|
||||
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
|
||||
@@ -150,10 +145,10 @@
|
||||
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
|
||||
<!-- Zip the files -->
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22 -x!dotLess.Core.dll" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebApp" DependsOnTargets="ZipUmbracoExaminePDF" >
|
||||
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
|
||||
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22 -x!dotLess.Core.dll" />
|
||||
@@ -162,14 +157,6 @@
|
||||
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipUmbracoExaminePDF" DependsOnTargets="CreateSystemFolders" >
|
||||
<Message Text="Starting to zip to $(buildDate)-$(BuildZipExaminePDFName)" Importance="high" />
|
||||
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipExaminePDFName)%22 %22$(ExaminePDFPath)*%22" />
|
||||
|
||||
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipExaminePDFName)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CreateSystemFolders" DependsOnTargets="CopyBelleBuild" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
|
||||
<MakeDir Directories="@(SystemFolders)" />
|
||||
</Target>
|
||||
@@ -177,14 +164,14 @@
|
||||
<Target Name="CopyBelleBuild" DependsOnTargets="CopyLibraries" >
|
||||
<ItemGroup>
|
||||
<BelleFiles Include="..\src\Umbraco.Web.UI.Client\build\belle\**\*.*" Exclude="..\src\Umbraco.Web.UI.Client\build\belle\index.html" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(BelleFiles)"
|
||||
DestinationFiles="@(BelleFiles->'$(WebAppFolder)umbraco\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(BelleFiles)"
|
||||
DestinationFiles="@(BelleFiles->'$(WebAppFolder)umbraco\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
|
||||
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
|
||||
<!-- Copy SQL CE -->
|
||||
<ItemGroup>
|
||||
@@ -217,7 +204,7 @@
|
||||
</Target>
|
||||
|
||||
<!-- Copy the transformed web.config file to the root -->
|
||||
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyTransformedConfig">
|
||||
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyTransformedConfig">
|
||||
<ItemGroup>
|
||||
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
|
||||
</ItemGroup>
|
||||
@@ -226,24 +213,24 @@
|
||||
DestinationFiles="$(WebAppFolder)Web.config"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the config files and rename them to *.config.transform -->
|
||||
<Target Name="CopyTransformedConfig" DependsOnTargets="CopyXmlDocumentation">
|
||||
</Target>
|
||||
|
||||
<!-- Copy the config files and rename them to *.config.transform -->
|
||||
<Target Name="CopyTransformedConfig" DependsOnTargets="CopyXmlDocumentation">
|
||||
<ItemGroup>
|
||||
<ConfigFiles Include="$(WebAppFolder)config\*.config;$(WebAppFolder)config\*.js" />
|
||||
<WebConfigTransformFile Include="$(WebAppFolder)Web.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(ConfigFiles)"
|
||||
DestinationFiles="@(ConfigFiles->'$(ConfigsFolder)\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<Copy SourceFiles="@(WebConfigTransformFile)"
|
||||
DestinationFiles="$(ConfigsFolder)Web.config.transform"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<ConfigFiles Include="$(WebAppFolder)config\*.config;$(WebAppFolder)config\*.js" />
|
||||
<WebConfigTransformFile Include="$(WebAppFolder)Web.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(ConfigFiles)"
|
||||
DestinationFiles="@(ConfigFiles->'$(ConfigsFolder)\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<Copy SourceFiles="@(WebConfigTransformFile)"
|
||||
DestinationFiles="$(ConfigsFolder)Web.config.transform"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the xml documentation to the bin folder -->
|
||||
@@ -261,78 +248,69 @@
|
||||
|
||||
<!-- Unlike 2010, the VS2012 build targets file doesn't clean up the umbraco.presentation dir, do it manually -->
|
||||
<Target Name="CleanupPresentation" DependsOnTargets="CompileProjects">
|
||||
<ItemGroup>
|
||||
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
|
||||
<ItemGroup>
|
||||
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
|
||||
</ItemGroup>
|
||||
<RemoveDir Directories="@(PresentationFolderToDelete)" />
|
||||
<RemoveDir Directories="@(PresentationFolderToDelete)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects" DependsOnTargets="CompileExternalExamineProjects">
|
||||
|
||||
<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 -->
|
||||
<!-- Build the Umbraco.Web.UI project -->
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Rebuild;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
|
||||
|
||||
<!-- DONE -->
|
||||
<Message Text="Finished compiling projects" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileExternalExamineProjects" DependsOnTargets="SetVersionNumber">
|
||||
<Message Text="Building externally shipped examine projects" Importance="high" />
|
||||
|
||||
<!-- First remove old files from the examine builds -->
|
||||
<ItemGroup>
|
||||
<FilesToDeleteBeforeBuild Include="$(ExaminePDFPath)*;$(ExamineAzurePath)*"/>
|
||||
</ItemGroup>
|
||||
<Delete Files="@(FilesToDeleteBeforeBuild)" />
|
||||
<!--
|
||||
Build the UmbracoExamine.PDF.Azure library ... this builds the 3 projects that we want to bundle separately so no need to build each one separately .
|
||||
We'll just build this one and then manually copy the DLLs to where we want them.
|
||||
-->
|
||||
<MSBuild Projects="..\src\UmbracoExamine.PDF.Azure\UmbracoExamine.PDF.Azure.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);PipelineDependsOnBuild=False;OutDir=$(ExaminePDFAzurePath);" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
<ItemGroup>
|
||||
<ExaminePDFFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.pdf;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.xml;$(ExaminePDFAzurePath)**\itextsharp.dll" />
|
||||
<ExamineAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.xml" />
|
||||
<ExaminePDFAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.xml" />
|
||||
</ItemGroup>
|
||||
<!-- Now copy the built files to their correct deployment folders-->
|
||||
<Copy SourceFiles="@(ExaminePDFFiles)"
|
||||
DestinationFolder="$(ExaminePDFPath)"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(ExamineAzureFiles)"
|
||||
DestinationFolder="$(ExamineAzurePath)"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<!-- Then just delete the files we don't want to ship in the UmbracoExamine.Azure.PDF folder -->
|
||||
<ItemGroup>
|
||||
<FilesToDeleteAfterBuild Include="$(ExaminePDFAzurePath)*" Exclude="$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.dll;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.pdb;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.xml"/>
|
||||
</ItemGroup>
|
||||
<Delete Files="@(FilesToDeleteAfterBuild)" />
|
||||
</Target>
|
||||
|
||||
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<PropertyGroup>
|
||||
<NewVersion>$(BUILD_RELEASE)</NewVersion>
|
||||
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
|
||||
<PropertyGroup>
|
||||
<NewVersion>$(BUILD_RELEASE)</NewVersion>
|
||||
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
|
||||
<FileUpdate
|
||||
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
|
||||
ReplacementText="$(BUILD_RELEASE)"/>
|
||||
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="CurrentComment { get { return "([a-zA-Z]+)?""
|
||||
Regex="CurrentComment { get { return "(.+)?""
|
||||
ReplacementText="CurrentComment { get { return "$(BUILD_COMMENT)""/>
|
||||
|
||||
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.props"
|
||||
Namespaces="<Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' />"
|
||||
Query="//x:UmbracoVersion"
|
||||
Value="$(NewVersion)" />
|
||||
|
||||
<!--This updates the AssemblyFileVersion for the solution to the umbraco version-->
|
||||
<FileUpdate
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyFileVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyFileVersion("$(BUILD_RELEASE)")"/>
|
||||
|
||||
<!--This updates the AssemblyInformationalVersion for the solution to the umbraco version and comment-->
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_COMMENT)'!=''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyInformationalVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyInformationalVersion("$(BUILD_RELEASE)-$(BUILD_COMMENT)")"/>
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_COMMENT)'==''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyInformationalVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyInformationalVersion("$(BUILD_RELEASE)")"/>
|
||||
|
||||
<!--This updates the copyright year-->
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_COMMENT)'==''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyCopyright\("Copyright © Umbraco (\d{4})"\)"
|
||||
ReplacementText="AssemblyCopyright("Copyright © Umbraco $([System.DateTime]::Now.ToString(`yyyy`))")"/>
|
||||
|
||||
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.props"
|
||||
Namespaces="<Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' />"
|
||||
Query="//x:UmbracoVersion"
|
||||
Value="$(NewVersion)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core.AllBinaries</id>
|
||||
<version>6.1.2</version>
|
||||
<title>Umbraco Cms Core All Binaries</title>
|
||||
<authors>Morten Christensen</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Contains the core assemblies and all of the dependant assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
|
||||
<summary>Contains the core assemblies and all of the dependant assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\bin\AutoMapper.dll" target="lib\AutoMapper.dll" />
|
||||
<file src="..\_BuildOutput\bin\AutoMapper.Net4.dll" target="lib\AutoMapper.Net4.dll" />
|
||||
<file src="..\_BuildOutput\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\bin\ClientDependency.Core.dll" target="lib\ClientDependency.Core.dll" />
|
||||
<file src="..\_BuildOutput\bin\ClientDependency.Core.Mvc.dll" target="lib\ClientDependency.Core.Mvc.dll" />
|
||||
<file src="..\_BuildOutput\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\bin\CookComputing.XmlRpcV2.dll" target="lib\CookComputing.XmlRpcV2.dll" />
|
||||
<file src="..\_BuildOutput\bin\Examine.dll" target="lib\Examine.dll" />
|
||||
<file src="..\_BuildOutput\bin\HtmlAgilityPack.dll" target="lib\HtmlAgilityPack.dll" />
|
||||
<file src="..\_BuildOutput\bin\ICSharpCode.SharpZipLib.dll" target="lib\ICSharpCode.SharpZipLib.dll" />
|
||||
<file src="..\_BuildOutput\bin\ImageProcessor.dll" target="lib\ImageProcessor.dll" />
|
||||
<file src="..\_BuildOutput\bin\ImageProcessor.Web.dll" target="lib\ImageProcessor.Web.dll" />
|
||||
<file src="..\_BuildOutput\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\bin\log4net.dll" target="lib\log4net.dll" />
|
||||
<file src="..\_BuildOutput\bin\Lucene.Net.dll" target="lib\Lucene.Net.dll" />
|
||||
<file src="..\_BuildOutput\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="..\_BuildOutput\bin\Microsoft.Threading.Tasks.dll" target="lib\Microsoft.Threading.Tasks.dll" />
|
||||
<file src="..\_BuildOutput\bin\Microsoft.Threading.Tasks.Extensions.dll" target="lib\Microsoft.Threading.Tasks.Extensions.dll" />
|
||||
<file src="..\_BuildOutput\bin\Microsoft.Web.Helpers.dll" target="lib\Microsoft.Web.Helpers.dll" />
|
||||
<file src="..\_BuildOutput\bin\Microsoft.Web.Infrastructure.dll" target="lib\Microsoft.Web.Infrastructure.dll" />
|
||||
<file src="..\_BuildOutput\bin\Microsoft.Web.Mvc.FixedDisplayModes.dll" target="lib\Microsoft.Web.Mvc.FixedDisplayModes.dll" />
|
||||
<file src="..\_BuildOutput\bin\MiniProfiler.dll" target="lib\MiniProfiler.dll" />
|
||||
<file src="..\_BuildOutput\bin\MySql.Data.dll" target="lib\MySql.Data.dll" />
|
||||
<file src="..\_BuildOutput\bin\Newtonsoft.Json.dll" target="lib\Newtonsoft.Json.dll" />
|
||||
<file src="..\_BuildOutput\bin\NuGet.Core.dll" target="lib\NuGet.Core.dll" />
|
||||
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Net.Http.dll" target="lib\System.Net.Http.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Net.Http.Extensions.dll" target="lib\System.Net.Http.Extensions.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Net.Http.Formatting.dll" target="lib\System.Net.Http.Formatting.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Net.Http.Primitives.dll" target="lib\System.Net.Http.Primitives.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Net.Http.WebRequest.dll" target="lib\System.Net.Http.WebRequest.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.Helpers.dll" target="lib\System.Web.Helpers.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.Http.dll" target="lib\System.Web.Http.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.Http.WebHost.dll" target="lib\System.Web.Http.WebHost.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.Mvc.dll" target="lib\System.Web.Mvc.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.Razor.dll" target="lib\System.Web.Razor.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.WebPages.Administration.dll" target="lib\System.Web.WebPages.Administration.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.WebPages.Deployment.dll" target="lib\System.Web.WebPages.Deployment.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.WebPages.dll" target="lib\System.Web.WebPages.dll" />
|
||||
<file src="..\_BuildOutput\bin\System.Web.WebPages.Razor.dll" target="lib\System.Web.WebPages.Razor.dll" />
|
||||
<file src="..\_BuildOutput\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -1,71 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\..\src\SQLCE4Umbraco\obj\Debug\SQLCE4Umbraco.dll" target="lib" />
|
||||
<file src="..\..\src\SQLCE4Umbraco\obj\Debug\SQLCE4Umbraco.pdb" target="lib" />
|
||||
<file src="..\..\src\SQLCE4Umbraco\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\SQLCE4Umbraco" />
|
||||
|
||||
<file src="..\..\src\umbraco.businesslogic\obj\Debug\businesslogic.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.businesslogic\obj\Debug\businesslogic.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.businesslogic\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.businesslogic" />
|
||||
|
||||
<file src="..\..\src\umbraco.cms\obj\Debug\cms.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.cms\obj\Debug\cms.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.cms\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.cms" />
|
||||
|
||||
<file src="..\..\src\umbraco.controls\obj\Debug\controls.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.controls\obj\Debug\controls.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.controls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.controls" />
|
||||
|
||||
<file src="..\..\src\umbraco.interfaces\obj\Debug\interfaces.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.interfaces\obj\Debug\interfaces.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.interfaces\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.interfaces" />
|
||||
|
||||
<file src="..\..\src\Umbraco.Core\obj\Debug\Umbraco.Core.dll" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Core\obj\Debug\Umbraco.Core.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Core\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Core" />
|
||||
|
||||
<file src="..\..\src\umbraco.datalayer\obj\Debug\umbraco.DataLayer.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.datalayer\obj\Debug\umbraco.DataLayer.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.datalayer\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.datalayer" />
|
||||
|
||||
<file src="..\..\src\umbraco.editorControls\obj\Debug\umbraco.editorControls.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.editorControls\obj\Debug\umbraco.editorControls.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.editorControls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.editorControls" />
|
||||
|
||||
<file src="..\..\src\umbraco.MacroEngines\obj\Debug\umbraco.MacroEngines.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.MacroEngines\obj\Debug\umbraco.MacroEngines.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.MacroEngines\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.MacroEngines" />
|
||||
|
||||
<file src="..\..\src\umbraco.providers\obj\Debug\umbraco.providers.dll" target="lib" />
|
||||
<file src="..\..\src\umbraco.providers\obj\Debug\umbraco.providers.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.providers\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.providers" />
|
||||
|
||||
<file src="..\..\src\Umbraco.Web\obj\Debug\umbraco.dll" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Web\obj\Debug\umbraco.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Web\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web" />
|
||||
|
||||
<file src="..\..\src\bin\Debug\Umbraco.Web.UI.dll" target="lib" />
|
||||
<file src="..\..\src\bin\Debug\Umbraco.Web.UI.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Web.UI\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web.UI" />
|
||||
|
||||
<file src="..\..\src\UmbracoExamine\obj\Debug\UmbracoExamine.dll" target="lib" />
|
||||
<file src="..\..\src\UmbracoExamine\obj\Debug\UmbracoExamine.pdb" target="lib" />
|
||||
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -1,73 +1,104 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.30506.0,5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="[4.0.30506,5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi.WebHost" version="[4.0.30506, 5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi.Core" version="[4.0.30506, 5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi.Client" version="[4.0.30506, 5.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" />
|
||||
<dependency id="Microsoft.Net.Http" version="[2.0.20710.0, 3.0.0)" />
|
||||
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.4.6, 2.0.0)" />
|
||||
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
|
||||
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
|
||||
<dependency id="MySql.Data" version="[6.6.5]" />
|
||||
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
|
||||
<dependency id="ClientDependency" version="[1.8.0, 2.0.0)" />
|
||||
<dependency id="ClientDependency-Mvc" version="[1.8.0, 2.0.0)" />
|
||||
<dependency id="AutoMapper" version="[3.0.0, 4.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[6.0.5, 7.0.0)" />
|
||||
<dependency id="Examine" version="[0.1.57, 1.0.0)" />
|
||||
<dependency id="ImageProcessor" version="[1.9.5, 3.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[3.3.1, 5.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
|
||||
<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\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
<file src="tools\install.core.ps1" target="tools\install.ps1" />
|
||||
</files>
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Contains the core assemblies needed to run Umbraco Cms. This package only contains assemblies and can be used for package development. Use the UmbracoCms-package to setup Umbraco in Visual Studio as an ASP.NET project.</description>
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.40804.0,6.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.3,6.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.1" />
|
||||
<dependency id="Microsoft.Net.Http" version="[2.0.20710.0, 3.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.0, 3.0.0)" />
|
||||
<dependency id="Microsoft.Owin.Security.Cookies" version="[3.0.1, 4.0.0)" />
|
||||
<dependency id="Microsoft.Owin.Security.OAuth" version="[3.0.1, 4.0.0)" />
|
||||
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[3.0.1, 4.0.0)" />
|
||||
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.4.6, 2.0.0)" />
|
||||
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
|
||||
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
|
||||
<dependency id="MySql.Data" version="[6.9.6, 7.0.0)" />
|
||||
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
|
||||
<dependency id="ClientDependency" version="[1.8.3.1, 2.0.0)" />
|
||||
<dependency id="ClientDependency-Mvc" version="[1.8.0, 2.0.0)" />
|
||||
<dependency id="AutoMapper" version="[3.0.0, 4.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[6.0.5, 7.0.0)" />
|
||||
<dependency id="Examine" version="[0.1.63, 1.0.0)" />
|
||||
<dependency id="ImageProcessor" version="[1.9.5, 3.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[3.3.1, 5.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
|
||||
<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\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.xml" target="lib\SQLCE4Umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\UmbracoExamine.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UrlRewritingNet.UrlRewriter.dll" target="lib\UrlRewritingNet.UrlRewriter.dll" />
|
||||
<file src="tools\install.core.ps1" target="tools\install.ps1" />
|
||||
|
||||
<!-- Added to be able to produce a symbols package -->
|
||||
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.pdb" target="lib" />
|
||||
<file src="..\..\src\SQLCE4Umbraco\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\SQLCE4Umbraco" />
|
||||
<file src="..\_BuildOutput\bin\businesslogic.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.businesslogic\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.businesslogic" />
|
||||
<file src="..\_BuildOutput\bin\cms.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.cms\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.cms" />
|
||||
<file src="..\_BuildOutput\bin\controls.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.controls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.controls" />
|
||||
<file src="..\_BuildOutput\bin\interfaces.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.interfaces\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.interfaces" />
|
||||
<file src="..\_BuildOutput\bin\Umbraco.Core.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Core\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Core" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.DataLayer.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.datalayer\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.datalayer" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.editorControls.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.editorControls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.editorControls" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.MacroEngines\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.MacroEngines" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.providers.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.providers\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.providers" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Web\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web" />
|
||||
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Web.UI\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web.UI" />
|
||||
<file src="..\_BuildOutput\bin\UmbracoExamine.pdb" target="lib" />
|
||||
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -1,45 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="2.8">
|
||||
<id>UmbracoCms</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Installs Umbraco Cms in your Visual Studio ASP.NET project</description>
|
||||
<summary>Installs Umbraco Cms in your Visual Studio ASP.NET project</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="UmbracoCms.Core" version="[$version$]" />
|
||||
<dependency id="Newtonsoft.Json" version="[6.0.5, 7.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<metadata minClientVersion="2.8">
|
||||
<id>UmbracoCms</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Installs Umbraco Cms in your Visual Studio ASP.NET project</description>
|
||||
<summary>Installs Umbraco Cms in your Visual Studio ASP.NET project</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="UmbracoCms.Core" version="[$version$]" />
|
||||
<dependency id="Newtonsoft.Json" version="[6.0.5, 7.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\Configs\**" target="Content\config" exclude="..\_BuildOutput\Configs\Web.config.transform" />
|
||||
<file src="..\_BuildOutput\WebApp\css\**" target="Content\css" />
|
||||
<file src="..\_BuildOutput\WebApp\masterpages\**" target="Content\masterpages" />
|
||||
<file src="..\_BuildOutput\WebApp\media\**" target="Content\media" />
|
||||
<file src="..\_BuildOutput\WebApp\scripts\**" target="Content\scripts" />
|
||||
<file src="..\_BuildOutput\WebApp\usercontrols\**" target="Content\usercontrols" />
|
||||
<file src="..\_BuildOutput\WebApp\Views\**" target="Content\Views" exclude="..\_BuildOutput\WebApp\Views\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\xslt\**" target="Content\xslt" />
|
||||
<file src="..\_BuildOutput\WebApp\default.aspx" target="Content\default.aspx" />
|
||||
<file src="..\_BuildOutput\WebApp\Global.asax" target="Content\Global.asax" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="UmbracoFiles\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Browsers\**" target="UmbracoFiles\App_Browsers" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="UmbracoFiles\bin\amd64" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="UmbracoFiles\bin\x86" />
|
||||
<file src="..\_BuildOutput\WebApp\config\splashes\**" target="UmbracoFiles\config\splashes" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="..\_BuildOutput\Configs\**" target="Content\Config" exclude="..\_BuildOutput\Configs\Web.config.transform" />
|
||||
<file src="..\_BuildOutput\WebApp\Views\**" target="Content\Views" exclude="..\_BuildOutput\WebApp\Views\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\default.aspx" target="Content\default.aspx" />
|
||||
<file src="..\_BuildOutput\WebApp\Global.asax" target="Content\Global.asax" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="UmbracoFiles\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Browsers\**" target="UmbracoFiles\App_Browsers" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Plugins\**" target="UmbracoFiles\App_Plugins" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="UmbracoFiles\bin\amd64" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="UmbracoFiles\bin\x86" />
|
||||
<file src="..\_BuildOutput\WebApp\config\splashes\**" target="UmbracoFiles\Config\splashes" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="tools\install.ps1" target="tools\install.ps1" />
|
||||
<file src="tools\Readme.txt" target="tools\Readme.txt" />
|
||||
<file src="tools\ReadmeUpgrade.txt" target="tools\ReadmeUpgrade.txt" />
|
||||
<file src="tools\Web.config.install.xdt" target="Content\Web.config.install.xdt" />
|
||||
<file src="tools\applications.config.install.xdt" target="Content\config\applications.config.install.xdt" />
|
||||
<file src="tools\ClientDependency.config.install.xdt" target="Content\config\ClientDependency.config.install.xdt" />
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>UmbracoExamine.PDF</id>
|
||||
<version>0.7.0</version>
|
||||
<authors>Umbraco HQ</authors>
|
||||
<owners>Umbraco HQ</owners>
|
||||
<licenseUrl>http://umbraco.codeplex.com/license</licenseUrl>
|
||||
<projectUrl>http://umbraco.com/</projectUrl>
|
||||
<iconUrl>http://umbraco.com/media/357769/100px_transparent.png</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>UmbracoExmine.PDF</description>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="UmbracoCms.Core" version="[7.0.0, 8.0.0)" />
|
||||
<dependency id="iTextSharp" version="[5.5.3, 6.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\_BuildOutput\UmbracoExamine.PDF\UmbracoExamine.PDF.dll" target="lib\UmbracoExamine.PDF.dll" />
|
||||
<file src="..\_BuildOutput\UmbracoExamine.PDF\UmbracoExamine.PDF.XML" target="lib\UmbracoExamine.PDF.XML" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -1,18 +1,18 @@
|
||||
A note about running Umbraco from Visual Studio.
|
||||
|
||||
_ _ __ __ ____ _____ _____ ____
|
||||
| | | | \/ | _ \| __ \ /\ / ____/ __ \
|
||||
| | | | \ / | |_) | |__) | / \ | | | | | |
|
||||
| | | | |\/| | _ <| _ / / /\ \| | | | | |
|
||||
| |__| | | | | |_) | | \ \ / ____ | |___| |__| |
|
||||
\____/|_| |_|____/|_| \_/_/ \_\_____\____/
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Don't forget to build!
|
||||
|
||||
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
|
||||
file (and config files in the config folder).
|
||||
|
||||
We've done our best to transform your configuration files but in case something is not quite right: remember we
|
||||
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
|
||||
|
||||
We've overwritten all the files in the Umbraco and Umbraco_Client folder, these have been backed up in
|
||||
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or
|
||||
a package might have added. Only the existing files were overwritten. If you customized anything then make
|
||||
sure to do a compare and merge with the NuGetBackup folder.
|
||||
|
||||
This NuGet package includes build targets that extend the creation of a deploy package, which is generated by
|
||||
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
|
||||
Publish this won't affect you.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
_ _ __ __ ____ _____ _____ ____
|
||||
| | | | \/ | _ \| __ \ /\ / ____/ __ \
|
||||
| | | | \ / | |_) | |__) | / \ | | | | | |
|
||||
| | | | |\/| | _ <| _ / / /\ \| | | | | |
|
||||
| |__| | | | | |_) | | \ \ / ____ | |___| |__| |
|
||||
\____/|_| |_|____/|_| \_/_/ \_\_____\____/
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Don't forget to build!
|
||||
|
||||
When upgrading your website using NuGet you should answer "No" to the questions to overwrite the Web.config
|
||||
file (and config files in the config folder).
|
||||
|
||||
We've done our best to transform your configuration files but in case something is not quite right: remember we
|
||||
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
|
||||
|
||||
We've overwritten all the files in the Umbraco and Umbraco_Client folder, these have been backed up in
|
||||
App_Data\NuGetBackup. We didn't overwrite the UI.xml file nor did we remove any files or folders that you or
|
||||
a package might have added. Only the existing files were overwritten. If you customized anything then make
|
||||
sure to do a compare and merge with the NuGetBackup folder.
|
||||
|
||||
This NuGet package includes build targets that extend the creation of a deploy package, which is generated by
|
||||
Publishing from Visual Studio. The targets will only work once Publishing is configured, so if you don't use
|
||||
Publish this won't affect you.
|
||||
The following items will now be automatically included when creating a deploy package or publishing to the file
|
||||
system: umbraco, umbraco_client, config\splashes and global.asax.
|
||||
|
||||
Please read the release notes on our.umbraco.org:
|
||||
http://our.umbraco.org/contribute/releases
|
||||
|
||||
- Umbraco
|
||||
@@ -21,6 +21,7 @@
|
||||
<appSettings xdt:Transform="InsertIfMissing" />
|
||||
<appSettings>
|
||||
<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
|
||||
<add key="owin:appStartup" value="UmbracoDefaultOwinStartup" xdt:Locator="Match(key)" xdt:Transform="InsertIfMissing" />
|
||||
</appSettings>
|
||||
|
||||
<umbracoConfiguration xdt:Transform="InsertIfMissing">
|
||||
@@ -37,8 +38,10 @@
|
||||
<DbProviderFactories xdt:Transform="InsertIfMissing">
|
||||
<remove invariant="System.Data.SqlServerCe.4.0" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
|
||||
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(invariant,description,type)" />
|
||||
<remove invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(invariant,description,type)" />
|
||||
<remove invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
|
||||
<add invariant="MySql.Data.MySqlClient" xdt:Locator="Match(invariant)" xdt:Transform="Remove" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="InsertIfMissing" />
|
||||
<add invariant="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" xdt:Locator="Match(invariant)" xdt:Transform="SetAttributes(type)" />
|
||||
</DbProviderFactories>
|
||||
</system.data>
|
||||
<clientDependency xdt:Transform="RemoveAttributes(version)" />
|
||||
@@ -141,6 +144,7 @@
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Newtonsoft.Json')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Web.Mvc')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Web.Htttp')" xdt:Transform="Remove" />
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -158,6 +162,10 @@
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ if ($project) {
|
||||
if(Test-Path $umbracoBinFolder\interfaces.dll) { Remove-Item $umbracoBinFolder\interfaces.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\log4net.dll) { Remove-Item $umbracoBinFolder\log4net.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll) { Remove-Item $umbracoBinFolder\Microsoft.ApplicationBlocks.Data.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Microsoft.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\Microsoft.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\SQLCE4Umbraco.dll) { Remove-Item $umbracoBinFolder\SQLCE4Umbraco.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll) { Remove-Item $umbracoBinFolder\System.Data.SqlServerCe.Entity.dll -Force -Confirm:$false }
|
||||
@@ -64,7 +63,6 @@ if ($project) {
|
||||
if(Test-Path $umbracoBinFolder\MySql.Data.dll) { Remove-Item $umbracoBinFolder\MySql.Data.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Newtonsoft.Json.dll) { Remove-Item $umbracoBinFolder\Newtonsoft.Json.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Net.Http.Formatting.dll) { Remove-Item $umbracoBinFolder\System.Net.Http.Formatting.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Helpers.dll) { Remove-Item $umbracoBinFolder\System.Web.Helpers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Http.WebHost.dll) { Remove-Item $umbracoBinFolder\System.Web.Http.WebHost.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\System.Web.Mvc.dll) { Remove-Item $umbracoBinFolder\System.Web.Mvc.dll -Force -Confirm:$false }
|
||||
|
||||
@@ -47,108 +47,46 @@ if ($project) {
|
||||
robocopy $umbracoClientFolder $umbracoClientBackupPath /e /LOG:$copyLogsPath\UmbracoClientBackup.log
|
||||
robocopy $umbracoClientFolderSource $umbracoClientFolder /is /it /e /LOG:$copyLogsPath\UmbracoClientCopy.log
|
||||
}
|
||||
|
||||
$copyWebconfig = $false
|
||||
try
|
||||
{
|
||||
# SJ - What can I say: big up for James Newton King for teaching us a hack for detecting if this is a new install vs. an upgrade!
|
||||
# https://github.com/JamesNK/Newtonsoft.Json/pull/387 - would never have seen this without the controversial pull request..
|
||||
$dte2 = Get-Interface $dte ([EnvDTE80.DTE2])
|
||||
|
||||
if ($dte2.ActiveWindow.Caption -eq "Package Manager Console")
|
||||
{
|
||||
# user is installing from VS NuGet console
|
||||
# get reference to the window, the console host and the input history
|
||||
# copy web.config if "install-package UmbracoCms" was last input
|
||||
|
||||
$consoleWindow = $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow])
|
||||
|
||||
$props = $consoleWindow.GetType().GetProperties([System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
|
||||
$prop = $props | ? { $_.Name -eq "ActiveHostInfo" } | select -first 1
|
||||
if ($prop -eq $null) { return }
|
||||
|
||||
$hostInfo = $prop.GetValue($consoleWindow)
|
||||
if ($hostInfo -eq $null) { return }
|
||||
|
||||
$history = $hostInfo.WpfConsole.InputHistory.History
|
||||
|
||||
$lastCommand = $history | select -last 1
|
||||
|
||||
if ($lastCommand)
|
||||
{
|
||||
$lastCommand = $lastCommand.Trim().ToLower()
|
||||
if ($lastCommand.StartsWith("install-package") -and $lastCommand.Contains("umbracocms"))
|
||||
{
|
||||
$copyWebconfig = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# user is installing from VS NuGet dialog
|
||||
# get reference to the window, then smart output console provider
|
||||
# copy web.config if messages in buffered console contains "installing...UmbracoCms" in last operation
|
||||
|
||||
$instanceField = [NuGet.Dialog.PackageManagerWindow].GetField("CurrentInstance", [System.Reflection.BindingFlags]::Static -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
$consoleField = [NuGet.Dialog.PackageManagerWindow].GetField("_smartOutputConsoleProvider", [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($instanceField -eq $null -or $consoleField -eq $null) { return }
|
||||
|
||||
$instance = $instanceField.GetValue($null)
|
||||
if ($instance -eq $null) { return }
|
||||
|
||||
$consoleProvider = $consoleField.GetValue($instance)
|
||||
if ($consoleProvider -eq $null) { return }
|
||||
|
||||
$console = $consoleProvider.CreateOutputConsole($false)
|
||||
|
||||
$messagesField = $console.GetType().GetField("_messages", [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::NonPublic)
|
||||
if ($messagesField -eq $null) { return }
|
||||
|
||||
$messages = $messagesField.GetValue($console)
|
||||
if ($messages -eq $null) { return }
|
||||
|
||||
$operations = $messages -split "=============================="
|
||||
|
||||
$lastOperation = $operations | select -last 1
|
||||
|
||||
if ($lastOperation)
|
||||
{
|
||||
$lastOperation = $lastOperation.ToLower()
|
||||
|
||||
$lines = $lastOperation -split "`r`n"
|
||||
|
||||
$installMatch = $lines | ? { $_.StartsWith("------- installing...umbracocms ") } | select -first 1
|
||||
|
||||
if ($installMatch)
|
||||
{
|
||||
$copyWebconfig = $true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
# stop potential errors from bubbling up
|
||||
$ErrorMessage = $_.Exception.Message
|
||||
$FailedItem = $_.Exception.ItemName
|
||||
$installLogFile = Join-Path $projectDestinationPath "NuGetInstallError.log"
|
||||
$text = "Error occurred: " + $ErrorMessage + " failure: " + $FailedItem
|
||||
$text | Out-File $installLogFile
|
||||
}
|
||||
|
||||
$copyWebconfig = $true
|
||||
$destinationWebConfig = Join-Path $projectDestinationPath "Web.config"
|
||||
|
||||
if(Test-Path $destinationWebConfig)
|
||||
{
|
||||
Try
|
||||
{
|
||||
[xml]$config = Get-Content $destinationWebConfig
|
||||
|
||||
$config.configuration.appSettings.ChildNodes | ForEach-Object {
|
||||
if($_.key -eq "umbracoConfigurationStatus")
|
||||
{
|
||||
# The web.config has an umbraco-specific appSetting in it
|
||||
# don't overwrite it and let config transforms do their thing
|
||||
$copyWebconfig = $false
|
||||
}
|
||||
}
|
||||
}
|
||||
Catch { }
|
||||
}
|
||||
|
||||
if($copyWebconfig -eq $true)
|
||||
{
|
||||
$packageWebConfigSource = Join-Path $rootPath "UmbracoFiles\Web.config"
|
||||
$destinationWebConfig = Join-Path $projectDestinationPath "Web.config"
|
||||
Copy-Item $packageWebConfigSource $destinationWebConfig -Force
|
||||
}
|
||||
}
|
||||
|
||||
$installFolder = Join-Path $projectDestinationPath "Install"
|
||||
if(Test-Path $installFolder) {
|
||||
Remove-Item $installFolder -Force -Recurse -Confirm:$false
|
||||
}
|
||||
|
||||
# Open readme.txt file
|
||||
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
|
||||
# Open appropriate readme
|
||||
if($copyWebconfig -eq $true)
|
||||
{
|
||||
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
|
||||
}
|
||||
else
|
||||
{
|
||||
$DTE.ItemOperations.OpenFile($toolsPath + '\ReadmeUpgrade.txt')
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
||||
7.2.0
|
||||
7.3.0
|
||||
beta
|
||||
@@ -1,13 +0,0 @@
|
||||
Umbraco CMS version 4.5 is licensed under the OSI approved MIT License:
|
||||
|
||||
Copyright (c) 2007-2010 umbraco I/S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Umbraco versions prior to 4.5 were licensed under a combination of MIT and a propriatary UI license. The license history can be found here:
|
||||
http://umbraco.codeplex.com/license
|
||||
@@ -1,33 +0,0 @@
|
||||
Umbraco - the simple, flexible and friendly ASP.NET CMS
|
||||
=======================================================
|
||||
For the first time on the Microsoft platform a free user and developer friendly cms that makes it quick and easy to create websites - or a breeze to build complex web applications. umbraco got award-winning integration capabilities and supports your ASP.NET User and Custom Controls out of the box. It's a developers dream and your users will love it too. Used by more than 57.000 active websites including Heinz.com, Peugeot.com, NAIAS.com and Microsofts documentinteropinitiative.org website you can be sure that the technology is proven, stable and scales.
|
||||
|
||||
More info at http://umbraco.com
|
||||
|
||||
Exploring the repository
|
||||
========================
|
||||
Most contributors will work on their own fork and should pick the branch in which they need their fix. For more information see:
|
||||
http://our.umbraco.org/contribute/guidelines-for-core-contribution
|
||||
|
||||
Exploring the source
|
||||
====================
|
||||
The Umbraco source code is never required for you to start building sites. If you are not using the source code for debugging purposes or to contribute to the source then please download the binaries listed at http://umbraco.codeplex.com
|
||||
|
||||
With that said, the Umbraco solution can be opened in Visual Studio 2010 with SP1 installed or Visual Studio 2012.
|
||||
|
||||
Contributing
|
||||
============
|
||||
Umbraco is Open Source which means you can contribute to make it great!
|
||||
Read all about it at http://our.umbraco.org/contribute
|
||||
|
||||
Forums
|
||||
======
|
||||
We have a forum running on http://our.umbraco.org for friendly community support.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
Our documentation section provides help on installing and using Umbraco including API reference documentation: http://our.umbraco.org/documentation
|
||||
|
||||
Submitting Issues
|
||||
=================
|
||||
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our online guide at http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature
|
||||
Binary file not shown.
@@ -77,8 +77,9 @@
|
||||
<Compile Include="SqlCEUtility.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="app.config" />
|
||||
<None Include="app.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -14,6 +14,22 @@
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
+6
-3
@@ -1,8 +1,8 @@
|
||||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
|
||||
[assembly: AssemblyCompany("umbraco")]
|
||||
[assembly: AssemblyCopyright("Copyright © Umbraco 2012")]
|
||||
[assembly: AssemblyCompany("Umbraco")]
|
||||
[assembly: AssemblyCopyright("Copyright © Umbraco 2015")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@@ -10,3 +10,6 @@ using System.Resources;
|
||||
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.3.0")]
|
||||
[assembly: AssemblyInformationalVersion("7.3.0-beta")]
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
@@ -12,13 +13,14 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
internal sealed class ActionsResolver : LazyManyObjectsResolverBase<ActionsResolver, IAction>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="packageActions"></param>
|
||||
internal ActionsResolver(Func<IEnumerable<Type>> packageActions)
|
||||
: base(packageActions)
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="packageActions"></param>
|
||||
internal ActionsResolver(IServiceProvider serviceProvider, ILogger logger, Func<IEnumerable<Type>> packageActions)
|
||||
: base(serviceProvider, logger, packageActions)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -55,7 +57,7 @@ namespace Umbraco.Core
|
||||
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);
|
||||
typeInstance = ServiceProvider.GetService(type) as IAction;
|
||||
else
|
||||
typeInstance = instance.GetValue(null, null) as IAction;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Helper methods for Activation
|
||||
/// </summary>
|
||||
internal static class ActivatorHelper
|
||||
@@ -14,7 +12,9 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
public static T CreateInstance<T>() where T : class, new()
|
||||
{
|
||||
return Activator.CreateInstance(typeof(T)) as T;
|
||||
return new ActivatorServiceProvider().GetService(typeof (T)) as T;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal class ActivatorServiceProvider : IServiceProvider
|
||||
{
|
||||
public object GetService(Type serviceType)
|
||||
{
|
||||
return Activator.CreateInstance(serviceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
|
||||
@@ -21,21 +22,35 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
public class ApplicationContext : IDisposable
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <param name="cache"></param>
|
||||
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
|
||||
{
|
||||
/// <param name="logger"></param>
|
||||
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger)
|
||||
{
|
||||
if (dbContext == null) throw new ArgumentNullException("dbContext");
|
||||
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
|
||||
if (cache == null) throw new ArgumentNullException("cache");
|
||||
_databaseContext = dbContext;
|
||||
_services = serviceContext;
|
||||
ApplicationCache = cache;
|
||||
ProfilingLogger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <param name="cache"></param>
|
||||
[Obsolete("Use the other constructor specifying an ILogger instead")]
|
||||
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
|
||||
: this(dbContext, serviceContext, cache,
|
||||
new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -83,6 +98,7 @@ namespace Umbraco.Core
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
[Obsolete("Use the other method specifying an ProfilingLogger instead")]
|
||||
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, bool replaceContext)
|
||||
{
|
||||
if (ApplicationContext.Current != null)
|
||||
@@ -95,6 +111,33 @@ namespace Umbraco.Core
|
||||
return ApplicationContext.Current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method used to create and ensure that a global ApplicationContext singleton is created.
|
||||
/// </summary>
|
||||
/// <param name="cache"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="replaceContext">
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// startup if for some reason the boot manager is not the umbraco boot manager.
|
||||
/// </param>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger, bool replaceContext)
|
||||
{
|
||||
if (ApplicationContext.Current != null)
|
||||
{
|
||||
if (!replaceContext)
|
||||
return ApplicationContext.Current;
|
||||
}
|
||||
var ctx = new ApplicationContext(dbContext, serviceContext, cache, logger);
|
||||
ApplicationContext.Current = ctx;
|
||||
return ApplicationContext.Current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
@@ -108,7 +151,13 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
public CacheHelper ApplicationCache { get; private set; }
|
||||
|
||||
// IsReady is set to true by the boot manager once it has successfully booted
|
||||
/// <summary>
|
||||
/// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
|
||||
/// on most base classes or injected with IoC
|
||||
/// </summary>
|
||||
public ProfilingLogger ProfilingLogger { 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;
|
||||
@@ -153,6 +202,25 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If the db is configured, there is a database context and there is an umbraco schema, but we are not 'configured' , then it means we are upgrading
|
||||
/// </summary>
|
||||
public bool IsUpgrading
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsConfigured == false
|
||||
&& DatabaseContext != null
|
||||
&& DatabaseContext.IsDatabaseConfigured)
|
||||
{
|
||||
var schemaresult = DatabaseContext.ValidateDatabaseSchema();
|
||||
if (schemaresult.ValidTables.Count > 0) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The original/first url that the web application executes
|
||||
/// </summary>
|
||||
@@ -165,6 +233,8 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
internal string OriginalRequestUrl { get; set; }
|
||||
|
||||
private bool _versionsDifferenceReported;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the version configured matches the assembly version
|
||||
/// </summary>
|
||||
@@ -174,17 +244,19 @@ namespace Umbraco.Core
|
||||
{
|
||||
try
|
||||
{
|
||||
string configStatus = ConfigurationStatus;
|
||||
string currentVersion = UmbracoVersion.Current.ToString(3);
|
||||
var configStatus = ConfigurationStatus;
|
||||
var currentVersion = UmbracoVersion.Current.ToString(3);
|
||||
var ok = configStatus == currentVersion;
|
||||
|
||||
|
||||
if (currentVersion != configStatus)
|
||||
if (ok == false && _versionsDifferenceReported == false)
|
||||
{
|
||||
LogHelper.Info<ApplicationContext>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
|
||||
// remember it's been reported so we don't flood the log
|
||||
// no thread-safety so there may be a few log entries, doesn't matter
|
||||
_versionsDifferenceReported = true;
|
||||
ProfilingLogger.Logger.Debug<ApplicationContext>("CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'");
|
||||
}
|
||||
|
||||
|
||||
return (configStatus == currentVersion);
|
||||
return ok;
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -289,7 +361,7 @@ namespace Umbraco.Core
|
||||
this.ApplicationCache = null;
|
||||
if (_databaseContext != null) //need to check the internal field here
|
||||
{
|
||||
if (DatabaseContext.IsDatabaseConfigured)
|
||||
if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.Database != null)
|
||||
{
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
using System;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
// http://blogs.msdn.com/b/pfxteam/archive/2012/02/12/10266988.aspx
|
||||
//
|
||||
// notes:
|
||||
// - this is NOT a reader/writer lock
|
||||
// - this is NOT a recursive lock
|
||||
//
|
||||
// using a named Semaphore here and not a Mutex because mutexes have thread
|
||||
// affinity which does not work with async situations
|
||||
//
|
||||
// it is important that managed code properly release the Semaphore before
|
||||
// going down else it will maintain the lock - however note that when the
|
||||
// whole process (w3wp.exe) goes down and all handles to the Semaphore have
|
||||
// been closed, the Semaphore system object is destroyed - so in any case
|
||||
// an iisreset should clean up everything
|
||||
//
|
||||
internal class AsyncLock
|
||||
{
|
||||
private readonly SemaphoreSlim _semaphore;
|
||||
private readonly Semaphore _semaphore2;
|
||||
private readonly IDisposable _releaser;
|
||||
private readonly Task<IDisposable> _releaserTask;
|
||||
|
||||
public AsyncLock()
|
||||
: this (null)
|
||||
{ }
|
||||
|
||||
public AsyncLock(string name)
|
||||
{
|
||||
// WaitOne() waits until count > 0 then decrements count
|
||||
// Release() increments count
|
||||
// initial count: the initial count value
|
||||
// maximum count: the max value of count, and then Release() throws
|
||||
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
// anonymous semaphore
|
||||
// use one unique releaser, that will not release the semaphore when finalized
|
||||
// because the semaphore is destroyed anyway if the app goes down
|
||||
|
||||
_semaphore = new SemaphoreSlim(1, 1); // create a local (to the app domain) semaphore
|
||||
_releaser = new SemaphoreSlimReleaser(_semaphore);
|
||||
_releaserTask = Task.FromResult(_releaser);
|
||||
}
|
||||
else
|
||||
{
|
||||
// named semaphore
|
||||
// use dedicated releasers, that will release the semaphore when finalized
|
||||
// because the semaphore is system-wide and we cannot leak counts
|
||||
|
||||
_semaphore2 = new Semaphore(1, 1, name); // create a system-wide named semaphore
|
||||
}
|
||||
}
|
||||
|
||||
private IDisposable CreateReleaser()
|
||||
{
|
||||
// for anonymous semaphore, use the unique releaser, else create a new one
|
||||
return _semaphore != null
|
||||
? _releaser // (IDisposable)new SemaphoreSlimReleaser(_semaphore)
|
||||
: (IDisposable)new NamedSemaphoreReleaser(_semaphore2);
|
||||
}
|
||||
|
||||
public Task<IDisposable> LockAsync()
|
||||
{
|
||||
var wait = _semaphore != null
|
||||
? _semaphore.WaitAsync()
|
||||
: WaitOneAsync(_semaphore2);
|
||||
|
||||
return wait.IsCompleted
|
||||
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
: wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
|
||||
this, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
public IDisposable Lock()
|
||||
{
|
||||
if (_semaphore != null)
|
||||
_semaphore.Wait();
|
||||
else
|
||||
_semaphore2.WaitOne();
|
||||
return _releaser ?? CreateReleaser(); // anonymous vs named
|
||||
}
|
||||
|
||||
public IDisposable Lock(int millisecondsTimeout)
|
||||
{
|
||||
var entered = _semaphore != null
|
||||
? _semaphore.Wait(millisecondsTimeout)
|
||||
: _semaphore2.WaitOne(millisecondsTimeout);
|
||||
if (entered == false)
|
||||
throw new TimeoutException("Failed to enter the lock within timeout.");
|
||||
return _releaser ?? CreateReleaser(); // anonymous vs named
|
||||
}
|
||||
|
||||
// note - before making those classes some structs, read
|
||||
// about "impure methods" and mutating readonly structs...
|
||||
|
||||
private class NamedSemaphoreReleaser : CriticalFinalizerObject, IDisposable
|
||||
{
|
||||
private readonly Semaphore _semaphore;
|
||||
|
||||
internal NamedSemaphoreReleaser(Semaphore semaphore)
|
||||
{
|
||||
_semaphore = semaphore;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
// critical
|
||||
_semaphore.Release();
|
||||
}
|
||||
|
||||
// we WANT to release the semaphore because it's a system object
|
||||
// ie a critical non-managed resource - so we inherit from CriticalFinalizerObject
|
||||
// which means that the finalizer "should" run in all situations
|
||||
|
||||
// however... that can fail with System.ObjectDisposedException because the
|
||||
// underlying handle was closed... because we cannot guarantee that the semaphore
|
||||
// is not gone already... unless we get a GCHandle = GCHandle.Alloc(_semaphore);
|
||||
// which should keep it around and then we free the handle?
|
||||
|
||||
// so... I'm not sure this is safe really...
|
||||
|
||||
~NamedSemaphoreReleaser()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
|
||||
private class SemaphoreSlimReleaser : IDisposable
|
||||
{
|
||||
private readonly SemaphoreSlim _semaphore;
|
||||
|
||||
internal SemaphoreSlimReleaser(SemaphoreSlim semaphore)
|
||||
{
|
||||
_semaphore = semaphore;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// normal
|
||||
_semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
~SemaphoreSlimReleaser()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
|
||||
// http://stackoverflow.com/questions/25382583/waiting-on-a-named-semaphore-with-waitone100-vs-waitone0-task-delay100
|
||||
// http://blog.nerdbank.net/2011/07/c-await-for-waithandle.html
|
||||
// F# has a AwaitWaitHandle method that accepts a time out... and seems pretty complex...
|
||||
// version below should be OK
|
||||
|
||||
private static Task WaitOneAsync(WaitHandle handle)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
var callbackHandleInitLock = new object();
|
||||
lock (callbackHandleInitLock)
|
||||
{
|
||||
RegisteredWaitHandle callbackHandle = null;
|
||||
// ReSharper disable once RedundantAssignment
|
||||
callbackHandle = ThreadPool.RegisterWaitForSingleObject(
|
||||
handle,
|
||||
(state, timedOut) =>
|
||||
{
|
||||
tcs.SetResult(null);
|
||||
|
||||
// we take a lock here to make sure the outer method has completed setting the local variable callbackHandle.
|
||||
lock (callbackHandleInitLock)
|
||||
{
|
||||
// ReSharper disable once PossibleNullReferenceException
|
||||
// ReSharper disable once AccessToModifiedClosure
|
||||
callbackHandle.Unregister(null);
|
||||
}
|
||||
},
|
||||
/*state:*/ null,
|
||||
/*millisecondsTimeOutInterval:*/ Timeout.Infinite,
|
||||
/*executeOnlyOnce:*/ true);
|
||||
}
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,17 @@
|
||||
namespace Umbraco.Core.Auditing
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core.Auditing
|
||||
{
|
||||
/// <summary>
|
||||
/// Public method to create new audit trail
|
||||
/// </summary>
|
||||
[Obsolete("Use Umbraco.Core.Services.IAuditService instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class Audit
|
||||
{
|
||||
public static void Add(AuditTypes type, string comment, int userId, int objectId)
|
||||
public static void Add(Umbraco.Core.Auditing.AuditTypes type, string comment, int userId, int objectId)
|
||||
{
|
||||
AuditTrail.Current.AddEntry(type, comment, userId, objectId);
|
||||
ApplicationContext.Current.Services.AuditService.Add(
|
||||
Enum<Umbraco.Core.Models.AuditType>.Parse(type.ToString()),
|
||||
comment, userId, objectId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Auditing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Audit implementation
|
||||
/// </summary>
|
||||
internal class AuditTrail
|
||||
{
|
||||
#region Singleton
|
||||
|
||||
private static readonly Lazy<AuditTrail> lazy = new Lazy<AuditTrail>(() => new AuditTrail());
|
||||
|
||||
public static AuditTrail Current { get { return lazy.Value; } }
|
||||
|
||||
private AuditTrail()
|
||||
{
|
||||
WriteProvider = new DataAuditWriteProvider();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private IAuditWriteProvider WriteProvider { get; set; }
|
||||
|
||||
public void AddEntry(AuditTypes type, string comment, int userId, int objectId)
|
||||
{
|
||||
WriteProvider.WriteEntry(objectId, userId, DateTime.Now, type.ToString(), comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
namespace Umbraco.Core.Auditing
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core.Auditing
|
||||
{
|
||||
/// <summary>
|
||||
/// Enums for vailable types of auditing
|
||||
/// </summary>
|
||||
[Obsolete("Use Umbraco.Core.Models.AuditType instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public enum AuditTypes
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
|
||||
namespace Umbraco.Core.Auditing
|
||||
{
|
||||
internal class DataAuditWriteProvider : IAuditWriteProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes an audit entry to the underlaying datastore.
|
||||
/// </summary>
|
||||
/// <param name="objectId">Id of the object (Content, ContentType, Media, etc.)</param>
|
||||
/// <param name="userId">Id of the user</param>
|
||||
/// <param name="date">Datestamp</param>
|
||||
/// <param name="header">Audit header</param>
|
||||
/// <param name="comment">Audit comment</param>
|
||||
public void WriteEntry(int objectId, int userId, DateTime date, string header, string comment)
|
||||
{
|
||||
ApplicationContext.Current.DatabaseContext.Database.Insert(new LogDto
|
||||
{
|
||||
Comment = comment,
|
||||
Datestamp = date,
|
||||
Header = header,
|
||||
NodeId = objectId,
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Auditing
|
||||
{
|
||||
internal interface IAuditWriteProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Writes an audit entry to the underlaying datastore.
|
||||
/// </summary>
|
||||
/// <param name="objectId">Id of the object (Content, ContentType, Media, etc.)</param>
|
||||
/// <param name="userId">Id of the user</param>
|
||||
/// <param name="date">Datestamp</param>
|
||||
/// <param name="header">Audit header</param>
|
||||
/// <param name="comment">Audit comment</param>
|
||||
void WriteEntry(int objectId, int userId, DateTime date, string header, string comment);
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,8 @@ namespace Umbraco.Core.Cache
|
||||
public const string MemberBusinessLogicCacheKey = "MemberCacheItem_";
|
||||
|
||||
public const string TemplateFrontEndCacheKey = "template";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
|
||||
|
||||
public const string UserContextCacheKey = "UmbracoUserContext";
|
||||
@@ -45,14 +47,21 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string LanguageCacheKey = "UmbracoLanguageCache";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string DomainCacheKey = "UmbracoDomainList";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string StylesheetCacheKey = "UmbracoStylesheet";
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
|
||||
|
||||
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
|
||||
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
|
||||
|
||||
public const string IdToKeyCacheKey = "UI2K";
|
||||
public const string KeyToIdCacheKey = "UK2I";
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Cache
|
||||
/// <summary>
|
||||
/// Extensions for strongly typed access
|
||||
/// </summary>
|
||||
internal static class CacheProviderExtensions
|
||||
public static class CacheProviderExtensions
|
||||
{
|
||||
public static T GetCacheItem<T>(this IRuntimeCacheProvider provider,
|
||||
string cacheKey,
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Cache
|
||||
protected const string CacheItemPrefix = "umbrtmche";
|
||||
|
||||
// an object that represent a value that has not been created yet
|
||||
protected readonly object ValueNotCreated = new object();
|
||||
protected internal static readonly object ValueNotCreated = new object();
|
||||
|
||||
// manupulate the underlying cache entries
|
||||
// these *must* be called from within the appropriate locks
|
||||
@@ -30,21 +30,58 @@ namespace Umbraco.Core.Cache
|
||||
return string.Format("{0}-{1}", CacheItemPrefix, key);
|
||||
}
|
||||
|
||||
protected object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
|
||||
protected internal static Lazy<object> GetSafeLazy(Func<object> getCacheItem)
|
||||
{
|
||||
// try to generate the value and if it fails,
|
||||
// wrap in an ExceptionHolder - would be much simpler
|
||||
// to just use lazy.IsValueFaulted alas that field is
|
||||
// internal
|
||||
return new Lazy<object>(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new ExceptionHolder(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected internal static object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
|
||||
{
|
||||
// if onlyIfValueIsCreated, do not trigger value creation
|
||||
// must return something, though, to differenciate from null values
|
||||
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
|
||||
|
||||
// if execution has thrown then lazy.IsValueCreated is false
|
||||
// and lazy.IsValueFaulted is true (but internal) so we use our
|
||||
// own exception holder (see Lazy<T> source code) to return null
|
||||
if (lazy.Value is ExceptionHolder) return null;
|
||||
|
||||
// we have a value and execution has not thrown so returning
|
||||
// here does not throw - unless we're re-entering, take care of it
|
||||
try
|
||||
{
|
||||
// if onlyIfValueIsCreated, do not trigger value creation
|
||||
// must return something, though, to differenciate from null values
|
||||
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
|
||||
return lazy.Value;
|
||||
}
|
||||
catch
|
||||
catch (InvalidOperationException e)
|
||||
{
|
||||
return null;
|
||||
throw new InvalidOperationException("The method that computes a value for the cache has tried to read that value from the cache.", e);
|
||||
}
|
||||
}
|
||||
|
||||
internal class ExceptionHolder
|
||||
{
|
||||
public ExceptionHolder(Exception e)
|
||||
{
|
||||
Exception = e;
|
||||
}
|
||||
|
||||
public Exception Exception { get; private set; }
|
||||
}
|
||||
|
||||
#region Clear
|
||||
|
||||
public virtual void ClearAllCache()
|
||||
@@ -68,6 +105,9 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public virtual void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
var type = TypeFinder.GetTypeByName(typeName);
|
||||
if (type == null) return;
|
||||
var isInterface = type.IsInterface;
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
@@ -77,7 +117,10 @@ namespace Umbraco.Core.Cache
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
return value == null || value.GetType().ToString().InvariantEquals(typeName);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (type.IsInstanceOfType(value)) : (value.GetType() == type));
|
||||
})
|
||||
.ToArray())
|
||||
RemoveEntry((string) entry.Key);
|
||||
@@ -87,6 +130,7 @@ namespace Umbraco.Core.Cache
|
||||
public virtual void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
using (WriteLock)
|
||||
{
|
||||
foreach (var entry in GetDictionaryEntries()
|
||||
@@ -97,7 +141,10 @@ namespace Umbraco.Core.Cache
|
||||
// compare on exact type, don't use "is"
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
return value == null || value.GetType() == typeOfT;
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (value is T) : (value.GetType() == typeOfT));
|
||||
})
|
||||
.ToArray())
|
||||
RemoveEntry((string) entry.Key);
|
||||
@@ -107,6 +154,7 @@ namespace Umbraco.Core.Cache
|
||||
public virtual void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate)
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
var plen = CacheItemPrefix.Length + 1;
|
||||
using (WriteLock)
|
||||
{
|
||||
@@ -119,9 +167,12 @@ namespace Umbraco.Core.Cache
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
if (value == null) return true;
|
||||
return value.GetType() == typeOfT
|
||||
// run predicate on the 'public key' part only, ie without prefix
|
||||
&& predicate(((string)x.Key).Substring(plen), (T)value);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return (isInterface ? (value is T) : (value.GetType() == typeOfT))
|
||||
// run predicate on the 'public key' part only, ie without prefix
|
||||
&& predicate(((string) x.Key).Substring(plen), (T) value);
|
||||
}))
|
||||
RemoveEntry((string) entry.Key);
|
||||
}
|
||||
|
||||
@@ -105,15 +105,22 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = new Lazy<object>(getCacheItem);
|
||||
result = GetSafeLazy(getCacheItem);
|
||||
ContextItems[cacheKey] = result;
|
||||
}
|
||||
}
|
||||
|
||||
// this may throw if getCacheItem throws, but this is the only place where
|
||||
// it would throw as everywhere else we use GetLazySaveValue() to hide exceptions
|
||||
// and pretend exceptions were never inserted into cache to begin with.
|
||||
return result.Value;
|
||||
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
|
||||
// exceptions (but try again and again) and silently eat them - however at
|
||||
// some point we have to report them - so need to re-throw here
|
||||
|
||||
// this does not throw anymore
|
||||
//return result.Value;
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
var eh = value as ExceptionHolder;
|
||||
if (eh != null) throw eh.Exception; // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -20,9 +20,15 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
private readonly System.Web.Caching.Cache _cache;
|
||||
|
||||
/// <summary>
|
||||
/// Used for debugging
|
||||
/// </summary>
|
||||
internal Guid InstanceId { get; private set; }
|
||||
|
||||
public HttpRuntimeCacheProvider(System.Web.Caching.Cache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
InstanceId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
protected override IEnumerable<DictionaryEntry> GetDictionaryEntries()
|
||||
@@ -129,19 +135,27 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = new Lazy<object>(getCacheItem);
|
||||
result = GetSafeLazy(getCacheItem);
|
||||
var absolute = isSliding ? System.Web.Caching.Cache.NoAbsoluteExpiration : (timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value));
|
||||
var sliding = isSliding == false ? System.Web.Caching.Cache.NoSlidingExpiration : (timeout ?? System.Web.Caching.Cache.NoSlidingExpiration);
|
||||
|
||||
lck.UpgradeToWriteLock();
|
||||
//NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update!
|
||||
_cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
// this may throw if getCacheItem throws, but this is the only place where
|
||||
// it would throw as everywhere else we use GetLazySaveValue() to hide exceptions
|
||||
// and pretend exceptions were never inserted into cache to begin with.
|
||||
return result.Value;
|
||||
// using GetSafeLazy and GetSafeLazyValue ensures that we don't cache
|
||||
// exceptions (but try again and again) and silently eat them - however at
|
||||
// some point we have to report them - so need to re-throw here
|
||||
|
||||
// this does not throw anymore
|
||||
//return result.Value;
|
||||
|
||||
value = result.Value; // will not throw (safe lazy)
|
||||
var eh = value as ExceptionHolder;
|
||||
if (eh != null) throw eh.Exception; // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem, TimeSpan? timeout, bool isSliding = false, CacheItemPriority priority = CacheItemPriority.Normal, CacheItemRemovedCallback removedCallback = null, string[] dependentFiles = null)
|
||||
@@ -173,7 +187,7 @@ namespace Umbraco.Core.Cache
|
||||
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
|
||||
// and make sure we don't store a null value.
|
||||
|
||||
var result = new Lazy<object>(getCacheItem);
|
||||
var result = GetSafeLazy(getCacheItem);
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
if (value == null) return; // do not store null values (backward compat)
|
||||
|
||||
@@ -184,6 +198,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
using (new WriteLock(_locker))
|
||||
{
|
||||
//NOTE: 'Insert' on System.Web.Caching.Cache actually does an add or update!
|
||||
_cache.Insert(cacheKey, result, dependency, absolute, sliding, priority, removedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,51 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
public interface ICacheProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// Removes all items from the cache.
|
||||
/// </summary>
|
||||
void ClearAllCache();
|
||||
|
||||
/// <summary>
|
||||
/// Removes an item from the cache, identified by its key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
void ClearCacheItem(string key);
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from the cache, of a specified type.
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the type to remove.</param>
|
||||
/// <remarks>
|
||||
/// <para>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</para>
|
||||
/// <para>Performs a case-sensitive search.</para>
|
||||
/// </remarks>
|
||||
void ClearCacheObjectTypes(string typeName);
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from the cache, of a specified type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items to remove.</typeparam>
|
||||
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</remarks>
|
||||
void ClearCacheObjectTypes<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Removes items from the cache, of a specified type, satisfying a predicate.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the items to remove.</typeparam>
|
||||
/// <param name="predicate">The predicate to satisfy.</param>
|
||||
/// <remarks>If the type is an interface, then all items of a type implementing that interface are
|
||||
/// removed. Otherwise, only items of that exact type are removed (items of type inheriting from
|
||||
/// the specified type are not removed).</remarks>
|
||||
void ClearCacheObjectTypes<T>(Func<string, T, bool> predicate);
|
||||
|
||||
void ClearCacheByKeySearch(string keyStartsWith);
|
||||
void ClearCacheByKeyExpression(string regexString);
|
||||
|
||||
IEnumerable<object> GetCacheItemsByKeySearch(string keyStartsWith);
|
||||
IEnumerable<object> GetCacheItemsByKeyExpression(string regexString);
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A cache refresher that supports refreshing cache based on a custom payload
|
||||
/// </summary>
|
||||
interface IPayloadCacheRefresher : IJsonCacheRefresher
|
||||
{
|
||||
/// <summary>
|
||||
/// Refreshes, clears, etc... any cache based on the information provided in the payload
|
||||
/// </summary>
|
||||
/// <param name="payload"></param>
|
||||
void Refresh(object payload);
|
||||
}
|
||||
}
|
||||
@@ -4,17 +4,16 @@ using umbraco.interfaces;
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for json cache refreshers that ensures the correct events are raised when
|
||||
/// cache refreshing occurs.
|
||||
/// Provides a base class for "json" cache refreshers.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
|
||||
public abstract class JsonCacheRefresherBase<TInstanceType> : CacheRefresherBase<TInstanceType>, IJsonCacheRefresher
|
||||
where TInstanceType : ICacheRefresher
|
||||
/// <typeparam name="TInstance">The actual cache refresher type.</typeparam>
|
||||
/// <remarks>Ensures that the correct events are raised when cache refreshing occurs.</remarks>
|
||||
public abstract class JsonCacheRefresherBase<TInstance> : CacheRefresherBase<TInstance>, IJsonCacheRefresher
|
||||
where TInstance : ICacheRefresher
|
||||
{
|
||||
|
||||
public virtual void Refresh(string jsonPayload)
|
||||
public virtual void Refresh(string json)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson));
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(json, MessageType.RefreshByJson));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Caching;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
@@ -16,30 +17,19 @@ namespace Umbraco.Core.Cache
|
||||
/// </summary>
|
||||
internal class ObjectCacheRuntimeCacheProvider : IRuntimeCacheProvider
|
||||
{
|
||||
|
||||
private readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
|
||||
internal ObjectCache MemoryCache;
|
||||
|
||||
// an object that represent a value that has not been created yet
|
||||
protected readonly object ValueNotCreated = new object();
|
||||
/// <summary>
|
||||
/// Used for debugging
|
||||
/// </summary>
|
||||
internal Guid InstanceId { get; private set; }
|
||||
|
||||
public ObjectCacheRuntimeCacheProvider()
|
||||
{
|
||||
MemoryCache = new MemoryCache("in-memory");
|
||||
}
|
||||
|
||||
protected object GetSafeLazyValue(Lazy<object> lazy, bool onlyIfValueIsCreated = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
// if onlyIfValueIsCreated, do not trigger value creation
|
||||
// must return something, though, to differenciate from null values
|
||||
if (onlyIfValueIsCreated && lazy.IsValueCreated == false) return ValueNotCreated;
|
||||
return lazy.Value;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
InstanceId = Guid.NewGuid();
|
||||
}
|
||||
|
||||
#region Clear
|
||||
@@ -64,6 +54,9 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public virtual void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
var type = TypeFinder.GetTypeByName(typeName);
|
||||
if (type == null) return;
|
||||
var isInterface = type.IsInterface;
|
||||
using (new WriteLock(_locker))
|
||||
{
|
||||
foreach (var key in MemoryCache
|
||||
@@ -72,8 +65,11 @@ namespace Umbraco.Core.Cache
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
return value == null || value.GetType().ToString().InvariantEquals(typeName);
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (type.IsInstanceOfType(value)) : (value.GetType() == type));
|
||||
})
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
@@ -86,14 +82,19 @@ namespace Umbraco.Core.Cache
|
||||
using (new WriteLock(_locker))
|
||||
{
|
||||
var typeOfT = typeof (T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x =>
|
||||
{
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
return value == null || value.GetType() == typeOfT;
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return value == null || (isInterface ? (value is T) : (value.GetType() == typeOfT));
|
||||
|
||||
})
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
@@ -106,16 +107,20 @@ namespace Umbraco.Core.Cache
|
||||
using (new WriteLock(_locker))
|
||||
{
|
||||
var typeOfT = typeof(T);
|
||||
var isInterface = typeOfT.IsInterface;
|
||||
foreach (var key in MemoryCache
|
||||
.Where(x =>
|
||||
{
|
||||
// x.Value is Lazy<object> and not null, its value may be null
|
||||
// remove null values as well, does not hurt
|
||||
// get non-created as NonCreatedValue & exceptions as null
|
||||
var value = GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
var value = DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value, true);
|
||||
if (value == null) return true;
|
||||
return value.GetType() == typeOfT
|
||||
&& predicate(x.Key, (T) value);
|
||||
|
||||
// if T is an interface remove anything that implements that interface
|
||||
// otherwise remove exact types (not inherited types)
|
||||
return (isInterface ? (value is T) : (value.GetType() == typeOfT))
|
||||
&& predicate(x.Key, (T)value);
|
||||
})
|
||||
.Select(x => x.Key)
|
||||
.ToArray()) // ToArray required to remove
|
||||
@@ -161,7 +166,7 @@ namespace Umbraco.Core.Cache
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
return entries
|
||||
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
@@ -176,7 +181,7 @@ namespace Umbraco.Core.Cache
|
||||
.ToArray(); // evaluate while locked
|
||||
}
|
||||
return entries
|
||||
.Select(x => GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Select(x => DictionaryCacheProviderBase.GetSafeLazyValue((Lazy<object>)x.Value)) // return exceptions as null
|
||||
.Where(x => x != null) // backward compat, don't store null values in the cache
|
||||
.ToList();
|
||||
}
|
||||
@@ -188,7 +193,7 @@ namespace Umbraco.Core.Cache
|
||||
{
|
||||
result = MemoryCache.Get(cacheKey) as Lazy<object>; // null if key not found
|
||||
}
|
||||
return result == null ? null : GetSafeLazyValue(result); // return exceptions as null
|
||||
return result == null ? null : DictionaryCacheProviderBase.GetSafeLazyValue(result); // return exceptions as null
|
||||
}
|
||||
|
||||
public object GetCacheItem(string cacheKey, Func<object> getCacheItem)
|
||||
@@ -205,17 +210,23 @@ namespace Umbraco.Core.Cache
|
||||
using (var lck = new UpgradeableReadLock(_locker))
|
||||
{
|
||||
result = MemoryCache.Get(cacheKey) as Lazy<object>;
|
||||
if (result == null || GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
if (result == null || DictionaryCacheProviderBase.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null
|
||||
{
|
||||
result = new Lazy<object>(getCacheItem);
|
||||
result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
|
||||
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
|
||||
|
||||
lck.UpgradeToWriteLock();
|
||||
//NOTE: This does an add or update
|
||||
MemoryCache.Set(cacheKey, result, policy);
|
||||
}
|
||||
}
|
||||
|
||||
return result.Value;
|
||||
//return result.Value;
|
||||
|
||||
var value = result.Value; // will not throw (safe lazy)
|
||||
var eh = value as DictionaryCacheProviderBase.ExceptionHolder;
|
||||
if (eh != null) throw eh.Exception; // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -227,11 +238,12 @@ namespace Umbraco.Core.Cache
|
||||
// NOTE - here also we must insert a Lazy<object> but we can evaluate it right now
|
||||
// and make sure we don't store a null value.
|
||||
|
||||
var result = new Lazy<object>(getCacheItem);
|
||||
var result = DictionaryCacheProviderBase.GetSafeLazy(getCacheItem);
|
||||
var value = result.Value; // force evaluation now
|
||||
if (value == null) return; // do not store null values (backward compat)
|
||||
|
||||
var policy = GetPolicy(timeout, isSliding, removedCallback, dependentFiles);
|
||||
//NOTE: This does an add or update
|
||||
MemoryCache.Set(cacheKey, result, policy);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for "payload" cache refreshers.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstance">The actual cache refresher type.</typeparam>
|
||||
/// <remarks>Ensures that the correct events are raised when cache refreshing occurs.</remarks>
|
||||
public abstract class PayloadCacheRefresherBase<TInstance> : JsonCacheRefresherBase<TInstance>, IPayloadCacheRefresher
|
||||
where TInstance : ICacheRefresher
|
||||
{
|
||||
protected abstract object Deserialize(string json);
|
||||
|
||||
public override void Refresh(string json)
|
||||
{
|
||||
var payload = Deserialize(json);
|
||||
Refresh(payload);
|
||||
}
|
||||
|
||||
public virtual void Refresh(object payload)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(payload, MessageType.RefreshByPayload));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
@@ -12,13 +13,14 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
internal sealed class CacheRefreshersResolver : LegacyTransientObjectsResolver<CacheRefreshersResolver, ICacheRefresher>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="refreshers"></param>
|
||||
internal CacheRefreshersResolver(Func<IEnumerable<Type>> refreshers)
|
||||
: base(refreshers)
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="refreshers"></param>
|
||||
internal CacheRefreshersResolver(IServiceProvider serviceProvider, ILogger logger, Func<IEnumerable<Type>> refreshers)
|
||||
: base(serviceProvider, logger, refreshers)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -8,10 +8,13 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
internal class ClientDependencyConfiguration
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly string _fileName;
|
||||
|
||||
public ClientDependencyConfiguration()
|
||||
public ClientDependencyConfiguration(ILogger logger)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
_logger = logger;
|
||||
_fileName = IOHelper.MapPath(string.Format("{0}/ClientDependency.config", SystemDirectories.Config));
|
||||
}
|
||||
|
||||
@@ -35,13 +38,13 @@ namespace Umbraco.Core.Configuration
|
||||
versionAttribute.SetValue(newVersion);
|
||||
clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting);
|
||||
|
||||
LogHelper.Info<ClientDependencyConfiguration>(string.Format("Updated version number from {0} to {1}", oldVersion, newVersion));
|
||||
_logger.Info<ClientDependencyConfiguration>(string.Format("Updated version number from {0} to {1}", oldVersion, newVersion));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogHelper.Error<ClientDependencyConfiguration>("Couldn't update ClientDependency version number", ex);
|
||||
_logger.Error<ClientDependencyConfiguration>("Couldn't update ClientDependency version number", ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something
|
||||
/// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco".
|
||||
/// </remarks>
|
||||
internal static string UmbracoMvcArea
|
||||
public static string UmbracoMvcArea
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
var converted = ObjectExtensions.TryConvertTo<T>(RawValue);
|
||||
var converted = RawValue.TryConvertTo<T>();
|
||||
if (converted.Success == false)
|
||||
throw new InvalidCastException("Could not convert value " + RawValue + " to type " + typeof(T));
|
||||
return converted.Result;
|
||||
|
||||
@@ -83,14 +83,20 @@ namespace Umbraco.Core.Configuration
|
||||
return _dashboardSection;
|
||||
}
|
||||
|
||||
//ONLY for unit testing
|
||||
/// <summary>
|
||||
/// Only for testing
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
internal void SetDashboardSettings(IDashboardSection value)
|
||||
{
|
||||
_dashboardSection = value;
|
||||
}
|
||||
|
||||
//ONLY for unit testing
|
||||
internal void SetUmbracoSettings(IUmbracoSettingsSection value)
|
||||
/// <summary>
|
||||
/// Only for testing
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetUmbracoSettings(IUmbracoSettingsSection value)
|
||||
{
|
||||
_umbracoSettings = value;
|
||||
}
|
||||
@@ -110,7 +116,10 @@ namespace Umbraco.Core.Configuration
|
||||
return _umbracoSettings;
|
||||
}
|
||||
|
||||
//ONLY for unit testing
|
||||
/// <summary>
|
||||
/// Only for testing
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetBaseRestExtensions(IBaseRestSection value)
|
||||
{
|
||||
_baseRestExtensions = value;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using System.Xml.Linq;
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
internal class ContentErrorPageElement : InnerTextConfigurationElement<int>, IContentErrorPage
|
||||
internal class ContentErrorPageElement : InnerTextConfigurationElement<string>, IContentErrorPage
|
||||
{
|
||||
public ContentErrorPageElement(XElement rawXml)
|
||||
: base(rawXml)
|
||||
@@ -14,7 +15,43 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
}
|
||||
|
||||
public bool HasContentId
|
||||
{
|
||||
get { return ContentId != int.MinValue; }
|
||||
}
|
||||
|
||||
public bool HasContentKey
|
||||
{
|
||||
get { return ContentKey != Guid.Empty; }
|
||||
}
|
||||
|
||||
public int ContentId
|
||||
{
|
||||
get
|
||||
{
|
||||
int parsed;
|
||||
if (int.TryParse(Value, out parsed))
|
||||
{
|
||||
return parsed;
|
||||
}
|
||||
return int.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
public Guid ContentKey
|
||||
{
|
||||
get
|
||||
{
|
||||
Guid parsed;
|
||||
if (Guid.TryParse(Value, out parsed))
|
||||
{
|
||||
return parsed;
|
||||
}
|
||||
return Guid.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public string ContentXPath
|
||||
{
|
||||
get { return Value; }
|
||||
}
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
public interface IContentErrorPage
|
||||
{
|
||||
int ContentId { get; }
|
||||
Guid ContentKey { get; }
|
||||
string ContentXPath { get; }
|
||||
bool HasContentId { get; }
|
||||
bool HasContentKey { get; }
|
||||
string Culture { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
public interface ITemplatesSection : IUmbracoConfigurationSection
|
||||
{
|
||||
@@ -8,6 +10,7 @@
|
||||
|
||||
RenderingEngine DefaultRenderingEngine { get; }
|
||||
|
||||
[Obsolete("This has no affect and will be removed in future versions")]
|
||||
bool EnableTemplateFolders { get; }
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,10 @@
|
||||
|
||||
bool InternalRedirectPreservesTemplate { get; }
|
||||
|
||||
bool DisableAlternativeTemplates { get; }
|
||||
|
||||
bool DisableFindContentByIdPath { get; }
|
||||
|
||||
string UrlProviderMode { get; }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Configuration;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
@@ -40,6 +41,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("This has no affect and will be removed in future versions")]
|
||||
[ConfigurationProperty("enableTemplateFolders")]
|
||||
internal InnerTextConfigurationElement<bool> EnableTemplateFolders
|
||||
{
|
||||
@@ -67,6 +69,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return DefaultRenderingEngine; }
|
||||
}
|
||||
|
||||
[Obsolete("This has no affect and will be removed in future versions")]
|
||||
bool ITemplatesSection.EnableTemplateFolders
|
||||
{
|
||||
get { return EnableTemplateFolders; }
|
||||
|
||||
@@ -16,6 +16,17 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return (bool) base["internalRedirectPreservesTemplate"]; }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("disableAlternativeTemplates", DefaultValue = "false")]
|
||||
public bool DisableAlternativeTemplates
|
||||
{
|
||||
get { return (bool) base["disableAlternativeTemplates"]; }
|
||||
}
|
||||
[ConfigurationProperty("disableFindContentByIdPath", DefaultValue = "false")]
|
||||
public bool DisableFindContentByIdPath
|
||||
{
|
||||
get { return (bool) base["disableFindContentByIdPath"]; }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("urlProviderMode", DefaultValue = "AutoLegacy")]
|
||||
public string UrlProviderMode
|
||||
{
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.2.0");
|
||||
private static readonly Version Version = new Version("7.3.0");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return ""; } }
|
||||
public static string CurrentComment { get { return "beta"; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -78,12 +78,12 @@
|
||||
/// </summary>
|
||||
public const string Dictionary = "dictionary";
|
||||
|
||||
//TODO: Fill in the rest!
|
||||
public const string Stylesheets = "stylesheets";
|
||||
|
||||
/// <summary>
|
||||
/// alias for the media tree.
|
||||
/// alias for the template tree.
|
||||
/// </summary>
|
||||
public const string Templates = "template";
|
||||
public const string Templates = "templates";
|
||||
|
||||
public const string RelationTypes = "relationTypes";
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
|
||||
public const string Languages = "languages";
|
||||
|
||||
//TODO: Fill in the rest!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,25 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class Conventions
|
||||
{
|
||||
public static class PublicAccess
|
||||
{
|
||||
public const string MemberUsernameRuleType = "MemberUsername";
|
||||
public const string MemberRoleRuleType = "MemberRole";
|
||||
|
||||
[Obsolete("No longer supported, this is here for backwards compatibility only")]
|
||||
public const string MemberIdRuleType = "MemberId";
|
||||
[Obsolete("No longer supported, this is here for backwards compatibility only")]
|
||||
public const string MemberGroupIdRuleType = "MemberGroupId";
|
||||
}
|
||||
|
||||
public static class Localization
|
||||
{
|
||||
/// <summary>
|
||||
/// The root id for all top level dictionary items
|
||||
/// </summary>
|
||||
public const string DictionaryItemRootId = "41c7638d-f529-4bff-853e-59a0c2fb1bde";
|
||||
}
|
||||
|
||||
public static class DataTypes
|
||||
{
|
||||
public const string ListViewPrefix = "List View - ";
|
||||
@@ -192,73 +211,64 @@ namespace Umbraco.Core
|
||||
{
|
||||
{
|
||||
Comments,
|
||||
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext, true)
|
||||
new PropertyType(PropertyEditors.TextboxMultipleAlias, DataTypeDatabaseType.Ntext, true, Comments)
|
||||
{
|
||||
Alias = Comments,
|
||||
Name = CommentsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Integer, true)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Integer, true, FailedPasswordAttempts)
|
||||
{
|
||||
Alias = FailedPasswordAttempts,
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true, IsApproved)
|
||||
{
|
||||
Alias = IsApproved,
|
||||
Name = IsApprovedLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true)
|
||||
new PropertyType(PropertyEditors.TrueFalseAlias, DataTypeDatabaseType.Integer, true, IsLockedOut)
|
||||
{
|
||||
Alias = IsLockedOut,
|
||||
Name = IsLockedOutLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true, LastLockoutDate)
|
||||
{
|
||||
Alias = LastLockoutDate,
|
||||
Name = LastLockoutDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true, LastLoginDate)
|
||||
{
|
||||
Alias = LastLoginDate,
|
||||
Name = LastLoginDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Date, true, LastPasswordChangeDate)
|
||||
{
|
||||
Alias = LastPasswordChangeDate,
|
||||
Name = LastPasswordChangeDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true, PasswordAnswer)
|
||||
{
|
||||
Alias = PasswordAnswer,
|
||||
Name = PasswordAnswerLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true)
|
||||
new PropertyType(PropertyEditors.NoEditAlias, DataTypeDatabaseType.Nvarchar, true, PasswordQuestion)
|
||||
{
|
||||
Alias = PasswordQuestion,
|
||||
Name = PasswordQuestionLabel
|
||||
}
|
||||
}
|
||||
@@ -293,7 +303,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the alias identifiers for Umbraco relation types.
|
||||
/// Defines the alias identifiers for built-in Umbraco relation types.
|
||||
/// </summary>
|
||||
public static class RelationTypes
|
||||
{
|
||||
@@ -306,6 +316,16 @@ namespace Umbraco.Core
|
||||
/// ContentType alias for default relation type "Relate Document On Copy".
|
||||
/// </summary>
|
||||
public const string RelateDocumentOnCopyAlias = "relateDocumentOnCopy";
|
||||
|
||||
/// <summary>
|
||||
/// ContentType name for default relation type "Relate Parent Document On Delete".
|
||||
/// </summary>
|
||||
public const string RelateParentDocumentOnDeleteName = "Relate Parent Document On Delete";
|
||||
|
||||
/// <summary>
|
||||
/// ContentType alias for default relation type "Relate Parent Document On Delete".
|
||||
/// </summary>
|
||||
public const string RelateParentDocumentOnDeleteAlias = "relateParentDocumentOnDelete";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
@@ -70,7 +72,11 @@
|
||||
/// <summary>
|
||||
/// Guid for a Stylesheet object.
|
||||
/// </summary>
|
||||
public const string Stylesheet = "9F68DA4F-A3A8-44C2-8226-DCBD125E4840";
|
||||
[Obsolete("This no longer exists in the database")]
|
||||
public const string Stylesheet = "9F68DA4F-A3A8-44C2-8226-DCBD125E4840";
|
||||
|
||||
[Obsolete("This no longer exists in the database")]
|
||||
internal const string StylesheetProperty = "5555da4f-a123-42b2-4488-dcdfb25e4111";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the System Root.
|
||||
|
||||
@@ -18,5 +18,29 @@
|
||||
public const string AuthCookieName = "UMB_UCONTEXT";
|
||||
|
||||
}
|
||||
|
||||
public static class Security
|
||||
{
|
||||
|
||||
public const string BackOfficeAuthenticationType = "UmbracoBackOffice";
|
||||
public const string BackOfficeExternalAuthenticationType = "UmbracoExternalCookie";
|
||||
public const string BackOfficeExternalCookieName = "UMB_EXTLOGIN";
|
||||
public const string BackOfficeTokenAuthenticationType = "UmbracoBackOfficeToken";
|
||||
|
||||
/// <summary>
|
||||
/// The prefix used for external identity providers for their authentication type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default we don't want to interfere with front-end external providers and their default setup, for back office the
|
||||
/// providers need to be setup differently and each auth type for the back office will be prefixed with this value
|
||||
/// </remarks>
|
||||
public const string BackOfficeExternalAuthenticationTypePrefix = "Umbraco.";
|
||||
|
||||
public const string StartContentNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startcontentnode";
|
||||
public const string StartMediaNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startmedianode";
|
||||
public const string AllowedApplicationsClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/allowedapp";
|
||||
public const string SessionIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/sessionid";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+169
-116
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using AutoMapper;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Mapping;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
@@ -21,6 +23,7 @@ using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Macros;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Core.Strings;
|
||||
@@ -29,66 +32,90 @@ using MigrationsVersionFourNineZero = Umbraco.Core.Persistence.Migrations.Upgrad
|
||||
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>
|
||||
public class CoreBootManager : IBootManager
|
||||
{
|
||||
|
||||
private DisposableTimer _timer;
|
||||
private bool _isInitialized = false;
|
||||
private bool _isStarted = false;
|
||||
private bool _isComplete = false;
|
||||
/// 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>
|
||||
public class CoreBootManager : IBootManager
|
||||
{
|
||||
private ProfilingLogger _profilingLogger;
|
||||
private DisposableTimer _timer;
|
||||
private bool _isInitialized = false;
|
||||
private bool _isStarted = false;
|
||||
private bool _isComplete = false;
|
||||
private readonly IServiceProvider _serviceProvider = new ActivatorServiceProvider();
|
||||
private readonly UmbracoApplicationBase _umbracoApplication;
|
||||
protected ApplicationContext ApplicationContext { get; set; }
|
||||
protected ApplicationContext ApplicationContext { get; set; }
|
||||
protected CacheHelper ApplicationCache { get; set; }
|
||||
protected PluginManager PluginManager { get; private set; }
|
||||
|
||||
protected UmbracoApplicationBase UmbracoApplication
|
||||
{
|
||||
get { return _umbracoApplication; }
|
||||
}
|
||||
protected UmbracoApplicationBase UmbracoApplication
|
||||
{
|
||||
get { return _umbracoApplication; }
|
||||
}
|
||||
|
||||
public CoreBootManager(UmbracoApplicationBase umbracoApplication)
|
||||
{
|
||||
protected IServiceProvider ServiceProvider
|
||||
{
|
||||
get { return _serviceProvider; }
|
||||
}
|
||||
|
||||
public CoreBootManager(UmbracoApplicationBase umbracoApplication)
|
||||
{
|
||||
if (umbracoApplication == null) throw new ArgumentNullException("umbracoApplication");
|
||||
_umbracoApplication = umbracoApplication;
|
||||
}
|
||||
|
||||
public virtual IBootManager Initialize()
|
||||
{
|
||||
if (_isInitialized)
|
||||
throw new InvalidOperationException("The boot manager has already been initialized");
|
||||
public virtual IBootManager Initialize()
|
||||
{
|
||||
if (_isInitialized)
|
||||
throw new InvalidOperationException("The boot manager has already been initialized");
|
||||
|
||||
InitializeProfilerResolver();
|
||||
InitializeLoggerResolver();
|
||||
InitializeProfilerResolver();
|
||||
|
||||
_timer = DisposableTimer.DebugDuration<CoreBootManager>("Umbraco application starting", "Umbraco application startup complete");
|
||||
|
||||
CreateApplicationCache();
|
||||
_profilingLogger = new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler);
|
||||
|
||||
_timer = _profilingLogger.TraceDuration<CoreBootManager>("Umbraco application starting", "Umbraco application startup complete");
|
||||
|
||||
CreateApplicationCache();
|
||||
|
||||
//create and set the plugin manager (I'd much prefer to not use this singleton anymore but many things are using it unfortunately and
|
||||
// the way that it is setup, there must only ever be one per app so without IoC it would be hard to make this not a singleton)
|
||||
PluginManager = new PluginManager(ServiceProvider, ApplicationCache.RuntimeCache, _profilingLogger);
|
||||
PluginManager.Current = PluginManager;
|
||||
|
||||
//Create the legacy prop-eds mapping
|
||||
LegacyPropertyEditorIdToAliasConverter.CreateMappingsForCoreEditors();
|
||||
LegacyParameterEditorAliasConverter.CreateMappingsForCoreEditors();
|
||||
|
||||
//create database and service contexts for the app context
|
||||
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName);
|
||||
Database.Mapper = new PetaPocoMapper();
|
||||
var dbContext = new DatabaseContext(dbFactory);
|
||||
var serviceContext = new ServiceContext(
|
||||
new PetaPocoUnitOfWorkProvider(dbFactory),
|
||||
new FileUnitOfWorkProvider(),
|
||||
new PublishingStrategy(),
|
||||
ApplicationCache);
|
||||
//create database and service contexts for the app context
|
||||
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, LoggerResolver.Current.Logger);
|
||||
Database.Mapper = new PetaPocoMapper();
|
||||
|
||||
var dbContext = new DatabaseContext(
|
||||
dbFactory,
|
||||
LoggerResolver.Current.Logger,
|
||||
SqlSyntaxProviders.CreateDefault(LoggerResolver.Current.Logger));
|
||||
|
||||
//initialize the DatabaseContext
|
||||
dbContext.Initialize();
|
||||
|
||||
var serviceContext = new ServiceContext(
|
||||
new RepositoryFactory(ApplicationCache, LoggerResolver.Current.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
|
||||
new PetaPocoUnitOfWorkProvider(dbFactory),
|
||||
new FileUnitOfWorkProvider(),
|
||||
new PublishingStrategy(),
|
||||
ApplicationCache,
|
||||
LoggerResolver.Current.Logger);
|
||||
|
||||
CreateApplicationContext(dbContext, serviceContext);
|
||||
|
||||
InitializeApplicationEventsResolver();
|
||||
|
||||
InitializeResolvers();
|
||||
InitializeResolvers();
|
||||
|
||||
//initialize the DatabaseContext
|
||||
dbContext.Initialize();
|
||||
|
||||
|
||||
InitializeModelMappers();
|
||||
|
||||
@@ -96,10 +123,10 @@ namespace Umbraco.Core
|
||||
ApplicationEventsResolver.Current.ApplicationEventHandlers
|
||||
.ForEach(x => x.OnApplicationInitialized(UmbracoApplication, ApplicationContext));
|
||||
|
||||
_isInitialized = true;
|
||||
_isInitialized = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates and assigns the application context singleton
|
||||
@@ -109,7 +136,7 @@ namespace Umbraco.Core
|
||||
protected virtual void CreateApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
|
||||
{
|
||||
//create the ApplicationContext
|
||||
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext, ApplicationCache);
|
||||
ApplicationContext = ApplicationContext.Current = new ApplicationContext(dbContext, serviceContext, ApplicationCache, _profilingLogger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,7 +147,7 @@ namespace Umbraco.Core
|
||||
var cacheHelper = new CacheHelper(
|
||||
new ObjectCacheRuntimeCacheProvider(),
|
||||
new StaticCacheProvider(),
|
||||
//we have no request based cache when not running in web-based context
|
||||
//we have no request based cache when not running in web-based context
|
||||
new NullCacheProvider());
|
||||
|
||||
ApplicationCache = cacheHelper;
|
||||
@@ -144,18 +171,31 @@ namespace Umbraco.Core
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to initialize the LoggerResolver
|
||||
/// </summary>
|
||||
protected virtual void InitializeLoggerResolver()
|
||||
{
|
||||
LoggerResolver.Current = new LoggerResolver(Logger.CreateWithDefaultLog4NetConfiguration())
|
||||
{
|
||||
//This is another special resolver that needs to be resolvable before resolution is frozen
|
||||
//since it is used for profiling the application startup
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Special method to initialize the ProfilerResolver
|
||||
/// </summary>
|
||||
protected virtual void InitializeProfilerResolver()
|
||||
{
|
||||
//By default we'll initialize the Log profiler (in the web project, we'll override with the web profiler)
|
||||
ProfilerResolver.Current = new ProfilerResolver(new LogProfiler())
|
||||
{
|
||||
//This is another special resolver that needs to be resolvable before resolution is frozen
|
||||
//since it is used for profiling the application startup
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
ProfilerResolver.Current = new ProfilerResolver(new LogProfiler(LoggerResolver.Current.Logger))
|
||||
{
|
||||
//This is another special resolver that needs to be resolvable before resolution is frozen
|
||||
//since it is used for profiling the application startup
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -170,7 +210,9 @@ namespace Umbraco.Core
|
||||
//ApplicationStartupHandler.RegisterHandlers();
|
||||
//... and set the special flag to let us resolve before frozen resolution
|
||||
ApplicationEventsResolver.Current = new ApplicationEventsResolver(
|
||||
PluginManager.Current.ResolveApplicationStartupHandlers())
|
||||
ServiceProvider,
|
||||
LoggerResolver.Current.Logger,
|
||||
PluginManager.ResolveApplicationStartupHandlers())
|
||||
{
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
@@ -187,16 +229,16 @@ namespace Umbraco.Core
|
||||
Umbraco.Core.IO.IOHelper.SetRootDirectory(rootPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires after initialization and calls the callback to allow for customizations to occur &
|
||||
/// <summary>
|
||||
/// Fires after initialization and calls the callback to allow for customizations to occur &
|
||||
/// Ensure that the OnApplicationStarting methods of the IApplicationEvents are called
|
||||
/// </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");
|
||||
/// </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");
|
||||
|
||||
//call OnApplicationStarting of each application events handler
|
||||
ApplicationEventsResolver.Current.ApplicationEventHandlers
|
||||
@@ -207,23 +249,23 @@ namespace Umbraco.Core
|
||||
afterStartup(ApplicationContext.Current);
|
||||
}
|
||||
|
||||
_isStarted = true;
|
||||
_isStarted = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
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");
|
||||
/// <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");
|
||||
|
||||
FreezeResolution();
|
||||
|
||||
FreezeResolution();
|
||||
|
||||
//call OnApplicationStarting of each application events handler
|
||||
ApplicationEventsResolver.Current.ApplicationEventHandlers
|
||||
.ForEach(x => x.OnApplicationStarted(UmbracoApplication, ApplicationContext));
|
||||
@@ -236,15 +278,15 @@ namespace Umbraco.Core
|
||||
afterComplete(ApplicationContext.Current);
|
||||
}
|
||||
|
||||
_isComplete = true;
|
||||
_isComplete = true;
|
||||
|
||||
// we're ready to serve content!
|
||||
ApplicationContext.IsReady = true;
|
||||
|
||||
//stop the timer and log the output
|
||||
_timer.Dispose();
|
||||
return this;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Freeze resolution to not allow Resolvers to be modified
|
||||
@@ -253,17 +295,22 @@ namespace Umbraco.Core
|
||||
{
|
||||
Resolution.Freeze();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the resolvers
|
||||
/// </summary>
|
||||
protected virtual void InitializeResolvers()
|
||||
{
|
||||
PropertyEditorResolver.Current = new PropertyEditorResolver(() => PluginManager.Current.ResolvePropertyEditors());
|
||||
ParameterEditorResolver.Current = new ParameterEditorResolver(() => PluginManager.Current.ResolveParameterEditors());
|
||||
|
||||
/// <summary>
|
||||
/// Create the resolvers
|
||||
/// </summary>
|
||||
protected virtual void InitializeResolvers()
|
||||
{
|
||||
var builder = new ManifestBuilder(
|
||||
ApplicationCache.RuntimeCache,
|
||||
new ManifestParser(new DirectoryInfo(IOHelper.MapPath("~/App_Plugins")), ApplicationCache.RuntimeCache));
|
||||
|
||||
PropertyEditorResolver.Current = new PropertyEditorResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolvePropertyEditors(), builder);
|
||||
ParameterEditorResolver.Current = new ParameterEditorResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveParameterEditors(), builder);
|
||||
|
||||
//setup the validators resolver with our predefined validators
|
||||
ValidatorsResolver.Current = new ValidatorsResolver(new[]
|
||||
ValidatorsResolver.Current = new ValidatorsResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger, new[]
|
||||
{
|
||||
new Lazy<Type>(() => typeof (RequiredManifestValueValidator)),
|
||||
new Lazy<Type>(() => typeof (RegexValidator)),
|
||||
@@ -274,63 +321,69 @@ namespace Umbraco.Core
|
||||
|
||||
//by default we'll use the standard configuration based sync
|
||||
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
|
||||
new ConfigServerRegistrar());
|
||||
new ConfigServerRegistrar());
|
||||
|
||||
//by default (outside of the web) we'll use the default server messenger without
|
||||
//supplying a username/password, this will automatically disable distributed calls
|
||||
// .. we'll override this in the WebBootManager
|
||||
ServerMessengerResolver.Current = new ServerMessengerResolver(
|
||||
new DefaultServerMessenger());
|
||||
new WebServiceServerMessenger());
|
||||
|
||||
MappingResolver.Current = new MappingResolver(
|
||||
() => PluginManager.Current.ResolveAssignedMapperTypes());
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
() => PluginManager.ResolveAssignedMapperTypes());
|
||||
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory(ApplicationCache));
|
||||
|
||||
|
||||
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
|
||||
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
|
||||
{
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
//RepositoryResolver.Current = new RepositoryResolver(
|
||||
// new RepositoryFactory(ApplicationCache));
|
||||
|
||||
CacheRefreshersResolver.Current = new CacheRefreshersResolver(
|
||||
() => PluginManager.Current.ResolveCacheRefreshers());
|
||||
CacheRefreshersResolver.Current = new CacheRefreshersResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
() => PluginManager.ResolveCacheRefreshers());
|
||||
|
||||
DataTypesResolver.Current = new DataTypesResolver(
|
||||
() => PluginManager.Current.ResolveDataTypes());
|
||||
DataTypesResolver.Current = new DataTypesResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
() => PluginManager.ResolveDataTypes());
|
||||
|
||||
MacroFieldEditorsResolver.Current = new MacroFieldEditorsResolver(
|
||||
() => PluginManager.Current.ResolveMacroRenderings());
|
||||
MacroFieldEditorsResolver.Current = new MacroFieldEditorsResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
() => PluginManager.ResolveMacroRenderings());
|
||||
|
||||
PackageActionsResolver.Current = new PackageActionsResolver(
|
||||
() => PluginManager.Current.ResolvePackageActions());
|
||||
PackageActionsResolver.Current = new PackageActionsResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
() => PluginManager.ResolvePackageActions());
|
||||
|
||||
ActionsResolver.Current = new ActionsResolver(
|
||||
() => PluginManager.Current.ResolveActions());
|
||||
ActionsResolver.Current = new ActionsResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
() => PluginManager.ResolveActions());
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(
|
||||
() => PluginManager.Current.ResolveTypes<IMigration>());
|
||||
LoggerResolver.Current.Logger,
|
||||
() => PluginManager.ResolveTypes<IMigration>());
|
||||
|
||||
// todo: remove once we drop IPropertyEditorValueConverter support.
|
||||
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
|
||||
PluginManager.Current.ResolvePropertyEditorValueConverters());
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
PluginManager.ResolvePropertyEditorValueConverters());
|
||||
|
||||
// need to filter out the ones we dont want!!
|
||||
PropertyValueConvertersResolver.Current = new PropertyValueConvertersResolver(
|
||||
PluginManager.Current.ResolveTypes<IPropertyValueConverter>());
|
||||
// need to filter out the ones we dont want!!
|
||||
PropertyValueConvertersResolver.Current = new PropertyValueConvertersResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
PluginManager.ResolveTypes<IPropertyValueConverter>());
|
||||
|
||||
// use the new DefaultShortStringHelper
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
//new LegacyShortStringHelper());
|
||||
new DefaultShortStringHelper().WithDefaultConfig());
|
||||
|
||||
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
|
||||
typeof (DefaultUrlSegmentProvider));
|
||||
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
|
||||
ServiceProvider, LoggerResolver.Current.Logger,
|
||||
typeof(DefaultUrlSegmentProvider));
|
||||
|
||||
// by default, no factory is activated
|
||||
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver();
|
||||
}
|
||||
}
|
||||
PublishedContentModelFactoryResolver.Current = new PublishedContentModelFactoryResolver();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
@@ -11,12 +12,14 @@ namespace Umbraco.Core
|
||||
[Obsolete("IDataType is obsolete and is no longer used, it will be removed from the codebase in future versions")]
|
||||
internal sealed class DataTypesResolver : LegacyTransientObjectsResolver<DataTypesResolver, IDataType>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dataTypes"></param>
|
||||
internal DataTypesResolver(Func<IEnumerable<Type>> dataTypes)
|
||||
: base(dataTypes)
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="dataTypes"></param>
|
||||
internal DataTypesResolver(IServiceProvider serviceProvider, ILogger logger, Func<IEnumerable<Type>> dataTypes)
|
||||
: base(serviceProvider, logger, dataTypes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ namespace Umbraco.Core
|
||||
public class DatabaseContext
|
||||
{
|
||||
private readonly IDatabaseFactory _factory;
|
||||
private readonly ILogger _logger;
|
||||
private readonly SqlSyntaxProviders _syntaxProviders;
|
||||
private bool _configured;
|
||||
private bool _canConnect;
|
||||
private volatile bool _connectCheck = false;
|
||||
@@ -33,11 +35,53 @@ namespace Umbraco.Core
|
||||
private string _providerName;
|
||||
private DatabaseSchemaResult _result;
|
||||
|
||||
[Obsolete("Use the constructor specifying all dependencies instead")]
|
||||
public DatabaseContext(IDatabaseFactory factory)
|
||||
: this(factory, LoggerResolver.Current.Logger, new SqlSyntaxProviders(new ISqlSyntaxProvider[]
|
||||
{
|
||||
new MySqlSyntaxProvider(LoggerResolver.Current.Logger),
|
||||
new SqlCeSyntaxProvider(),
|
||||
new SqlServerSyntaxProvider()
|
||||
}))
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="syntaxProviders"></param>
|
||||
public DatabaseContext(IDatabaseFactory factory, ILogger logger, SqlSyntaxProviders syntaxProviders)
|
||||
{
|
||||
if (factory == null) throw new ArgumentNullException("factory");
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
if (syntaxProviders == null) throw new ArgumentNullException("syntaxProviders");
|
||||
|
||||
_factory = factory;
|
||||
_logger = logger;
|
||||
_syntaxProviders = syntaxProviders;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a configured DatabaseContext
|
||||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="sqlSyntax"></param>
|
||||
/// <param name="providerName"></param>
|
||||
public DatabaseContext(IDatabaseFactory factory, ILogger logger, ISqlSyntaxProvider sqlSyntax, string providerName)
|
||||
{
|
||||
_providerName = providerName;
|
||||
SqlSyntax = sqlSyntax;
|
||||
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
|
||||
_factory = factory;
|
||||
_logger = logger;
|
||||
_configured = true;
|
||||
}
|
||||
|
||||
public ISqlSyntaxProvider SqlSyntax { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="Database"/> object for doing CRUD operations
|
||||
/// against custom tables that resides in the Umbraco database.
|
||||
@@ -324,7 +368,7 @@ namespace Umbraco.Core
|
||||
|
||||
xml.Save(fileName, SaveOptions.DisableFormatting);
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Configured a new ConnectionString using the '" + providerName + "' provider.");
|
||||
_logger.Info<DatabaseContext>("Configured a new ConnectionString using the '" + providerName + "' provider.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -398,12 +442,23 @@ namespace Umbraco.Core
|
||||
|
||||
internal void Initialize(string providerName)
|
||||
{
|
||||
//only configure once!
|
||||
if (_configured == true) return;
|
||||
|
||||
_providerName = providerName;
|
||||
|
||||
try
|
||||
{
|
||||
SqlSyntaxContext.SqlSyntaxProvider =
|
||||
SqlSyntaxProvidersResolver.Current.GetByProviderNameOrDefault(providerName);
|
||||
if (_syntaxProviders != null)
|
||||
{
|
||||
SqlSyntax = _syntaxProviders.GetByProviderNameOrDefault(providerName);
|
||||
}
|
||||
else if (SqlSyntax == null)
|
||||
{
|
||||
throw new InvalidOperationException("No " + typeof(ISqlSyntaxProvider) + " specified or no " + typeof(SqlSyntaxProviders) + " instance specified");
|
||||
}
|
||||
|
||||
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
|
||||
|
||||
_configured = true;
|
||||
}
|
||||
@@ -411,8 +466,8 @@ namespace Umbraco.Core
|
||||
{
|
||||
_configured = false;
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Initialization of the DatabaseContext failed with following error: " + e.Message);
|
||||
LogHelper.Info<DatabaseContext>(e.StackTrace);
|
||||
_logger.Info<DatabaseContext>("Initialization of the DatabaseContext failed with following error: " + e.Message);
|
||||
_logger.Info<DatabaseContext>(e.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,8 +482,8 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
private void DetermineSqlServerVersion()
|
||||
{
|
||||
|
||||
var sqlServerSyntax = SqlSyntaxContext.SqlSyntaxProvider as SqlServerSyntaxProvider;
|
||||
|
||||
var sqlServerSyntax = SqlSyntax as SqlServerSyntaxProvider;
|
||||
if (sqlServerSyntax != null)
|
||||
{
|
||||
//this will not execute now, it is lazy so will only execute when we need to actually know
|
||||
@@ -479,8 +534,8 @@ namespace Umbraco.Core
|
||||
throw new InvalidOperationException("Cannot use MySql in Medium Trust configuration");
|
||||
}
|
||||
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName);
|
||||
var dbSchema = new DatabaseSchemaCreation(database);
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName, _logger);
|
||||
var dbSchema = new DatabaseSchemaCreation(database, _logger, SqlSyntax);
|
||||
_result = dbSchema.ValidateSchema();
|
||||
}
|
||||
return _result;
|
||||
@@ -496,17 +551,17 @@ namespace Umbraco.Core
|
||||
return readyForInstall.Result;
|
||||
}
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Database configuration status: Started");
|
||||
_logger.Info<DatabaseContext>("Database configuration status: Started");
|
||||
|
||||
string message;
|
||||
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName);
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName, _logger);
|
||||
|
||||
// If MySQL, we're going to ensure that database calls are maintaining proper casing as to remove the necessity for checks
|
||||
// for case insensitive queries. In an ideal situation (which is what we're striving for), all calls would be case sensitive.
|
||||
|
||||
/*
|
||||
var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
|
||||
var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
|
||||
if (supportsCaseInsensitiveQueries == false)
|
||||
{
|
||||
message = "<p> </p><p>The database you're trying to use does not support case insensitive queries. <br />We currently do not support these types of databases.</p>" +
|
||||
@@ -532,12 +587,12 @@ namespace Umbraco.Core
|
||||
message = message + "<p>Installation completed!</p>";
|
||||
|
||||
//now that everything is done, we need to determine the version of SQL server that is executing
|
||||
LogHelper.Info<DatabaseContext>("Database configuration status: " + message);
|
||||
_logger.Info<DatabaseContext>("Database configuration status: " + message);
|
||||
return new Result { Message = message, Success = true, Percentage = "100" };
|
||||
}
|
||||
|
||||
//we need to do an upgrade so return a new status message and it will need to be done during the next step
|
||||
LogHelper.Info<DatabaseContext>("Database requires upgrade");
|
||||
_logger.Info<DatabaseContext>("Database requires upgrade");
|
||||
message = "<p>Upgrading database, this may take some time...</p>";
|
||||
return new Result
|
||||
{
|
||||
@@ -568,10 +623,10 @@ namespace Umbraco.Core
|
||||
return readyForInstall.Result;
|
||||
}
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Database upgrade started");
|
||||
_logger.Info<DatabaseContext>("Database upgrade started");
|
||||
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName);
|
||||
//var supportsCaseInsensitiveQueries = SqlSyntaxContext.SqlSyntaxProvider.SupportsCaseInsensitiveQueries(database);
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName, _logger);
|
||||
//var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
|
||||
|
||||
var message = GetResultMessageForMySql();
|
||||
|
||||
@@ -584,13 +639,13 @@ namespace Umbraco.Core
|
||||
? installedVersion
|
||||
: new Version(GlobalSettings.ConfigurationStatus);
|
||||
var targetVersion = UmbracoVersion.Current;
|
||||
var runner = new MigrationRunner(currentVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
|
||||
var runner = new MigrationRunner(_logger, currentVersion, targetVersion, GlobalSettings.UmbracoMigrationName);
|
||||
var upgraded = runner.Execute(database, true);
|
||||
message = message + "<p>Upgrade completed!</p>";
|
||||
|
||||
//now that everything is done, we need to determine the version of SQL server that is executing
|
||||
|
||||
LogHelper.Info<DatabaseContext>("Database configuration status: " + message);
|
||||
_logger.Info<DatabaseContext>("Database configuration status: " + message);
|
||||
|
||||
return new Result { Message = message, Success = true, Percentage = "100" };
|
||||
}
|
||||
@@ -602,7 +657,7 @@ namespace Umbraco.Core
|
||||
|
||||
private string GetResultMessageForMySql()
|
||||
{
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
|
||||
if (SqlSyntax.GetType() == typeof(MySqlSyntaxProvider))
|
||||
{
|
||||
return "<p> </p><p>Congratulations, the database step ran successfully!</p>" +
|
||||
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
|
||||
@@ -628,7 +683,7 @@ namespace Umbraco.Core
|
||||
"<p>For more technical information on case sensitivity in MySQL, have a look at " +
|
||||
"<a href='http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html'>the documentation on the subject</a></p>";
|
||||
}
|
||||
if (SqlSyntaxContext.SqlSyntaxProvider.GetType() == typeof(MySqlSyntaxProvider))
|
||||
if (SqlSyntax.GetType() == typeof(MySqlSyntaxProvider))
|
||||
{
|
||||
return "<p> </p><p>Congratulations, the database step ran successfully!</p>" +
|
||||
"<p>Note: You're using MySQL and the database instance you're connecting to seems to support case insensitive queries.</p>" +
|
||||
@@ -665,11 +720,11 @@ namespace Umbraco.Core
|
||||
|
||||
private Result HandleInstallException(Exception ex)
|
||||
{
|
||||
LogHelper.Error<DatabaseContext>("Database configuration failed", ex);
|
||||
_logger.Error<DatabaseContext>("Database configuration failed", ex);
|
||||
|
||||
if (_result != null)
|
||||
{
|
||||
LogHelper.Info<DatabaseContext>("The database schema validation produced the following summary: \n" + _result.GetSummary());
|
||||
_logger.Info<DatabaseContext>("The database schema validation produced the following summary: \n" + _result.GetSummary());
|
||||
}
|
||||
|
||||
return new Result
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Dictionary
|
||||
@@ -12,15 +14,22 @@ namespace Umbraco.Core.Dictionary
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can be used by developers at runtime to set their ICultureDictionaryFactory at app startup
|
||||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
[Obsolete("Use SetDictionaryFactory instead")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public void SetContentStore(ICultureDictionaryFactory factory)
|
||||
{
|
||||
Value = factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Can be used by developers at runtime to set their ICultureDictionaryFactory at app startup
|
||||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
public void SetDictionaryFactory(ICultureDictionaryFactory factory)
|
||||
{
|
||||
Value = factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the ICultureDictionaryFactory
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Umbraco.Core.Dictionary
|
||||
@@ -19,5 +20,12 @@ namespace Umbraco.Core.Dictionary
|
||||
/// Returns the current culture
|
||||
/// </summary>
|
||||
CultureInfo Culture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the child dictionary entries for a given key
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
IDictionary<string, string> GetChildren(string key);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Mvc;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -135,20 +134,6 @@ namespace Umbraco.Core
|
||||
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>
|
||||
/// Merges all key/values from the sources dictionaries into the destination dictionary
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Logging;
|
||||
@@ -9,32 +10,65 @@ 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>
|
||||
///
|
||||
/// using (DisposableTimer.TraceDuration{MyType}("starting", "finished"))
|
||||
/// {
|
||||
/// Thread.Sleep(567);
|
||||
/// }
|
||||
///
|
||||
/// 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 Stopwatch _stopwatch = Stopwatch.StartNew();
|
||||
private readonly Action<long> _callback;
|
||||
|
||||
protected DisposableTimer(Action<long> callback)
|
||||
{
|
||||
_callback = callback;
|
||||
}
|
||||
internal enum LogType
|
||||
{
|
||||
Debug, Info
|
||||
}
|
||||
|
||||
public Stopwatch Stopwatch
|
||||
internal DisposableTimer(ILogger logger, LogType logType, IProfiler profiler, Type loggerType, string startMessage, string endMessage)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
if (loggerType == null) throw new ArgumentNullException("loggerType");
|
||||
|
||||
_callback = x =>
|
||||
{
|
||||
if (profiler != null)
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
}
|
||||
switch (logType)
|
||||
{
|
||||
case LogType.Debug:
|
||||
logger.Debug(loggerType, () => endMessage + " (took " + x + "ms)");
|
||||
break;
|
||||
case LogType.Info:
|
||||
logger.Info(loggerType, () => endMessage + " (took " + x + "ms)");
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("logType");
|
||||
}
|
||||
|
||||
};
|
||||
switch (logType)
|
||||
{
|
||||
case LogType.Debug:
|
||||
logger.Debug(loggerType, startMessage);
|
||||
break;
|
||||
case LogType.Info:
|
||||
logger.Info(loggerType, startMessage);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("logType");
|
||||
}
|
||||
|
||||
if (profiler != null)
|
||||
{
|
||||
profiler.Step(loggerType, startMessage);
|
||||
}
|
||||
}
|
||||
|
||||
protected internal DisposableTimer(Action<long> callback)
|
||||
{
|
||||
if (callback == null) throw new ArgumentNullException("callback");
|
||||
_callback = callback;
|
||||
}
|
||||
|
||||
public Stopwatch Stopwatch
|
||||
{
|
||||
get { return _stopwatch; }
|
||||
}
|
||||
@@ -51,25 +85,25 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
#region TraceDuration
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the other methods that specify strings instead of Func")]
|
||||
public static DisposableTimer TraceDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the other methods that specify strings instead of Func")]
|
||||
public static DisposableTimer TraceDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
var startMsg = startMessage();
|
||||
LogHelper.Info(loggerType, startMsg);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMsg);
|
||||
var profiler = ActivateProfiler(loggerType, startMsg);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Info(loggerType, () => completeMessage() + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMsg);
|
||||
});
|
||||
return new DisposableTimer(
|
||||
LoggerResolver.Current.Logger,
|
||||
LogType.Info,
|
||||
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
|
||||
loggerType,
|
||||
startMessage(),
|
||||
completeMessage());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -79,11 +113,19 @@ namespace Umbraco.Core
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Use the Umbraco.Core.Logging.ProfilingLogger to create instances of DisposableTimer")]
|
||||
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>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="startMessage"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Use the Umbraco.Core.Logging.ProfilingLogger to create instances of DisposableTimer")]
|
||||
public static DisposableTimer TraceDuration<T>(string startMessage)
|
||||
{
|
||||
return TraceDuration(typeof(T), startMessage, "Complete");
|
||||
@@ -96,20 +138,18 @@ namespace Umbraco.Core
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Use the Umbraco.Core.Logging.ProfilingLogger to create instances of DisposableTimer")]
|
||||
public static DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Info(loggerType, startMessage);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, startMessage);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Info(loggerType, () => completeMessage + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
}
|
||||
return new DisposableTimer(
|
||||
LoggerResolver.Current.Logger,
|
||||
LogType.Info,
|
||||
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
|
||||
loggerType,
|
||||
startMessage,
|
||||
completeMessage);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DebugDuration
|
||||
@@ -120,23 +160,26 @@ namespace Umbraco.Core
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Use the Umbraco.Core.Logging.ProfilingLogger to create instances of DisposableTimer")]
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
/// <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>
|
||||
[Obsolete("Use the Umbraco.Core.Logging.ProfilingLogger to create instances of DisposableTimer")]
|
||||
public static DisposableTimer DebugDuration<T>(string startMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the other methods that specify strings instead of Func")]
|
||||
public static DisposableTimer DebugDuration<T>(Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
return DebugDuration(typeof(T), startMessage, completeMessage);
|
||||
@@ -149,42 +192,29 @@ namespace Umbraco.Core
|
||||
/// <param name="startMessage"></param>
|
||||
/// <param name="completeMessage"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Use the Umbraco.Core.Logging.ProfilingLogger to create instances of DisposableTimer")]
|
||||
public static DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
LogHelper.Debug(loggerType, startMessage);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, startMessage);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Debug(loggerType, () => completeMessage + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
return new DisposableTimer(
|
||||
LoggerResolver.Current.Logger,
|
||||
LogType.Debug,
|
||||
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
|
||||
loggerType,
|
||||
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>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[Obsolete("Use the other methods that specify strings instead of Func")]
|
||||
public static DisposableTimer DebugDuration(Type loggerType, Func<string> startMessage, Func<string> completeMessage)
|
||||
{
|
||||
var msg = startMessage();
|
||||
LogHelper.Debug(loggerType, msg);
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("Start: " + startMessage);
|
||||
var profiler = ActivateProfiler(loggerType, msg);
|
||||
return new DisposableTimer(x =>
|
||||
{
|
||||
profiler.DisposeIfDisposable();
|
||||
LogHelper.Debug(loggerType, () => completeMessage() + " (took " + x + "ms)");
|
||||
if (HttpContext.Current != null)
|
||||
HttpContext.Current.Trace.Write("End: " + startMessage);
|
||||
});
|
||||
return new DisposableTimer(
|
||||
LoggerResolver.Current.Logger,
|
||||
LogType.Debug,
|
||||
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : null,
|
||||
loggerType,
|
||||
startMessage(),
|
||||
completeMessage());
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -196,18 +226,5 @@ namespace Umbraco.Core
|
||||
_callback.Invoke(Stopwatch.ElapsedMilliseconds);
|
||||
}
|
||||
|
||||
private static IDisposable ActivateProfiler(Type loggerType, string profileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ProfilerResolver.Current.Profiler.Step(loggerType, profileName);
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
//swallow this exception, it will occur if the ProfilerResolver is not initialized... generally only in
|
||||
// unit tests.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
@@ -34,38 +35,42 @@ namespace Umbraco.Core.Dynamics
|
||||
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)
|
||||
/// <summary>
|
||||
/// Attempts to invoke a member based on the dynamic instance
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="runtimeCache"></param>
|
||||
/// <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>(IRuntimeCacheProvider runtimeCache, T thisObject, InvokeMemberBinder binder, object[] args)
|
||||
{
|
||||
return TryInvokeMember<T>(thisObject, binder, args, null);
|
||||
return TryInvokeMember<T>(runtimeCache, 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,
|
||||
/// <summary>
|
||||
/// Attempts to invoke a member based on the dynamic instance
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="runtimeCache"></param>
|
||||
/// <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>(
|
||||
IRuntimeCacheProvider runtimeCache,
|
||||
T thisObject,
|
||||
InvokeMemberBinder binder,
|
||||
object[] args,
|
||||
IEnumerable<Type> findExtensionMethodsOnTypes)
|
||||
@@ -76,9 +81,9 @@ namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
//Property?
|
||||
result = typeof(T).InvokeMember(binder.Name,
|
||||
System.Reflection.BindingFlags.Instance |
|
||||
System.Reflection.BindingFlags.Public |
|
||||
System.Reflection.BindingFlags.GetProperty,
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Public |
|
||||
BindingFlags.GetProperty,
|
||||
null,
|
||||
thisObject,
|
||||
args);
|
||||
@@ -90,10 +95,10 @@ namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
//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,
|
||||
BindingFlags.Instance |
|
||||
BindingFlags.Public |
|
||||
BindingFlags.Static |
|
||||
BindingFlags.InvokeMethod,
|
||||
null,
|
||||
thisObject,
|
||||
args);
|
||||
@@ -105,7 +110,7 @@ namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
try
|
||||
{
|
||||
result = FindAndExecuteExtensionMethod(thisObject, args, binder.Name, findExtensionMethodsOnTypes);
|
||||
result = FindAndExecuteExtensionMethod(runtimeCache, thisObject, args, binder.Name, findExtensionMethodsOnTypes);
|
||||
return Attempt.Succeed(new TryInvokeMemberResult(result, TryInvokeMemberSuccessReason.FoundExtensionMethod));
|
||||
}
|
||||
catch (TargetInvocationException ext)
|
||||
@@ -138,16 +143,19 @@ namespace Umbraco.Core.Dynamics
|
||||
}
|
||||
}
|
||||
|
||||
/// <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,
|
||||
/// <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="runtimeCache"></param>
|
||||
/// <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>(
|
||||
IRuntimeCacheProvider runtimeCache,
|
||||
T thisObject,
|
||||
object[] args,
|
||||
string name,
|
||||
IEnumerable<Type> findMethodsOnTypes)
|
||||
@@ -158,7 +166,7 @@ namespace Umbraco.Core.Dynamics
|
||||
MethodInfo toExecute = null;
|
||||
foreach (var t in findMethodsOnTypes)
|
||||
{
|
||||
toExecute = ExtensionMethodFinder.FindExtensionMethod(t, args, name, false);
|
||||
toExecute = ExtensionMethodFinder.FindExtensionMethod(runtimeCache, t, args, name, false);
|
||||
if (toExecute != null)
|
||||
break;
|
||||
}
|
||||
@@ -166,6 +174,13 @@ namespace Umbraco.Core.Dynamics
|
||||
if (toExecute != null)
|
||||
{
|
||||
var genericArgs = (new[] { (object)thisObject }).Concat(args);
|
||||
|
||||
// else we'd get an exception w/ message "Late bound operations cannot
|
||||
// be performed on types or methods for which ContainsGenericParameters is true."
|
||||
// because MakeGenericMethod must be used to obtain an actual method that can run
|
||||
if (toExecute.ContainsGenericParameters)
|
||||
throw new InvalidOperationException("Method contains generic parameters, something's wrong.");
|
||||
|
||||
result = toExecute.Invoke(null, genericArgs.ToArray());
|
||||
}
|
||||
else
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Collections;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
@@ -162,8 +163,10 @@ namespace Umbraco.Core.Dynamics
|
||||
return true; //anyway
|
||||
}
|
||||
|
||||
var runtimeCache = ApplicationContext.Current != null ? ApplicationContext.Current.ApplicationCache.RuntimeCache : new NullCacheProvider();
|
||||
|
||||
//ok, now lets try to match by member, property, extensino method
|
||||
var attempt = DynamicInstanceHelper.TryInvokeMember(this, binder, args, new[]
|
||||
var attempt = DynamicInstanceHelper.TryInvokeMember(runtimeCache, this, binder, args, new[]
|
||||
{
|
||||
typeof (IEnumerable<DynamicXml>),
|
||||
typeof (IEnumerable<XElement>),
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
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;
|
||||
using System.Web.Services.Description;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
@@ -14,279 +15,152 @@ namespace Umbraco.Core.Dynamics
|
||||
/// </summary>
|
||||
internal static class ExtensionMethodFinder
|
||||
{
|
||||
private static readonly MethodInfo[] AllExtensionMethods;
|
||||
/// <summary>
|
||||
/// The static cache for extension methods found that match the criteria that we are looking for
|
||||
/// </summary>
|
||||
private static readonly ConcurrentDictionary<Tuple<Type, string, int>, MethodInfo[]> MethodCache = new ConcurrentDictionary<Tuple<Type, string, int>, MethodInfo[]>();
|
||||
|
||||
static ExtensionMethodFinder()
|
||||
{
|
||||
AllExtensionMethods = TypeFinder.GetAssembliesWithKnownExclusions()
|
||||
/// <summary>
|
||||
/// Returns the enumerable of all extension method info's in the app domain = USE SPARINGLY!!!
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// We cache this as a sliding 5 minute exiration, in unit tests there's over 1100 methods found, surely that will eat up a bit of memory so we want
|
||||
/// to make sure we give it back.
|
||||
/// </remarks>
|
||||
private static IEnumerable<MethodInfo> GetAllExtensionMethodsInAppDomain(IRuntimeCacheProvider runtimeCacheProvider)
|
||||
{
|
||||
if (runtimeCacheProvider == null) throw new ArgumentNullException("runtimeCacheProvider");
|
||||
|
||||
return runtimeCacheProvider.GetCacheItem<MethodInfo[]>(typeof (ExtensionMethodFinder).Name, () => TypeFinder.GetAssembliesWithKnownExclusions()
|
||||
// assemblies that contain extension methods
|
||||
.Where(a => a.IsDefined(typeof(ExtensionAttribute), false))
|
||||
.Where(a => a.IsDefined(typeof (ExtensionAttribute), false))
|
||||
// types that contain extension methods
|
||||
.SelectMany(a => a.GetTypes()
|
||||
.Where(t => t.IsDefined(typeof(ExtensionAttribute), false) && t.IsSealed && t.IsGenericType == false && t.IsNested == false))
|
||||
.Where(t => t.IsDefined(typeof (ExtensionAttribute), false) && t.IsSealed && t.IsGenericType == false && t.IsNested == false))
|
||||
// actual extension methods
|
||||
.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public)
|
||||
.Where(m => m.IsDefined(typeof(ExtensionAttribute), false)))
|
||||
.Where(m => m.IsDefined(typeof (ExtensionAttribute), false)))
|
||||
// and also IEnumerable<T> extension methods - because the assembly is excluded
|
||||
.Concat(typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public))
|
||||
.ToArray();
|
||||
}
|
||||
.Concat(typeof (Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public))
|
||||
//If we don't do this then we'll be scanning all assemblies each time!
|
||||
.ToArray(),
|
||||
|
||||
//only cache for 5 minutes
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
|
||||
// ORIGINAL CODE IS NOT COMPLETE, DOES NOT HANDLE GENERICS, ETC...
|
||||
|
||||
// so this is an attempt at fixing things, but it's not done yet
|
||||
// and do we really want to do this? extension methods are not supported on dynamics, period
|
||||
// we should use strongly typed content instead of dynamics.
|
||||
|
||||
/*
|
||||
|
||||
// get all extension methods for type thisType, with name name,
|
||||
// accepting argsCount arguments (not counting the instance of thisType).
|
||||
private static IEnumerable<MethodInfo> GetExtensionMethods(Type thisType, string name, int argsCount)
|
||||
{
|
||||
var key = string.Format("{0}.{1}::{2}", thisType.FullName, name, argsCount);
|
||||
|
||||
var types = thisType.GetBaseTypes(true); // either do this OR have MatchFirstParameter handle the stuff... F*XME
|
||||
|
||||
var methods = AllExtensionMethods
|
||||
.Where(m => m.Name == name)
|
||||
.Where(m => m.GetParameters().Length == argsCount)
|
||||
.Where(m => MatchFirstParameter(thisType, m.GetParameters()[0].ParameterType));
|
||||
|
||||
// f*xme - is this what we should cache?
|
||||
return methods;
|
||||
//each time this is accessed it will be for 5 minutes longer
|
||||
isSliding:true);
|
||||
}
|
||||
|
||||
// find out whether the first parameter is a match for thisType
|
||||
private static bool MatchFirstParameter(Type thisType, Type firstParameterType)
|
||||
{
|
||||
return MethodArgZeroHasCorrectTargetType(null, firstParameterType, thisType);
|
||||
}
|
||||
|
||||
// get the single extension method for type thisType, with name name,
|
||||
// that accepts the arguments in args (which does not contain the instance of thisType).
|
||||
public static MethodInfo GetExtensionMethod(Type thisType, string name, object[] args)
|
||||
{
|
||||
MethodInfo result = null;
|
||||
foreach (var method in GetExtensionMethods(thisType, name, args.Length).Where(m => MatchParameters(m, args)))
|
||||
{
|
||||
if (result == null)
|
||||
result = method;
|
||||
else
|
||||
throw new AmbiguousMatchException("More than one matching extension method was found.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// find out whether the method can accept the arguments
|
||||
private static bool MatchParameters(MethodInfo method, IList<object> args)
|
||||
{
|
||||
var parameters = method.GetParameters();
|
||||
|
||||
var i = 0;
|
||||
for (; i < parameters.Length; ++i)
|
||||
{
|
||||
if (MatchParameter(parameters[i].ParameterType, args[i].GetType()) == false)
|
||||
break;
|
||||
}
|
||||
return (i == parameters.Length);
|
||||
}
|
||||
|
||||
internal static bool MatchParameter(Type parameterType, Type argumentType)
|
||||
{
|
||||
// public static int DoSomething<T>(Foo foo, T t1, T t2)
|
||||
// DoSomething(foo, t1, t2) => how can we match?!
|
||||
return parameterType == argumentType; // f*xme of course!
|
||||
}
|
||||
*
|
||||
*/
|
||||
|
||||
// BELOW IS THE ORIGINAL CODE...
|
||||
|
||||
/// <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)
|
||||
{
|
||||
// at *least* we can cache the extension methods discovery
|
||||
var candidates = AllExtensionMethods;
|
||||
|
||||
/*
|
||||
//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)
|
||||
/// <summary>
|
||||
/// Returns all extension methods found matching the definition
|
||||
/// </summary>
|
||||
/// <param name="runtimeCache">
|
||||
/// The runtime cache is used to temporarily cache all extension methods found in the app domain so that
|
||||
/// while we search for individual extension methods, the process will be reasonably 'quick'. We then statically
|
||||
/// cache the MethodInfo's that we are looking for and then the runtime cache will expire and give back all that memory.
|
||||
/// </param>
|
||||
/// <param name="thisType"></param>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="argumentCount">
|
||||
/// The arguments EXCLUDING the 'this' argument in an extension method
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// NOTE: This will be an intensive method to call! Results will be cached based on the key (args) of this method
|
||||
/// </remarks>
|
||||
internal static IEnumerable<MethodInfo> GetAllExtensionMethods(IRuntimeCacheProvider runtimeCache, Type thisType, string name, int argumentCount)
|
||||
{
|
||||
var key = new Tuple<Type, string, int>(thisType, name, argumentCount);
|
||||
|
||||
return MethodCache.GetOrAdd(key, tuple =>
|
||||
{
|
||||
var candidates = GetAllExtensionMethodsInAppDomain(runtimeCache);
|
||||
|
||||
// filter by name
|
||||
var filtr1 = candidates.Where(m => m.Name == name);
|
||||
|
||||
// filter by args count
|
||||
// ensure we add + 1 to the arg count because the 'this' arg is not included in the count above!
|
||||
var filtr2 = filtr1.Where(m => m.GetParameters().Length == argumentCount + 1);
|
||||
|
||||
// filter by first parameter type (target of the extension method)
|
||||
// ie find the right overload that can take genericParameterType
|
||||
// (which will be either DynamicNodeList or List<DynamicNode> which is IEnumerable)
|
||||
var filtr3 = filtr2.Select(x =>
|
||||
{
|
||||
var t = x.GetParameters()[0].ParameterType; // exists because of +1 above
|
||||
var bindings = new Dictionary<string, Type>();
|
||||
if (TypeHelper.MatchType(thisType, t, bindings) == false) return null;
|
||||
|
||||
// create the generic method if necessary
|
||||
if (x.ContainsGenericParameters == false) return x;
|
||||
var targs = t.GetGenericArguments().Select(y => bindings[y.Name]).ToArray();
|
||||
return x.MakeGenericMethod(targs);
|
||||
}).Where(x => x != null);
|
||||
|
||||
return filtr3.ToArray();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
//Given the args, lets get the types and compare the type sequence to try and find the correct overload
|
||||
var argTypes = args.Select(o =>
|
||||
{
|
||||
var oe = (o as Expression);
|
||||
return oe != null ? oe.Type : o.GetType();
|
||||
});
|
||||
|
||||
var methodsWithArgTypes = methods.Select(method => new
|
||||
{
|
||||
method,
|
||||
//skip the first arg because that is the extension method type ('this') that we are looking for
|
||||
types = method.GetParameters().Select(pi => pi.ParameterType).Skip(1)
|
||||
});
|
||||
|
||||
//This type comparer will check
|
||||
var typeComparer = new DelegateEqualityComparer<Type>(
|
||||
//Checks if the argument type passed in can be assigned from the parameter type in the method. For
|
||||
// example, if the argument type is HtmlHelper<MyModel> but the method parameter type is HtmlHelper then
|
||||
// it will match because the argument is assignable to that parameter type and will be able to execute
|
||||
TypeHelper.IsTypeAssignableFrom,
|
||||
//This will not ever execute but if it does we need to get the hash code of the string because the hash
|
||||
// code of a type is random
|
||||
type => type.FullName.GetHashCode());
|
||||
|
||||
var firstMatchingOverload = methodsWithArgTypes
|
||||
.FirstOrDefault(m => m.types.SequenceEqual(argTypes, typeComparer));
|
||||
|
||||
if (firstMatchingOverload != null)
|
||||
{
|
||||
methodToExecute = firstMatchingOverload.method;
|
||||
}
|
||||
|
||||
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)
|
||||
public static MethodInfo FindExtensionMethod(IRuntimeCacheProvider runtimeCache, 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);
|
||||
args = args
|
||||
//if the args contains 'this', remove the first one since that is 'this' and we don't want to use
|
||||
//that in the method searching
|
||||
.Skip(argsContainsThis ? 1 : 0)
|
||||
.ToArray();
|
||||
|
||||
var methods = GetAllExtensionMethods(runtimeCache, thisType, name, args.Length).ToArray();
|
||||
|
||||
return DetermineMethodFromParams(methods, genericType, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core
|
||||
/// <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
|
||||
public 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());
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
@@ -114,13 +115,7 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
public static bool ContainsAll<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> other)
|
||||
{
|
||||
var matches = true;
|
||||
foreach (var i in other)
|
||||
{
|
||||
matches = source.Contains(i);
|
||||
if (!matches) break;
|
||||
}
|
||||
return matches;
|
||||
return other.Except(source).Any() == false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -132,7 +127,7 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
public static bool ContainsAny<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> other)
|
||||
{
|
||||
return other.Any(i => source.Contains(i));
|
||||
return other.Any(source.Contains);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -224,7 +219,7 @@ namespace Umbraco.Core
|
||||
return sequence.Select(
|
||||
x =>
|
||||
{
|
||||
if (typeof(TActual).IsAssignableFrom(x.GetType()))
|
||||
if (x is TActual)
|
||||
{
|
||||
var casted = x as TActual;
|
||||
projection.Invoke(casted);
|
||||
@@ -276,6 +271,34 @@ namespace Umbraco.Core
|
||||
///<param name="items">The enumerable to search.</param>
|
||||
///<param name="item">The item to find.</param>
|
||||
///<returns>The index of the first matching item, or -1 if the item was not found.</returns>
|
||||
public static int IndexOf<T>(this IEnumerable<T> items, T item) { return items.FindIndex(i => EqualityComparer<T>.Default.Equals(item, i)); }
|
||||
public static int IndexOf<T>(this IEnumerable<T> items, T item)
|
||||
{
|
||||
return items.FindIndex(i => EqualityComparer<T>.Default.Equals(item, i));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if 2 lists have equal elements within them regardless of how they are sorted
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="source"></param>
|
||||
/// <param name="other"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// The logic for this is taken from:
|
||||
/// http://stackoverflow.com/questions/4576723/test-whether-two-ienumerablet-have-the-same-values-with-the-same-frequencies
|
||||
///
|
||||
/// There's a few answers, this one seems the best for it's simplicity and based on the comment of Eamon
|
||||
/// </remarks>
|
||||
public static bool UnsortedSequenceEqual<T>(this IEnumerable<T> source, IEnumerable<T> other)
|
||||
{
|
||||
if (source == null && other == null) return true;
|
||||
if (source == null || other == null) return false;
|
||||
|
||||
var list1Groups = source.ToLookup(i => i);
|
||||
var list2Groups = other.ToLookup(i => i);
|
||||
return list1Groups.Count == list2Groups.Count
|
||||
&& list1Groups.All(g => g.Count() == list2Groups[g.Key].Count());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static class HttpContextExtensions
|
||||
{
|
||||
public static string GetCurrentRequestIpAddress(this HttpContextBase httpContext)
|
||||
{
|
||||
if (httpContext == null)
|
||||
{
|
||||
return "Unknown, httpContext is null";
|
||||
}
|
||||
if (httpContext.Request == null)
|
||||
{
|
||||
return "Unknown, httpContext.Request is null";
|
||||
}
|
||||
if (httpContext.Request.ServerVariables == null)
|
||||
{
|
||||
return "Unknown, httpContext.Request.ServerVariables is null";
|
||||
}
|
||||
|
||||
// From: http://stackoverflow.com/a/740431/5018
|
||||
|
||||
try
|
||||
{
|
||||
var ipAddress = httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
|
||||
|
||||
if (string.IsNullOrEmpty(ipAddress))
|
||||
return httpContext.Request.ServerVariables["REMOTE_ADDR"];
|
||||
|
||||
var addresses = ipAddress.Split(',');
|
||||
if (addresses.Length != 0)
|
||||
return addresses[0];
|
||||
|
||||
return httpContext.Request.ServerVariables["REMOTE_ADDR"];
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
//This try catch is to just always ensure that no matter what we're not getting any exceptions caused since
|
||||
// that would cause people to not be able to login
|
||||
return string.Format("Unknown, exception occurred trying to resolve IP {0}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,51 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
{
|
||||
public static class FileSystemExtensions
|
||||
{
|
||||
public static long GetSize(this IFileSystem fs, string path)
|
||||
{
|
||||
using (var s = fs.OpenFile(path))
|
||||
{
|
||||
var size = s.Length;
|
||||
s.Close();
|
||||
|
||||
return size;
|
||||
/// <summary>
|
||||
/// Attempts to open the file at <code>filePath</code> up to <code>maxRetries</code> times,
|
||||
/// with a thread sleep time of <code>sleepPerRetryInMilliseconds</code> between retries.
|
||||
/// </summary>
|
||||
public static FileStream OpenReadWithRetry(this FileInfo file, int maxRetries = 5, int sleepPerRetryInMilliseconds = 50)
|
||||
{
|
||||
var retries = maxRetries;
|
||||
|
||||
while (retries > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
return File.OpenRead(file.FullName);
|
||||
}
|
||||
catch(IOException)
|
||||
{
|
||||
retries--;
|
||||
|
||||
if (retries == 0)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
Thread.Sleep(sleepPerRetryInMilliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ArgumentException("Retries must be greater than zero");
|
||||
}
|
||||
|
||||
public static long GetSize(this IFileSystem fs, string path)
|
||||
{
|
||||
using (var file = fs.OpenFile(path))
|
||||
{
|
||||
using (var sr = new StreamReader(file))
|
||||
{
|
||||
var str = sr.ReadToEnd();
|
||||
return str.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,14 +58,14 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
|
||||
public static string GetExtension(this IFileSystem fs, string path)
|
||||
{
|
||||
return Path.GetExtension(fs.GetFullPath(path));
|
||||
}
|
||||
{
|
||||
return Path.GetExtension(fs.GetFullPath(path));
|
||||
}
|
||||
|
||||
public static string GetFileName(this IFileSystem fs, string path)
|
||||
{
|
||||
return Path.GetFileName(fs.GetFullPath(path));
|
||||
}
|
||||
{
|
||||
return Path.GetFileName(fs.GetFullPath(path));
|
||||
}
|
||||
|
||||
//TODO: Currently this is the only way to do this
|
||||
internal static void CreateFolder(this IFileSystem fs, string folderPath)
|
||||
|
||||
@@ -56,11 +56,11 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
if (UmbracoConfig.For.UmbracoSettings().Content.ResolveUrlsFromTextString)
|
||||
{
|
||||
using (var timer = DisposableTimer.DebugDuration(typeof(IOHelper), "ResolveUrlsFromTextString starting", "ResolveUrlsFromTextString complete"))
|
||||
using (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 = "";
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
internal class MasterPageHelper
|
||||
{
|
||||
private readonly IFileSystem _masterPageFileSystem;
|
||||
internal static readonly string DefaultMasterTemplate = SystemDirectories.Umbraco + "/masterpages/default.master";
|
||||
//private static readonly char[] NewLineChars = Environment.NewLine.ToCharArray();
|
||||
|
||||
public MasterPageHelper(IFileSystem masterPageFileSystem)
|
||||
{
|
||||
if (masterPageFileSystem == null) throw new ArgumentNullException("masterPageFileSystem");
|
||||
_masterPageFileSystem = masterPageFileSystem;
|
||||
}
|
||||
|
||||
public bool MasterPageExists(ITemplate t)
|
||||
{
|
||||
return _masterPageFileSystem.FileExists(GetFilePath(t));
|
||||
}
|
||||
|
||||
[Obsolete("This is only used for legacy purposes and will be removed in future versions")]
|
||||
internal string GetPhysicalFilePath(ITemplate t)
|
||||
{
|
||||
return _masterPageFileSystem.GetFullPath(GetFilePath(t.Alias));
|
||||
}
|
||||
|
||||
private string GetFilePath(ITemplate t)
|
||||
{
|
||||
return GetFilePath(t.Alias);
|
||||
}
|
||||
|
||||
private string GetFilePath(string alias)
|
||||
{
|
||||
return alias + ".master";
|
||||
}
|
||||
|
||||
public string CreateMasterPage(ITemplate t, ITemplateRepository templateRepo, bool overWrite = false)
|
||||
{
|
||||
string masterpageContent = "";
|
||||
|
||||
var filePath = GetFilePath(t);
|
||||
if (_masterPageFileSystem.FileExists(filePath) == false || overWrite)
|
||||
{
|
||||
masterpageContent = t.Content.IsNullOrWhiteSpace() ? CreateDefaultMasterPageContent(t, templateRepo) : t.Content;
|
||||
|
||||
var data = Encoding.UTF8.GetBytes(masterpageContent);
|
||||
var withBom = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
|
||||
|
||||
using (var ms = new MemoryStream(withBom))
|
||||
{
|
||||
_masterPageFileSystem.AddFile(filePath, ms, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var s = _masterPageFileSystem.OpenFile(filePath))
|
||||
using (var tr = new StreamReader(s, Encoding.UTF8))
|
||||
{
|
||||
masterpageContent = tr.ReadToEnd();
|
||||
tr.Close();
|
||||
}
|
||||
}
|
||||
|
||||
return masterpageContent;
|
||||
}
|
||||
|
||||
//internal string GetFileContents(ITemplate t)
|
||||
//{
|
||||
// var masterpageContent = "";
|
||||
// if (_masterPageFileSystem.FileExists(GetFilePath(t)))
|
||||
// {
|
||||
// using (var s = _masterPageFileSystem.OpenFile(GetFilePath(t)))
|
||||
// using (var tr = new StreamReader(s))
|
||||
// {
|
||||
// masterpageContent = tr.ReadToEnd();
|
||||
// tr.Close();
|
||||
// }
|
||||
// }
|
||||
|
||||
// return masterpageContent;
|
||||
//}
|
||||
|
||||
public string UpdateMasterPageFile(ITemplate t, string currentAlias, ITemplateRepository templateRepo)
|
||||
{
|
||||
var template = UpdateMasterPageContent(t, currentAlias);
|
||||
UpdateChildTemplates(t, currentAlias, templateRepo);
|
||||
var filePath = GetFilePath(t);
|
||||
|
||||
var data = Encoding.UTF8.GetBytes(template);
|
||||
var withBom = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
|
||||
|
||||
using (var ms = new MemoryStream(withBom))
|
||||
{
|
||||
_masterPageFileSystem.AddFile(filePath, ms, true);
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
private string CreateDefaultMasterPageContent(ITemplate template, ITemplateRepository templateRepo)
|
||||
{
|
||||
var design = new StringBuilder();
|
||||
design.Append(GetMasterPageHeader(template) + Environment.NewLine);
|
||||
|
||||
if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
var master = templateRepo.Get(template.MasterTemplateAlias);
|
||||
if (master != null)
|
||||
{
|
||||
foreach (var cpId in GetContentPlaceholderIds(master))
|
||||
{
|
||||
design.Append("<asp:content ContentPlaceHolderId=\"" + cpId + "\" runat=\"server\">" +
|
||||
Environment.NewLine +
|
||||
Environment.NewLine +
|
||||
"</asp:content>" +
|
||||
Environment.NewLine +
|
||||
Environment.NewLine);
|
||||
}
|
||||
|
||||
return design.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
design.Append(GetMasterContentElement(template) + Environment.NewLine);
|
||||
design.Append(template.Content + Environment.NewLine);
|
||||
design.Append("</asp:Content>" + Environment.NewLine);
|
||||
|
||||
return design.ToString();
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetContentPlaceholderIds(ITemplate template)
|
||||
{
|
||||
var retVal = new List<string>();
|
||||
|
||||
var mp = template.Content;
|
||||
var path = "<asp:ContentPlaceHolder+(\\s+[a-zA-Z]+\\s*=\\s*(\"([^\"]*)\"|'([^']*)'))*\\s*/?>";
|
||||
var r = new Regex(path, RegexOptions.IgnoreCase);
|
||||
var m = r.Match(mp);
|
||||
|
||||
while (m.Success)
|
||||
{
|
||||
var cc = m.Groups[3].Captures;
|
||||
retVal.AddRange(cc.Cast<Capture>().Where(c => c.Value != "server").Select(c => c.Value));
|
||||
|
||||
m = m.NextMatch();
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private static string UpdateMasterPageContent(ITemplate template, string currentAlias)
|
||||
{
|
||||
var masterPageContent = template.Content;
|
||||
|
||||
if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias)
|
||||
{
|
||||
var masterHeader =
|
||||
masterPageContent.Substring(0, masterPageContent.IndexOf("%>", StringComparison.Ordinal) + 2).Trim(
|
||||
Environment.NewLine.ToCharArray());
|
||||
|
||||
// find the masterpagefile attribute
|
||||
var m = Regex.Matches(masterHeader, "(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"",
|
||||
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
foreach (Match attributeSet in m)
|
||||
{
|
||||
if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile")
|
||||
{
|
||||
// validate the masterpagefile
|
||||
var currentMasterPageFile = attributeSet.Groups["attributeValue"].Value;
|
||||
var currentMasterTemplateFile = ParentTemplatePath(template);
|
||||
|
||||
if (currentMasterPageFile != currentMasterTemplateFile)
|
||||
{
|
||||
masterPageContent =
|
||||
masterPageContent.Replace(
|
||||
attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"",
|
||||
attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile +
|
||||
"\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return masterPageContent;
|
||||
}
|
||||
|
||||
private void UpdateChildTemplates(ITemplate template, string currentAlias, ITemplateRepository templateRepo)
|
||||
{
|
||||
//if we have a Old Alias if the alias and therefor the masterpage file name has changed...
|
||||
//so before we save the new masterfile, we'll clear the old one, so we don't up with
|
||||
//Unused masterpage files
|
||||
if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias)
|
||||
{
|
||||
//Ensure that child templates have the right master masterpage file name
|
||||
if (template.IsMasterTemplate)
|
||||
{
|
||||
var children = templateRepo.GetChildren(template.Id);
|
||||
foreach (var t in children)
|
||||
UpdateMasterPageFile(t, null, templateRepo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//private void SaveDesignToFile(ITemplate t, string currentAlias, string design)
|
||||
//{
|
||||
// //kill the old file..
|
||||
// if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != t.Alias)
|
||||
// {
|
||||
// var oldFile =
|
||||
// IOHelper.MapPath(SystemDirectories.Masterpages + "/" + currentAlias.Replace(" ", "") + ".master");
|
||||
// if (System.IO.File.Exists(oldFile))
|
||||
// System.IO.File.Delete(oldFile);
|
||||
// }
|
||||
|
||||
// // save the file in UTF-8
|
||||
// System.IO.File.WriteAllText(GetFilePath(t), design, Encoding.UTF8);
|
||||
//}
|
||||
|
||||
//internal static void RemoveMasterPageFile(string alias)
|
||||
//{
|
||||
// if (string.IsNullOrWhiteSpace(alias) == false)
|
||||
// {
|
||||
// string file = IOHelper.MapPath(SystemDirectories.Masterpages + "/" + alias.Replace(" ", "") + ".master");
|
||||
// if (System.IO.File.Exists(file))
|
||||
// System.IO.File.Delete(file);
|
||||
// }
|
||||
//}
|
||||
|
||||
//internal string SaveTemplateToFile(ITemplate template, string currentAlias, ITemplateRepository templateRepo)
|
||||
//{
|
||||
// var masterPageContent = template.Content;
|
||||
// if (IsMasterPageSyntax(masterPageContent) == false)
|
||||
// masterPageContent = ConvertToMasterPageSyntax(template);
|
||||
|
||||
// // Add header to master page if it doesn't exist
|
||||
// if (masterPageContent.TrimStart().StartsWith("<%@") == false)
|
||||
// {
|
||||
// masterPageContent = GetMasterPageHeader(template) + Environment.NewLine + masterPageContent;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // verify that the masterpage attribute is the same as the masterpage
|
||||
// var masterHeader =
|
||||
// masterPageContent.Substring(0, masterPageContent.IndexOf("%>", StringComparison.Ordinal) + 2).Trim(NewLineChars);
|
||||
|
||||
// // find the masterpagefile attribute
|
||||
// var m = Regex.Matches(masterHeader, "(?<attributeName>\\S*)=\"(?<attributeValue>[^\"]*)\"",
|
||||
// RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
// foreach (Match attributeSet in m)
|
||||
// {
|
||||
// if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile")
|
||||
// {
|
||||
// // validate the masterpagefile
|
||||
// var currentMasterPageFile = attributeSet.Groups["attributeValue"].Value;
|
||||
// var currentMasterTemplateFile = ParentTemplatePath(template);
|
||||
|
||||
// if (currentMasterPageFile != currentMasterTemplateFile)
|
||||
// {
|
||||
// masterPageContent =
|
||||
// masterPageContent.Replace(
|
||||
// attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"",
|
||||
// attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile +
|
||||
// "\"");
|
||||
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// //we have a Old Alias if the alias and therefor the masterpage file name has changed...
|
||||
// //so before we save the new masterfile, we'll clear the old one, so we don't up with
|
||||
// //Unused masterpage files
|
||||
// if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias)
|
||||
// {
|
||||
|
||||
// //Ensure that child templates have the right master masterpage file name
|
||||
// if (template.IsMasterTemplate)
|
||||
// {
|
||||
// var children = templateRepo.GetChildren(template.Id);
|
||||
|
||||
// foreach (var t in children)
|
||||
// UpdateMasterPageFile(t, null, templateRepo);
|
||||
// }
|
||||
|
||||
// //then kill the old file..
|
||||
// var oldFile = GetFilePath(currentAlias);
|
||||
// if (_masterPageFileSystem.FileExists(oldFile))
|
||||
// _masterPageFileSystem.DeleteFile(oldFile);
|
||||
// }
|
||||
|
||||
// // save the file in UTF-8
|
||||
// System.IO.File.WriteAllText(GetFilePath(template), masterPageContent, Encoding.UTF8);
|
||||
|
||||
// return masterPageContent;
|
||||
//}
|
||||
|
||||
//internal static string ConvertToMasterPageSyntax(ITemplate template)
|
||||
//{
|
||||
// string masterPageContent = GetMasterContentElement(template) + Environment.NewLine;
|
||||
|
||||
// masterPageContent += template.Content;
|
||||
|
||||
// // Parse the design for getitems
|
||||
// masterPageContent = EnsureMasterPageSyntax(template.Alias, masterPageContent);
|
||||
|
||||
// // append ending asp:content element
|
||||
// masterPageContent += Environment.NewLine + "</asp:Content>" + Environment.NewLine;
|
||||
|
||||
// return masterPageContent;
|
||||
//}
|
||||
|
||||
public static bool IsMasterPageSyntax(string code)
|
||||
{
|
||||
return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) ||
|
||||
code.InvariantContains("<umbraco:Item") || code.InvariantContains("<asp:") || code.InvariantContains("<umbraco:Macro");
|
||||
}
|
||||
|
||||
private static string GetMasterPageHeader(ITemplate template)
|
||||
{
|
||||
return String.Format("<%@ Master Language=\"C#\" MasterPageFile=\"{0}\" AutoEventWireup=\"true\" %>", ParentTemplatePath(template)) + Environment.NewLine;
|
||||
}
|
||||
|
||||
private static string ParentTemplatePath(ITemplate template)
|
||||
{
|
||||
var masterTemplate = DefaultMasterTemplate;
|
||||
if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false)
|
||||
masterTemplate = SystemDirectories.Masterpages + "/" + template.MasterTemplateAlias + ".master";
|
||||
|
||||
return masterTemplate;
|
||||
}
|
||||
|
||||
private static string GetMasterContentElement(ITemplate template)
|
||||
{
|
||||
if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
string masterAlias = template.MasterTemplateAlias;
|
||||
return
|
||||
String.Format("<asp:Content ContentPlaceHolderID=\"{0}ContentPlaceHolder\" runat=\"server\">", masterAlias);
|
||||
}
|
||||
else
|
||||
return
|
||||
String.Format("<asp:Content ContentPlaceHolderID=\"ContentPlaceHolderDefault\" runat=\"server\">");
|
||||
|
||||
}
|
||||
|
||||
//internal static string EnsureMasterPageSyntax(string templateAlias, string masterPageContent)
|
||||
//{
|
||||
// ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", true);
|
||||
// ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", false);
|
||||
|
||||
// // Parse the design for macros
|
||||
// ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", true);
|
||||
// ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", false);
|
||||
|
||||
// // Parse the design for load childs
|
||||
// masterPageContent = masterPageContent.Replace("<?UMBRACO_TEMPLATE_LOAD_CHILD/>", CreateDefaultPlaceHolder(templateAlias))
|
||||
// .Replace("<?UMBRACO_TEMPLATE_LOAD_CHILD />", CreateDefaultPlaceHolder(templateAlias));
|
||||
// // Parse the design for aspnet forms
|
||||
// GetAspNetMasterPageForm(ref masterPageContent, templateAlias);
|
||||
// masterPageContent = masterPageContent.Replace("</?ASPNET_FORM>", "</form>");
|
||||
// // Parse the design for aspnet heads
|
||||
// masterPageContent = masterPageContent.Replace("</ASPNET_HEAD>", String.Format("<head id=\"{0}Head\" runat=\"server\">", templateAlias.Replace(" ", "")));
|
||||
// masterPageContent = masterPageContent.Replace("</?ASPNET_HEAD>", "</head>");
|
||||
// return masterPageContent;
|
||||
//}
|
||||
|
||||
|
||||
//private static void GetAspNetMasterPageForm(ref string design, string templateAlias)
|
||||
//{
|
||||
// var formElement = Regex.Match(design, GetElementRegExp("?ASPNET_FORM", false), RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
// if (string.IsNullOrEmpty(formElement.Value) == false)
|
||||
// {
|
||||
// string formReplace = String.Format("<form id=\"{0}Form\" runat=\"server\">", templateAlias.Replace(" ", ""));
|
||||
// if (formElement.Groups.Count == 0)
|
||||
// {
|
||||
// formReplace += "<asp:scriptmanager runat=\"server\"></asp:scriptmanager>";
|
||||
// }
|
||||
// design = design.Replace(formElement.Value, formReplace);
|
||||
// }
|
||||
//}
|
||||
|
||||
//private static string CreateDefaultPlaceHolder(string templateAlias)
|
||||
//{
|
||||
// return String.Format("<asp:ContentPlaceHolder ID=\"{0}ContentPlaceHolder\" runat=\"server\"></asp:ContentPlaceHolder>", templateAlias.Replace(" ", ""));
|
||||
//}
|
||||
|
||||
//private static void ReplaceElement(ref string design, string elementName, string newElementName, bool checkForQuotes)
|
||||
//{
|
||||
// var m =
|
||||
// Regex.Matches(design, GetElementRegExp(elementName, checkForQuotes),
|
||||
// RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);
|
||||
|
||||
// foreach (Match match in m)
|
||||
// {
|
||||
// GroupCollection groups = match.Groups;
|
||||
|
||||
// // generate new element (compensate for a closing trail on single elements ("/"))
|
||||
// string elementAttributes = groups[1].Value;
|
||||
// // test for macro alias
|
||||
// if (elementName == "?UMBRACO_MACRO")
|
||||
// {
|
||||
// var tags = XmlHelper.GetAttributesFromElement(match.Value);
|
||||
// if (tags["macroAlias"] != null)
|
||||
// elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroAlias"]) + elementAttributes;
|
||||
// else if (tags["macroalias"] != null)
|
||||
// elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroalias"]) + elementAttributes;
|
||||
// }
|
||||
// string newElement = "<" + newElementName + " runat=\"server\" " + elementAttributes.Trim() + ">";
|
||||
// if (elementAttributes.EndsWith("/"))
|
||||
// {
|
||||
// elementAttributes = elementAttributes.Substring(0, elementAttributes.Length - 1);
|
||||
// }
|
||||
// else if (groups[0].Value.StartsWith("</"))
|
||||
// // It's a closing element, so generate that instead of a starting element
|
||||
// newElement = "</" + newElementName + ">";
|
||||
|
||||
// if (checkForQuotes)
|
||||
// {
|
||||
// // if it's inside quotes, we'll change element attribute quotes to single quotes
|
||||
// newElement = newElement.Replace("\"", "'");
|
||||
// newElement = String.Format("\"{0}\"", newElement);
|
||||
// }
|
||||
// design = design.Replace(match.Value, newElement);
|
||||
// }
|
||||
//}
|
||||
|
||||
//private static string GetElementRegExp(string elementName, bool checkForQuotes)
|
||||
//{
|
||||
// if (checkForQuotes)
|
||||
// return String.Format("\"<[^>\\s]*\\b{0}(\\b[^>]*)>\"", elementName);
|
||||
// else
|
||||
// return String.Format("<[^>\\s]*\\b{0}(\\b[^>]*)>", elementName);
|
||||
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Core.IO
|
||||
public PhysicalFileSystem(string virtualRoot)
|
||||
{
|
||||
if (virtualRoot == null) throw new ArgumentNullException("virtualRoot");
|
||||
if (!virtualRoot.StartsWith("~/"))
|
||||
if (virtualRoot.StartsWith("~/") == false)
|
||||
throw new ArgumentException("The virtualRoot argument must be a virtual path and start with '~/'");
|
||||
|
||||
RootPath = IOHelper.MapPath(virtualRoot);
|
||||
@@ -65,7 +65,7 @@ namespace Umbraco.Core.IO
|
||||
|
||||
public void DeleteDirectory(string path, bool recursive)
|
||||
{
|
||||
if (!DirectoryExists(path))
|
||||
if (DirectoryExists(path) == false)
|
||||
return;
|
||||
|
||||
try
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Core.IO
|
||||
{
|
||||
public class SystemFiles
|
||||
{
|
||||
|
||||
[Obsolete("This file is no longer used and should not be accessed!")]
|
||||
public static string AccessXml
|
||||
{
|
||||
get
|
||||
|
||||
@@ -154,12 +154,8 @@ namespace Umbraco.Core.IO
|
||||
EnsureFileSupportsResizing();
|
||||
|
||||
using (var fs = _fs.OpenFile(Path))
|
||||
using (var image = Image.FromStream(fs))
|
||||
{
|
||||
|
||||
var fileWidth = image.Width;
|
||||
var fileHeight = image.Height;
|
||||
_size = new Size(fileWidth, fileHeight);
|
||||
_size = ImageHelper.GetDimensions(fs);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.IO
|
||||
{
|
||||
internal class ViewHelper
|
||||
{
|
||||
private readonly IFileSystem _viewFileSystem;
|
||||
|
||||
public ViewHelper(IFileSystem viewFileSystem)
|
||||
{
|
||||
if (viewFileSystem == null) throw new ArgumentNullException("viewFileSystem");
|
||||
_viewFileSystem = viewFileSystem;
|
||||
}
|
||||
|
||||
internal bool ViewExists(ITemplate t)
|
||||
{
|
||||
return _viewFileSystem.FileExists(ViewPath(t.Alias));
|
||||
}
|
||||
|
||||
[Obsolete("This is only used for legacy purposes and will be removed in future versions")]
|
||||
internal string GetPhysicalFilePath(ITemplate t)
|
||||
{
|
||||
return _viewFileSystem.GetFullPath(ViewPath(t.Alias));
|
||||
}
|
||||
|
||||
internal string GetFileContents(ITemplate t)
|
||||
{
|
||||
string viewContent = "";
|
||||
string path = ViewPath(t.Alias);
|
||||
|
||||
if (_viewFileSystem.FileExists(path))
|
||||
{
|
||||
using (var tr = new StreamReader(_viewFileSystem.OpenFile(path)))
|
||||
{
|
||||
viewContent = tr.ReadToEnd();
|
||||
tr.Close();
|
||||
}
|
||||
}
|
||||
|
||||
return viewContent;
|
||||
}
|
||||
|
||||
public string CreateView(ITemplate t, bool overWrite = false)
|
||||
{
|
||||
string viewContent;
|
||||
string path = ViewPath(t.Alias);
|
||||
|
||||
if (_viewFileSystem.FileExists(path) == false || overWrite)
|
||||
{
|
||||
viewContent = SaveTemplateToFile(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var tr = new StreamReader(_viewFileSystem.OpenFile(path)))
|
||||
{
|
||||
viewContent = tr.ReadToEnd();
|
||||
tr.Close();
|
||||
}
|
||||
}
|
||||
|
||||
return viewContent;
|
||||
}
|
||||
|
||||
internal static string GetDefaultFileContent(string layoutPageAlias = null)
|
||||
{
|
||||
var design = @"@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
|
||||
@{
|
||||
Layout = null;
|
||||
}";
|
||||
|
||||
if (layoutPageAlias.IsNullOrWhiteSpace() == false)
|
||||
design = design.Replace("null", string.Format("\"{0}.cshtml\"", layoutPageAlias));
|
||||
|
||||
return design;
|
||||
}
|
||||
|
||||
private string SaveTemplateToFile(ITemplate template)
|
||||
{
|
||||
var design = template.Content.IsNullOrWhiteSpace() ? EnsureInheritedLayout(template) : template.Content;
|
||||
var path = ViewPath(template.Alias);
|
||||
|
||||
var data = Encoding.UTF8.GetBytes(design);
|
||||
var withBom = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
|
||||
|
||||
using (var ms = new MemoryStream(withBom))
|
||||
{
|
||||
_viewFileSystem.AddFile(path, ms, true);
|
||||
}
|
||||
|
||||
return design;
|
||||
}
|
||||
|
||||
public string UpdateViewFile(ITemplate t, string currentAlias = null)
|
||||
{
|
||||
var path = ViewPath(t.Alias);
|
||||
|
||||
if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != t.Alias)
|
||||
{
|
||||
//then kill the old file..
|
||||
var oldFile = ViewPath(currentAlias);
|
||||
if (_viewFileSystem.FileExists(oldFile))
|
||||
_viewFileSystem.DeleteFile(oldFile);
|
||||
}
|
||||
|
||||
var data = Encoding.UTF8.GetBytes(t.Content);
|
||||
var withBom = Encoding.UTF8.GetPreamble().Concat(data).ToArray();
|
||||
|
||||
using (var ms = new MemoryStream(withBom))
|
||||
{
|
||||
_viewFileSystem.AddFile(path, ms, true);
|
||||
}
|
||||
return t.Content;
|
||||
}
|
||||
|
||||
internal void RemoveViewFile(string alias)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(alias) == false)
|
||||
{
|
||||
var file = ViewPath(alias);
|
||||
if (_viewFileSystem.FileExists(file))
|
||||
_viewFileSystem.DeleteFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
public string ViewPath(string alias)
|
||||
{
|
||||
return _viewFileSystem.GetRelativePath(alias.Replace(" ", "") + ".cshtml");
|
||||
|
||||
//return SystemDirectories.MvcViews + "/" + alias.Replace(" ", "") + ".cshtml";
|
||||
}
|
||||
|
||||
private string EnsureInheritedLayout(ITemplate template)
|
||||
{
|
||||
string design = template.Content;
|
||||
|
||||
if (string.IsNullOrEmpty(design))
|
||||
{
|
||||
design = GetDefaultFileContent(template.MasterTemplateAlias);
|
||||
}
|
||||
|
||||
return design;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows for outputting a normalized appdomainappid token in a log format
|
||||
/// </summary>
|
||||
public sealed class AppDomainTokenConverter : log4net.Util.PatternConverter
|
||||
{
|
||||
protected override void Convert(TextWriter writer, object state)
|
||||
{
|
||||
writer.Write(HttpRuntime.AppDomainAppId.ReplaceNonAlphanumericChars(string.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
internal class DebugDiagnosticsLogger : ILogger
|
||||
{
|
||||
public void Error(Type callingType, string message, Exception exception)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(message + Environment.NewLine + exception, callingType.ToString());
|
||||
}
|
||||
|
||||
public void Warn(Type callingType, string message, params Func<object>[] formatItems)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(message, formatItems.Select(x => x()).ToArray()), callingType.ToString());
|
||||
}
|
||||
|
||||
public void WarnWithException(Type callingType, string message, Exception e, params Func<object>[] formatItems)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(message + Environment.NewLine + e, formatItems.Select(x => x()).ToArray()), callingType.ToString());
|
||||
}
|
||||
|
||||
public void Info(Type callingType, Func<string> generateMessage)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(generateMessage(), callingType.ToString());
|
||||
}
|
||||
|
||||
public void Info(Type type, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(generateMessageFormat, formatItems.Select(x => x()).ToArray()), type.ToString());
|
||||
}
|
||||
|
||||
public void Debug(Type callingType, Func<string> generateMessage)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(generateMessage(), callingType.ToString());
|
||||
}
|
||||
|
||||
public void Debug(Type type, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(string.Format(generateMessageFormat, formatItems.Select(x => x()).ToArray()), type.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for logging service.
|
||||
/// </summary>
|
||||
public interface ILogger
|
||||
{
|
||||
void Error(Type callingType, string message, Exception exception);
|
||||
|
||||
void Warn(Type callingType, string message, params Func<object>[] formatItems);
|
||||
|
||||
void WarnWithException(Type callingType, string message, Exception e, params Func<object>[] formatItems);
|
||||
|
||||
void Info(Type callingType, Func<string> generateMessage);
|
||||
|
||||
void Info(Type type, string generateMessageFormat, params Func<object>[] formatItems);
|
||||
|
||||
void Debug(Type callingType, Func<string> generateMessage);
|
||||
|
||||
void Debug(Type type, string generateMessageFormat, params Func<object>[] formatItems);
|
||||
}
|
||||
}
|
||||
@@ -6,43 +6,14 @@ using log4net;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
///<summary>
|
||||
/// Used for logging
|
||||
///<summary>
|
||||
/// Used for logging, ILogger should be used instead but this is available for static access to logging
|
||||
///</summary>
|
||||
/// <remarks>
|
||||
/// this wraps ILogger
|
||||
/// </remarks>
|
||||
public static class LogHelper
|
||||
{
|
||||
///<summary>
|
||||
/// Returns a logger for the type specified
|
||||
///</summary>
|
||||
///<typeparam name="T"></typeparam>
|
||||
///<returns></returns>
|
||||
internal static ILog LoggerFor<T>()
|
||||
{
|
||||
return LogManager.GetLogger(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a logger for the object's type
|
||||
/// </summary>
|
||||
/// <param name="getTypeFromInstance"></param>
|
||||
/// <returns></returns>
|
||||
internal static ILog LoggerFor(object getTypeFromInstance)
|
||||
{
|
||||
if (getTypeFromInstance == null) throw new ArgumentNullException("getTypeFromInstance");
|
||||
|
||||
return LogManager.GetLogger(getTypeFromInstance.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Useful if the logger itself is running on another thread
|
||||
/// </summary>
|
||||
/// <param name="generateMessageFormat"></param>
|
||||
/// <returns></returns>
|
||||
private static string PrefixThreadId(string generateMessageFormat)
|
||||
{
|
||||
return "[Thread " + Thread.CurrentThread.ManagedThreadId + "] " + generateMessageFormat;
|
||||
}
|
||||
|
||||
#region Error
|
||||
/// <summary>
|
||||
/// Adds an error log
|
||||
@@ -52,14 +23,14 @@ namespace Umbraco.Core.Logging
|
||||
/// <param name="exception"></param>
|
||||
public static void Error<T>(string message, Exception exception)
|
||||
{
|
||||
Error(typeof (T), message, exception);
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Error<T>(message, exception);
|
||||
}
|
||||
|
||||
public static void Error(Type callingType, string message, Exception exception)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger != null)
|
||||
logger.Error(PrefixThreadId(message), exception);
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Error(callingType, message, exception);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -68,11 +39,11 @@ namespace Umbraco.Core.Logging
|
||||
|
||||
public static void Warn(Type callingType, string message, params Func<object>[] formatItems)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || !logger.IsWarnEnabled) return;
|
||||
logger.WarnFormat(PrefixThreadId(message), formatItems.Select(x => x.Invoke()).ToArray());
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Warn(callingType, message, formatItems);
|
||||
}
|
||||
|
||||
[Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")]
|
||||
public static void Warn(Type callingType, string message, bool showHttpTrace, params Func<object>[] formatItems)
|
||||
{
|
||||
Mandate.ParameterNotNull(callingType, "callingType");
|
||||
@@ -81,11 +52,10 @@ namespace Umbraco.Core.Logging
|
||||
if (showHttpTrace && HttpContext.Current != null)
|
||||
{
|
||||
HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()));
|
||||
}
|
||||
}
|
||||
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || !logger.IsWarnEnabled) return;
|
||||
logger.WarnFormat(PrefixThreadId(message), formatItems.Select(x => x.Invoke()).ToArray());
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Warn(callingType, message, formatItems);
|
||||
|
||||
}
|
||||
|
||||
@@ -94,6 +64,7 @@ namespace Umbraco.Core.Logging
|
||||
WarnWithException(callingType, message, false, e, formatItems);
|
||||
}
|
||||
|
||||
[Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")]
|
||||
public static void WarnWithException(Type callingType, string message, bool showHttpTrace, Exception e, params Func<object>[] formatItems)
|
||||
{
|
||||
Mandate.ParameterNotNull(e, "e");
|
||||
@@ -108,10 +79,8 @@ namespace Umbraco.Core.Logging
|
||||
e);
|
||||
}
|
||||
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || !logger.IsWarnEnabled) return;
|
||||
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
|
||||
logger.WarnFormat(PrefixThreadId(message) + ". Exception: " + e, executedParams);
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.WarnWithException(callingType, message, e, formatItems);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -125,6 +94,7 @@ namespace Umbraco.Core.Logging
|
||||
Warn(typeof(T), message, formatItems);
|
||||
}
|
||||
|
||||
[Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")]
|
||||
public static void Warn<T>(string message, bool showHttpTrace, params Func<object>[] formatItems)
|
||||
{
|
||||
Warn(typeof(T), message, showHttpTrace, formatItems);
|
||||
@@ -134,6 +104,8 @@ namespace Umbraco.Core.Logging
|
||||
{
|
||||
WarnWithException(typeof(T), message, e, formatItems);
|
||||
}
|
||||
|
||||
[Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")]
|
||||
public static void WarnWithException<T>(string message, bool showHttpTrace, Exception e, params Func<object>[] formatItems)
|
||||
{
|
||||
WarnWithException(typeof(T), message, showHttpTrace, e, formatItems);
|
||||
@@ -160,9 +132,8 @@ namespace Umbraco.Core.Logging
|
||||
/// <param name="generateMessage"></param>
|
||||
public static void Info(Type callingType, Func<string> generateMessage)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || !logger.IsInfoEnabled) return;
|
||||
logger.Info(PrefixThreadId(generateMessage.Invoke()));
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Info(callingType, generateMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -173,10 +144,8 @@ namespace Umbraco.Core.Logging
|
||||
/// <param name="formatItems">The format items.</param>
|
||||
public static void Info(Type type, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
var logger = LogManager.GetLogger(type);
|
||||
if (logger == null || !logger.IsInfoEnabled) return;
|
||||
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
|
||||
logger.InfoFormat(PrefixThreadId(generateMessageFormat), executedParams);
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Info(type, generateMessageFormat, formatItems);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -211,9 +180,8 @@ namespace Umbraco.Core.Logging
|
||||
/// <param name="generateMessage"></param>
|
||||
public static void Debug(Type callingType, Func<string> generateMessage)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || !logger.IsDebugEnabled) return;
|
||||
logger.Debug(PrefixThreadId(generateMessage.Invoke()));
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Debug(callingType, generateMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -224,10 +192,8 @@ namespace Umbraco.Core.Logging
|
||||
/// <param name="formatItems">The format items.</param>
|
||||
public static void Debug(Type type, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
var logger = LogManager.GetLogger(type);
|
||||
if (logger == null || !logger.IsDebugEnabled) return;
|
||||
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
|
||||
logger.DebugFormat(PrefixThreadId(generateMessageFormat), executedParams);
|
||||
if (LoggerResolver.HasCurrent == false || LoggerResolver.Current.HasValue == false) return;
|
||||
LoggerResolver.Current.Logger.Debug(type, generateMessageFormat, formatItems);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -250,6 +216,7 @@ namespace Umbraco.Core.Logging
|
||||
/// <param name="generateMessageFormat"></param>
|
||||
/// <param name="showHttpTrace"></param>
|
||||
/// <param name="formatItems"></param>
|
||||
[Obsolete("Warnings with http trace should not be used. This method will be removed in future versions")]
|
||||
public static void Debug<T>(string generateMessageFormat, bool showHttpTrace, params Func<object>[] formatItems)
|
||||
{
|
||||
if (showHttpTrace && HttpContext.Current != null)
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
///<summary>
|
||||
/// Used for logging
|
||||
///</summary>
|
||||
public class Logger : ILogger
|
||||
{
|
||||
public Logger(FileInfo log4NetConfigFile)
|
||||
{
|
||||
XmlConfigurator.Configure(log4NetConfigFile);
|
||||
}
|
||||
|
||||
private Logger()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a logger with the default log4net configuration discovered (i.e. from the web.config)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Logger CreateWithDefaultLog4NetConfiguration()
|
||||
{
|
||||
return new Logger();
|
||||
}
|
||||
|
||||
///<summary>
|
||||
/// Returns a logger for the type specified
|
||||
///</summary>
|
||||
///<typeparam name="T"></typeparam>
|
||||
///<returns></returns>
|
||||
internal ILog LoggerFor<T>()
|
||||
{
|
||||
return LogManager.GetLogger(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a logger for the object's type
|
||||
/// </summary>
|
||||
/// <param name="getTypeFromInstance"></param>
|
||||
/// <returns></returns>
|
||||
internal ILog LoggerFor(object getTypeFromInstance)
|
||||
{
|
||||
if (getTypeFromInstance == null) throw new ArgumentNullException("getTypeFromInstance");
|
||||
|
||||
return LogManager.GetLogger(getTypeFromInstance.GetType());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Useful if the logger itself is running on another thread
|
||||
/// </summary>
|
||||
/// <param name="generateMessageFormat"></param>
|
||||
/// <returns></returns>
|
||||
private string PrefixThreadId(string generateMessageFormat)
|
||||
{
|
||||
return "[Thread " + Thread.CurrentThread.ManagedThreadId + "] " + generateMessageFormat;
|
||||
}
|
||||
|
||||
public void Error(Type callingType, string message, Exception exception)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger != null)
|
||||
logger.Error(PrefixThreadId(message), exception);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Warn(Type callingType, string message, params Func<object>[] formatItems)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || logger.IsWarnEnabled == false) return;
|
||||
logger.WarnFormat(PrefixThreadId(message), formatItems.Select(x => x.Invoke()).ToArray());
|
||||
}
|
||||
|
||||
public void Warn(Type callingType, string message, bool showHttpTrace, params Func<object>[] formatItems)
|
||||
{
|
||||
Mandate.ParameterNotNull(callingType, "callingType");
|
||||
Mandate.ParameterNotNullOrEmpty(message, "message");
|
||||
|
||||
if (showHttpTrace && HttpContext.Current != null)
|
||||
{
|
||||
HttpContext.Current.Trace.Warn(callingType.Name, string.Format(message, formatItems.Select(x => x.Invoke()).ToArray()));
|
||||
}
|
||||
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || logger.IsWarnEnabled == false) return;
|
||||
logger.WarnFormat(PrefixThreadId(message), formatItems.Select(x => x.Invoke()).ToArray());
|
||||
|
||||
}
|
||||
|
||||
public void WarnWithException(Type callingType, string message, Exception e, params Func<object>[] formatItems)
|
||||
{
|
||||
Mandate.ParameterNotNull(e, "e");
|
||||
Mandate.ParameterNotNull(callingType, "callingType");
|
||||
Mandate.ParameterNotNullOrEmpty(message, "message");
|
||||
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || logger.IsWarnEnabled == false) return;
|
||||
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
|
||||
logger.WarnFormat(PrefixThreadId(message) + ". Exception: " + e, executedParams);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Traces if tracing is enabled.
|
||||
/// </summary>
|
||||
/// <param name="callingType"></param>
|
||||
/// <param name="generateMessage"></param>
|
||||
public void Info(Type callingType, Func<string> generateMessage)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || logger.IsInfoEnabled == false) return;
|
||||
logger.Info(PrefixThreadId(generateMessage.Invoke()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Traces if tracing is enabled.
|
||||
/// </summary>
|
||||
/// <param name="type">The type for the logging namespace.</param>
|
||||
/// <param name="generateMessageFormat">The message format.</param>
|
||||
/// <param name="formatItems">The format items.</param>
|
||||
public void Info(Type type, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
var logger = LogManager.GetLogger(type);
|
||||
if (logger == null || logger.IsInfoEnabled == false) return;
|
||||
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
|
||||
logger.InfoFormat(PrefixThreadId(generateMessageFormat), executedParams);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Debugs if tracing is enabled.
|
||||
/// </summary>
|
||||
/// <param name="callingType"></param>
|
||||
/// <param name="generateMessage"></param>
|
||||
public void Debug(Type callingType, Func<string> generateMessage)
|
||||
{
|
||||
var logger = LogManager.GetLogger(callingType);
|
||||
if (logger == null || logger.IsDebugEnabled == false) return;
|
||||
logger.Debug(PrefixThreadId(generateMessage.Invoke()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debugs if tracing is enabled.
|
||||
/// </summary>
|
||||
/// <param name="type">The type for the logging namespace.</param>
|
||||
/// <param name="generateMessageFormat">The message format.</param>
|
||||
/// <param name="formatItems">The format items.</param>
|
||||
public void Debug(Type type, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
var logger = LogManager.GetLogger(type);
|
||||
if (logger == null || logger.IsDebugEnabled == false) return;
|
||||
var executedParams = formatItems.Select(x => x.Invoke()).ToArray();
|
||||
logger.DebugFormat(PrefixThreadId(generateMessageFormat), executedParams);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows for strongly typed log sources
|
||||
/// </summary>
|
||||
public static class LoggerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds an error log
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="exception"></param>
|
||||
public static void Error<T>(this ILogger logger, string message, Exception exception)
|
||||
{
|
||||
logger.Error(typeof(T), message, exception);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a warn log
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="formatItems"></param>
|
||||
public static void Warn<T>(this ILogger logger, string message, params Func<object>[] formatItems)
|
||||
{
|
||||
logger.Warn(typeof(T), message, formatItems);
|
||||
}
|
||||
|
||||
public static void WarnWithException<T>(this ILogger logger, string message, Exception e, params Func<object>[] formatItems)
|
||||
{
|
||||
logger.WarnWithException(typeof(T), message, e, formatItems);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Traces a message, only generating the message if tracing is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="generateMessageFormat">The generate message format.</param>
|
||||
/// <param name="formatItems">The format items.</param>
|
||||
/// <remarks></remarks>
|
||||
public static void Info<T>(this ILogger logger, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
logger.Info(typeof(T), generateMessageFormat, formatItems);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Traces a message, only generating the message if tracing is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="generateMessage">The delegate to generate a message.</param>
|
||||
/// <remarks></remarks>
|
||||
public static void Info<T>(this ILogger logger, Func<string> generateMessage)
|
||||
{
|
||||
logger.Info(typeof(T), generateMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debugs a message, only generating the message if tracing is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="generateMessage">The delegate to generate a message.</param>
|
||||
/// <remarks></remarks>
|
||||
public static void Debug<T>(this ILogger logger, Func<string> generateMessage)
|
||||
{
|
||||
logger.Debug(typeof(T), generateMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Debugs a message, only generating the message if debug is actually enabled. Use this method to avoid calling any long-running methods such as "ToDebugString" if logging is disabled.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="generateMessageFormat">The generate message format.</param>
|
||||
/// <param name="formatItems">The format items.</param>
|
||||
/// <remarks></remarks>
|
||||
public static void Debug<T>(this ILogger logger, string generateMessageFormat, params Func<object>[] formatItems)
|
||||
{
|
||||
logger.Debug(typeof(T), generateMessageFormat, formatItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
public sealed class LoggerResolver : SingleObjectResolverBase<LoggerResolver, ILogger>
|
||||
{
|
||||
public LoggerResolver(ILogger logger)
|
||||
: base(logger)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method allowing to change the logger during startup
|
||||
/// </summary>
|
||||
/// <param name="profiler"></param>
|
||||
internal void SetLogger(ILogger profiler)
|
||||
{
|
||||
Value = profiler;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current logger
|
||||
/// </summary>
|
||||
public ILogger Logger
|
||||
{
|
||||
get { return Value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
internal class OwinLogger : Microsoft.Owin.Logging.ILogger
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly Lazy<Type> _type;
|
||||
|
||||
public OwinLogger(ILogger logger, Lazy<Type> type)
|
||||
{
|
||||
_logger = logger;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggregates most logging patterns to a single method. This must be compatible with the Func representation in the OWIN environment.
|
||||
/// To check IsEnabled call WriteCore with only TraceEventType and check the return value, no event will be written.
|
||||
/// </summary>
|
||||
/// <param name="eventType"/><param name="eventId"/><param name="state"/><param name="exception"/><param name="formatter"/>
|
||||
/// <returns/>
|
||||
public bool WriteCore(TraceEventType eventType, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
||||
{
|
||||
if (state == null) state = "";
|
||||
switch (eventType)
|
||||
{
|
||||
case TraceEventType.Critical:
|
||||
_logger.Error(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state), exception ?? new Exception("Critical error"));
|
||||
return true;
|
||||
case TraceEventType.Error:
|
||||
_logger.Error(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state), exception ?? new Exception("Error"));
|
||||
return true;
|
||||
case TraceEventType.Warning:
|
||||
_logger.Warn(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
case TraceEventType.Information:
|
||||
_logger.Info(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
case TraceEventType.Verbose:
|
||||
_logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
case TraceEventType.Start:
|
||||
_logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
case TraceEventType.Stop:
|
||||
_logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
case TraceEventType.Suspend:
|
||||
_logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
case TraceEventType.Resume:
|
||||
_logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
case TraceEventType.Transfer:
|
||||
_logger.Debug(_type.Value, string.Format("Event Id: {0}, state: {1}", eventId, state));
|
||||
return true;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("eventType");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Owin.Logging;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
internal class OwinLoggerFactory : ILoggerFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new ILogger instance of the given name.
|
||||
/// </summary>
|
||||
/// <param name="name"/>
|
||||
/// <returns/>
|
||||
public Microsoft.Owin.Logging.ILogger Create(string name)
|
||||
{
|
||||
return new OwinLogger(
|
||||
LoggerResolver.HasCurrent ? LoggerResolver.Current.Logger : new DebugDiagnosticsLogger(),
|
||||
new Lazy<Type>(() => Type.GetType(name) ?? typeof (OwinLogger)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using Umbraco.Core.Profiling;
|
||||
|
||||
namespace Umbraco.Core.Logging
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to create DisposableTimer instances for debugging or tracing durations
|
||||
/// </summary>
|
||||
public sealed class ProfilingLogger
|
||||
{
|
||||
public ILogger Logger { get; private set; }
|
||||
public IProfiler Profiler { get; private set; }
|
||||
|
||||
public ProfilingLogger(ILogger logger, IProfiler profiler)
|
||||
{
|
||||
Logger = logger;
|
||||
Profiler = profiler;
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
if (profiler == null) throw new ArgumentNullException("profiler");
|
||||
}
|
||||
|
||||
public DisposableTimer TraceDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return new DisposableTimer(Logger, DisposableTimer.LogType.Info, Profiler, typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public DisposableTimer TraceDuration<T>(string startMessage)
|
||||
{
|
||||
return new DisposableTimer(Logger, DisposableTimer.LogType.Info, Profiler, typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
public DisposableTimer TraceDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
return new DisposableTimer(Logger, DisposableTimer.LogType.Info, Profiler, loggerType, startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public DisposableTimer DebugDuration<T>(string startMessage, string completeMessage)
|
||||
{
|
||||
return new DisposableTimer(Logger, DisposableTimer.LogType.Debug, Profiler, typeof(T), startMessage, completeMessage);
|
||||
}
|
||||
|
||||
public DisposableTimer DebugDuration<T>(string startMessage)
|
||||
{
|
||||
return new DisposableTimer(Logger, DisposableTimer.LogType.Debug, Profiler, typeof(T), startMessage, "Complete");
|
||||
}
|
||||
|
||||
public DisposableTimer DebugDuration(Type loggerType, string startMessage, string completeMessage)
|
||||
{
|
||||
return new DisposableTimer(Logger, DisposableTimer.LogType.Debug, Profiler, loggerType, startMessage, completeMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using umbraco.interfaces;
|
||||
|
||||
@@ -18,13 +19,14 @@ namespace Umbraco.Core.Macros
|
||||
/// </remarks>
|
||||
internal sealed class MacroFieldEditorsResolver : LazyManyObjectsResolverBase<MacroFieldEditorsResolver, IMacroGuiRendering>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="macroEditors"></param>
|
||||
internal MacroFieldEditorsResolver(Func<IEnumerable<Type>> macroEditors)
|
||||
: base(macroEditors, ObjectLifetimeScope.Transient)
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="macroEditors"></param>
|
||||
internal MacroFieldEditorsResolver(IServiceProvider serviceProvider, ILogger logger, Func<IEnumerable<Type>> macroEditors)
|
||||
: base(serviceProvider, logger, macroEditors, ObjectLifetimeScope.Transient)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
@@ -70,10 +72,10 @@ namespace Umbraco.Core.Macros
|
||||
internal Control GetMacroRenderControlByType(PersistableMacroProperty prop, string uniqueId)
|
||||
{
|
||||
var m = MacroControlTypes.FindLast(macroGuiCcontrol => macroGuiCcontrol.ToString() == string.Format("{0}.{1}", prop.AssemblyName, prop.TypeName));
|
||||
var instance = PluginManager.Current.CreateInstance<IMacroGuiRendering>(m);
|
||||
var instance = ServiceProvider.GetService(m) as IMacroGuiRendering;
|
||||
if (instance != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(prop.Value))
|
||||
if (string.IsNullOrEmpty(prop.Value) == false)
|
||||
{
|
||||
instance.Value = HttpUtility.HtmlDecode(prop.Value);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Umbraco.Core.Macros
|
||||
internal class MacroTagParser
|
||||
{
|
||||
private static readonly Regex MacroRteContent = new Regex(@"(<!--\s*?)(<\?UMBRACO_MACRO.*?/>)(\s*?-->)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO macroAlias=[""']([\w\.]+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
private static readonly Regex MacroPersistedFormat = new Regex(@"(<\?UMBRACO_MACRO (?:.+)?macroAlias=[""']([^""\'\n\r]+?)[""'].+?)(?:/>|>.*?</\?UMBRACO_MACRO>)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
|
||||
|
||||
/// <summary>
|
||||
/// This formats the persisted string to something useful for the rte so that the macro renders properly since we
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
|
||||
namespace Umbraco.Core.Macros
|
||||
@@ -9,13 +10,14 @@ namespace Umbraco.Core.Macros
|
||||
/// </summary>
|
||||
internal sealed class XsltExtensionsResolver : LazyManyObjectsResolverBase<XsltExtensionsResolver, XsltExtension>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="packageActions"></param>
|
||||
internal XsltExtensionsResolver(Func<IEnumerable<Type>> packageActions)
|
||||
: base(packageActions, ObjectLifetimeScope.Application)
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="packageActions"></param>
|
||||
internal XsltExtensionsResolver(IServiceProvider serviceProvider, ILogger logger, Func<IEnumerable<Type>> packageActions)
|
||||
: base(serviceProvider, logger, packageActions, ObjectLifetimeScope.Application)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures that virtual paths are taken care of
|
||||
/// </summary>
|
||||
internal class GridEditorConverter : JsonCreationConverter<GridEditor>
|
||||
{
|
||||
protected override GridEditor Create(Type objectType, JObject jObject)
|
||||
{
|
||||
return new GridEditor();
|
||||
}
|
||||
|
||||
protected override void Deserialize(JObject jObject, GridEditor target, JsonSerializer serializer)
|
||||
{
|
||||
base.Deserialize(jObject, target, serializer);
|
||||
|
||||
if (target.View.IsNullOrWhiteSpace() == false && target.View.StartsWith("~/"))
|
||||
{
|
||||
target.View = IOHelper.ResolveUrl(target.View);
|
||||
}
|
||||
|
||||
if (target.Render.IsNullOrWhiteSpace() == false && target.Render.StartsWith("~/"))
|
||||
{
|
||||
target.Render = IOHelper.ResolveUrl(target.Render);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
@@ -11,73 +13,92 @@ namespace Umbraco.Core.Manifest
|
||||
/// </summary>
|
||||
internal class ManifestBuilder
|
||||
{
|
||||
private readonly IRuntimeCacheProvider _cache;
|
||||
private readonly ManifestParser _parser;
|
||||
|
||||
private static readonly ConcurrentDictionary<string, object> StaticCache = new ConcurrentDictionary<string, object>();
|
||||
|
||||
private const string ManifestKey = "manifests";
|
||||
public ManifestBuilder(IRuntimeCacheProvider cache, ManifestParser parser)
|
||||
{
|
||||
_cache = cache;
|
||||
_parser = parser;
|
||||
}
|
||||
|
||||
private const string GridEditorsKey = "grideditors";
|
||||
private const string PropertyEditorsKey = "propertyeditors";
|
||||
private const string ParameterEditorsKey = "parametereditors";
|
||||
|
||||
/// <summary>
|
||||
/// Returns all property editors found in the manfifests
|
||||
/// Returns all grid editors found in the manfifests
|
||||
/// </summary>
|
||||
internal static IEnumerable<PropertyEditor> PropertyEditors
|
||||
internal IEnumerable<GridEditor> GridEditors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (IEnumerable<PropertyEditor>) StaticCache.GetOrAdd(
|
||||
PropertyEditorsKey,
|
||||
s =>
|
||||
return _cache.GetCacheItem<IEnumerable<GridEditor>>(
|
||||
typeof (ManifestBuilder) + GridEditorsKey,
|
||||
() =>
|
||||
{
|
||||
var editors = new List<GridEditor>();
|
||||
foreach (var manifest in _parser.GetManifests())
|
||||
{
|
||||
var editors = new List<PropertyEditor>();
|
||||
foreach (var manifest in GetManifests())
|
||||
if (manifest.GridEditors != null)
|
||||
{
|
||||
if (manifest.PropertyEditors != null)
|
||||
{
|
||||
editors.AddRange(ManifestParser.GetPropertyEditors(manifest.PropertyEditors));
|
||||
}
|
||||
|
||||
editors.AddRange(ManifestParser.GetGridEditors(manifest.GridEditors));
|
||||
}
|
||||
return editors;
|
||||
});
|
||||
|
||||
}
|
||||
return editors;
|
||||
}, new TimeSpan(0, 10, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all property editors found in the manfifests
|
||||
/// </summary>
|
||||
internal IEnumerable<PropertyEditor> PropertyEditors
|
||||
{
|
||||
get
|
||||
{
|
||||
return _cache.GetCacheItem<IEnumerable<PropertyEditor>>(
|
||||
typeof(ManifestBuilder) + PropertyEditorsKey,
|
||||
() =>
|
||||
{
|
||||
var editors = new List<PropertyEditor>();
|
||||
foreach (var manifest in _parser.GetManifests())
|
||||
{
|
||||
if (manifest.PropertyEditors != null)
|
||||
{
|
||||
editors.AddRange(ManifestParser.GetPropertyEditors(manifest.PropertyEditors));
|
||||
}
|
||||
|
||||
}
|
||||
return editors;
|
||||
}, new TimeSpan(0, 10, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all parameter editors found in the manfifests and all property editors that are flagged to be parameter editors
|
||||
/// </summary>
|
||||
internal static IEnumerable<ParameterEditor> ParameterEditors
|
||||
internal IEnumerable<ParameterEditor> ParameterEditors
|
||||
{
|
||||
get
|
||||
{
|
||||
return (IEnumerable<ParameterEditor>)StaticCache.GetOrAdd(
|
||||
ParameterEditorsKey,
|
||||
s =>
|
||||
return _cache.GetCacheItem<IEnumerable<ParameterEditor>>(
|
||||
typeof (ManifestBuilder) + ParameterEditorsKey,
|
||||
() =>
|
||||
{
|
||||
var editors = new List<ParameterEditor>();
|
||||
foreach (var manifest in GetManifests())
|
||||
foreach (var manifest in _parser.GetManifests())
|
||||
{
|
||||
if (manifest.ParameterEditors != null)
|
||||
{
|
||||
editors.AddRange(ManifestParser.GetParameterEditors(manifest.ParameterEditors));
|
||||
editors.AddRange(ManifestParser.GetParameterEditors(manifest.ParameterEditors));
|
||||
}
|
||||
}
|
||||
return editors;
|
||||
});
|
||||
}, new TimeSpan(0, 10, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the manifests are found and loaded into memory
|
||||
/// </summary>
|
||||
private static IEnumerable<PackageManifest> GetManifests()
|
||||
{
|
||||
return (IEnumerable<PackageManifest>) StaticCache.GetOrAdd(ManifestKey, s =>
|
||||
{
|
||||
var parser = new ManifestParser(new DirectoryInfo(IOHelper.MapPath("~/App_Plugins")));
|
||||
return parser.GetManifests();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
@@ -17,15 +18,29 @@ namespace Umbraco.Core.Manifest
|
||||
internal class ManifestParser
|
||||
{
|
||||
private readonly DirectoryInfo _pluginsDir;
|
||||
|
||||
private readonly IRuntimeCacheProvider _cache;
|
||||
|
||||
//used to strip comments
|
||||
private static readonly Regex CommentsSurround = new Regex(@"/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/", RegexOptions.Compiled);
|
||||
private static readonly Regex CommentsLine = new Regex(@"//.*?$", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
private static readonly Regex CommentsLine = new Regex(@"^\s*//.*?$", RegexOptions.Compiled | RegexOptions.Multiline);
|
||||
|
||||
public ManifestParser(DirectoryInfo pluginsDir)
|
||||
public ManifestParser(DirectoryInfo pluginsDir, IRuntimeCacheProvider cache)
|
||||
{
|
||||
if (pluginsDir == null) throw new ArgumentNullException("pluginsDir");
|
||||
_pluginsDir = pluginsDir;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the grid editors from the json array
|
||||
/// </summary>
|
||||
/// <param name="jsonEditors"></param>
|
||||
/// <returns></returns>
|
||||
internal static IEnumerable<GridEditor> GetGridEditors(JArray jsonEditors)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<IEnumerable<GridEditor>>(
|
||||
jsonEditors.ToString(),
|
||||
new GridEditorConverter());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,11 +72,17 @@ namespace Umbraco.Core.Manifest
|
||||
/// Get all registered manifests
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This ensures that we only build and look for all manifests once per Web app (based on the IRuntimeCache)
|
||||
/// </remarks>
|
||||
public IEnumerable<PackageManifest> GetManifests()
|
||||
{
|
||||
//get all Manifest.js files in the appropriate folders
|
||||
var manifestFileContents = GetAllManfifestFileContents(_pluginsDir);
|
||||
return CreateManifests(manifestFileContents.ToArray());
|
||||
return _cache.GetCacheItem<IEnumerable<PackageManifest>>(typeof (ManifestParser) + "GetManifests", () =>
|
||||
{
|
||||
//get all Manifest.js files in the appropriate folders
|
||||
var manifestFileContents = GetAllManifestFileContents(_pluginsDir);
|
||||
return CreateManifests(manifestFileContents.ToArray());
|
||||
}, new TimeSpan(0, 10, 0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -69,7 +90,7 @@ namespace Umbraco.Core.Manifest
|
||||
/// </summary>
|
||||
/// <param name="currDir"></param>
|
||||
/// <returns></returns>
|
||||
private IEnumerable<string> GetAllManfifestFileContents(DirectoryInfo currDir)
|
||||
private IEnumerable<string> GetAllManifestFileContents(DirectoryInfo currDir)
|
||||
{
|
||||
var depth = FolderDepth(_pluginsDir, currDir);
|
||||
|
||||
@@ -79,7 +100,7 @@ namespace Umbraco.Core.Manifest
|
||||
var result = new List<string>();
|
||||
foreach (var d in dirs)
|
||||
{
|
||||
result.AddRange(GetAllManfifestFileContents(d));
|
||||
result.AddRange(GetAllManifestFileContents(d));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -154,6 +175,20 @@ namespace Umbraco.Core.Manifest
|
||||
throw new FormatException("The manifest is not formatted correctly contains more than one 'propertyEditors' element");
|
||||
}
|
||||
|
||||
//validate the parameterEditors section
|
||||
var paramEditors = deserialized.Properties().Where(x => x.Name == "parameterEditors").ToArray();
|
||||
if (paramEditors.Length > 1)
|
||||
{
|
||||
throw new FormatException("The manifest is not formatted correctly contains more than one 'parameterEditors' element");
|
||||
}
|
||||
|
||||
//validate the gridEditors section
|
||||
var gridEditors = deserialized.Properties().Where(x => x.Name == "gridEditors").ToArray();
|
||||
if (gridEditors.Length > 1)
|
||||
{
|
||||
throw new FormatException("The manifest is not formatted correctly contains more than one 'gridEditors' element");
|
||||
}
|
||||
|
||||
var jConfig = init.Any() ? (JArray)deserialized["javascript"] : new JArray();
|
||||
ReplaceVirtualPaths(jConfig);
|
||||
|
||||
@@ -175,13 +210,30 @@ namespace Umbraco.Core.Manifest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//replace virtual paths for each property editor
|
||||
if (deserialized["gridEditors"] != null)
|
||||
{
|
||||
foreach (JObject p in deserialized["gridEditors"])
|
||||
{
|
||||
if (p["view"] != null)
|
||||
{
|
||||
ReplaceVirtualPaths(p["view"]);
|
||||
}
|
||||
if (p["render"] != null)
|
||||
{
|
||||
ReplaceVirtualPaths(p["render"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var manifest = new PackageManifest()
|
||||
{
|
||||
JavaScriptInitialize = jConfig,
|
||||
StylesheetInitialize = cssConfig,
|
||||
PropertyEditors = propEditors.Any() ? (JArray)deserialized["propertyEditors"] : new JArray(),
|
||||
ParameterEditors = propEditors.Any() ? (JArray)deserialized["parameterEditors"] : new JArray()
|
||||
ParameterEditors = paramEditors.Any() ? (JArray)deserialized["parameterEditors"] : new JArray(),
|
||||
GridEditors = gridEditors.Any() ? (JArray)deserialized["gridEditors"] : new JArray()
|
||||
};
|
||||
result.Add(manifest);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
@@ -7,10 +8,17 @@ namespace Umbraco.Core.Manifest
|
||||
{
|
||||
internal class ManifestWatcher : DisposableObject
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly List<FileSystemWatcher> _fws = new List<FileSystemWatcher>();
|
||||
private static volatile bool _isRestarting = false;
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
public ManifestWatcher(ILogger logger)
|
||||
{
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public void Start(params string[] packageFolders)
|
||||
{
|
||||
foreach (var packageFolder in packageFolders)
|
||||
@@ -43,7 +51,7 @@ namespace Umbraco.Core.Manifest
|
||||
{
|
||||
_isRestarting = true;
|
||||
|
||||
LogHelper.Info<ManifestWatcher>("manifest has changed, app pool is restarting (" + e.FullPath + ")");
|
||||
_logger.Info<ManifestWatcher>("manifest has changed, app pool is restarting (" + e.FullPath + ")");
|
||||
HttpRuntime.UnloadAppDomain();
|
||||
Dispose();
|
||||
}
|
||||
|
||||
@@ -26,5 +26,10 @@ namespace Umbraco.Core.Manifest
|
||||
/// The json array of parameter editors
|
||||
/// </summary>
|
||||
public JArray ParameterEditors { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The json array of grid editors
|
||||
/// </summary>
|
||||
public JArray GridEditors { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Media.Exif
|
||||
{
|
||||
/// <summary>
|
||||
/// An endian-aware converter for converting between base data types
|
||||
/// and an array of bytes.
|
||||
/// </summary>
|
||||
internal class BitConverterEx
|
||||
{
|
||||
#region Public Enums
|
||||
/// <summary>
|
||||
/// Represents the byte order.
|
||||
/// </summary>
|
||||
public enum ByteOrder
|
||||
{
|
||||
LittleEndian = 1,
|
||||
BigEndian = 2,
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Member Variables
|
||||
private ByteOrder mFrom, mTo;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public BitConverterEx(ByteOrder from, ByteOrder to)
|
||||
{
|
||||
mFrom = from;
|
||||
mTo = to;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>
|
||||
/// Indicates the byte order in which data is stored in this platform.
|
||||
/// </summary>
|
||||
public static ByteOrder SystemByteOrder
|
||||
{
|
||||
get
|
||||
{
|
||||
return (BitConverter.IsLittleEndian ? ByteOrder.LittleEndian : ByteOrder.BigEndian);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Predefined Values
|
||||
/// <summary>
|
||||
/// Returns a bit converter that converts between little-endian and system byte-order.
|
||||
/// </summary>
|
||||
public static BitConverterEx LittleEndian
|
||||
{
|
||||
get
|
||||
{
|
||||
return new BitConverterEx(ByteOrder.LittleEndian, BitConverterEx.SystemByteOrder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a bit converter that converts between big-endian and system byte-order.
|
||||
/// </summary>
|
||||
public static BitConverterEx BigEndian
|
||||
{
|
||||
get
|
||||
{
|
||||
return new BitConverterEx(ByteOrder.BigEndian, BitConverterEx.SystemByteOrder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a bit converter that does not do any byte-order conversion.
|
||||
/// </summary>
|
||||
public static BitConverterEx SystemEndian
|
||||
{
|
||||
get
|
||||
{
|
||||
return new BitConverterEx(BitConverterEx.SystemByteOrder, BitConverterEx.SystemByteOrder);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Static Methods
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a Unicode character.
|
||||
/// </summary>
|
||||
public static char ToChar(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 2, from, to);
|
||||
return BitConverter.ToChar(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 16-bit unsigned integer.
|
||||
/// </summary>
|
||||
public static ushort ToUInt16(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 2, from, to);
|
||||
return BitConverter.ToUInt16(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 32-bit unsigned integer.
|
||||
/// </summary>
|
||||
public static uint ToUInt32(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 4, from, to);
|
||||
return BitConverter.ToUInt32(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 64-bit unsigned integer.
|
||||
/// </summary>
|
||||
public static ulong ToUInt64(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 8, from, to);
|
||||
return BitConverter.ToUInt64(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 16-bit signed integer.
|
||||
/// </summary>
|
||||
public static short ToInt16(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 2, from, to);
|
||||
return BitConverter.ToInt16(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 32-bit signed integer.
|
||||
/// </summary>
|
||||
public static int ToInt32(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 4, from, to);
|
||||
return BitConverter.ToInt32(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 64-bit signed integer.
|
||||
/// </summary>
|
||||
public static long ToInt64(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 8, from, to);
|
||||
return BitConverter.ToInt64(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a single precision floating number.
|
||||
/// </summary>
|
||||
public static float ToSingle(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 4, from, to);
|
||||
return BitConverter.ToSingle(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a double precision floating number.
|
||||
/// </summary>
|
||||
public static double ToDouble(byte[] value, long startIndex, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = CheckData(value, startIndex, 8, from, to);
|
||||
return BitConverter.ToDouble(data, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 16-bit unsigned integer to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(ushort value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 32-bit unsigned integer to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(uint value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 64-bit unsigned integer to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(ulong value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 16-bit signed integer to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(short value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 32-bit signed integer to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(int value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 64-bit signed integer to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(long value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given single precision floating-point number to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(float value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given double precision floating-point number to an array of bytes.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(double value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = BitConverter.GetBytes(value);
|
||||
data = CheckData(data, from, to);
|
||||
return data;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Instance Methods
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 16-bit unsigned integer.
|
||||
/// </summary>
|
||||
public char ToChar(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToChar(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 16-bit unsigned integer.
|
||||
/// </summary>
|
||||
public ushort ToUInt16(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToUInt16(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 32-bit unsigned integer.
|
||||
/// </summary>
|
||||
public uint ToUInt32(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToUInt32(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 64-bit unsigned integer.
|
||||
/// </summary>
|
||||
public ulong ToUInt64(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToUInt64(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 16-bit signed integer.
|
||||
/// </summary>
|
||||
public short ToInt16(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToInt16(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 32-bit signed integer.
|
||||
/// </summary>
|
||||
public int ToInt32(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToInt32(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a 64-bit signed integer.
|
||||
/// </summary>
|
||||
public long ToInt64(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToInt64(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a single precision floating number.
|
||||
/// </summary>
|
||||
public float ToSingle(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToSingle(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of bytes to a double precision floating number.
|
||||
/// </summary>
|
||||
public double ToDouble(byte[] value, long startIndex)
|
||||
{
|
||||
return BitConverterEx.ToDouble(value, startIndex, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 16-bit unsigned integer to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(ushort value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 32-bit unsigned integer to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(uint value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 64-bit unsigned integer to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(ulong value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 16-bit signed integer to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(short value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 32-bit signed integer to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(int value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given 64-bit signed integer to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(long value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given single precision floating-point number to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(float value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given double precision floating-point number to an array of bytes.
|
||||
/// </summary>
|
||||
public byte[] GetBytes(double value)
|
||||
{
|
||||
return BitConverterEx.GetBytes(value, mFrom, mTo);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Private Helpers
|
||||
/// <summary>
|
||||
/// Reverse the array of bytes as needed.
|
||||
/// </summary>
|
||||
private static byte[] CheckData(byte[] value, long startIndex, long length, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
byte[] data = new byte[length];
|
||||
Array.Copy(value, startIndex, data, 0, length);
|
||||
if (from != to)
|
||||
Array.Reverse(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverse the array of bytes as needed.
|
||||
/// </summary>
|
||||
private static byte[] CheckData(byte[] value, ByteOrder from, ByteOrder to)
|
||||
{
|
||||
return CheckData(value, 0, value.Length, from, to);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,357 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Media.Exif
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts between exif data types and array of bytes.
|
||||
/// </summary>
|
||||
internal class ExifBitConverter : BitConverterEx
|
||||
{
|
||||
#region Constructors
|
||||
public ExifBitConverter(ByteOrder from, ByteOrder to)
|
||||
: base(from, to)
|
||||
{
|
||||
;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Static Methods
|
||||
/// <summary>
|
||||
/// Returns an ASCII string converted from the given byte array.
|
||||
/// </summary>
|
||||
public static string ToAscii(byte[] data, bool endatfirstnull, Encoding encoding)
|
||||
{
|
||||
int len = data.Length;
|
||||
if (endatfirstnull)
|
||||
{
|
||||
len = Array.IndexOf(data, (byte)0);
|
||||
if (len == -1) len = data.Length;
|
||||
}
|
||||
return encoding.GetString(data, 0, len);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an ASCII string converted from the given byte array.
|
||||
/// </summary>
|
||||
public static string ToAscii(byte[] data, Encoding encoding)
|
||||
{
|
||||
return ToAscii(data, true, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string converted from the given byte array.
|
||||
/// from the numeric value of each byte.
|
||||
/// </summary>
|
||||
public static string ToString(byte[] data)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (byte b in data)
|
||||
sb.Append(b);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a DateTime object converted from the given byte array.
|
||||
/// </summary>
|
||||
public static DateTime ToDateTime(byte[] data, bool hastime)
|
||||
{
|
||||
string str = ToAscii(data, Encoding.ASCII);
|
||||
string[] parts = str.Split(new char[] { ':', ' ' });
|
||||
try
|
||||
{
|
||||
if (hastime && parts.Length == 6)
|
||||
{
|
||||
// yyyy:MM:dd HH:mm:ss
|
||||
// This is the expected format though some cameras
|
||||
// can use single digits. See Issue 21.
|
||||
return new DateTime(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]), int.Parse(parts[3]), int.Parse(parts[4]), int.Parse(parts[5]));
|
||||
}
|
||||
else if (!hastime && parts.Length == 3)
|
||||
{
|
||||
// yyyy:MM:dd
|
||||
return new DateTime(int.Parse(parts[0]), int.Parse(parts[1]), int.Parse(parts[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return DateTime.MinValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a DateTime object converted from the given byte array.
|
||||
/// </summary>
|
||||
public static DateTime ToDateTime(byte[] data)
|
||||
{
|
||||
return ToDateTime(data, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an unsigned rational number converted from the first
|
||||
/// eight bytes of the given byte array. The first four bytes are
|
||||
/// assumed to be the numerator and the next four bytes are the
|
||||
/// denumerator.
|
||||
/// Numbers are converted from the given byte-order to platform byte-order.
|
||||
/// </summary>
|
||||
public static MathEx.UFraction32 ToURational(byte[] data, ByteOrder frombyteorder)
|
||||
{
|
||||
byte[] num = new byte[4];
|
||||
byte[] den = new byte[4];
|
||||
Array.Copy(data, 0, num, 0, 4);
|
||||
Array.Copy(data, 4, den, 0, 4);
|
||||
return new MathEx.UFraction32(ToUInt32(num, 0, frombyteorder, BitConverterEx.SystemByteOrder), ToUInt32(den, 0, frombyteorder, BitConverterEx.SystemByteOrder));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a signed rational number converted from the first
|
||||
/// eight bytes of the given byte array. The first four bytes are
|
||||
/// assumed to be the numerator and the next four bytes are the
|
||||
/// denumerator.
|
||||
/// Numbers are converted from the given byte-order to platform byte-order.
|
||||
/// </summary>
|
||||
public static MathEx.Fraction32 ToSRational(byte[] data, ByteOrder frombyteorder)
|
||||
{
|
||||
byte[] num = new byte[4];
|
||||
byte[] den = new byte[4];
|
||||
Array.Copy(data, 0, num, 0, 4);
|
||||
Array.Copy(data, 4, den, 0, 4);
|
||||
return new MathEx.Fraction32(ToInt32(num, 0, frombyteorder, BitConverterEx.SystemByteOrder), ToInt32(den, 0, frombyteorder, BitConverterEx.SystemByteOrder));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of 16-bit unsigned integers converted from
|
||||
/// the given byte array.
|
||||
/// Numbers are converted from the given byte-order to platform byte-order.
|
||||
/// </summary>
|
||||
public static ushort[] ToUShortArray(byte[] data, int count, ByteOrder frombyteorder)
|
||||
{
|
||||
ushort[] numbers = new ushort[count];
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
byte[] num = new byte[2];
|
||||
Array.Copy(data, i * 2, num, 0, 2);
|
||||
numbers[i] = ToUInt16(num, 0, frombyteorder, BitConverterEx.SystemByteOrder);
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of 32-bit unsigned integers converted from
|
||||
/// the given byte array.
|
||||
/// Numbers are converted from the given byte-order to platform byte-order.
|
||||
/// </summary>
|
||||
public static uint[] ToUIntArray(byte[] data, int count, ByteOrder frombyteorder)
|
||||
{
|
||||
uint[] numbers = new uint[count];
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
byte[] num = new byte[4];
|
||||
Array.Copy(data, i * 4, num, 0, 4);
|
||||
numbers[i] = ToUInt32(num, 0, frombyteorder, BitConverterEx.SystemByteOrder);
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of 32-bit signed integers converted from
|
||||
/// the given byte array.
|
||||
/// Numbers are converted from the given byte-order to platform byte-order.
|
||||
/// </summary>
|
||||
public static int[] ToSIntArray(byte[] data, int count, ByteOrder byteorder)
|
||||
{
|
||||
int[] numbers = new int[count];
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
byte[] num = new byte[4];
|
||||
Array.Copy(data, i * 4, num, 0, 4);
|
||||
numbers[i] = ToInt32(num, 0, byteorder, BitConverterEx.SystemByteOrder);
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of unsigned rational numbers converted from
|
||||
/// the given byte array.
|
||||
/// Numbers are converted from the given byte-order to platform byte-order.
|
||||
/// </summary>
|
||||
public static MathEx.UFraction32[] ToURationalArray(byte[] data, int count, ByteOrder frombyteorder)
|
||||
{
|
||||
MathEx.UFraction32[] numbers = new MathEx.UFraction32[count];
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
byte[] num = new byte[4];
|
||||
byte[] den = new byte[4];
|
||||
Array.Copy(data, i * 8, num, 0, 4);
|
||||
Array.Copy(data, i * 8 + 4, den, 0, 4);
|
||||
numbers[i].Set(ToUInt32(num, 0, frombyteorder, BitConverterEx.SystemByteOrder), ToUInt32(den, 0, frombyteorder, BitConverterEx.SystemByteOrder));
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of signed rational numbers converted from
|
||||
/// the given byte array.
|
||||
/// Numbers are converted from the given byte-order to platform byte-order.
|
||||
/// </summary>
|
||||
public static MathEx.Fraction32[] ToSRationalArray(byte[] data, int count, ByteOrder frombyteorder)
|
||||
{
|
||||
MathEx.Fraction32[] numbers = new MathEx.Fraction32[count];
|
||||
for (uint i = 0; i < count; i++)
|
||||
{
|
||||
byte[] num = new byte[4];
|
||||
byte[] den = new byte[4];
|
||||
Array.Copy(data, i * 8, num, 0, 4);
|
||||
Array.Copy(data, i * 8 + 4, den, 0, 4);
|
||||
numbers[i].Set(ToInt32(num, 0, frombyteorder, BitConverterEx.SystemByteOrder), ToInt32(den, 0, frombyteorder, BitConverterEx.SystemByteOrder));
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given ascii string to an array of bytes optionally adding a null terminator.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(string value, bool addnull, Encoding encoding)
|
||||
{
|
||||
if (addnull) value += '\0';
|
||||
return encoding.GetBytes(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given ascii string to an array of bytes without adding a null terminator.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(string value, Encoding encoding)
|
||||
{
|
||||
return GetBytes(value, false, encoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given datetime to an array of bytes with a null terminator.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(DateTime value, bool hastime)
|
||||
{
|
||||
string str = "";
|
||||
if (hastime)
|
||||
str = value.ToString("yyyy:MM:dd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
|
||||
else
|
||||
str = value.ToString("yyyy:MM:dd", System.Globalization.CultureInfo.InvariantCulture);
|
||||
return GetBytes(str, true, Encoding.ASCII);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given unsigned rational number to an array of bytes.
|
||||
/// Numbers are converted from the platform byte-order to the given byte-order.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(MathEx.UFraction32 value, ByteOrder tobyteorder)
|
||||
{
|
||||
byte[] num = GetBytes(value.Numerator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
byte[] den = GetBytes(value.Denominator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
byte[] data = new byte[8];
|
||||
Array.Copy(num, 0, data, 0, 4);
|
||||
Array.Copy(den, 0, data, 4, 4);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given signed rational number to an array of bytes.
|
||||
/// Numbers are converted from the platform byte-order to the given byte-order.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(MathEx.Fraction32 value, ByteOrder tobyteorder)
|
||||
{
|
||||
byte[] num = GetBytes(value.Numerator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
byte[] den = GetBytes(value.Denominator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
byte[] data = new byte[8];
|
||||
Array.Copy(num, 0, data, 0, 4);
|
||||
Array.Copy(den, 0, data, 4, 4);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of 16-bit unsigned integers to an array of bytes.
|
||||
/// Numbers are converted from the platform byte-order to the given byte-order.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(ushort[] value, ByteOrder tobyteorder)
|
||||
{
|
||||
byte[] data = new byte[2 * value.Length];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
byte[] num = GetBytes(value[i], BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
Array.Copy(num, 0, data, i * 2, 2);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of 32-bit unsigned integers to an array of bytes.
|
||||
/// Numbers are converted from the platform byte-order to the given byte-order.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(uint[] value, ByteOrder tobyteorder)
|
||||
{
|
||||
byte[] data = new byte[4 * value.Length];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
byte[] num = GetBytes(value[i], BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
Array.Copy(num, 0, data, i * 4, 4);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of 32-bit signed integers to an array of bytes.
|
||||
/// Numbers are converted from the platform byte-order to the given byte-order.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(int[] value, ByteOrder tobyteorder)
|
||||
{
|
||||
byte[] data = new byte[4 * value.Length];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
byte[] num = GetBytes(value[i], BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
Array.Copy(num, 0, data, i * 4, 4);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of unsigned rationals to an array of bytes.
|
||||
/// Numbers are converted from the platform byte-order to the given byte-order.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(MathEx.UFraction32[] value, ByteOrder tobyteorder)
|
||||
{
|
||||
byte[] data = new byte[8 * value.Length];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
byte[] num = GetBytes(value[i].Numerator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
byte[] den = GetBytes(value[i].Denominator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
Array.Copy(num, 0, data, i * 8, 4);
|
||||
Array.Copy(den, 0, data, i * 8 + 4, 4);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given array of signed rationals to an array of bytes.
|
||||
/// Numbers are converted from the platform byte-order to the given byte-order.
|
||||
/// </summary>
|
||||
public static byte[] GetBytes(MathEx.Fraction32[] value, ByteOrder tobyteorder)
|
||||
{
|
||||
byte[] data = new byte[8 * value.Length];
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
byte[] num = GetBytes(value[i].Numerator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
byte[] den = GetBytes(value[i].Denominator, BitConverterEx.SystemByteOrder, tobyteorder);
|
||||
Array.Copy(num, 0, data, i * 8, 4);
|
||||
Array.Copy(den, 0, data, i * 8 + 4, 4);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Media.Exif
|
||||
{
|
||||
internal enum Compression : ushort
|
||||
{
|
||||
Uncompressed = 1,
|
||||
CCITT1D = 2,
|
||||
Group3Fax = 3,
|
||||
Group4Fax = 4,
|
||||
LZW = 5,
|
||||
JPEG = 6,
|
||||
PackBits = 32773,
|
||||
}
|
||||
|
||||
internal enum PhotometricInterpretation : ushort
|
||||
{
|
||||
WhiteIsZero = 0,
|
||||
BlackIsZero = 1,
|
||||
RGB = 2,
|
||||
RGBPalette = 3,
|
||||
TransparencyMask = 4,
|
||||
CMYK = 5,
|
||||
YCbCr = 6,
|
||||
CIELab = 8,
|
||||
}
|
||||
|
||||
internal enum Orientation : ushort
|
||||
{
|
||||
Normal = 1,
|
||||
MirroredVertically = 2,
|
||||
Rotated180 = 3,
|
||||
MirroredHorizontally = 4,
|
||||
RotatedLeftAndMirroredVertically = 5,
|
||||
RotatedRight = 6,
|
||||
RotatedLeft = 7,
|
||||
RotatedRightAndMirroredVertically = 8,
|
||||
}
|
||||
|
||||
internal enum PlanarConfiguration : ushort
|
||||
{
|
||||
ChunkyFormat = 1,
|
||||
PlanarFormat = 2,
|
||||
}
|
||||
|
||||
internal enum YCbCrPositioning : ushort
|
||||
{
|
||||
Centered = 1,
|
||||
CoSited = 2,
|
||||
}
|
||||
|
||||
internal enum ResolutionUnit : ushort
|
||||
{
|
||||
Inches = 2,
|
||||
Centimeters = 3,
|
||||
}
|
||||
|
||||
internal enum ColorSpace : ushort
|
||||
{
|
||||
sRGB = 1,
|
||||
Uncalibrated = 0xfff,
|
||||
}
|
||||
|
||||
internal enum ExposureProgram : ushort
|
||||
{
|
||||
NotDefined = 0,
|
||||
Manual = 1,
|
||||
Normal = 2,
|
||||
AperturePriority = 3,
|
||||
ShutterPriority = 4,
|
||||
/// <summary>
|
||||
/// Biased toward depth of field.
|
||||
/// </summary>
|
||||
Creative = 5,
|
||||
/// <summary>
|
||||
/// Biased toward fast shutter speed.
|
||||
/// </summary>
|
||||
Action = 6,
|
||||
/// <summary>
|
||||
/// For closeup photos with the background out of focus.
|
||||
/// </summary>
|
||||
Portrait = 7,
|
||||
/// <summary>
|
||||
/// For landscape photos with the background in focus.
|
||||
/// </summary>
|
||||
Landscape = 8,
|
||||
}
|
||||
|
||||
internal enum MeteringMode : ushort
|
||||
{
|
||||
Unknown = 0,
|
||||
Average = 1,
|
||||
CenterWeightedAverage = 2,
|
||||
Spot = 3,
|
||||
MultiSpot = 4,
|
||||
Pattern = 5,
|
||||
Partial = 6,
|
||||
Other = 255,
|
||||
}
|
||||
|
||||
internal enum LightSource : ushort
|
||||
{
|
||||
Unknown = 0,
|
||||
Daylight = 1,
|
||||
Fluorescent = 2,
|
||||
Tungsten = 3,
|
||||
Flash = 4,
|
||||
FineWeather = 9,
|
||||
CloudyWeather = 10,
|
||||
Shade = 11,
|
||||
/// <summary>
|
||||
/// D 5700 – 7100K
|
||||
/// </summary>
|
||||
DaylightFluorescent = 12,
|
||||
/// <summary>
|
||||
/// N 4600 – 5400K
|
||||
/// </summary>
|
||||
DayWhiteFluorescent = 13,
|
||||
/// <summary>
|
||||
/// W 3900 – 4500K
|
||||
/// </summary>
|
||||
CoolWhiteFluorescent = 14,
|
||||
/// <summary>
|
||||
/// WW 3200 – 3700K
|
||||
/// </summary>
|
||||
WhiteFluorescent = 15,
|
||||
StandardLightA = 17,
|
||||
StandardLightB = 18,
|
||||
StandardLightC = 19,
|
||||
D55 = 20,
|
||||
D65 = 21,
|
||||
D75 = 22,
|
||||
D50 = 23,
|
||||
ISOStudioTungsten = 24,
|
||||
OtherLightSource = 255,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum Flash : ushort
|
||||
{
|
||||
FlashDidNotFire = 0,
|
||||
StrobeReturnLightNotDetected = 4,
|
||||
StrobeReturnLightDetected = 2,
|
||||
FlashFired = 1,
|
||||
CompulsoryFlashMode = 8,
|
||||
AutoMode = 16,
|
||||
NoFlashFunction = 32,
|
||||
RedEyeReductionMode = 64,
|
||||
}
|
||||
|
||||
internal enum SensingMethod : ushort
|
||||
{
|
||||
NotDefined = 1,
|
||||
OneChipColorAreaSensor = 2,
|
||||
TwoChipColorAreaSensor = 3,
|
||||
ThreeChipColorAreaSensor = 4,
|
||||
ColorSequentialAreaSensor = 5,
|
||||
TriLinearSensor = 7,
|
||||
ColorSequentialLinearSensor = 8,
|
||||
}
|
||||
|
||||
internal enum FileSource : byte // UNDEFINED
|
||||
{
|
||||
DSC = 3,
|
||||
}
|
||||
|
||||
internal enum SceneType : byte // UNDEFINED
|
||||
{
|
||||
DirectlyPhotographedImage = 1,
|
||||
}
|
||||
|
||||
internal enum CustomRendered : ushort
|
||||
{
|
||||
NormalProcess = 0,
|
||||
CustomProcess = 1,
|
||||
}
|
||||
|
||||
internal enum ExposureMode : ushort
|
||||
{
|
||||
Auto = 0,
|
||||
Manual = 1,
|
||||
AutoBracket = 2,
|
||||
}
|
||||
|
||||
internal enum WhiteBalance : ushort
|
||||
{
|
||||
Auto = 0,
|
||||
Manual = 1,
|
||||
}
|
||||
|
||||
internal enum SceneCaptureType : ushort
|
||||
{
|
||||
Standard = 0,
|
||||
Landscape = 1,
|
||||
Portrait = 2,
|
||||
NightScene = 3,
|
||||
}
|
||||
|
||||
internal enum GainControl : ushort
|
||||
{
|
||||
None = 0,
|
||||
LowGainUp = 1,
|
||||
HighGainUp = 2,
|
||||
LowGainDown = 3,
|
||||
HighGainDown = 4,
|
||||
}
|
||||
|
||||
internal enum Contrast : ushort
|
||||
{
|
||||
Normal = 0,
|
||||
Soft = 1,
|
||||
Hard = 2,
|
||||
}
|
||||
|
||||
internal enum Saturation : ushort
|
||||
{
|
||||
Normal = 0,
|
||||
Low = 1,
|
||||
High = 2,
|
||||
}
|
||||
|
||||
internal enum Sharpness : ushort
|
||||
{
|
||||
Normal = 0,
|
||||
Soft = 1,
|
||||
Hard = 2,
|
||||
}
|
||||
|
||||
internal enum SubjectDistanceRange : ushort
|
||||
{
|
||||
Unknown = 0,
|
||||
Macro = 1,
|
||||
CloseView = 2,
|
||||
DistantView = 3,
|
||||
}
|
||||
|
||||
internal enum GPSLatitudeRef : byte // ASCII
|
||||
{
|
||||
North = 78, // 'N'
|
||||
South = 83, // 'S'
|
||||
}
|
||||
|
||||
internal enum GPSLongitudeRef : byte // ASCII
|
||||
{
|
||||
West = 87, // 'W'
|
||||
East = 69, // 'E'
|
||||
}
|
||||
|
||||
internal enum GPSAltitudeRef : byte
|
||||
{
|
||||
AboveSeaLevel = 0,
|
||||
BelowSeaLevel = 1,
|
||||
}
|
||||
|
||||
internal enum GPSStatus : byte // ASCII
|
||||
{
|
||||
MeasurementInProgress = 65, // 'A'
|
||||
MeasurementInteroperability = 86, // 'V'
|
||||
}
|
||||
|
||||
internal enum GPSMeasureMode : byte // ASCII
|
||||
{
|
||||
TwoDimensional = 50, // '2'
|
||||
ThreeDimensional = 51, // '3'
|
||||
}
|
||||
|
||||
internal enum GPSSpeedRef : byte // ASCII
|
||||
{
|
||||
KilometersPerHour = 75, // 'K'
|
||||
MilesPerHour = 77, // 'M'
|
||||
Knots = 78, // 'N'
|
||||
}
|
||||
|
||||
internal enum GPSDirectionRef : byte // ASCII
|
||||
{
|
||||
TrueDirection = 84, // 'T'
|
||||
MagneticDirection = 77, // 'M'
|
||||
}
|
||||
|
||||
internal enum GPSDistanceRef : byte // ASCII
|
||||
{
|
||||
Kilometers = 75, // 'K'
|
||||
Miles = 77, // 'M'
|
||||
Knots = 78, // 'N'
|
||||
}
|
||||
|
||||
internal enum GPSDifferential : ushort
|
||||
{
|
||||
MeasurementWithoutDifferentialCorrection = 0,
|
||||
DifferentialCorrectionApplied = 1,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Media.Exif
|
||||
{
|
||||
/// <summary>
|
||||
/// The exception that is thrown when the format of the JPEG/Exif file
|
||||
/// could not be understood.
|
||||
/// </summary>
|
||||
internal class NotValidExifFileException : Exception
|
||||
{
|
||||
public NotValidExifFileException()
|
||||
: base("Not a valid JPEG/Exif file.")
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public NotValidExifFileException(string message)
|
||||
: base(message)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exception that is thrown when the IFD section ID could not be understood.
|
||||
/// </summary>
|
||||
internal class UnknownIFDSectionException : Exception
|
||||
{
|
||||
public UnknownIFDSectionException()
|
||||
: base("Unknown IFD section.")
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public UnknownIFDSectionException(string message)
|
||||
: base(message)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exception that is thrown when an invalid enum type is given to an
|
||||
/// ExifEnumProperty.
|
||||
/// </summary>
|
||||
internal class UnknownEnumTypeException : Exception
|
||||
{
|
||||
public UnknownEnumTypeException()
|
||||
: base("Unknown enum type.")
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public UnknownEnumTypeException(string message)
|
||||
: base(message)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exception that is thrown when the 0th IFD section does not contain any fields.
|
||||
/// </summary>
|
||||
internal class IFD0IsEmptyException : Exception
|
||||
{
|
||||
public IFD0IsEmptyException()
|
||||
: base("0th IFD section cannot be empty.")
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public IFD0IsEmptyException(string message)
|
||||
: base(message)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Media.Exif
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an enumerated value.
|
||||
/// </summary>
|
||||
internal class ExifEnumProperty<T> : ExifProperty
|
||||
{
|
||||
protected T mValue;
|
||||
protected bool mIsBitField;
|
||||
protected override object _Value { get { return Value; } set { Value = (T)value; } }
|
||||
public new T Value { get { return mValue; } set { mValue = value; } }
|
||||
public bool IsBitField { get { return mIsBitField; } }
|
||||
|
||||
static public implicit operator T(ExifEnumProperty<T> obj) { return (T)obj.mValue; }
|
||||
|
||||
public override string ToString() { return mValue.ToString(); }
|
||||
|
||||
public ExifEnumProperty(ExifTag tag, T value, bool isbitfield)
|
||||
: base(tag)
|
||||
{
|
||||
mValue = value;
|
||||
mIsBitField = isbitfield;
|
||||
}
|
||||
|
||||
public ExifEnumProperty(ExifTag tag, T value)
|
||||
: this(tag, value, false)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public override ExifInterOperability Interoperability
|
||||
{
|
||||
get
|
||||
{
|
||||
ushort tagid = ExifTagFactory.GetTagID(mTag);
|
||||
|
||||
Type type = typeof(T);
|
||||
Type basetype = Enum.GetUnderlyingType(type);
|
||||
|
||||
if (type == typeof(FileSource) || type == typeof(SceneType))
|
||||
{
|
||||
// UNDEFINED
|
||||
return new ExifInterOperability(tagid, 7, 1, new byte[] { (byte)((object)mValue) });
|
||||
}
|
||||
else if (type == typeof(GPSLatitudeRef) || type == typeof(GPSLongitudeRef) ||
|
||||
type == typeof(GPSStatus) || type == typeof(GPSMeasureMode) ||
|
||||
type == typeof(GPSSpeedRef) || type == typeof(GPSDirectionRef) ||
|
||||
type == typeof(GPSDistanceRef))
|
||||
{
|
||||
// ASCII
|
||||
return new ExifInterOperability(tagid, 2, 2, new byte[] { (byte)((object)mValue), 0 });
|
||||
}
|
||||
else if (basetype == typeof(byte))
|
||||
{
|
||||
// BYTE
|
||||
return new ExifInterOperability(tagid, 1, 1, new byte[] { (byte)((object)mValue) });
|
||||
}
|
||||
else if (basetype == typeof(ushort))
|
||||
{
|
||||
// SHORT
|
||||
return new ExifInterOperability(tagid, 3, 1, ExifBitConverter.GetBytes((ushort)((object)mValue), BitConverterEx.SystemByteOrder, BitConverterEx.SystemByteOrder));
|
||||
}
|
||||
else
|
||||
throw new UnknownEnumTypeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an ASCII string. (EXIF Specification: UNDEFINED) Used for the UserComment field.
|
||||
/// </summary>
|
||||
internal class ExifEncodedString : ExifProperty
|
||||
{
|
||||
protected string mValue;
|
||||
private Encoding mEncoding;
|
||||
protected override object _Value { get { return Value; } set { Value = (string)value; } }
|
||||
public new string Value { get { return mValue; } set { mValue = value; } }
|
||||
public Encoding Encoding { get { return mEncoding; } set { mEncoding = value; } }
|
||||
|
||||
static public implicit operator string(ExifEncodedString obj) { return obj.mValue; }
|
||||
|
||||
public override string ToString() { return mValue; }
|
||||
|
||||
public ExifEncodedString(ExifTag tag, string value, Encoding encoding)
|
||||
: base(tag)
|
||||
{
|
||||
mValue = value;
|
||||
mEncoding = encoding;
|
||||
}
|
||||
|
||||
public override ExifInterOperability Interoperability
|
||||
{
|
||||
get
|
||||
{
|
||||
string enc = "";
|
||||
if (mEncoding == null)
|
||||
enc = "\0\0\0\0\0\0\0\0";
|
||||
else if (mEncoding.EncodingName == "US-ASCII")
|
||||
enc = "ASCII\0\0\0";
|
||||
else if (mEncoding.EncodingName == "Japanese (JIS 0208-1990 and 0212-1990)")
|
||||
enc = "JIS\0\0\0\0\0";
|
||||
else if (mEncoding.EncodingName == "Unicode")
|
||||
enc = "Unicode\0";
|
||||
else
|
||||
enc = "\0\0\0\0\0\0\0\0";
|
||||
|
||||
byte[] benc = Encoding.ASCII.GetBytes(enc);
|
||||
byte[] bstr = (mEncoding == null ? Encoding.ASCII.GetBytes(mValue) : mEncoding.GetBytes(mValue));
|
||||
byte[] data = new byte[benc.Length + bstr.Length];
|
||||
Array.Copy(benc, 0, data, 0, benc.Length);
|
||||
Array.Copy(bstr, 0, data, benc.Length, bstr.Length);
|
||||
|
||||
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), 7, (uint)data.Length, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an ASCII string formatted as DateTime. (EXIF Specification: ASCII) Used for the date time fields.
|
||||
/// </summary>
|
||||
internal class ExifDateTime : ExifProperty
|
||||
{
|
||||
protected DateTime mValue;
|
||||
protected override object _Value { get { return Value; } set { Value = (DateTime)value; } }
|
||||
public new DateTime Value { get { return mValue; } set { mValue = value; } }
|
||||
|
||||
static public implicit operator DateTime(ExifDateTime obj) { return obj.mValue; }
|
||||
|
||||
public override string ToString() { return mValue.ToString("yyyy.MM.dd HH:mm:ss"); }
|
||||
|
||||
public ExifDateTime(ExifTag tag, DateTime value)
|
||||
: base(tag)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
public override ExifInterOperability Interoperability
|
||||
{
|
||||
get
|
||||
{
|
||||
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), 2, (uint)20, ExifBitConverter.GetBytes(mValue, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the exif version as a 4 byte ASCII string. (EXIF Specification: UNDEFINED)
|
||||
/// Used for the ExifVersion, FlashpixVersion, InteroperabilityVersion and GPSVersionID fields.
|
||||
/// </summary>
|
||||
internal class ExifVersion : ExifProperty
|
||||
{
|
||||
protected string mValue;
|
||||
protected override object _Value { get { return Value; } set { Value = (string)value; } }
|
||||
public new string Value { get { return mValue; } set { mValue = value.Substring(0, 4); } }
|
||||
|
||||
public ExifVersion(ExifTag tag, string value)
|
||||
: base(tag)
|
||||
{
|
||||
if (value.Length > 4)
|
||||
mValue = value.Substring(0, 4);
|
||||
else if (value.Length < 4)
|
||||
mValue = value + new string(' ', 4 - value.Length);
|
||||
else
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return mValue;
|
||||
}
|
||||
|
||||
public override ExifInterOperability Interoperability
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mTag == ExifTag.ExifVersion || mTag == ExifTag.FlashpixVersion || mTag == ExifTag.InteroperabilityVersion)
|
||||
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), 7, 4, Encoding.ASCII.GetBytes(mValue));
|
||||
else
|
||||
{
|
||||
byte[] data = new byte[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
data[i] = byte.Parse(mValue[0].ToString());
|
||||
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), 7, 4, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the location and area of the subject (EXIF Specification: 2xSHORT)
|
||||
/// The coordinate values, width, and height are expressed in relation to the
|
||||
/// upper left as origin, prior to rotation processing as per the Rotation tag.
|
||||
/// </summary>
|
||||
internal class ExifPointSubjectArea : ExifUShortArray
|
||||
{
|
||||
protected new ushort[] Value { get { return mValue; } set { mValue = value; } }
|
||||
public ushort X { get { return mValue[0]; } set { mValue[0] = value; } }
|
||||
public ushort Y { get { return mValue[1]; } set { mValue[1] = value; } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("({0:d}, {1:d})", mValue[0], mValue[1]);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public ExifPointSubjectArea(ExifTag tag, ushort[] value)
|
||||
: base(tag, value)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public ExifPointSubjectArea(ExifTag tag, ushort x, ushort y)
|
||||
: base(tag, new ushort[] { x, y })
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the location and area of the subject (EXIF Specification: 3xSHORT)
|
||||
/// The coordinate values, width, and height are expressed in relation to the
|
||||
/// upper left as origin, prior to rotation processing as per the Rotation tag.
|
||||
/// </summary>
|
||||
internal class ExifCircularSubjectArea : ExifPointSubjectArea
|
||||
{
|
||||
public ushort Diamater { get { return mValue[2]; } set { mValue[2] = value; } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("({0:d}, {1:d}) {2:d}", mValue[0], mValue[1], mValue[2]);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public ExifCircularSubjectArea(ExifTag tag, ushort[] value)
|
||||
: base(tag, value)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public ExifCircularSubjectArea(ExifTag tag, ushort x, ushort y, ushort d)
|
||||
: base(tag, new ushort[] { x, y, d })
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the location and area of the subject (EXIF Specification: 4xSHORT)
|
||||
/// The coordinate values, width, and height are expressed in relation to the
|
||||
/// upper left as origin, prior to rotation processing as per the Rotation tag.
|
||||
/// </summary>
|
||||
internal class ExifRectangularSubjectArea : ExifPointSubjectArea
|
||||
{
|
||||
public ushort Width { get { return mValue[2]; } set { mValue[2] = value; } }
|
||||
public ushort Height { get { return mValue[3]; } set { mValue[3] = value; } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendFormat("({0:d}, {1:d}) ({2:d} x {3:d})", mValue[0], mValue[1], mValue[2], mValue[3]);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public ExifRectangularSubjectArea(ExifTag tag, ushort[] value)
|
||||
: base(tag, value)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public ExifRectangularSubjectArea(ExifTag tag, ushort x, ushort y, ushort w, ushort h)
|
||||
: base(tag, new ushort[] { x, y, w, h })
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents GPS latitudes and longitudes (EXIF Specification: 3xRATIONAL)
|
||||
/// </summary>
|
||||
internal class GPSLatitudeLongitude : ExifURationalArray
|
||||
{
|
||||
protected new MathEx.UFraction32[] Value { get { return mValue; } set { mValue = value; } }
|
||||
public MathEx.UFraction32 Degrees { get { return mValue[0]; } set { mValue[0] = value; } }
|
||||
public MathEx.UFraction32 Minutes { get { return mValue[1]; } set { mValue[1] = value; } }
|
||||
public MathEx.UFraction32 Seconds { get { return mValue[2]; } set { mValue[2] = value; } }
|
||||
|
||||
public static explicit operator float(GPSLatitudeLongitude obj) { return obj.ToFloat(); }
|
||||
public float ToFloat()
|
||||
{
|
||||
return (float)Degrees + ((float)Minutes) / 60.0f + ((float)Seconds) / 3600.0f;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0:F2}°{1:F2}'{2:F2}\"", (float)Degrees, (float)Minutes, (float)Seconds);
|
||||
}
|
||||
|
||||
public GPSLatitudeLongitude(ExifTag tag, MathEx.UFraction32[] value)
|
||||
: base(tag, value)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public GPSLatitudeLongitude(ExifTag tag, float d, float m, float s)
|
||||
: base(tag, new MathEx.UFraction32[] { new MathEx.UFraction32(d), new MathEx.UFraction32(m), new MathEx.UFraction32(s) })
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a GPS time stamp as UTC (EXIF Specification: 3xRATIONAL)
|
||||
/// </summary>
|
||||
internal class GPSTimeStamp : ExifURationalArray
|
||||
{
|
||||
protected new MathEx.UFraction32[] Value { get { return mValue; } set { mValue = value; } }
|
||||
public MathEx.UFraction32 Hour { get { return mValue[0]; } set { mValue[0] = value; } }
|
||||
public MathEx.UFraction32 Minute { get { return mValue[1]; } set { mValue[1] = value; } }
|
||||
public MathEx.UFraction32 Second { get { return mValue[2]; } set { mValue[2] = value; } }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0:F2}:{1:F2}:{2:F2}\"", (float)Hour, (float)Minute, (float)Second);
|
||||
}
|
||||
|
||||
public GPSTimeStamp(ExifTag tag, MathEx.UFraction32[] value)
|
||||
: base(tag, value)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public GPSTimeStamp(ExifTag tag, float h, float m, float s)
|
||||
: base(tag, new MathEx.UFraction32[] { new MathEx.UFraction32(h), new MathEx.UFraction32(m), new MathEx.UFraction32(s) })
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents an ASCII string. (EXIF Specification: BYTE)
|
||||
/// Used by Windows XP.
|
||||
/// </summary>
|
||||
internal class WindowsByteString : ExifProperty
|
||||
{
|
||||
protected string mValue;
|
||||
protected override object _Value { get { return Value; } set { Value = (string)value; } }
|
||||
public new string Value { get { return mValue; } set { mValue = value; } }
|
||||
|
||||
static public implicit operator string(WindowsByteString obj) { return obj.mValue; }
|
||||
|
||||
public override string ToString() { return mValue; }
|
||||
|
||||
public WindowsByteString(ExifTag tag, string value)
|
||||
: base(tag)
|
||||
{
|
||||
mValue = value;
|
||||
}
|
||||
|
||||
public override ExifInterOperability Interoperability
|
||||
{
|
||||
get
|
||||
{
|
||||
byte[] data = Encoding.Unicode.GetBytes(mValue);
|
||||
return new ExifInterOperability(ExifTagFactory.GetTagID(mTag), 1, (uint)data.Length, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core.Media.Exif
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a custom type descriptor for an ExifFile instance.
|
||||
/// </summary>
|
||||
internal sealed class ExifFileTypeDescriptionProvider : TypeDescriptionProvider
|
||||
{
|
||||
public ExifFileTypeDescriptionProvider()
|
||||
: this(TypeDescriptor.GetProvider(typeof(ImageFile)))
|
||||
{
|
||||
}
|
||||
|
||||
public ExifFileTypeDescriptionProvider(TypeDescriptionProvider parent)
|
||||
: base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a custom type descriptor for the given type and object.
|
||||
/// </summary>
|
||||
/// <param name="objectType">The type of object for which to retrieve the type descriptor.</param>
|
||||
/// <param name="instance">An instance of the type. Can be null if no instance was passed to the <see cref="T:System.ComponentModel.TypeDescriptor"/>.</param>
|
||||
/// <returns>
|
||||
/// An <see cref="T:System.ComponentModel.ICustomTypeDescriptor"/> that can provide metadata for the type.
|
||||
/// </returns>
|
||||
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
|
||||
{
|
||||
return new ExifFileTypeDescriptor(base.GetTypeDescriptor(objectType, instance), instance);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expands ExifProperty objects contained in an ExifFile as seperate properties.
|
||||
/// </summary>
|
||||
internal sealed class ExifFileTypeDescriptor : CustomTypeDescriptor
|
||||
{
|
||||
ImageFile owner;
|
||||
|
||||
public ExifFileTypeDescriptor(ICustomTypeDescriptor parent, object instance)
|
||||
: base(parent)
|
||||
{
|
||||
owner = (ImageFile)instance;
|
||||
}
|
||||
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
|
||||
{
|
||||
return GetProperties();
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a collection of property descriptors for the object represented by this type descriptor.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.ComponentModel.PropertyDescriptorCollection"/> containing the property descriptions for the object represented by this type descriptor. The default is <see cref="F:System.ComponentModel.PropertyDescriptorCollection.Empty"/>.
|
||||
/// </returns>
|
||||
public override PropertyDescriptorCollection GetProperties()
|
||||
{
|
||||
// Enumerate the original set of properties and create our new set with it
|
||||
List<PropertyDescriptor> properties = new List<PropertyDescriptor>();
|
||||
|
||||
foreach (ExifProperty prop in owner.Properties)
|
||||
{
|
||||
ExifPropertyDescriptor pd = new ExifPropertyDescriptor(prop);
|
||||
properties.Add(pd);
|
||||
}
|
||||
|
||||
// Finally return the list
|
||||
return new PropertyDescriptorCollection(properties.ToArray(), true);
|
||||
}
|
||||
}
|
||||
internal sealed class ExifPropertyDescriptor : PropertyDescriptor
|
||||
{
|
||||
object originalValue;
|
||||
ExifProperty linkedProperty;
|
||||
|
||||
public ExifPropertyDescriptor(ExifProperty property)
|
||||
: base(property.Name, new Attribute[] { new BrowsableAttribute(true) })
|
||||
{
|
||||
linkedProperty = property;
|
||||
originalValue = property.Value;
|
||||
}
|
||||
|
||||
public override bool CanResetValue(object component)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override Type ComponentType
|
||||
{
|
||||
get { return typeof(JPEGFile); }
|
||||
}
|
||||
|
||||
public override object GetValue(object component)
|
||||
{
|
||||
return linkedProperty.Value;
|
||||
}
|
||||
|
||||
public override bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override Type PropertyType
|
||||
{
|
||||
get { return linkedProperty.Value.GetType(); }
|
||||
}
|
||||
|
||||
public override void ResetValue(object component)
|
||||
{
|
||||
linkedProperty.Value = originalValue;
|
||||
}
|
||||
|
||||
public override void SetValue(object component, object value)
|
||||
{
|
||||
linkedProperty.Value = value;
|
||||
}
|
||||
|
||||
public override bool ShouldSerializeValue(object component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user