mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-01 00:00:02 -04:00
Compare commits
635 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fe591d9b6c | |||
| 06d988377e | |||
| 360b4e9bba | |||
| 867a46d281 | |||
| 9972f966f7 | |||
| f066a48d55 | |||
| 5af87372aa | |||
| defadbbbcd | |||
| 66363f8d09 | |||
| 1bef35daba | |||
| 0be5efc534 | |||
| 35da57dfcf | |||
| 5d09bb664e | |||
| 5590072cc7 | |||
| 31117c7cea | |||
| ae0899fe76 | |||
| df51ef340d | |||
| 71d8295042 | |||
| a8f77a9a45 | |||
| eb3176b447 | |||
| 20e308dd8f | |||
| 9fa9bc5fe0 | |||
| 4da3e2e441 | |||
| 4516d84e54 | |||
| a815e5f180 | |||
| 35658a888f | |||
| 6cd6b6113d | |||
| f8b919ee58 | |||
| 8989ba07d8 | |||
| bc38ec1034 | |||
| e37c1fbb50 | |||
| 75b6de7102 | |||
| 22a16db463 | |||
| 3e93753073 | |||
| ad3cbbd86d | |||
| 076e417010 | |||
| 0b84a99954 | |||
| e2f4241a99 | |||
| 6eedaa129d | |||
| f5dbc0c2f4 | |||
| 7d79185fb2 | |||
| c885ed6dbb | |||
| e116c98db2 | |||
| be9493af20 | |||
| 5ffe3087ad | |||
| ffc7dad821 | |||
| 2a4ff2aa12 | |||
| 1e9669d6c3 | |||
| caca51d5ce | |||
| 015728a57d | |||
| 4272c6c8ed | |||
| b5582e32f6 | |||
| 76045ab0d9 | |||
| 4fc8f28cc6 | |||
| 7198a92a2e | |||
| e2fbd80c36 | |||
| 6b28cbe4a1 | |||
| 76198b0655 | |||
| f81b14df71 | |||
| da3f79f0c9 | |||
| d39418eca2 | |||
| cbbc2bc6fe | |||
| b0b423de4f | |||
| 1c4ec8d20e | |||
| ec99a8ce1f | |||
| c49a887cd3 | |||
| 14af75d191 | |||
| 0ce205638e | |||
| fe4119ca1c | |||
| c927f4c1ec | |||
| 161368084a | |||
| d958aba69e | |||
| 931429724c | |||
| dcd21db2ef | |||
| 7a3022ebf2 | |||
| 274886b1d9 | |||
| 0cf784ee60 | |||
| a797f1ea26 | |||
| baff849b6c | |||
| 408977d896 | |||
| d78e6373a8 | |||
| 9610256ddb | |||
| 34c9b9b4b5 | |||
| 9d5823d982 | |||
| 10e824df36 | |||
| 3bc90bfad1 | |||
| 543acce8a3 | |||
| a67fdd4b80 | |||
| 9c936d3f11 | |||
| fb2bff1404 | |||
| 3c605f8796 | |||
| 7817af91a3 | |||
| 1ed1076714 | |||
| a90d375422 | |||
| 815007ab2b | |||
| b3c8f53512 | |||
| d2977a18ac | |||
| 7e5e905d18 | |||
| 0fcba279f1 | |||
| d7d9552216 | |||
| e48a78aa77 | |||
| bf351c01a6 | |||
| 9bd4389142 | |||
| 984383bd56 | |||
| 77247772d0 | |||
| ae482bc7e5 | |||
| 119700487b | |||
| 5e5d530498 | |||
| 3dfc0850cc | |||
| 8f285327fc | |||
| 734b90863a | |||
| 18f31f2dd4 | |||
| a7294af89c | |||
| ea63a5bdc1 | |||
| 2cc50bbdad | |||
| f4a5f57d52 | |||
| 7fc47a338c | |||
| f8311164af | |||
| 84c10ed96d | |||
| 9c8ae4ac3e | |||
| aab7b6f7f5 | |||
| 3c01071452 | |||
| 4fc9c3513b | |||
| 59b08bfc79 | |||
| 743f1f9356 | |||
| d90b1c984c | |||
| 1160be4995 | |||
| 2978c901ae | |||
| e4b465a0d4 | |||
| 297a27c5be | |||
| 9d9593dba2 | |||
| 66683a2ead | |||
| 4be4f4e2b6 | |||
| 7f59d41b2a | |||
| a060c105e1 | |||
| f3318ee818 | |||
| afa306a787 | |||
| ed032b6c7a | |||
| 894e5dc30a | |||
| 8e02fb36e9 | |||
| 88a2e226ca | |||
| 203ad0258f | |||
| 2a1ecf80fa | |||
| 4239ce5e31 | |||
| 61ca2fc3e0 | |||
| 9e502899ac | |||
| 16fd8d1453 | |||
| 81ae64b65c | |||
| b0d5480445 | |||
| 9e989680c6 | |||
| dd174c7f7e | |||
| 72ef50b677 | |||
| a7349278b2 | |||
| 858f519f0b | |||
| d797ff0bb3 | |||
| fef4c4dd7a | |||
| a99762b5de | |||
| c7d0c902db | |||
| e8e2026d48 | |||
| f1dc50c276 | |||
| 0e615192e7 | |||
| d9b82f80ef | |||
| 41f316e621 | |||
| 5f2b0c0ccf | |||
| ee7d4ba724 | |||
| f7d4557c57 | |||
| 20d8c34dae | |||
| eaee82f3e7 | |||
| a0d87ec6d8 | |||
| ac5d4a02a9 | |||
| a26932cd70 | |||
| 7b8e5433dd | |||
| 1471af3e68 | |||
| 4f0dd84cf6 | |||
| 143e25c39c | |||
| 3d0ba82422 | |||
| 34f626914a | |||
| d6587ad292 | |||
| 46eaa72a13 | |||
| b3d48bdc50 | |||
| 981d2da1e6 | |||
| cf40b5f4a0 | |||
| 34128c66a4 | |||
| 1aa02477a7 | |||
| fa49dd93a7 | |||
| 83cff35076 | |||
| 93e3ae5ef8 | |||
| d8857c2997 | |||
| 7b119ce7dc | |||
| 3e7ad05973 | |||
| 1e574ca429 | |||
| dce193b113 | |||
| 05517e1fed | |||
| d707793211 | |||
| 39cfeedc6b | |||
| 1dcbbc39e3 | |||
| c933dbf69f | |||
| 5fc7dc1963 | |||
| f42d5e0a32 | |||
| d1c3a9bacb | |||
| 21ad54b820 | |||
| e11fc63730 | |||
| 2a70e744e0 | |||
| 60550ba8a8 | |||
| d3b16cdd35 | |||
| add7b06fa4 | |||
| b99391854d | |||
| a22188bd72 | |||
| d5f5f295f5 | |||
| d95de31908 | |||
| 4fda5af141 | |||
| b54827ae1b | |||
| 2762b9705a | |||
| 2d6248e293 | |||
| 8a43e4539c | |||
| 8ecf203263 | |||
| 8e50af2804 | |||
| 58e31aebd1 | |||
| b8e3e7825c | |||
| 155e9850fb | |||
| 0c4adf36ba | |||
| fd32bc9089 | |||
| 6ad010dc44 | |||
| c9b14ea4af | |||
| f162c873ed | |||
| c21b971655 | |||
| d1b0247055 | |||
| 6d3605c080 | |||
| a188dcf9fd | |||
| 08938c6b4d | |||
| 016ef952ce | |||
| 2844c396c8 | |||
| 2f95716b8a | |||
| cf7fce647d | |||
| 4014ae4644 | |||
| 4e46e81e3f | |||
| ec43410fa6 | |||
| 721fc5b5a5 | |||
| 0c71981158 | |||
| ac0ed5ed8f | |||
| d1b11ee1d1 | |||
| 210eeccb39 | |||
| e07e7c3685 | |||
| 611cb6cb4d | |||
| 54d9feef94 | |||
| 54b4ded602 | |||
| e360ed2a6a | |||
| 2325cef5a3 | |||
| 465eb09dd3 | |||
| feae2a0f79 | |||
| 860cb32a58 | |||
| b9bd19b950 | |||
| 3742e6ef08 | |||
| 52aa582ccd | |||
| adda52053b | |||
| 6501321fac | |||
| 57d9bfda59 | |||
| 1226375ba6 | |||
| 9c2d3058fd | |||
| e89cadd95f | |||
| 0ec299c2e6 | |||
| b91d02a562 | |||
| 2b5f897841 | |||
| e65078bdb7 | |||
| 36d8555172 | |||
| 80e3170820 | |||
| 90bc04b030 | |||
| dcba9b0667 | |||
| dc755c4c3c | |||
| 6e4f1e0739 | |||
| 7117cd1fd6 | |||
| 2b954c1067 | |||
| 77a1745106 | |||
| 0378f504e7 | |||
| 1d3a7fe812 | |||
| 8715b6b696 | |||
| a95235b422 | |||
| 9f4b09fc7d | |||
| 03455f0132 | |||
| ac5779d8d6 | |||
| fef8ff3aab | |||
| a9e4b2e262 | |||
| 7147e2dfb1 | |||
| 1680fadf83 | |||
| d1df8c13ed | |||
| 031937fe99 | |||
| 24c473ae45 | |||
| 57941cb638 | |||
| d325b6deec | |||
| 3f67430b2d | |||
| 314071dde8 | |||
| 83ad25c2dd | |||
| d7dae90e2e | |||
| ad437c2470 | |||
| dabc26bdb5 | |||
| b441298a9a | |||
| 345ca0ac13 | |||
| 9720a931c5 | |||
| 4d3f691e6a | |||
| 2e0e575183 | |||
| 2c7c47b158 | |||
| 57680f1bec | |||
| 8dc83c4e9e | |||
| 929bea6b6b | |||
| 699662d054 | |||
| 1bebee1851 | |||
| b0e8dd86bb | |||
| 5bdb0b5502 | |||
| 85d47528a3 | |||
| a7ebd66149 | |||
| f0a032a7b9 | |||
| 690cb064e7 | |||
| e65f471a8f | |||
| f2cc9faaf8 | |||
| 8bd3f4f34a | |||
| be348543d8 | |||
| 80229b8c3c | |||
| a5ee53569d | |||
| c22ada03cd | |||
| b61341ce3b | |||
| e73b0a7bcf | |||
| ea9d1c0dc5 | |||
| e0563ee7dd | |||
| 44bcd202e8 | |||
| 5b57b51ff1 | |||
| 0b5f8a071e | |||
| d3dc578936 | |||
| 2ae937b870 | |||
| 2a7763299a | |||
| a57a1d35f9 | |||
| e618805786 | |||
| e3cb923d37 | |||
| 4513b0c166 | |||
| b55d4e8c1b | |||
| 399c75f59e | |||
| a7f7d73e2d | |||
| 41a83191b7 | |||
| 49e805eeb7 | |||
| f426637fdd | |||
| 4081ff1545 | |||
| ae4fbcc726 | |||
| 66208bfa03 | |||
| e72255805e | |||
| 780ccd7916 | |||
| 957e917281 | |||
| 9daf8337ee | |||
| 89c104d59f | |||
| 8608ee76c5 | |||
| aab2d36e92 | |||
| 608b37232d | |||
| e3ebf8e0fa | |||
| 9af10625a2 | |||
| ccc4e7b411 | |||
| 439323c5e5 | |||
| 332e191d0d | |||
| 58d1a89028 | |||
| 72fe799cc8 | |||
| 18af213e27 | |||
| 9d267f352f | |||
| f8f6f9f1e4 | |||
| 2841d26785 | |||
| 98ae5967ca | |||
| da9d87a561 | |||
| d472191926 | |||
| a8472170c4 | |||
| b2f7cada21 | |||
| 2a4c152c3d | |||
| 660932b7e7 | |||
| d0a17ff3b3 | |||
| 4259903bdd | |||
| 3018d2a342 | |||
| 8f94318f28 | |||
| 60b7151eb6 | |||
| 8ad21307e8 | |||
| 8c854f1e20 | |||
| 1445ff2533 | |||
| e8f1e80d4e | |||
| 18e29e9ed5 | |||
| ec4003b1c1 | |||
| 164b8db988 | |||
| 21feace385 | |||
| ba1f754611 | |||
| 822b5da631 | |||
| c785f6932f | |||
| 43e2a27c7f | |||
| 9d50acd2fe | |||
| ba73a308d6 | |||
| 20cd259abd | |||
| 033a1423ff | |||
| 7c8c520006 | |||
| 9162458e36 | |||
| d38af3cb16 | |||
| c57e8f80fa | |||
| 4750359ada | |||
| cbe8038619 | |||
| 2d8125e69c | |||
| 57a664c093 | |||
| 7f82377fd7 | |||
| 72b9f19a51 | |||
| 0083b8e77e | |||
| 79982cd493 | |||
| f0db338f3b | |||
| 9db4e0b3ed | |||
| cd4cbdcb82 | |||
| 15dc4b3852 | |||
| a3534ecd59 | |||
| 7bb5fee23b | |||
| 6cb7424bd0 | |||
| 9aa04d311e | |||
| 967e71dc92 | |||
| 628523ddc8 | |||
| 783c28ae0e | |||
| d35d67651f | |||
| 816d48efef | |||
| 25ee21d090 | |||
| 536ea7ba88 | |||
| d2687383f5 | |||
| 3ce35e059c | |||
| 1d5359dd35 | |||
| 2699b75b79 | |||
| 4e614dfc7e | |||
| 3a2efd9491 | |||
| c5dc2e4e53 | |||
| 41460bd32a | |||
| 13b37b3839 | |||
| 6dd74070f4 | |||
| 81b358b377 | |||
| 9715f4e74c | |||
| 38256c8be0 | |||
| bf3c1fad17 | |||
| b8488ae39b | |||
| d3bea0ae38 | |||
| 9435410b1e | |||
| f74e8c8ba1 | |||
| 0ae2c2f01d | |||
| 77c81a06bc | |||
| 2bbcd88798 | |||
| 829fbe7547 | |||
| 078425eed9 | |||
| 8ddcbbd2b2 | |||
| 507cca5fd7 | |||
| a4caac0c82 | |||
| 54c07b849c | |||
| c531d4f5d3 | |||
| aa2e8e5d7e | |||
| 76a35331b0 | |||
| 6b3f1c6ee3 | |||
| c731e10e8f | |||
| 4a8c3530f7 | |||
| e8996daa12 | |||
| 9196e60c74 | |||
| eabb8fd02b | |||
| 1794e336de | |||
| ac7612b3df | |||
| 606fd53823 | |||
| 614a07e040 | |||
| 34e8d88007 | |||
| 9b727df901 | |||
| f1f98bb4a4 | |||
| b34b26e08c | |||
| 993e07ee34 | |||
| a377712bdb | |||
| e5dc6aa878 | |||
| 46b1c1cf96 | |||
| d9300b1c90 | |||
| 0a2efb9eac | |||
| 3eabc591d8 | |||
| 5cefce2dbf | |||
| 4c645c0220 | |||
| 703848ca45 | |||
| 0ebd18fcb6 | |||
| 29f7547a99 | |||
| 25cd351eee | |||
| 77c98c917e | |||
| 4bbe946f46 | |||
| 78832ed923 | |||
| 164cc11592 | |||
| 8f5c1b409f | |||
| 26981513d8 | |||
| a3a30d54d4 | |||
| 102e9cff51 | |||
| da800be8c8 | |||
| 70493bd323 | |||
| 304d050bc3 | |||
| 0443172666 | |||
| cee2663f06 | |||
| 8f44cfc43c | |||
| 8a240aac68 | |||
| 61424f33b6 | |||
| c7b9b1fadd | |||
| ab08ec1e0d | |||
| cbe78dc67f | |||
| c9e11f171f | |||
| bc2c0c2301 | |||
| 6581e2e2a1 | |||
| c2873b1f27 | |||
| 35f2f0be9f | |||
| b5856fd110 | |||
| 1919d77a45 | |||
| 37afe24aac | |||
| 081f2efea2 | |||
| 627bb1bf1f | |||
| a77b62b6ba | |||
| 2500d8cc15 | |||
| c01336fb8a | |||
| 6f9b9bee01 | |||
| b9b1a35408 | |||
| 7ed5663633 | |||
| 6458fcdcbd | |||
| 9375bfda9a | |||
| 0160fb70f8 | |||
| 29dca0f124 | |||
| c21f14efe1 | |||
| 81ba43e1e8 | |||
| a1fcfc3958 | |||
| c60116a611 | |||
| 15e6ddc1fd | |||
| 49f4e5401e | |||
| e333c7d1b2 | |||
| cda34b704b | |||
| 7c4487be04 | |||
| 5a4525aaa1 | |||
| b766420e3e | |||
| c858454c5a | |||
| 67b48ce1e3 | |||
| 6608f61353 | |||
| 326b98d5e5 | |||
| fafa58b718 | |||
| 0ed0246762 | |||
| b3004a1227 | |||
| 7ab627a754 | |||
| 008e57a7ce | |||
| 28270b4d5b | |||
| 7382151db8 | |||
| b856ce07af | |||
| 190fe87ee9 | |||
| d1872ce94f | |||
| a5c52a99b4 | |||
| 4170b393fa | |||
| 53f9ba91e0 | |||
| be2d7d5f10 | |||
| 00aec2c90e | |||
| 2b04f7205c | |||
| 7d401d0194 | |||
| 48691139a3 | |||
| bcb87c09d2 | |||
| 84a8ceeb93 | |||
| 0cb99feedf | |||
| 91493c5145 | |||
| 6ddb799a95 | |||
| 8a187f6657 | |||
| b7d865f2cf | |||
| d50fb1a51e | |||
| 8992406f50 | |||
| 44eebff62f | |||
| 8c85c4ca96 | |||
| fa5c77bff0 | |||
| d87b80deea | |||
| ae138c3b4e | |||
| ab13fdd09d | |||
| aab5b062bd | |||
| 00d6acd1bf | |||
| 0f8a7ea482 | |||
| 9fe87fe10d | |||
| a33dbaf897 | |||
| 9e2f369459 | |||
| d34b0b7fcf | |||
| 5effcb1344 | |||
| b67d687761 | |||
| d0881c8b5c | |||
| 976928f48c | |||
| e1c2f2ee73 | |||
| 92632fa2a3 | |||
| 5a563e315f | |||
| c06d47d123 | |||
| fea6beb364 | |||
| 4b951c06cc | |||
| a3e6e52c95 | |||
| 5347015cbd | |||
| 4d190892df | |||
| 60eab81709 | |||
| b400b6b157 | |||
| 499b3ef120 | |||
| 92bc9c73f6 | |||
| 2a77558cac | |||
| 816cad60a8 | |||
| 7167f81c69 | |||
| f5cfa0e619 | |||
| 73ad024833 | |||
| 379449b621 | |||
| e17faad6fb | |||
| 1271a3d55e | |||
| 1cd594d113 | |||
| b76f74e79a | |||
| 78817a489b | |||
| b8f2a80ca6 | |||
| ac8a36db1c | |||
| 7e0d8922da | |||
| 9a6b8c9bfe | |||
| eced5b8efd | |||
| 74611e4e52 | |||
| b8614eca4d | |||
| efd24456ac | |||
| 191b2371c8 | |||
| 33419ef291 | |||
| 123f0bb7fc | |||
| 99b5f28a49 | |||
| b30fb4f8c3 | |||
| dc0bdcbd5b | |||
| 0cf29c167d | |||
| 98e4b76206 | |||
| aa4b5db054 | |||
| 433311c10d | |||
| f50178bc78 | |||
| e016e970e5 | |||
| 4223d13898 | |||
| 444aeabf21 | |||
| 05507a59d6 | |||
| c4c89a0a25 | |||
| b0ad6b2a4b | |||
| 25c703f4b2 | |||
| 529c59f93f | |||
| 584b1d9b21 | |||
| 312ce364cc | |||
| 7de8231471 | |||
| 0de9f79029 | |||
| eeb56acdde | |||
| a6862cfec8 | |||
| f8284700b4 | |||
| 38caeb22e0 | |||
| b2c5915db8 | |||
| 3911191b04 | |||
| bc328419ac | |||
| da4efe98bf | |||
| 6653f4a85d |
@@ -7,14 +7,14 @@ assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem or use case is.
|
||||
**Is your feature request related to a use case or a problem you are working on? Please describe.**
|
||||
A clear and concise description of what the problem or use case is. Understanding the rationale is key, to be able to implemeent the right solution.
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
A clear and concise description of any alternative solutions or features you've already considered, and why they won't work.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here, like links to specifications or sample files.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Maven/Java library updates
|
||||
- package-ecosystem: "maven"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
||||
# GitHub actions updates
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/.github/workflows"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
@@ -0,0 +1,127 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
- '!dependabot/**'
|
||||
pull_request:
|
||||
branches: [ 'master' ]
|
||||
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test OpenJDK ${{ matrix.java }} on ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest, macos-latest ]
|
||||
java: [ 11, 17, 21, 23 ]
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
checks: write
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ matrix.java }}
|
||||
java-package: jdk
|
||||
cache: 'maven'
|
||||
- name: Run Tests
|
||||
run: mvn --batch-mode --no-transfer-progress test
|
||||
- name: Publish Test Report
|
||||
uses: mikepenz/action-junit-report@65fe03598d8d251738592a497a9e8547a5c48eaa # v5
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
report_paths: "**/target/surefire-reports/TEST*.xml"
|
||||
check_name: Unit Test Results for OpenJDK ${{ matrix.java }} on ${{ matrix.os }}
|
||||
|
||||
test-jdk8:
|
||||
name: Test OpenJDK ${{ matrix.java }} on ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ ubuntu-latest, windows-latest, macos-13 ]
|
||||
runs-on: ${{ matrix.os }}
|
||||
permissions:
|
||||
checks: write
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '8'
|
||||
java-package: jdk
|
||||
cache: 'maven'
|
||||
- name: Run Tests
|
||||
run: mvn --batch-mode --no-transfer-progress test
|
||||
- name: Publish Test Report
|
||||
uses: mikepenz/action-junit-report@65fe03598d8d251738592a497a9e8547a5c48eaa # v5
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
report_paths: "**/target/surefire-reports/TEST*.xml"
|
||||
check_name: Unit Test Results for OpenJDK ${{ matrix.java }} on ${{ matrix.os }}
|
||||
|
||||
test-oracle:
|
||||
name: Test Oracle JDK 8 with KCMS=${{ matrix.kcms }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
checks: write
|
||||
strategy:
|
||||
matrix:
|
||||
kcms: [ true, false ]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- run: |
|
||||
download_url="https://javadl.oracle.com/webapps/download/AutoDL?BundleId=245038_d3c52aa6bfa54d3ca74e617f18309292"
|
||||
wget -O $RUNNER_TEMP/java_package.tar.gz $download_url
|
||||
- uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||||
with:
|
||||
distribution: 'jdkfile'
|
||||
jdkFile: ${{ runner.temp }}/java_package.tar.gz
|
||||
java-version: '8'
|
||||
cache: 'maven'
|
||||
- name: Set MAVEN_OPTS
|
||||
if: ${{ matrix.kcms }}
|
||||
run: |
|
||||
echo "MAVEN_OPTS=-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider" >> $GITHUB_ENV
|
||||
- name: Display Java version
|
||||
run: java -version
|
||||
- name: Run Tests
|
||||
run: mvn --batch-mode --no-transfer-progress test
|
||||
- name: Publish Test Report
|
||||
uses: mikepenz/action-junit-report@65fe03598d8d251738592a497a9e8547a5c48eaa # v5
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
report_paths: "**/target/surefire-reports/TEST*.xml"
|
||||
check_name: Unit Test Results for Oracle JDK 8 with KCMS=${{ matrix.kcms }}
|
||||
|
||||
release:
|
||||
name: Deploy
|
||||
needs: [ test, test-jdk8, test-oracle ]
|
||||
if: github.ref == 'refs/heads/master' # only perform on latest master
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Set up Maven Central
|
||||
uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
|
||||
with: # running setup-java again overwrites the settings.xml
|
||||
distribution: 'temurin'
|
||||
java-version: '8'
|
||||
java-package: jdk
|
||||
server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
server-username: MAVEN_CENTRAL_USERNAME # env variable for username in deploy (1)
|
||||
server-password: MAVEN_CENTRAL_PASSWORD # env variable for token in deploy (2)
|
||||
- name: Get Project Version
|
||||
run: |
|
||||
echo "PROJECT_VERSION=$(mvn --batch-mode help:evaluate -Dexpression=project.version -q -DforceStdout)" >> $GITHUB_ENV
|
||||
- name: Publish to Maven Central
|
||||
if: ${{ endsWith(env.PROJECT_VERSION, '-SNAPSHOT') }}
|
||||
run: mvn --batch-mode --no-transfer-progress deploy -P release -DskipTests -Dgpg.signer=bc
|
||||
env:
|
||||
MAVEN_CENTRAL_USERNAME: ${{ secrets.SONATYPE_USERNAME }} # must be the same env variable name as (1)
|
||||
MAVEN_CENTRAL_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} # must be the same env variable name as (2)
|
||||
MAVEN_GPG_KEY: ${{ secrets.GPG_KEY }} # Value of the GPG private key to import
|
||||
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
@@ -0,0 +1,69 @@
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '26 13 * * 6'
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners
|
||||
# Consider using larger runners for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'java' ]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
@@ -0,0 +1,62 @@
|
||||
# This workflow uses actions that are not certified by GitHub. They are provided
|
||||
# by a third-party and are governed by separate terms of service, privacy
|
||||
# policy, and support documentation.
|
||||
|
||||
name: Scorecard supply-chain security
|
||||
on:
|
||||
# For Branch-Protection check. Only the default branch is supported. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||
branch_protection_rule:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: '38 8 * * 2'
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
||||
permissions: read-all # Declare default permissions as read only.
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write # to upload the results to code-scanning dashboard.
|
||||
id-token: write # to publish results and get a badge
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@05b42c624433fc40578a4040d5cf5e36ddca8cde # v2.4.2
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
|
||||
# you want to enable the Branch-Protection check on the repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-fine-grained-pat-optional.
|
||||
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
|
||||
|
||||
# Publish Results:
|
||||
# - Publish results to OpenSSF REST API for easy access by consumers
|
||||
# - Allows the repository to include the Scorecard badge.
|
||||
# - See https://github.com/ossf/scorecard-action#publishing-results.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@fca7ace96b7d713c7035871441bd52efbe39e27e # v3.28.19
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
@@ -15,3 +15,4 @@ private
|
||||
profiles.xml
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
/.metadata/
|
||||
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
dist: trusty
|
||||
language: java
|
||||
jdk:
|
||||
- oraclejdk8 # LTS until Mar 2022
|
||||
- oraclejdk11 # LTS until Sep 2023
|
||||
- oraclejdk15 # out of support
|
||||
- oraclejdk16 # out of support
|
||||
- oraclejdk17 # LTS until Sep 2026
|
||||
jobs:
|
||||
include:
|
||||
# Extra job, testing legacy CMM option
|
||||
- jdk: oraclejdk8
|
||||
env: MAVEN_OPTS=-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
@@ -1,13 +1,20 @@
|
||||
[](https://travis-ci.com/github/haraldk/TwelveMonkeys)
|
||||
[](https://maven-badges.herokuapp.com/maven-central/com.twelvemonkeys.imageio/imageio)
|
||||
[](https://github.com/haraldk/TwelveMonkeys/actions/workflows/ci.yml)
|
||||
[](https://github.com/haraldk/TwelveMonkeys/actions/workflows/codeql.yml)
|
||||
[](https://securityscorecards.dev/viewer/?uri=github.com/haraldk/TwelveMonkeys)
|
||||
[](https://www.bestpractices.dev/projects/7900)
|
||||
|
||||
[](https://search.maven.org/search?q=g:com.twelvemonkeys.imageio)
|
||||
[](https://oss.sonatype.org/content/repositories/snapshots/com/twelvemonkeys/)
|
||||
[](https://stackoverflow.com/questions/tagged/twelvemonkeys)
|
||||
[](https://paypal.me/haraldk76/100)
|
||||
|
||||

|
||||
|
||||
## About
|
||||
|
||||
TwelveMonkeys ImageIO provides extended image file format support for the Java platform, through plugins for the `javax.imageio.*` package.
|
||||
|
||||
The main goal of this project is to provide support for formats not covered by the JRE itself.
|
||||
The main goal of this project is to provide support for file formats not covered by the JDK.
|
||||
Support for these formats is important, to be able to read data found
|
||||
"in the wild", as well as to maintain access to data in legacy formats.
|
||||
As there is lots of legacy data out there, we see the need for open implementations of readers for popular formats.
|
||||
@@ -16,40 +23,41 @@ As there is lots of legacy data out there, we see the need for open implementati
|
||||
|
||||
## File formats supported
|
||||
|
||||
| Plugin | Format | Description | Read | Write | Metadata | Notes |
|
||||
| ------ | -------- | ----------- |:----:|:-----:| -------- | ----- |
|
||||
| Batik | **SVG** | Scalable Vector Graphics | âś” | - | - | Requires [Batik](https://xmlgraphics.apache.org/batik/)
|
||||
| | WMF | MS Windows Metafile | âś” | - | - | Requires [Batik](https://xmlgraphics.apache.org/batik/)
|
||||
| [BMP](https://github.com/haraldk/TwelveMonkeys/wiki/BMP-Plugin) | **BMP** | MS Windows and IBM OS/2 Device Independent Bitmap | âś” | âś” | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/bmp_metadata.html) & [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | CUR | MS Windows Cursor Format | âś” | - | - |
|
||||
| | ICO | MS Windows Icon Format | âś” | âś” | - |
|
||||
| [HDR](https://github.com/haraldk/TwelveMonkeys/wiki/HDR-Plugin) | HDR | Radiance High Dynamic Range RGBE Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [ICNS](https://github.com/haraldk/TwelveMonkeys/wiki/ICNS-Plugin) | ICNS | Apple Icon Image | âś” | âś” | - |
|
||||
| [IFF](https://github.com/haraldk/TwelveMonkeys/wiki/IFF-Plugin) | IFF | Commodore Amiga/Electronic Arts Interchange File Format | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [JPEG](https://github.com/haraldk/TwelveMonkeys/wiki/JPEG-Plugin) | **JPEG** | Joint Photographers Expert Group | âś” | âś” | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/jpeg_metadata.html#image) & [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | JPEG Lossless | | âś” | - | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/jpeg_metadata.html#image) & [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PCX](https://github.com/haraldk/TwelveMonkeys/wiki/PCX-Plugin) | PCX | ZSoft Paintbrush Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | DCX | Multi-page PCX fax document | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PICT](https://github.com/haraldk/TwelveMonkeys/wiki/PICT-Plugin) | PICT | Apple QuickTime Picture Format | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PNTG | Apple MacPaint Picture Format | âś” | | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PNM](https://github.com/haraldk/TwelveMonkeys/wiki/PNM-Plugin) | PAM | NetPBM Portable Any Map | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PBM | NetPBM Portable Bit Map | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PGM | NetPBM Portable Grey Map | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PPM | NetPBM Portable Pix Map | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PFM | Portable Float Map | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PSD](https://github.com/haraldk/TwelveMonkeys/wiki/PSD-Plugin) | **PSD** | Adobe Photoshop Document | âś” | - | Native & [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PSB | Adobe Photoshop Large Document | âś” | - | Native & [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [SGI](https://github.com/haraldk/TwelveMonkeys/wiki/SGI-Plugin) | SGI | Silicon Graphics Image Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [TGA](https://github.com/haraldk/TwelveMonkeys/wiki/TGA-Plugin) | TGA | Truevision TGA Image Format | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
|ThumbsDB| Thumbs.db| MS Windows Thumbs DB | âś” | - | - | OLE2 Compound Document based format only
|
||||
| [TIFF](https://github.com/haraldk/TwelveMonkeys/wiki/TIFF-Plugin) | **TIFF** | Aldus/Adobe Tagged Image File Format | âś” | âś” | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html#ImageMetadata) & [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | BigTIFF | | âś” | - | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html#ImageMetadata) & [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [WebP](https://github.com/haraldk/TwelveMonkeys/wiki/WebP-Plugin) | **WebP** | Google WebP Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| XWD | XWD | X11 Window Dump Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| Plugin | Format | Description | R | W | Metadata | Notes |
|
||||
| ------ | -------- |---------------------------------------------------------|:---:|:---:| -------- | ----- |
|
||||
| Batik | **SVG** | Scalable Vector Graphics | âś” | - | - | Requires [Batik](https://xmlgraphics.apache.org/batik/) |
|
||||
| | WMF | MS Windows Metafile | âś” | - | - | Requires [Batik](https://xmlgraphics.apache.org/batik/) |
|
||||
| [BMP](https://github.com/haraldk/TwelveMonkeys/wiki/BMP-Plugin) | **BMP** | MS Windows and IBM OS/2 Device Independent Bitmap | âś” | âś” | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/bmp_metadata.html), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | CUR | MS Windows Cursor Format | âś” | - | - |
|
||||
| | ICO | MS Windows Icon Format | âś” | âś” | - |
|
||||
| [DDS](https://github.com/haraldk/TwelveMonkeys/wiki/DDS-Plugin) | DDS | MS Direct Draw Surface Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [HDR](https://github.com/haraldk/TwelveMonkeys/wiki/HDR-Plugin) | HDR | Radiance High Dynamic Range RGBE Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [ICNS](https://github.com/haraldk/TwelveMonkeys/wiki/ICNS-Plugin) | ICNS | Apple Icon Image | âś” | âś” | - |
|
||||
| [IFF](https://github.com/haraldk/TwelveMonkeys/wiki/IFF-Plugin) | IFF | Commodore Amiga/Electronic Arts Interchange File Format | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [JPEG](https://github.com/haraldk/TwelveMonkeys/wiki/JPEG-Plugin) | **JPEG** | Joint Photographers Expert Group | âś” | âś” | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/jpeg_metadata.html#image), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | JPEG Lossless | | âś” | - | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/jpeg_metadata.html#image), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PCX](https://github.com/haraldk/TwelveMonkeys/wiki/PCX-Plugin) | PCX | ZSoft Paintbrush Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | DCX | Multi-page PCX fax document | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PICT](https://github.com/haraldk/TwelveMonkeys/wiki/PICT-Plugin) | PICT | Apple QuickTime Picture Format | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PNTG | Apple MacPaint Picture Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PNM](https://github.com/haraldk/TwelveMonkeys/wiki/PNM-Plugin) | PAM | NetPBM Portable Any Map | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PBM | NetPBM Portable Bit Map | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PGM | NetPBM Portable Grey Map | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PPM | NetPBM Portable Pix Map | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PFM | Portable Float Map | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [PSD](https://github.com/haraldk/TwelveMonkeys/wiki/PSD-Plugin) | **PSD** | Adobe Photoshop Document | âś” | (âś”) | Native, [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | PSB | Adobe Photoshop Large Document | âś” | - | Native, [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [SGI](https://github.com/haraldk/TwelveMonkeys/wiki/SGI-Plugin) | SGI | Silicon Graphics Image Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [TGA](https://github.com/haraldk/TwelveMonkeys/wiki/TGA-Plugin) | TGA | Truevision TGA Image Format | âś” | âś” | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
|ThumbsDB| Thumbs.db| MS Windows Thumbs DB | âś” | - | - | OLE2 Compound Document based format only |
|
||||
| [TIFF](https://github.com/haraldk/TwelveMonkeys/wiki/TIFF-Plugin) | **TIFF** | Aldus/Adobe Tagged Image File Format | âś” | âś” | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html#ImageMetadata), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| | BigTIFF | | âś” | âś” | [Native](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html#ImageMetadata), [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| [WebP](https://github.com/haraldk/TwelveMonkeys/wiki/WebP-Plugin) | **WebP** | Google WebP Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
| XWD | XWD | X11 Window Dump Format | âś” | - | [Standard](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html) |
|
||||
|
||||
|
||||
**Important note on using Batik:** *Please read [The Apache™ XML Graphics Project - Security](https://xmlgraphics.apache.org/security.html),
|
||||
and make sure you use version 1.14 or later.*
|
||||
and make sure you use an updated and secure version.*
|
||||
|
||||
Note that GIF, PNG and WBMP formats are already supported through the ImageIO API, using the
|
||||
[JDK standard plugins](https://docs.oracle.com/en/java/javase/11/docs/api/java.desktop/javax/imageio/package-summary.html).
|
||||
@@ -215,6 +223,43 @@ BufferedImageOp ditherer = new DiffusionDither();
|
||||
BufferedImage output = ditherer.filter(input, null);
|
||||
```
|
||||
|
||||
#### Working with damaged images
|
||||
|
||||
When using the normal patterns for loading images, trying to load a damaged image will result in an `IOException` being thrown.
|
||||
|
||||
```java
|
||||
BufferedImage image = null;
|
||||
try {
|
||||
image = ImageIO.read(file);
|
||||
} catch (IOException exception) {
|
||||
// Handle, log a warning/error etc
|
||||
}
|
||||
```
|
||||
|
||||
In this scenario, if the image is damaged, and `ImageIO.read` throws an exception, `image` is still `null` - it's not possible for a function to both return a value and throw an exception.
|
||||
|
||||
However, in some cases it may be possible to get usable image data from a damaged image. The way to do this is use an `ImageReadParam` to set a `BufferedImage` as a destination.
|
||||
|
||||
```java
|
||||
int width = reader.getWidth(0);
|
||||
int height = reader.getHeight(0);
|
||||
ImageTypeSpecifier imageType = reader.getRawImageType(0);
|
||||
BufferedImage image = imageType.createBufferedImage(width, height);
|
||||
|
||||
ImageReadParam param = reader.getDefaultReadParam();
|
||||
param.setDestination(image);
|
||||
|
||||
try {
|
||||
reader.read(0, param);
|
||||
}
|
||||
catch (IOException e) {
|
||||
// Handle, log a warning/error etc
|
||||
}
|
||||
```
|
||||
|
||||
In theory this should work for all plugins, but the result is very much plugin/implementation specific. With some formats and some forms of damaged file, you may get an image that is mostly useful.
|
||||
However, you should be prepared for the possibility this just gives a blank or empty image.
|
||||
|
||||
## Building
|
||||
|
||||
Download the project (using [Git](https://git-scm.com/downloads)):
|
||||
@@ -271,12 +316,12 @@ To depend on the JPEG and TIFF plugin using Maven, add the following to your POM
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-jpeg</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-tiff</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
@@ -286,7 +331,17 @@ To depend on the JPEG and TIFF plugin using Maven, add the following to your POM
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.servlet</groupId>
|
||||
<artifactId>servlet</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
Or Jakarta version, for Servlet API 5.0
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.servlet</groupId>
|
||||
<artifactId>servlet</artifactId>
|
||||
<version>3.12.0</version>
|
||||
<classifier>jakarta</classifier>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
@@ -295,18 +350,18 @@ To depend on the JPEG and TIFF plugin using Maven, add the following to your POM
|
||||
|
||||
To depend on the JPEG and TIFF plugin in your IDE or program, add all of the following JARs to your class path:
|
||||
|
||||
twelvemonkeys-common-lang-3.7.0.jar
|
||||
twelvemonkeys-common-io-3.7.0.jar
|
||||
twelvemonkeys-common-image-3.7.0.jar
|
||||
twelvemonkeys-imageio-core-3.7.0.jar
|
||||
twelvemonkeys-imageio-metadata-3.7.0.jar
|
||||
twelvemonkeys-imageio-jpeg-3.7.0.jar
|
||||
twelvemonkeys-imageio-tiff-3.7.0.jar
|
||||
twelvemonkeys-common-lang-3.12.0.jar
|
||||
twelvemonkeys-common-io-3.12.0.jar
|
||||
twelvemonkeys-common-image-3.12.0.jar
|
||||
twelvemonkeys-imageio-core-3.12.0.jar
|
||||
twelvemonkeys-imageio-metadata-3.12.0.jar
|
||||
twelvemonkeys-imageio-jpeg-3.12.0.jar
|
||||
twelvemonkeys-imageio-tiff-3.12.0.jar
|
||||
|
||||
#### Deploying the plugins in a web app
|
||||
|
||||
Because the `ImageIO` plugin registry (the `IIORegistry`) is "VM global", it doesn't by default work well with
|
||||
servlet contexts. This is especially evident if you load plugins from the `WEB-INF/lib` or `classes` folder.
|
||||
Because the `ImageIO` plugin registry (the `IIORegistry`) is "VM global", it does not work well with
|
||||
servlet contexts as-is. This is especially evident if you load plugins from the `WEB-INF/lib` or `classes` folder.
|
||||
Unless you add `ImageIO.scanForPlugins()` somewhere in your code, the plugins might never be available at all.
|
||||
|
||||
In addition, servlet contexts dynamically loads and unloads classes (using a new class loader per context).
|
||||
@@ -342,6 +397,16 @@ or other ImageIO plugins as well.
|
||||
|
||||
Another safe option, is to place the JAR files in the application server's shared or common lib folder.
|
||||
|
||||
##### Jakarta Servlet Support
|
||||
|
||||
For those transitioning from the old `javax.servlet` to the new `jakarta.servlet` package, there is a separate
|
||||
dependency available. It contains exactly the same servlet classes as mentioned above, but built against the new Jakarta EE
|
||||
packages. The dependency has the same group name and identifier as before, but a `jakarta` *classifier* appended, to
|
||||
distinguish it from the non-Jakarta package.
|
||||
|
||||
See the [Maven dependency example](#maven-dependency-example) for how to enable it with Maven.
|
||||
Gradle or other build tools will have similar options.
|
||||
|
||||
#### Including the plugins in a "fat" JAR
|
||||
|
||||
The recommended way to use the plugins, is just to include the JARs as-is in your project, through a Maven dependency or similar.
|
||||
@@ -367,81 +432,52 @@ Other "fat" JAR bundlers will probably have similar mechanisms to merge entries
|
||||
|
||||
### Links to prebuilt binaries
|
||||
|
||||
##### Latest version (3.7.0)
|
||||
##### Latest version (3.12.0)
|
||||
|
||||
Requires Java 7 or later.
|
||||
The latest version that will run on Java 7 is 3.9.4. Later versions will require Java 8 or later.
|
||||
|
||||
Common dependencies
|
||||
* [common-lang-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.7.0/common-lang-3.7.0.jar)
|
||||
* [common-io-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.7.0/common-io-3.7.0.jar)
|
||||
* [common-image-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.7.0/common-image-3.7.0.jar)
|
||||
* [common-lang-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.12.0/common-lang-3.12.0.jar)
|
||||
* [common-io-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.12.0/common-io-3.12.0.jar)
|
||||
* [common-image-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.12.0/common-image-3.12.0.jar)
|
||||
|
||||
ImageIO dependencies
|
||||
* [imageio-core-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.7.0/imageio-core-3.7.0.jar)
|
||||
* [imageio-metadata-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.7.0/imageio-metadata-3.7.0.jar)
|
||||
* [imageio-core-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.12.0/imageio-core-3.12.0.jar)
|
||||
* [imageio-metadata-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.12.0/imageio-metadata-3.12.0.jar)
|
||||
|
||||
ImageIO plugins
|
||||
* [imageio-bmp-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-bmp/3.7.0/imageio-bmp-3.7.0.jar)
|
||||
* [imageio-hdr-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-hdr/3.7.0/imageio-hdr-3.7.0.jar)
|
||||
* [imageio-icns-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.7.0/imageio-icns-3.7.0.jar)
|
||||
* [imageio-iff-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.7.0/imageio-iff-3.7.0.jar)
|
||||
* [imageio-jpeg-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.7.0/imageio-jpeg-3.7.0.jar)
|
||||
* [imageio-pcx-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pcx/3.7.0/imageio-pcx-3.7.0.jar)
|
||||
* [imageio-pict-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.7.0/imageio-pict-3.7.0.jar)
|
||||
* [imageio-pnm-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pnm/3.7.0/imageio-pnm-3.7.0.jar)
|
||||
* [imageio-psd-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.7.0/imageio-psd-3.7.0.jar)
|
||||
* [imageio-sgi-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-sgi/3.7.0/imageio-sgi-3.7.0.jar)
|
||||
* [imageio-tga-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tga/3.7.0/imageio-tga-3.7.0.jar)
|
||||
* [imageio-thumbsdb-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.7.0/imageio-thumbsdb-3.7.0.jar)
|
||||
* [imageio-tiff-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.7.0/imageio-tiff-3.7.0.jar)
|
||||
* [imageio-webp-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-webp/3.7.0/imageio-webp-3.7.0.jar)
|
||||
* [imageio-xwd-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-xwd/3.7.0/imageio-xwd-3.7.0.jar)
|
||||
* [imageio-bmp-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-bmp/3.12.0/imageio-bmp-3.12.0.jar)
|
||||
* [imageio-dds-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-dds/3.12.0/imageio-dds-3.12.0.jar)
|
||||
* [imageio-hdr-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-hdr/3.12.0/imageio-hdr-3.12.0.jar)
|
||||
* [imageio-icns-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.12.0/imageio-icns-3.12.0.jar)
|
||||
* [imageio-iff-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.12.0/imageio-iff-3.12.0.jar)
|
||||
* [imageio-jpeg-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.12.0/imageio-jpeg-3.12.0.jar)
|
||||
* [imageio-pcx-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pcx/3.12.0/imageio-pcx-3.12.0.jar)
|
||||
* [imageio-pict-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.12.0/imageio-pict-3.12.0.jar)
|
||||
* [imageio-pnm-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pnm/3.12.0/imageio-pnm-3.12.0.jar)
|
||||
* [imageio-psd-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.12.0/imageio-psd-3.12.0.jar)
|
||||
* [imageio-sgi-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-sgi/3.12.0/imageio-sgi-3.12.0.jar)
|
||||
* [imageio-tga-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tga/3.12.0/imageio-tga-3.12.0.jar)
|
||||
* [imageio-thumbsdb-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.12.0/imageio-thumbsdb-3.12.0.jar)
|
||||
* [imageio-tiff-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.12.0/imageio-tiff-3.12.0.jar)
|
||||
* [imageio-webp-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-webp/3.12.0/imageio-webp-3.12.0.jar)
|
||||
* [imageio-xwd-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-xwd/3.12.0/imageio-xwd-3.12.0.jar)
|
||||
|
||||
ImageIO plugins requiring 3rd party libs
|
||||
* [imageio-batik-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.7.0/imageio-batik-3.7.0.jar)
|
||||
* [imageio-batik-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.12.0/imageio-batik-3.12.0.jar)
|
||||
|
||||
Photoshop Path support for ImageIO
|
||||
* [imageio-clippath-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-clippath/3.7.0/imageio-clippath-3.7.0.jar)
|
||||
* [imageio-clippath-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-clippath/3.12.0/imageio-clippath-3.12.0.jar)
|
||||
|
||||
Servlet support
|
||||
* [servlet-3.7.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.7.0/servlet-3.7.0.jar)
|
||||
|
||||
##### Old version (3.0.x)
|
||||
|
||||
Use this version for projects that requires Java 6 or need the JMagick support. *Does not support Java 8 or later*.
|
||||
|
||||
Common dependencies
|
||||
* [common-lang-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-lang/3.0.2/common-lang-3.0.2.jar)
|
||||
* [common-io-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-io/3.0.2/common-io-3.0.2.jar)
|
||||
* [common-image-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/common/common-image/3.0.2/common-image-3.0.2.jar)
|
||||
|
||||
ImageIO dependencies
|
||||
* [imageio-core-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-core/3.0.2/imageio-core-3.0.2.jar)
|
||||
* [imageio-metadata-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-metadata/3.0.2/imageio-metadata-3.0.2.jar)
|
||||
|
||||
ImageIO plugins
|
||||
* [imageio-jpeg-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jpeg/3.0.2/imageio-jpeg-3.0.2.jar)
|
||||
* [imageio-tiff-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-tiff/3.0.2/imageio-tiff-3.0.2.jar)
|
||||
* [imageio-psd-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-psd/3.0.2/imageio-psd-3.0.2.jar)
|
||||
* [imageio-pict-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-pict/3.0.2/imageio-pict-3.0.2.jar)
|
||||
* [imageio-iff-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-iff/3.0.2/imageio-iff-3.0.2.jar)
|
||||
* [imageio-icns-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-icns/3.0.2/imageio-icns-3.0.2.jar)
|
||||
* [imageio-ico-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-ico/3.0.2/imageio-ico-3.0.2.jar)
|
||||
* [imageio-thumbsdb-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-thumbsdb/3.0.2/imageio-thumbsdb-3.0.2.jar)
|
||||
|
||||
ImageIO plugins requiring 3rd party libs
|
||||
* [imageio-batik-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-batik/3.0.2/imageio-batik-3.0.2.jar)
|
||||
* [imageio-jmagick-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/imageio/imageio-jmagick/3.0.2/imageio-jmagick-3.0.2.jar)
|
||||
|
||||
Servlet support
|
||||
* [servlet-3.0.2.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.0.2/servlet-3.0.2.jar)
|
||||
|
||||
* [servlet-3.12.0.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.12.0/servlet-3.12.0.jar) for legacy Java EE (javax.servlet)
|
||||
* [servlet-3.12.0-jakarta.jar](https://search.maven.org/remotecontent?filepath=com/twelvemonkeys/servlet/servlet/3.12.0/servlet-3.12.0-jakrta.jar) for Jakarta EE (jakarta.servlet)
|
||||
|
||||
## License
|
||||
|
||||
This project is provided under the OSI approved [BSD license](https://opensource.org/licenses/BSD-3-Clause):
|
||||
|
||||
Copyright (c) 2008-2020, Harald Kuhr
|
||||
Copyright (c) 2008-2022, Harald Kuhr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -473,8 +509,9 @@ This project is provided under the OSI approved [BSD license](https://opensource
|
||||
|
||||
q: How do I use it?
|
||||
|
||||
a: The easiest way is to build your own project using Maven, and just add dependencies to the specific plug-ins you need.
|
||||
If you don't use Maven, make sure you have all the necessary JARs in classpath. See the Install section above.
|
||||
a: The easiest way is to build your own project using Maven, Gradle or other build tool with dependency management,
|
||||
and just add dependencies to the specific plug-ins you need.
|
||||
If you don't use such a build tool, make sure you have all the necessary JARs in classpath. See the Install section above.
|
||||
|
||||
|
||||
q: What changes do I have to make to my code in order to use the plug-ins?
|
||||
@@ -492,27 +529,41 @@ q: How does it work?
|
||||
|
||||
a: The TwelveMonkeys ImageIO project contains plug-ins for ImageIO. ImageIO uses a service lookup mechanism, to discover plug-ins at runtime.
|
||||
|
||||
All you have have to do, is to make sure you have the TwelveMonkeys JARs in your classpath.
|
||||
All you have to do, is to make sure you have the TwelveMonkeys ImageIO JARs in your classpath.
|
||||
|
||||
You can read more about the registry and the lookup mechanism in the [IIORegistry API doc](https://docs.oracle.com/javase/7/docs/api/javax/imageio/spi/IIORegistry.html).
|
||||
|
||||
The fine print: The TwelveMonkeys service providers for JPEG, BMP and TIFF, overrides the onRegistration method, and
|
||||
utilizes the pairwise partial ordering mechanism of the `IIOServiceRegistry` to make sure it is installed before
|
||||
the Sun/Oracle provided `JPEGImageReader` and `BMPImageReader`, and the Apple provided `TIFFImageReader` on OS X,
|
||||
the Sun/Oracle provided `JPEGImageReader`, `BMPImageReader` `TIFFImageReader`, and the Apple provided `TIFFImageReader` on OS X,
|
||||
respectively. Using the pairwise ordering will not remove any functionality form these implementations, but in most
|
||||
cases you'll end up using the TwelveMonkeys plug-ins instead.
|
||||
|
||||
|
||||
q: Why is there no support for common formats like GIF or PNG?
|
||||
|
||||
a: The short answer is simply that the built-in support in ImageIO for these formats are good enough as-is.
|
||||
a: The short answer is simply that the built-in support in ImageIO for these formats are considered good enough as-is.
|
||||
If you are looking for better PNG write performance on Java 7 and 8, see [JDK9 PNG Writer Backport](https://github.com/gredler/jdk9-png-writer-backport).
|
||||
|
||||
|
||||
q: When is the next release? What is the current release schedule?
|
||||
|
||||
a: The goal is to make monthly releases, containing bug fixes and minor new features.
|
||||
And quarterly releases with more "major" features.
|
||||
|
||||
|
||||
q: I love this project! How can I help?
|
||||
|
||||
a: Have a look at the open issues, and see if there are any issues you can help fix, or provide sample file or create test cases for.
|
||||
It is also possible for you or your organization to become a sponsor, through GitHub Sponsors.
|
||||
Providing funding will allow us to spend more time on fixing bugs and implementing new features.
|
||||
|
||||
|
||||
q: What about JAI? Several of the formats are already supported by JAI.
|
||||
|
||||
a: While JAI (and jai-imageio in particular) have support for some of the same formats, JAI has some major issues.
|
||||
The most obvious being:
|
||||
- It's not actively developed. No issues has been fixed for years.
|
||||
- It's not actively developed. No issue has been fixed for years.
|
||||
- To get full format support, you need native libs.
|
||||
Native libs does not exist for several popular platforms/architectures, and further the native libs are not open source.
|
||||
Some environments may also prevent deployment of native libs, which brings us back to square one.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Security Policy
|
||||
|
||||
To report a security issue, please disclose it at [security advisory](https://github.com/haraldk/TwelveMonkeys/security/advisories/new).
|
||||
|
||||
Vulnerabilities will be disclosed in a best effort base.
|
||||
+6
-1
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys</groupId>
|
||||
<artifactId>twelvemonkeys</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.twelvemonkeys.bom</groupId>
|
||||
@@ -63,6 +63,11 @@
|
||||
<artifactId>imageio-hdr</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-dds</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio-icns</artifactId>
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>common-image</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>TwelveMonkeys :: Common :: Image</name>
|
||||
<description>
|
||||
The TwelveMonkeys Common Image support
|
||||
TwelveMonkeys Common image support classes.
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
@@ -28,12 +28,14 @@
|
||||
<artifactId>common-io</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jmagick</groupId>
|
||||
<artifactId>jmagick</artifactId>
|
||||
<version>6.2.4</version>
|
||||
<optional>true</optional>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
+96
-86
@@ -79,7 +79,7 @@ public final class BufferedImageFactory {
|
||||
private int scanSize;
|
||||
|
||||
private ColorModel sourceColorModel;
|
||||
private Hashtable sourceProperties; // ImageConsumer API dictates Hashtable
|
||||
private Hashtable<?, ?> sourceProperties; // ImageConsumer API dictates Hashtable
|
||||
|
||||
private Object sourcePixels;
|
||||
|
||||
@@ -91,21 +91,21 @@ public final class BufferedImageFactory {
|
||||
|
||||
/**
|
||||
* Creates a {@code BufferedImageFactory}.
|
||||
* @param pSource the source image
|
||||
* @throws IllegalArgumentException if {@code pSource == null}
|
||||
* @param source the source image
|
||||
* @throws IllegalArgumentException if {@code source == null}
|
||||
*/
|
||||
public BufferedImageFactory(final Image pSource) {
|
||||
this(pSource != null ? pSource.getSource() : null);
|
||||
public BufferedImageFactory(final Image source) {
|
||||
this(source != null ? source.getSource() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@code BufferedImageFactory}.
|
||||
* @param pSource the source image producer
|
||||
* @throws IllegalArgumentException if {@code pSource == null}
|
||||
* @param source the source image producer
|
||||
* @throws IllegalArgumentException if {@code source == null}
|
||||
*/
|
||||
public BufferedImageFactory(final ImageProducer pSource) {
|
||||
Validate.notNull(pSource, "source");
|
||||
producer = pSource;
|
||||
public BufferedImageFactory(final ImageProducer source) {
|
||||
Validate.notNull(source, "source");
|
||||
producer = source;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,44 +155,44 @@ public final class BufferedImageFactory {
|
||||
/**
|
||||
* Sets the source region (AOI) for the new image.
|
||||
*
|
||||
* @param pRegion the source region
|
||||
* @param region the source region
|
||||
*/
|
||||
public void setSourceRegion(final Rectangle pRegion) {
|
||||
public void setSourceRegion(final Rectangle region) {
|
||||
// Re-fetch everything, if region changed
|
||||
if (x != pRegion.x || y != pRegion.y || width != pRegion.width || height != pRegion.height) {
|
||||
if (x != region.x || y != region.y || width != region.width || height != region.height) {
|
||||
dispose();
|
||||
}
|
||||
|
||||
x = pRegion.x;
|
||||
y = pRegion.y;
|
||||
width = pRegion.width;
|
||||
height = pRegion.height;
|
||||
x = region.x;
|
||||
y = region.y;
|
||||
width = region.width;
|
||||
height = region.height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source subsampling for the new image.
|
||||
*
|
||||
* @param pXSub horizontal subsampling factor
|
||||
* @param pYSub vertical subsampling factor
|
||||
* @param xSubsampling horizontal subsampling factor
|
||||
* @param ySubsampling vertical subsampling factor
|
||||
*/
|
||||
public void setSourceSubsampling(int pXSub, int pYSub) {
|
||||
public void setSourceSubsampling(int xSubsampling, int ySubsampling) {
|
||||
// Re-fetch everything, if subsampling changed
|
||||
if (xSub != pXSub || ySub != pYSub) {
|
||||
if (xSub != xSubsampling || ySub != ySubsampling) {
|
||||
dispose();
|
||||
}
|
||||
|
||||
if (pXSub > 1) {
|
||||
xSub = pXSub;
|
||||
if (xSubsampling > 1) {
|
||||
xSub = xSubsampling;
|
||||
}
|
||||
if (pYSub > 1) {
|
||||
ySub = pYSub;
|
||||
if (ySubsampling > 1) {
|
||||
ySub = ySubsampling;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void doFetch(boolean pColorModelOnly) throws ImageConversionException {
|
||||
if (!fetching && (!pColorModelOnly && buffered == null || buffered == null && sourceColorModel == null)) {
|
||||
private synchronized void doFetch(final boolean colorModelOnly) throws ImageConversionException {
|
||||
if (!fetching && (!colorModelOnly && buffered == null || buffered == null && sourceColorModel == null)) {
|
||||
// NOTE: Subsampling is only applied if extracting full image
|
||||
if (!pColorModelOnly && (xSub > 1 || ySub > 1)) {
|
||||
if (!colorModelOnly && (xSub > 1 || ySub > 1)) {
|
||||
// If only sampling a region, the region must be scaled too
|
||||
if (width > 0 && height > 0) {
|
||||
width = (width + xSub - 1) / xSub;
|
||||
@@ -207,38 +207,41 @@ public final class BufferedImageFactory {
|
||||
|
||||
// Start fetching
|
||||
fetching = true;
|
||||
readColorModelOnly = pColorModelOnly;
|
||||
readColorModelOnly = colorModelOnly;
|
||||
|
||||
producer.startProduction(consumer); // Note: If single-thread (synchronous), this call will block
|
||||
|
||||
// Wait until the producer wakes us up, by calling imageComplete
|
||||
while (fetching) {
|
||||
try {
|
||||
wait(200l);
|
||||
wait(200L);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new ImageConversionException("Image conversion aborted: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (consumerException != null) {
|
||||
throw new ImageConversionException("Image conversion failed: " + consumerException.getMessage(), consumerException);
|
||||
}
|
||||
try {
|
||||
if (consumerException != null) {
|
||||
throw new ImageConversionException("Image conversion failed: " + consumerException.getMessage(), consumerException);
|
||||
}
|
||||
|
||||
if (pColorModelOnly) {
|
||||
createColorModel();
|
||||
if (colorModelOnly) {
|
||||
createColorModel();
|
||||
}
|
||||
else {
|
||||
createBuffered();
|
||||
}
|
||||
}
|
||||
else {
|
||||
createBuffered();
|
||||
finally {
|
||||
// Clean up, in case any objects are copied/cloned, so we can free resources
|
||||
freeResources();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createColorModel() {
|
||||
colorModel = sourceColorModel;
|
||||
|
||||
// Clean up, in case any objects are copied/cloned, so we can free resources
|
||||
freeResources();
|
||||
}
|
||||
|
||||
private void createBuffered() {
|
||||
@@ -253,8 +256,9 @@ public final class BufferedImageFactory {
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up, in case any objects are copied/cloned, so we can free resources
|
||||
freeResources();
|
||||
if (buffered == null) {
|
||||
throw new ImageConversionException("Could not create BufferedImage");
|
||||
}
|
||||
}
|
||||
|
||||
private void freeResources() {
|
||||
@@ -280,27 +284,27 @@ public final class BufferedImageFactory {
|
||||
/**
|
||||
* Adds a progress listener to this factory.
|
||||
*
|
||||
* @param pListener the progress listener
|
||||
* @param listener the progress listener
|
||||
*/
|
||||
public void addProgressListener(ProgressListener pListener) {
|
||||
if (pListener == null) {
|
||||
public void addProgressListener(ProgressListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (listeners == null) {
|
||||
listeners = new CopyOnWriteArrayList<ProgressListener>();
|
||||
listeners = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
listeners.add(pListener);
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a progress listener from this factory.
|
||||
*
|
||||
* @param pListener the progress listener
|
||||
* @param listener the progress listener
|
||||
*/
|
||||
public void removeProgressListener(ProgressListener pListener) {
|
||||
if (pListener == null) {
|
||||
public void removeProgressListener(ProgressListener listener) {
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,7 +312,7 @@ public final class BufferedImageFactory {
|
||||
return;
|
||||
}
|
||||
|
||||
listeners.remove(pListener);
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -324,21 +328,22 @@ public final class BufferedImageFactory {
|
||||
* Converts an array of {@code int} pixels to an array of {@code short}
|
||||
* pixels. The conversion is done, by masking out the
|
||||
* <em>higher 16 bits</em> of the {@code int}.
|
||||
*
|
||||
* <p>
|
||||
* For any given {@code int}, the {@code short} value is computed as
|
||||
* follows:
|
||||
* <blockquote>{@code
|
||||
* short value = (short) (intValue & 0x0000ffff);
|
||||
* }</blockquote>
|
||||
* </p>
|
||||
*
|
||||
* @param pPixels the pixel data to convert
|
||||
* @return an array of {@code short}s, same lenght as {@code pPixels}
|
||||
* @param inputPixels the pixel data to convert
|
||||
* @return an array of {@code short}s, same length as {@code inputPixels}
|
||||
*/
|
||||
private static short[] toShortPixels(int[] pPixels) {
|
||||
short[] pixels = new short[pPixels.length];
|
||||
private static short[] toShortPixels(int[] inputPixels) {
|
||||
short[] pixels = new short[inputPixels.length];
|
||||
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
pixels[i] = (short) (pPixels[i] & 0xffff);
|
||||
pixels[i] = (short) (inputPixels[i] & 0xffff);
|
||||
}
|
||||
|
||||
return pixels;
|
||||
@@ -351,17 +356,17 @@ public final class BufferedImageFactory {
|
||||
* @see BufferedImageFactory#addProgressListener
|
||||
* @see BufferedImageFactory#removeProgressListener
|
||||
*/
|
||||
public static interface ProgressListener extends EventListener {
|
||||
public interface ProgressListener extends EventListener {
|
||||
|
||||
/**
|
||||
* Reports progress to this listener.
|
||||
* Invoked by the {@code BufferedImageFactory} to report progress in
|
||||
* the image decoding.
|
||||
*
|
||||
* @param pFactory the factory reporting the progress
|
||||
* @param pPercentage the percentage of progress
|
||||
* @param factory the factory reporting the progress
|
||||
* @param percentage the percentage of progress
|
||||
*/
|
||||
void progress(BufferedImageFactory pFactory, float pPercentage);
|
||||
void progress(BufferedImageFactory factory, float percentage);
|
||||
}
|
||||
|
||||
private class Consumer implements ImageConsumer {
|
||||
@@ -446,18 +451,18 @@ public final class BufferedImageFactory {
|
||||
processProgress(pY + pHeight);
|
||||
}
|
||||
|
||||
public void setPixels(int pX, int pY, int pWidth, int pHeight, ColorModel pModel, short[] pPixels, int pOffset, int pScanSize) {
|
||||
setPixelsImpl(pX, pY, pWidth, pHeight, pModel, pPixels, pOffset, pScanSize);
|
||||
public void setPixels(int x, int y, int width, int height, ColorModel colorModel, short[] pixels, int offset, int scanSize) {
|
||||
setPixelsImpl(x, y, width, height, colorModel, pixels, offset, scanSize);
|
||||
}
|
||||
|
||||
private void setColorModelOnce(final ColorModel pModel) {
|
||||
private void setColorModelOnce(final ColorModel colorModel) {
|
||||
// NOTE: There seems to be a "bug" in AreaAveragingScaleFilter, as it
|
||||
// first passes the original color model through in setColorModel, then
|
||||
// later replaces it with the default RGB in the first setPixels call
|
||||
// (this is probably allowed according to the spec, but it's a waste of time and space).
|
||||
if (sourceColorModel != pModel) {
|
||||
if (/*sourceColorModel == null ||*/ sourcePixels == null) {
|
||||
sourceColorModel = pModel;
|
||||
if (sourceColorModel != colorModel) {
|
||||
if (sourcePixels == null) {
|
||||
sourceColorModel = colorModel;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Change of ColorModel after pixel delivery not supported");
|
||||
@@ -470,17 +475,16 @@ public final class BufferedImageFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public void imageComplete(int pStatus) {
|
||||
@Override
|
||||
public void imageComplete(int status) {
|
||||
fetching = false;
|
||||
|
||||
if (producer != null) {
|
||||
producer.removeConsumer(this);
|
||||
}
|
||||
|
||||
switch (pStatus) {
|
||||
case ImageConsumer.IMAGEERROR:
|
||||
consumerException = new ImageConversionException("ImageConsumer.IMAGEERROR");
|
||||
break;
|
||||
if (status == ImageConsumer.IMAGEERROR) {
|
||||
consumerException = new ImageConversionException("ImageConsumer.IMAGEERROR");
|
||||
}
|
||||
|
||||
synchronized (BufferedImageFactory.this) {
|
||||
@@ -488,16 +492,18 @@ public final class BufferedImageFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public void setColorModel(ColorModel pModel) {
|
||||
setColorModelOnce(pModel);
|
||||
@Override
|
||||
public void setColorModel(ColorModel colorModel) {
|
||||
setColorModelOnce(colorModel);
|
||||
}
|
||||
|
||||
public void setDimensions(int pWidth, int pHeight) {
|
||||
@Override
|
||||
public void setDimensions(int w, int h) {
|
||||
if (width < 0) {
|
||||
width = pWidth - x;
|
||||
width = w - x;
|
||||
}
|
||||
if (height < 0) {
|
||||
height = pHeight - y;
|
||||
height = h - y;
|
||||
}
|
||||
|
||||
// Hmm.. Special case, but is it a good idea?
|
||||
@@ -506,27 +512,31 @@ public final class BufferedImageFactory {
|
||||
}
|
||||
}
|
||||
|
||||
public void setHints(int pHintflags) {
|
||||
@Override
|
||||
public void setHints(int hintFlags) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
public void setPixels(int pX, int pY, int pWidth, int pHeight, ColorModel pModel, byte[] pPixels, int pOffset, int pScanSize) {
|
||||
setPixelsImpl(pX, pY, pWidth, pHeight, pModel, pPixels, pOffset, pScanSize);
|
||||
@Override
|
||||
public void setPixels(int x, int y, int width, int height, ColorModel colorModel, byte[] pixels, int offset, int scanSize) {
|
||||
setPixelsImpl(x, y, width, height, colorModel, pixels, offset, scanSize);
|
||||
}
|
||||
|
||||
public void setPixels(int pX, int pY, int pWeigth, int pHeight, ColorModel pModel, int[] pPixels, int pOffset, int pScanSize) {
|
||||
if (pModel.getTransferType() == DataBuffer.TYPE_USHORT) {
|
||||
@Override
|
||||
public void setPixels(int x, int y, int width, int height, ColorModel colorModel, int[] pixels, int offset, int scanSize) {
|
||||
if (colorModel.getTransferType() == DataBuffer.TYPE_USHORT) {
|
||||
// NOTE: Workaround for limitation in ImageConsumer API
|
||||
// Convert int[] to short[], to be compatible with the ColorModel
|
||||
setPixelsImpl(pX, pY, pWeigth, pHeight, pModel, toShortPixels(pPixels), pOffset, pScanSize);
|
||||
setPixelsImpl(x, y, width, height, colorModel, toShortPixels(pixels), offset, scanSize);
|
||||
}
|
||||
else {
|
||||
setPixelsImpl(pX, pY, pWeigth, pHeight, pModel, pPixels, pOffset, pScanSize);
|
||||
setPixelsImpl(x, y, width, height, colorModel, pixels, offset, scanSize);
|
||||
}
|
||||
}
|
||||
|
||||
public void setProperties(Hashtable pProperties) {
|
||||
sourceProperties = pProperties;
|
||||
@Override
|
||||
public void setProperties(Hashtable properties) {
|
||||
sourceProperties = properties;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -844,7 +844,7 @@ public final class ImageUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i > mapSize1; i++) {
|
||||
for (int i = 0; i < mapSize1; i++) {
|
||||
if (icm1.getRGB(i) != icm2.getRGB(i)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import com.twelvemonkeys.lang.SystemUtil;
|
||||
import magick.MagickImage;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.BufferedImageOp;
|
||||
|
||||
/**
|
||||
* This class accelerates certain graphics operations, using
|
||||
* JMagick and ImageMagick, if available.
|
||||
* If those libraries are not installed, this class silently does nothing.
|
||||
* <p>
|
||||
* Set the system property {@code "com.twelvemonkeys.image.accel"} to
|
||||
* {@code false}, to disable, even if JMagick is installed.
|
||||
* Set the system property {@code "com.twelvemonkeys.image.magick.debug"} to
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/MagickAccelerator.java#3 $
|
||||
*/
|
||||
final class MagickAccelerator {
|
||||
|
||||
private static final boolean DEBUG = Magick.DEBUG;
|
||||
private static final boolean USE_MAGICK = useMagick();
|
||||
|
||||
private static final int RESAMPLE_OP = 0;
|
||||
|
||||
private static Class[] nativeOp = new Class[1];
|
||||
|
||||
static {
|
||||
try {
|
||||
nativeOp[RESAMPLE_OP] = Class.forName("com.twelvemonkeys.image.ResampleOp");
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
System.err.println("Could not find class: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean useMagick() {
|
||||
try {
|
||||
boolean available = SystemUtil.isClassAvailable("magick.MagickImage");
|
||||
|
||||
if (DEBUG && !available) {
|
||||
System.err.print("ImageMagick bindings not available.");
|
||||
}
|
||||
|
||||
boolean useMagick =
|
||||
available && !"FALSE".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.image.accel"));
|
||||
|
||||
if (DEBUG) {
|
||||
System.err.println(
|
||||
useMagick
|
||||
? "Will use ImageMagick bindings to accelerate image resampling operations."
|
||||
: "Will not use ImageMagick to accelerate image resampling operations."
|
||||
);
|
||||
}
|
||||
|
||||
return useMagick;
|
||||
}
|
||||
catch (Throwable t) {
|
||||
// Most probably in case of a SecurityManager
|
||||
System.err.println("Could not enable ImageMagick bindings: " + t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getNativeOpIndex(Class pOpClass) {
|
||||
for (int i = 0; i < nativeOp.length; i++) {
|
||||
if (pOpClass == nativeOp[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static BufferedImage filter(BufferedImageOp pOperation, BufferedImage pInput, BufferedImage pOutput) {
|
||||
if (!USE_MAGICK) {
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferedImage result = null;
|
||||
switch (getNativeOpIndex(pOperation.getClass())) {
|
||||
case RESAMPLE_OP:
|
||||
ResampleOp resample = (ResampleOp) pOperation;
|
||||
result = resampleMagick(pInput, resample.width, resample.height, resample.filterType);
|
||||
|
||||
// NOTE: If output parameter is non-null, we have to return that
|
||||
// image, instead of result
|
||||
if (pOutput != null) {
|
||||
//pOutput.setData(result.getRaster()); // Fast, but less compatible
|
||||
// NOTE: For some reason, this is sometimes super-slow...?
|
||||
ImageUtil.drawOnto(pOutput, result);
|
||||
result = pOutput;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// Simply fall through, allowing acceleration to be added later
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static BufferedImage resampleMagick(BufferedImage pSrc, int pWidth, int pHeight, int pFilterType) {
|
||||
// Convert to Magick, scale and convert back
|
||||
MagickImage image = null;
|
||||
MagickImage scaled = null;
|
||||
try {
|
||||
image = MagickUtil.toMagick(pSrc);
|
||||
|
||||
long start = 0;
|
||||
if (DEBUG) {
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
// NOTE: setFilter affects zoomImage, NOT scaleImage
|
||||
image.setFilter(pFilterType);
|
||||
scaled = image.zoomImage(pWidth, pHeight);
|
||||
//scaled = image.scaleImage(pWidth, pHeight); // AREA_AVERAGING
|
||||
|
||||
if (DEBUG) {
|
||||
long time = System.currentTimeMillis() - start;
|
||||
System.out.println("Filtered: " + time + " ms");
|
||||
}
|
||||
|
||||
return MagickUtil.toBuffered(scaled);
|
||||
}
|
||||
//catch (MagickException e) {
|
||||
catch (Exception e) {
|
||||
// NOTE: Stupid workaround: If MagickException is caught, a
|
||||
// NoClassDefFoundError is thrown, when MagickException class is
|
||||
// unavailable...
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
|
||||
throw new ImageConversionException(e.getMessage(), e);
|
||||
}
|
||||
finally {
|
||||
// NOTE: ImageMagick might be unstable after a while, if image data
|
||||
// is not deallocated. The GC/finalize method handles this, but in
|
||||
// special circumstances, it's not triggered often enough.
|
||||
if (image != null) {
|
||||
image.destroyImages();
|
||||
}
|
||||
if (scaled != null) {
|
||||
scaled.destroyImages();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,621 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import magick.ImageType;
|
||||
import magick.MagickException;
|
||||
import magick.MagickImage;
|
||||
import magick.PixelPacket;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.ICC_ColorSpace;
|
||||
import java.awt.color.ICC_Profile;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* Utility for converting JMagick {@code MagickImage}s to standard Java
|
||||
* {@code BufferedImage}s and back.
|
||||
* <p>
|
||||
* <em>NOTE: This class is considered an implementation detail and not part of
|
||||
* the public API. This class is subject to change without further notice.
|
||||
* You have been warned. :-)</em>
|
||||
* </p>
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/image/MagickUtil.java#4 $
|
||||
*/
|
||||
public final class MagickUtil {
|
||||
// IMPORTANT NOTE: Disaster happens if any of these constants are used outside this class
|
||||
// because you then have a dependency on MagickException (this is due to Java class loading
|
||||
// and initialization magic).
|
||||
// Do not use outside this class. If the constants need to be shared, move to Magick or ImageUtil.
|
||||
|
||||
/** Color Model usesd for bilevel (B/W) */
|
||||
private static final IndexColorModel CM_MONOCHROME = MonochromeColorModel.getInstance();
|
||||
|
||||
/** Color Model usesd for raw ABGR */
|
||||
private static final ColorModel CM_COLOR_ALPHA =
|
||||
new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8, 8, 8, 8},
|
||||
true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
|
||||
|
||||
/** Color Model usesd for raw BGR */
|
||||
private static final ColorModel CM_COLOR_OPAQUE =
|
||||
new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), new int[] {8, 8, 8},
|
||||
false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
|
||||
|
||||
/** Color Model usesd for raw RGB */
|
||||
//private static final ColorModel CM_COLOR_RGB = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
|
||||
|
||||
/** Color Model usesd for raw GRAY + ALPHA */
|
||||
private static final ColorModel CM_GRAY_ALPHA =
|
||||
new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
|
||||
true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
|
||||
|
||||
/** Color Model usesd for raw GRAY */
|
||||
private static final ColorModel CM_GRAY_OPAQUE =
|
||||
new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
|
||||
false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
|
||||
|
||||
/** Band offsets for raw ABGR */
|
||||
private static final int[] BAND_OFF_TRANS = new int[] {3, 2, 1, 0};
|
||||
|
||||
/** Band offsets for raw BGR */
|
||||
private static final int[] BAND_OFF_OPAQUE = new int[] {2, 1, 0};
|
||||
|
||||
/** The point at {@code 0, 0} */
|
||||
private static final Point LOCATION_UPPER_LEFT = new Point(0, 0);
|
||||
|
||||
private static final boolean DEBUG = Magick.DEBUG;
|
||||
|
||||
// Only static members and methods
|
||||
private MagickUtil() {}
|
||||
|
||||
/**
|
||||
* Converts a {@code MagickImage} to a {@code BufferedImage}.
|
||||
* <p>
|
||||
* The conversion depends on {@code pImage}'s {@code ImageType}:
|
||||
* </p>
|
||||
* <dl>
|
||||
* <dt>{@code ImageType.BilevelType}</dt>
|
||||
* <dd>{@code BufferedImage} of type {@code TYPE_BYTE_BINARY}</dd>
|
||||
*
|
||||
* <dt>{@code ImageType.GrayscaleType}</dt>
|
||||
* <dd>{@code BufferedImage} of type {@code TYPE_BYTE_GRAY}</dd>
|
||||
* <dt>{@code ImageType.GrayscaleMatteType}</dt>
|
||||
* <dd>{@code BufferedImage} of type {@code TYPE_USHORT_GRAY}</dd>
|
||||
*
|
||||
* <dt>{@code ImageType.PaletteType}</dt>
|
||||
* <dd>{@code BufferedImage} of type {@code TYPE_BYTE_BINARY} (for images
|
||||
* with a palette of <= 16 colors) or {@code TYPE_BYTE_INDEXED}</dd>
|
||||
* <dt>{@code ImageType.PaletteMatteType}</dt>
|
||||
* <dd>{@code BufferedImage} of type {@code TYPE_BYTE_BINARY} (for images
|
||||
* with a palette of <= 16 colors) or {@code TYPE_BYTE_INDEXED}</dd>
|
||||
*
|
||||
* <dt>{@code ImageType.TrueColorType}</dt>
|
||||
* <dd>{@code BufferedImage} of type {@code TYPE_3BYTE_BGR}</dd>
|
||||
* <dt>{@code ImageType.TrueColorPaletteType}</dt>
|
||||
* <dd>{@code BufferedImage} of type {@code TYPE_4BYTE_ABGR}</dd>
|
||||
* </dl>
|
||||
*
|
||||
* @param pImage the original {@code MagickImage}
|
||||
* @return a new {@code BufferedImage}
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code pImage} is {@code null}
|
||||
* or if the {@code ImageType} is not one mentioned above.
|
||||
* @throws MagickException if an exception occurs during conversion
|
||||
*
|
||||
* @see BufferedImage
|
||||
*/
|
||||
public static BufferedImage toBuffered(MagickImage pImage) throws MagickException {
|
||||
if (pImage == null) {
|
||||
throw new IllegalArgumentException("image == null");
|
||||
}
|
||||
|
||||
long start = 0L;
|
||||
if (DEBUG) {
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
BufferedImage image = null;
|
||||
try {
|
||||
switch (pImage.getImageType()) {
|
||||
case ImageType.BilevelType:
|
||||
image = bilevelToBuffered(pImage);
|
||||
break;
|
||||
case ImageType.GrayscaleType:
|
||||
image = grayToBuffered(pImage, false);
|
||||
break;
|
||||
case ImageType.GrayscaleMatteType:
|
||||
image = grayToBuffered(pImage, true);
|
||||
break;
|
||||
case ImageType.PaletteType:
|
||||
image = paletteToBuffered(pImage, false);
|
||||
break;
|
||||
case ImageType.PaletteMatteType:
|
||||
image = paletteToBuffered(pImage, true);
|
||||
break;
|
||||
case ImageType.TrueColorType:
|
||||
image = rgbToBuffered(pImage, false);
|
||||
break;
|
||||
case ImageType.TrueColorMatteType:
|
||||
image = rgbToBuffered(pImage, true);
|
||||
break;
|
||||
case ImageType.ColorSeparationType:
|
||||
image = cmykToBuffered(pImage, false);
|
||||
break;
|
||||
case ImageType.ColorSeparationMatteType:
|
||||
image = cmykToBuffered(pImage, true);
|
||||
break;
|
||||
case ImageType.OptimizeType:
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown JMagick image type: " + pImage.getImageType());
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
if (DEBUG) {
|
||||
long time = System.currentTimeMillis() - start;
|
||||
System.out.println("Converted JMagick image type: " + pImage.getImageType() + " to BufferedImage: " + image);
|
||||
System.out.println("Conversion to BufferedImage: " + time + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a {@code BufferedImage} to a {@code MagickImage}.
|
||||
* <p>
|
||||
* The conversion depends on {@code pImage}'s {@code ColorModel}:
|
||||
* </p>
|
||||
* <dl>
|
||||
* <dt>{@code IndexColorModel} with 1 bit b/w</dt>
|
||||
* <dd>{@code MagickImage} of type {@code ImageType.BilevelType}</dd>
|
||||
* <dt>{@code IndexColorModel} > 1 bit,</dt>
|
||||
* <dd>{@code MagickImage} of type {@code ImageType.PaletteType}
|
||||
* or {@code MagickImage} of type {@code ImageType.PaletteMatteType}
|
||||
* depending on <tt>ColorModel.getAlpha()</tt></dd>
|
||||
*
|
||||
* <dt>{@code ColorModel.getColorSpace().getType() == ColorSpace.TYPE_GRAY}</dt>
|
||||
* <dd>{@code MagickImage} of type {@code ImageType.GrayscaleType}
|
||||
* or {@code MagickImage} of type {@code ImageType.GrayscaleMatteType}
|
||||
* depending on <tt>ColorModel.getAlpha()</tt></dd>
|
||||
*
|
||||
* <dt>{@code ColorModel.getColorSpace().getType() == ColorSpace.TYPE_RGB}</dt>
|
||||
* <dd>{@code MagickImage} of type {@code ImageType.TrueColorType}
|
||||
* or {@code MagickImage} of type {@code ImageType.TrueColorPaletteType}</dd>
|
||||
* </dl>
|
||||
*
|
||||
* @param pImage the original {@code BufferedImage}
|
||||
* @return a new {@code MagickImage}
|
||||
*
|
||||
* @throws IllegalArgumentException if {@code pImage} is {@code null}
|
||||
* or if the {@code ColorModel} is not one mentioned above.
|
||||
* @throws MagickException if an exception occurs during conversion
|
||||
*
|
||||
* @see BufferedImage
|
||||
*/
|
||||
public static MagickImage toMagick(BufferedImage pImage) throws MagickException {
|
||||
if (pImage == null) {
|
||||
throw new IllegalArgumentException("image == null");
|
||||
}
|
||||
|
||||
long start = 0L;
|
||||
if (DEBUG) {
|
||||
start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
try {
|
||||
ColorModel cm = pImage.getColorModel();
|
||||
if (cm instanceof IndexColorModel) {
|
||||
// Handles both BilevelType, PaletteType and PaletteMatteType
|
||||
return indexedToMagick(pImage, (IndexColorModel) cm, cm.hasAlpha());
|
||||
}
|
||||
|
||||
switch (cm.getColorSpace().getType()) {
|
||||
case ColorSpace.TYPE_GRAY:
|
||||
// Handles GrayType and GrayMatteType
|
||||
return grayToMagick(pImage, cm.hasAlpha());
|
||||
case ColorSpace.TYPE_RGB:
|
||||
// Handles TrueColorType and TrueColorMatteType
|
||||
return rgbToMagic(pImage, cm.hasAlpha());
|
||||
case ColorSpace.TYPE_CMY:
|
||||
case ColorSpace.TYPE_CMYK:
|
||||
case ColorSpace.TYPE_HLS:
|
||||
case ColorSpace.TYPE_HSV:
|
||||
// Other types not supported yet
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown buffered image type: " + pImage);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (DEBUG) {
|
||||
long time = System.currentTimeMillis() - start;
|
||||
System.out.println("Conversion to MagickImage: " + time + " ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static MagickImage rgbToMagic(BufferedImage pImage, boolean pAlpha) throws MagickException {
|
||||
MagickImage image = new MagickImage();
|
||||
|
||||
BufferedImage buffered = ImageUtil.toBuffered(pImage, pAlpha ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_3BYTE_BGR);
|
||||
|
||||
// Need to get data of sub raster, not the full data array, this is
|
||||
// just a convenient way
|
||||
Raster raster;
|
||||
if (buffered.getRaster().getParent() != null) {
|
||||
raster = buffered.getData(new Rectangle(buffered.getWidth(), buffered.getHeight()));
|
||||
}
|
||||
else {
|
||||
raster = buffered.getRaster();
|
||||
}
|
||||
|
||||
image.constituteImage(buffered.getWidth(), buffered.getHeight(), pAlpha ? "ABGR" : "BGR",
|
||||
((DataBufferByte) raster.getDataBuffer()).getData());
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static MagickImage grayToMagick(BufferedImage pImage, boolean pAlpha) throws MagickException {
|
||||
MagickImage image = new MagickImage();
|
||||
|
||||
// TODO: Make a fix for TYPE_USHORT_GRAY
|
||||
// The code below does not seem to work (JMagick issues?)...
|
||||
/*
|
||||
if (pImage.getType() == BufferedImage.TYPE_USHORT_GRAY) {
|
||||
short[] data = ((DataBufferUShort) pImage.getRaster().getDataBuffer()).getData();
|
||||
int[] intData = new int[data.length];
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
intData[i] = (data[i] & 0xffff) * 0xffff;
|
||||
}
|
||||
image.constituteImage(pImage.getWidth(), pImage.getHeight(), "I", intData);
|
||||
|
||||
System.out.println("storageClass: " + image.getStorageClass());
|
||||
System.out.println("depth: " + image.getDepth());
|
||||
System.out.println("imageType: " + image.getImageType());
|
||||
}
|
||||
else {
|
||||
*/
|
||||
BufferedImage buffered = ImageUtil.toBuffered(pImage, pAlpha ? BufferedImage.TYPE_4BYTE_ABGR : BufferedImage.TYPE_BYTE_GRAY);
|
||||
|
||||
// Need to get data of sub raster, not the full data array, this is
|
||||
// just a convenient way
|
||||
Raster raster;
|
||||
if (buffered.getRaster().getParent() != null) {
|
||||
raster = buffered.getData(new Rectangle(buffered.getWidth(), buffered.getHeight()));
|
||||
}
|
||||
else {
|
||||
raster = buffered.getRaster();
|
||||
}
|
||||
|
||||
image.constituteImage(buffered.getWidth(), buffered.getHeight(), pAlpha ? "ABGR" : "I", ((DataBufferByte) raster.getDataBuffer()).getData());
|
||||
//}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static MagickImage indexedToMagick(BufferedImage pImage, IndexColorModel pColorModel, boolean pAlpha) throws MagickException {
|
||||
MagickImage image = rgbToMagic(pImage, pAlpha);
|
||||
|
||||
int mapSize = pColorModel.getMapSize();
|
||||
image.setNumberColors(mapSize);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/*
|
||||
public static MagickImage toMagick(BufferedImage pImage) throws MagickException {
|
||||
if (pImage == null) {
|
||||
throw new IllegalArgumentException("image == null");
|
||||
}
|
||||
|
||||
final int width = pImage.getWidth();
|
||||
final int height = pImage.getHeight();
|
||||
|
||||
// int ARGB -> byte RGBA conversion
|
||||
// NOTE: This is ImageMagick Q16 compatible raw RGBA format with 16 bits/sample...
|
||||
// For a Q8 build, we could probably go with half the space...
|
||||
// NOTE: This is close to insanity, as it wastes extreme ammounts of memory
|
||||
final int[] argb = new int[width];
|
||||
final byte[] raw16 = new byte[width * height * 8];
|
||||
for (int y = 0; y < height; y++) {
|
||||
// Fetch one line of ARGB data
|
||||
pImage.getRGB(0, y, width, 1, argb, 0, width);
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
int pixel = (x + (y * width)) * 8;
|
||||
raw16[pixel ] = (byte) ((argb[x] >> 16) & 0xff); // R
|
||||
raw16[pixel + 2] = (byte) ((argb[x] >> 8) & 0xff); // G
|
||||
raw16[pixel + 4] = (byte) ((argb[x] ) & 0xff); // B
|
||||
raw16[pixel + 6] = (byte) ((argb[x] >> 24) & 0xff); // A
|
||||
}
|
||||
}
|
||||
|
||||
// Create magick image
|
||||
ImageInfo info = new ImageInfo();
|
||||
info.setMagick("RGBA"); // Raw RGBA samples
|
||||
info.setSize(width + "x" + height); // String?!?
|
||||
|
||||
MagickImage image = new MagickImage(info);
|
||||
image.setImageAttribute("depth", "8");
|
||||
|
||||
// Set pixel data in 16 bit raw RGBA format
|
||||
image.blobToImage(info, raw16);
|
||||
|
||||
return image;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Converts a bi-level {@code MagickImage} to a {@code BufferedImage}, of
|
||||
* type {@code TYPE_BYTE_BINARY}.
|
||||
*
|
||||
* @param pImage the original {@code MagickImage}
|
||||
* @return a new {@code BufferedImage}
|
||||
*
|
||||
* @throws MagickException if an exception occurs during conversion
|
||||
*
|
||||
* @see BufferedImage
|
||||
*/
|
||||
private static BufferedImage bilevelToBuffered(MagickImage pImage) throws MagickException {
|
||||
// As there is no way to get the binary representation of the image,
|
||||
// convert to gray, and the create a binary image from it
|
||||
BufferedImage temp = grayToBuffered(pImage, false);
|
||||
|
||||
BufferedImage image = new BufferedImage(temp.getWidth(), temp.getHeight(), BufferedImage.TYPE_BYTE_BINARY, CM_MONOCHROME);
|
||||
|
||||
ImageUtil.drawOnto(image, temp);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a gray {@code MagickImage} to a {@code BufferedImage}, of
|
||||
* type {@code TYPE_USHORT_GRAY} or {@code TYPE_BYTE_GRAY}.
|
||||
*
|
||||
* @param pImage the original {@code MagickImage}
|
||||
* @param pAlpha keep alpha channel
|
||||
* @return a new {@code BufferedImage}
|
||||
*
|
||||
* @throws MagickException if an exception occurs during conversion
|
||||
*
|
||||
* @see BufferedImage
|
||||
*/
|
||||
private static BufferedImage grayToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
|
||||
Dimension size = pImage.getDimension();
|
||||
int length = size.width * size.height;
|
||||
int bands = pAlpha ? 2 : 1;
|
||||
byte[] pixels = new byte[length * bands];
|
||||
|
||||
// TODO: Make a fix for 16 bit TYPE_USHORT_GRAY?!
|
||||
// Note: The ordering AI or I corresponds to BufferedImage
|
||||
// TYPE_CUSTOM and TYPE_BYTE_GRAY respectively
|
||||
pImage.dispatchImage(0, 0, size.width, size.height, pAlpha ? "AI" : "I", pixels);
|
||||
|
||||
// Init databuffer with array, to avoid allocation of empty array
|
||||
DataBuffer buffer = new DataBufferByte(pixels, pixels.length);
|
||||
|
||||
int[] bandOffsets = pAlpha ? new int[] {1, 0} : new int[] {0};
|
||||
|
||||
WritableRaster raster =
|
||||
Raster.createInterleavedRaster(buffer, size.width, size.height,
|
||||
size.width * bands, bands, bandOffsets, LOCATION_UPPER_LEFT);
|
||||
|
||||
return new BufferedImage(pAlpha ? CM_GRAY_ALPHA : CM_GRAY_OPAQUE, raster, pAlpha, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a palette-based {@code MagickImage} to a
|
||||
* {@code BufferedImage}, of type {@code TYPE_BYTE_BINARY} (for images
|
||||
* with a palette of <= 16 colors) or {@code TYPE_BYTE_INDEXED}.
|
||||
*
|
||||
* @param pImage the original {@code MagickImage}
|
||||
* @param pAlpha keep alpha channel
|
||||
* @return a new {@code BufferedImage}
|
||||
*
|
||||
* @throws MagickException if an exception occurs during conversion
|
||||
*
|
||||
* @see BufferedImage
|
||||
*/
|
||||
private static BufferedImage paletteToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
|
||||
// Create indexcolormodel for the image
|
||||
IndexColorModel cm;
|
||||
|
||||
try {
|
||||
cm = createIndexColorModel(pImage.getColormap(), pAlpha);
|
||||
}
|
||||
catch (MagickException e) {
|
||||
// NOTE: Some MagickImages incorrecly (?) reports to be paletteType,
|
||||
// but does not have a colormap, this is a workaround.
|
||||
return rgbToBuffered(pImage, pAlpha);
|
||||
}
|
||||
|
||||
// As there is no way to get the indexes of an indexed image, convert to
|
||||
// RGB, and the create an indexed image from it
|
||||
BufferedImage temp = rgbToBuffered(pImage, pAlpha);
|
||||
|
||||
BufferedImage image;
|
||||
if (cm.getMapSize() <= 16) {
|
||||
image = new BufferedImage(temp.getWidth(), temp.getHeight(), BufferedImage.TYPE_BYTE_BINARY, cm);
|
||||
}
|
||||
else {
|
||||
image = new BufferedImage(temp.getWidth(), temp.getHeight(), BufferedImage.TYPE_BYTE_INDEXED, cm);
|
||||
}
|
||||
|
||||
// Create transparent background for images containing alpha
|
||||
if (pAlpha) {
|
||||
Graphics2D g = image.createGraphics();
|
||||
try {
|
||||
g.setComposite(AlphaComposite.Clear);
|
||||
g.fillRect(0, 0, temp.getWidth(), temp.getHeight());
|
||||
}
|
||||
finally {
|
||||
g.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This is (surprisingly) much faster than using g2d.drawImage()..
|
||||
// (Tests shows 20-30ms, vs. 600-700ms on the same image)
|
||||
BufferedImageOp op = new CopyDither(cm);
|
||||
op.filter(temp, image);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@code IndexColorModel} from an array of
|
||||
* {@code PixelPacket}s.
|
||||
*
|
||||
* @param pColormap the original colormap as a {@code PixelPacket} array
|
||||
* @param pAlpha keep alpha channel
|
||||
*
|
||||
* @return a new {@code IndexColorModel}
|
||||
*/
|
||||
public static IndexColorModel createIndexColorModel(PixelPacket[] pColormap, boolean pAlpha) {
|
||||
int[] colors = new int[pColormap.length];
|
||||
|
||||
// TODO: Verify if this is correct for alpha...?
|
||||
int trans = pAlpha ? colors.length - 1 : -1;
|
||||
|
||||
//for (int i = 0; i < pColormap.length; i++) {
|
||||
for (int i = pColormap.length - 1; i != 0; i--) {
|
||||
PixelPacket color = pColormap[i];
|
||||
if (pAlpha) {
|
||||
colors[i] = (0xff - (color.getOpacity() & 0xff)) << 24 |
|
||||
(color.getRed() & 0xff) << 16 |
|
||||
(color.getGreen() & 0xff) << 8 |
|
||||
(color.getBlue() & 0xff);
|
||||
}
|
||||
else {
|
||||
colors[i] = (color.getRed() & 0xff) << 16 |
|
||||
(color.getGreen() & 0xff) << 8 |
|
||||
(color.getBlue() & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
return new InverseColorMapIndexColorModel(8, colors.length, colors, 0, pAlpha, trans, DataBuffer.TYPE_BYTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an (A)RGB {@code MagickImage} to a {@code BufferedImage}, of
|
||||
* type {@code TYPE_4BYTE_ABGR} or {@code TYPE_3BYTE_BGR}.
|
||||
*
|
||||
* @param pImage the original {@code MagickImage}
|
||||
* @param pAlpha keep alpha channel
|
||||
* @return a new {@code BufferedImage}
|
||||
*
|
||||
* @throws MagickException if an exception occurs during conversion
|
||||
*
|
||||
* @see BufferedImage
|
||||
*/
|
||||
private static BufferedImage rgbToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
|
||||
Dimension size = pImage.getDimension();
|
||||
int length = size.width * size.height;
|
||||
int bands = pAlpha ? 4 : 3;
|
||||
byte[] pixels = new byte[length * bands];
|
||||
|
||||
// TODO: If we do multiple dispatches (one per line, typically), we could provide listener
|
||||
// feedback. But it's currently a lot slower than fetching all the pixels in one go.
|
||||
|
||||
// Note: The ordering ABGR or BGR corresponds to BufferedImage
|
||||
// TYPE_4BYTE_ABGR and TYPE_3BYTE_BGR respectively
|
||||
pImage.dispatchImage(0, 0, size.width, size.height, pAlpha ? "ABGR" : "BGR", pixels);
|
||||
|
||||
// Init databuffer with array, to avoid allocation of empty array
|
||||
DataBuffer buffer = new DataBufferByte(pixels, pixels.length);
|
||||
|
||||
int[] bandOffsets = pAlpha ? BAND_OFF_TRANS : BAND_OFF_OPAQUE;
|
||||
|
||||
WritableRaster raster =
|
||||
Raster.createInterleavedRaster(buffer, size.width, size.height,
|
||||
size.width * bands, bands, bandOffsets, LOCATION_UPPER_LEFT);
|
||||
|
||||
return new BufferedImage(pAlpha ? CM_COLOR_ALPHA : CM_COLOR_OPAQUE, raster, pAlpha, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Converts an {@code MagickImage} to a {@code BufferedImage} which holds an CMYK ICC profile
|
||||
*
|
||||
* @param pImage the original {@code MagickImage}
|
||||
* @param pAlpha keep alpha channel
|
||||
* @return a new {@code BufferedImage}
|
||||
*
|
||||
* @throws MagickException if an exception occurs during conversion
|
||||
*
|
||||
* @see BufferedImage
|
||||
*/
|
||||
private static BufferedImage cmykToBuffered(MagickImage pImage, boolean pAlpha) throws MagickException {
|
||||
Dimension size = pImage.getDimension();
|
||||
int length = size.width * size.height;
|
||||
|
||||
// Retreive the ICC profile
|
||||
ICC_Profile profile = ICC_Profile.getInstance(pImage.getColorProfile().getInfo());
|
||||
ColorSpace cs = new ICC_ColorSpace(profile);
|
||||
|
||||
int bands = cs.getNumComponents() + (pAlpha ? 1 : 0);
|
||||
|
||||
int[] bits = new int[bands];
|
||||
for (int i = 0; i < bands; i++) {
|
||||
bits[i] = 8;
|
||||
}
|
||||
|
||||
ColorModel cm = pAlpha ?
|
||||
new ComponentColorModel(cs, bits, true, true, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE) :
|
||||
new ComponentColorModel(cs, bits, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
|
||||
|
||||
byte[] pixels = new byte[length * bands];
|
||||
|
||||
// TODO: If we do multiple dispatches (one per line, typically), we could provide listener
|
||||
// feedback. But it's currently a lot slower than fetching all the pixels in one go.
|
||||
// TODO: handle more generic cases if profile is not CMYK
|
||||
// TODO: Test "ACMYK"
|
||||
pImage.dispatchImage(0, 0, size.width, size.height, pAlpha ? "ACMYK" : "CMYK", pixels);
|
||||
|
||||
// Init databuffer with array, to avoid allocation of empty array
|
||||
DataBuffer buffer = new DataBufferByte(pixels, pixels.length);
|
||||
|
||||
// TODO: build array from bands variable, here it just works for CMYK
|
||||
// The values has not been tested with an alpha picture actually...
|
||||
int[] bandOffsets = pAlpha ? new int[] {0, 1, 2, 3, 4} : new int[] {0, 1, 2, 3};
|
||||
|
||||
WritableRaster raster =
|
||||
Raster.createInterleavedRaster(buffer, size.width, size.height,
|
||||
size.width * bands, bands, bandOffsets, LOCATION_UPPER_LEFT);
|
||||
|
||||
return new BufferedImage(cm, raster, pAlpha, null);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -55,9 +55,7 @@
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
@@ -103,15 +101,6 @@ import java.awt.image.*;
|
||||
* BufferedImage scaled = new ResampleOp(w, h).filter(temp, null);
|
||||
* </pre></blockquote>
|
||||
* <p>
|
||||
* For maximum performance, this class will use native code, through
|
||||
* <a href="http://www.yeo.id.au/jmagick/">JMagick</a>, when available.
|
||||
* Otherwise, the class will silently fall back to pure Java mode.
|
||||
* Native code may be disabled globally, by setting the system property
|
||||
* {@code com.twelvemonkeys.image.accel} to {@code false}.
|
||||
* To allow debug of the native code, set the system property
|
||||
* {@code com.twelvemonkeys.image.magick.debug} to {@code true}.
|
||||
* </p>
|
||||
* <p>
|
||||
* This {@code BufferedImageOp} is based on C example code found in
|
||||
* <a href="http://www.acm.org/tog/GraphicsGems/">Graphics Gems III</a>,
|
||||
* Filtered Image Rescaling, by Dale Schumacher (with additional improvments by
|
||||
@@ -139,9 +128,6 @@ import java.awt.image.*;
|
||||
// TODO: Consider using AffineTransformOp for more operations!?
|
||||
public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
|
||||
|
||||
// NOTE: These MUST correspond to ImageMagick filter types, for the
|
||||
// MagickAccelerator to work consistently (see magick.FilterType).
|
||||
|
||||
/**
|
||||
* Undefined interpolation, filter method will use default filter.
|
||||
*/
|
||||
@@ -295,11 +281,10 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
|
||||
new Value(KEY_RESAMPLE_INTERPOLATION, "Blackman-Sinc", FILTER_BLACKMAN_SINC);
|
||||
|
||||
// Member variables
|
||||
// Package access, to allow access from MagickAccelerator
|
||||
int width;
|
||||
int height;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
int filterType;
|
||||
private final int filterType;
|
||||
|
||||
/**
|
||||
* RendereingHints.Key implementation, works only with Value values.
|
||||
@@ -547,16 +532,6 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
|
||||
// Fall through
|
||||
}
|
||||
|
||||
// Try to use native ImageMagick code
|
||||
BufferedImage result = MagickAccelerator.filter(this, input, output);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Otherwise, continue in pure Java mode
|
||||
|
||||
// TODO: What if output != null and wrong size? Create new? Render on only a part? Document?
|
||||
|
||||
// If filter type != POINT or BOX and input has IndexColorModel, convert
|
||||
// to true color, with alpha reflecting that of the original color model.
|
||||
BufferedImage temp;
|
||||
@@ -571,7 +546,7 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
|
||||
|
||||
// Create or convert output to a suitable image
|
||||
// TODO: OPTIMIZE: Don't really need to convert all types to same as input
|
||||
result = output != null && temp.getType() != BufferedImage.TYPE_CUSTOM ? /*output*/ ImageUtil.toBuffered(output, temp.getType()) : createCompatibleDestImage(temp, null);
|
||||
BufferedImage result = output != null && temp.getType() != BufferedImage.TYPE_CUSTOM ? /*output*/ ImageUtil.toBuffered(output, temp.getType()) : createCompatibleDestImage(temp, null);
|
||||
|
||||
resample(temp, result, filter);
|
||||
|
||||
@@ -1280,12 +1255,12 @@ public class ResampleOp implements BufferedImageOp/* TODO: RasterOp */ {
|
||||
/*
|
||||
* image rescaling routine
|
||||
*/
|
||||
class Contributor {
|
||||
static class Contributor {
|
||||
int pixel;
|
||||
double weight;
|
||||
}
|
||||
|
||||
class ContributorList {
|
||||
static class ContributorList {
|
||||
int n;/* number of contributors (may be < p.length) */
|
||||
Contributor[] p;/* pointer to list of contributions */
|
||||
}
|
||||
|
||||
+24
-26
@@ -31,9 +31,7 @@
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import static java.lang.Math.min;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.geom.AffineTransform;
|
||||
@@ -49,7 +47,7 @@ import java.util.List;
|
||||
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* AffineTransformOpTest.
|
||||
@@ -146,12 +144,12 @@ public class AffineTransformOpTest {
|
||||
BufferedImage jreResult = jreOp.filter(image, null);
|
||||
BufferedImage tmResult = tmOp.filter(image, null);
|
||||
|
||||
assertNotNull("No result!", tmResult);
|
||||
assertEquals("Bad type", jreResult.getType(), tmResult.getType());
|
||||
assertEquals("Incorrect color model", jreResult.getColorModel(), tmResult.getColorModel());
|
||||
assertNotNull(tmResult, "No result!");
|
||||
assertEquals(jreResult.getType(), tmResult.getType(), "Bad type");
|
||||
assertEquals(jreResult.getColorModel(), tmResult.getColorModel(), "Incorrect color model");
|
||||
|
||||
assertEquals("Incorrect width", jreResult.getWidth(), tmResult.getWidth());
|
||||
assertEquals("Incorrect height", jreResult.getHeight(), tmResult.getHeight());
|
||||
assertEquals(jreResult.getWidth(), tmResult.getWidth(), "Incorrect width");
|
||||
assertEquals(jreResult.getHeight(), tmResult.getHeight(), "Incorrect height");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +162,7 @@ public class AffineTransformOpTest {
|
||||
BufferedImage image = spec.createBufferedImage(width, height);
|
||||
|
||||
BufferedImage tmResult = tmOp.filter(image, null);
|
||||
assertNotNull("No result!", tmResult);
|
||||
assertNotNull(tmResult, "No result!");
|
||||
|
||||
BufferedImage jreResult = null;
|
||||
|
||||
@@ -176,18 +174,18 @@ public class AffineTransformOpTest {
|
||||
}
|
||||
|
||||
if (jreResult != null) {
|
||||
assertEquals("Bad type", jreResult.getType(), tmResult.getType());
|
||||
assertEquals("Incorrect color model", jreResult.getColorModel(), tmResult.getColorModel());
|
||||
assertEquals(jreResult.getType(), tmResult.getType(), "Bad type");
|
||||
assertEquals(jreResult.getColorModel(), tmResult.getColorModel(), "Incorrect color model");
|
||||
|
||||
assertEquals("Incorrect width", jreResult.getWidth(), tmResult.getWidth());
|
||||
assertEquals("Incorrect height", jreResult.getHeight(), tmResult.getHeight());
|
||||
assertEquals(jreResult.getWidth(), tmResult.getWidth(), "Incorrect width");
|
||||
assertEquals(jreResult.getHeight(), tmResult.getHeight(), "Incorrect height");
|
||||
}
|
||||
else {
|
||||
assertEquals("Bad type", spec.getBufferedImageType(), tmResult.getType());
|
||||
assertEquals("Incorrect color model", spec.getColorModel(), tmResult.getColorModel());
|
||||
assertEquals(spec.getBufferedImageType(), tmResult.getType(), "Bad type");
|
||||
assertEquals(spec.getColorModel(), tmResult.getColorModel(), "Incorrect color model");
|
||||
|
||||
assertEquals("Incorrect width", height, tmResult.getWidth());
|
||||
assertEquals("Incorrect height", width, tmResult.getHeight());
|
||||
assertEquals(height, tmResult.getWidth(), "Incorrect width");
|
||||
assertEquals(width, tmResult.getHeight(), "Incorrect height");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,12 +234,12 @@ public class AffineTransformOpTest {
|
||||
}
|
||||
|
||||
if (jreResult != null) {
|
||||
assertEquals("Incorrect width", jreResult.getWidth(), tmResult.getWidth());
|
||||
assertEquals("Incorrect height", jreResult.getHeight(), tmResult.getHeight());
|
||||
assertEquals(jreResult.getWidth(), tmResult.getWidth(), "Incorrect width");
|
||||
assertEquals(jreResult.getHeight(), tmResult.getHeight(), "Incorrect height");
|
||||
}
|
||||
else {
|
||||
assertEquals("Incorrect width", height, tmResult.getWidth());
|
||||
assertEquals("Incorrect height", width, tmResult.getHeight());
|
||||
assertEquals(height, tmResult.getWidth(), "Incorrect width");
|
||||
assertEquals(width, tmResult.getHeight(), "Incorrect height");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,12 +275,12 @@ public class AffineTransformOpTest {
|
||||
}
|
||||
|
||||
if (jreResult != null) {
|
||||
assertEquals("Incorrect width", jreResult.getWidth(), tmResult.getWidth());
|
||||
assertEquals("Incorrect height", jreResult.getHeight(), tmResult.getHeight());
|
||||
assertEquals(jreResult.getWidth(), tmResult.getWidth(), "Incorrect width");
|
||||
assertEquals(jreResult.getHeight(), tmResult.getHeight(), "Incorrect height");
|
||||
}
|
||||
else {
|
||||
assertEquals("Incorrect width", height, tmResult.getWidth());
|
||||
assertEquals("Incorrect height", width, tmResult.getHeight());
|
||||
assertEquals(height, tmResult.getWidth(), "Incorrect width");
|
||||
assertEquals(width, tmResult.getHeight(), "Incorrect height");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+48
-42
@@ -30,18 +30,16 @@
|
||||
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.color.*;
|
||||
import java.awt.image.*;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* BufferedImageFactoryTestCase
|
||||
@@ -51,50 +49,58 @@ import static org.junit.Assert.*;
|
||||
* @version $Id: BufferedImageFactoryTestCase.java,v 1.0 May 7, 2010 12:40:08 PM haraldk Exp$
|
||||
*/
|
||||
public class BufferedImageFactoryTest {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testCreateNullImage() {
|
||||
new BufferedImageFactory((Image) null);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new BufferedImageFactory((Image) null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testCreateNullProducer() {
|
||||
new BufferedImageFactory((ImageProducer) null);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new BufferedImageFactory((ImageProducer) null);
|
||||
});
|
||||
}
|
||||
|
||||
// NPE in Toolkit, ok
|
||||
@Test(expected = RuntimeException.class)
|
||||
@Test
|
||||
public void testGetBufferedImageErrorSourceByteArray() {
|
||||
Image source = Toolkit.getDefaultToolkit().createImage((byte[]) null);
|
||||
|
||||
new BufferedImageFactory(source);
|
||||
assertThrows(RuntimeException.class, () -> {
|
||||
Image source = Toolkit.getDefaultToolkit().createImage((byte[]) null);
|
||||
new BufferedImageFactory(source);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testGetBufferedImageErrorSourceImageProducer() {
|
||||
Image source = Toolkit.getDefaultToolkit().createImage((ImageProducer) null);
|
||||
|
||||
new BufferedImageFactory(source);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new BufferedImageFactory(source);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: This is a quite serious bug, however, the bug is in the Toolkit, allowing such images in the first place...
|
||||
// In any case, there's not much we can do, except until someone is bored and kills the app/thread... :-P
|
||||
@Ignore("Bug in Toolkit")
|
||||
@Test(timeout = 1000, expected = ImageConversionException.class)
|
||||
@Disabled("Bug in Toolkit")
|
||||
@Test
|
||||
public void testGetBufferedImageErrorSourceString() {
|
||||
Image source = Toolkit.getDefaultToolkit().createImage((String) null);
|
||||
|
||||
BufferedImageFactory factory = new BufferedImageFactory(source);
|
||||
factory.getBufferedImage();
|
||||
assertTimeoutPreemptively(Duration.ofMillis(1000), () -> {
|
||||
Image source = Toolkit.getDefaultToolkit().createImage((String) null);
|
||||
BufferedImageFactory factory = new BufferedImageFactory(source);
|
||||
assertThrows(ImageConversionException.class, factory::getBufferedImage);
|
||||
});
|
||||
}
|
||||
|
||||
// This is a little random, and it would be nicer if we could throw an IllegalArgumentException on create.
|
||||
// Unfortunately, the API doesn't allow this...
|
||||
@Test(timeout = 1000, expected = ImageConversionException.class)
|
||||
@Test
|
||||
public void testGetBufferedImageErrorSourceURL() {
|
||||
Image source = Toolkit.getDefaultToolkit().createImage(getClass().getResource("/META-INF/MANIFEST.MF"));
|
||||
|
||||
BufferedImageFactory factory = new BufferedImageFactory(source);
|
||||
factory.getBufferedImage();
|
||||
assertTimeoutPreemptively(Duration.ofMillis(1000), () -> {
|
||||
Image source = Toolkit.getDefaultToolkit().createImage((String) null);
|
||||
BufferedImageFactory factory = new BufferedImageFactory(source);
|
||||
assertThrows(ImageConversionException.class, factory::getBufferedImage);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -166,7 +172,7 @@ public class BufferedImageFactoryTest {
|
||||
|
||||
assertEquals(3, colorModel.getNumColorComponents());
|
||||
assertEquals(ColorSpace.getInstance(ColorSpace.CS_sRGB), colorModel.getColorSpace());
|
||||
assertTrue(colorModel instanceof IndexColorModel);
|
||||
assertInstanceOf(IndexColorModel.class, colorModel);
|
||||
|
||||
assertTrue(colorModel.hasAlpha());
|
||||
assertEquals(4, colorModel.getNumComponents());
|
||||
@@ -197,7 +203,7 @@ public class BufferedImageFactoryTest {
|
||||
|
||||
for (int y = 0; y < image.getHeight(); y++) {
|
||||
for (int x = 0; x < image.getWidth(); x++) {
|
||||
assertEquals("RGB[" + x + ", " + y + "]", original.getRGB(x * 2, y * 2), image.getRGB(x, y));
|
||||
assertEquals(original.getRGB(x * 2, y * 2), image.getRGB(x, y), "RGB[" + x + ", " + y + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,7 +226,7 @@ public class BufferedImageFactoryTest {
|
||||
|
||||
for (int y = 0; y < image.getHeight(); y++) {
|
||||
for (int x = 0; x < image.getWidth(); x++) {
|
||||
assertEquals("RGB[" + x + ", " + y + "]", original.getRGB(40 + x, 40 + y), image.getRGB(x, y));
|
||||
assertEquals(original.getRGB(40 + x, 40 + y), image.getRGB(x, y), "RGB[" + x + ", " + y + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,7 +250,7 @@ public class BufferedImageFactoryTest {
|
||||
|
||||
for (int y = 0; y < image.getHeight(); y++) {
|
||||
for (int x = 0; x < image.getWidth(); x++) {
|
||||
assertEquals("RGB[" + x + ", " + y + "]", original.getRGB(40 + x * 2, 40 + y * 2), image.getRGB(x, y));
|
||||
assertEquals(original.getRGB(40 + x * 2, 40 + y * 2), image.getRGB(x, y), "RGB[" + x + ", " + y + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -260,9 +266,9 @@ public class BufferedImageFactoryTest {
|
||||
|
||||
// Listener should abort ASAP
|
||||
factory.addProgressListener(new BufferedImageFactory.ProgressListener() {
|
||||
public void progress(BufferedImageFactory pFactory, float pPercentage) {
|
||||
if (pPercentage > 5) {
|
||||
pFactory.abort();
|
||||
public void progress(BufferedImageFactory factory, float percentage) {
|
||||
if (percentage > 5) {
|
||||
factory.abort();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -343,7 +349,7 @@ public class BufferedImageFactoryTest {
|
||||
VerifyingListener listener = new VerifyingListener(factory);
|
||||
factory.addProgressListener(listener);
|
||||
factory.removeProgressListener(new BufferedImageFactory.ProgressListener() {
|
||||
public void progress(BufferedImageFactory pFactory, float pPercentage) {
|
||||
public void progress(BufferedImageFactory factory, float percentage) {
|
||||
}
|
||||
});
|
||||
factory.getBufferedImage();
|
||||
@@ -380,11 +386,11 @@ public class BufferedImageFactoryTest {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
public void progress(BufferedImageFactory pFactory, float pPercentage) {
|
||||
assertEquals(factory, pFactory);
|
||||
assertTrue(pPercentage >= progress && pPercentage <= 100f);
|
||||
public void progress(BufferedImageFactory factory, float percentage) {
|
||||
assertEquals(this.factory, factory);
|
||||
assertTrue(percentage >= progress && percentage <= 100f);
|
||||
|
||||
progress = pPercentage;
|
||||
progress = percentage;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
@@ -39,7 +39,7 @@ import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ImageUtilTest {
|
||||
|
||||
@@ -116,8 +116,8 @@ public class ImageUtilTest {
|
||||
public void testImageIsNotBufferedImage() {
|
||||
// Should not be a buffered image
|
||||
assertFalse(
|
||||
"FOR SOME IMPLEMENTATIONS THIS MIGHT FAIL!\nIn that case, testToBufferedImage() will fail too.",
|
||||
scaled instanceof BufferedImage
|
||||
scaled instanceof BufferedImage,
|
||||
"FOR SOME IMPLEMENTATIONS THIS MIGHT FAIL!\nIn that case, testToBufferedImage() will fail too."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ public class ImageUtilTest {
|
||||
if (original != notContrasted) { // Don't care to test if images are same
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertEquals("0 constrast should not change image", original.getRGB(x, y), notContrasted.getRGB(x, y));
|
||||
assertEquals(original.getRGB(x, y), notContrasted.getRGB(x, y), "0 constrast should not change image");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,24 +275,24 @@ public class ImageUtilTest {
|
||||
|
||||
// RED
|
||||
if (oR < 127) {
|
||||
assertTrue("Contrast should be decreased or same", oR >= cR && cR >= dR);
|
||||
assertTrue(oR >= cR && cR >= dR, "Contrast should be decreased or same");
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oR <= cR && cR <= dR);
|
||||
assertTrue(oR <= cR && cR <= dR, "Contrast should be increased or same");
|
||||
}
|
||||
// GREEN
|
||||
if (oG < 127) {
|
||||
assertTrue("Contrast should be decreased or same", oG >= cG && cG >= dG);
|
||||
assertTrue(oG >= cG && cG >= dG, "Contrast should be decreased or same");
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oG <= cG && cG <= dG);
|
||||
assertTrue(oG <= cG && cG <= dG, "Contrast should be increased or same");
|
||||
}
|
||||
// BLUE
|
||||
if (oB < 127) {
|
||||
assertTrue("Contrast should be decreased or same", oB >= cB && cB >= dB);
|
||||
assertTrue(oB >= cB && cB >= dB, "Contrast should be decreased or same");
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oB <= cB && cB <= dB);
|
||||
assertTrue(oB <= cB && cB <= dB, "Contrast should be increased or same");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,9 +304,9 @@ public class ImageUtilTest {
|
||||
int r = rgb >> 16 & 0xFF;
|
||||
int g = rgb >> 8 & 0xFF;
|
||||
int b = rgb & 0xFF;
|
||||
assertTrue("Max contrast should only produce primary colors", r == 0 || r == 255);
|
||||
assertTrue("Max contrast should only produce primary colors", g == 0 || g == 255);
|
||||
assertTrue("Max contrast should only produce primary colors", b == 0 || b == 255);
|
||||
assertTrue(r == 0 || r == 255, "Max contrast should only produce primary colors");
|
||||
assertTrue(g == 0 || g == 255, "Max contrast should only produce primary colors");
|
||||
assertTrue(b == 0 || b == 255, "Max contrast should only produce primary colors");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,24 +327,24 @@ public class ImageUtilTest {
|
||||
|
||||
// RED
|
||||
if (oR >= 127) {
|
||||
assertTrue("Contrast should be decreased or same", oR >= cR);
|
||||
assertTrue(oR >= cR, "Contrast should be decreased or same");
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oR <= cR);
|
||||
assertTrue(oR <= cR, "Contrast should be increased or same");
|
||||
}
|
||||
// GREEN
|
||||
if (oG >= 127) {
|
||||
assertTrue("Contrast should be decreased or same", oG >= cG);
|
||||
assertTrue(oG >= cG, "Contrast should be decreased or same");
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oG <= cG);
|
||||
assertTrue(oG <= cG, "Contrast should be increased or same");
|
||||
}
|
||||
// BLUE
|
||||
if (oB >= 127) {
|
||||
assertTrue("Contrast should be decreased or same", oB >= cB);
|
||||
assertTrue(oB >= cB, "Contrast should be decreased or same");
|
||||
}
|
||||
else {
|
||||
assertTrue("Contrast should be increased or same", oB <= cB);
|
||||
assertTrue(oB <= cB, "Contrast should be increased or same");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -357,7 +357,7 @@ public class ImageUtilTest {
|
||||
int r = rgb >> 16 & 0xFF;
|
||||
int g = rgb >> 8 & 0xFF;
|
||||
int b = rgb & 0xFF;
|
||||
assertTrue("Minimum contrast should be all gray", r == 127 && g == 127 && b == 127);
|
||||
assertTrue(r == 127 && g == 127 && b == 127, "Minimum contrast should be all gray");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ public class ImageUtilTest {
|
||||
if (original != notSharpened) { // Don't care to test if images are same
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertEquals("0 sharpen should not change image", original.getRGB(x, y), notSharpened.getRGB(x, y));
|
||||
assertEquals(original.getRGB(x, y), notSharpened.getRGB(x, y), "0 sharpen should not change image");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,13 +446,13 @@ public class ImageUtilTest {
|
||||
}
|
||||
|
||||
// assertEquals("Difference should not change", diffOriginal, diffSharpened);
|
||||
assertTrue("Abs difference should increase", absDiffOriginal < absDiffSharpened);
|
||||
assertTrue(absDiffOriginal < absDiffSharpened, "Abs difference should increase");
|
||||
// assertEquals("Difference should not change", diffOriginal, diffDefault);
|
||||
assertTrue("Abs difference should increase", absDiffOriginal < absDiffDefault);
|
||||
assertTrue(absDiffOriginal < absDiffDefault, "Abs difference should increase");
|
||||
// assertEquals("Difference should not change", diffOriginal, diffMore);
|
||||
assertTrue("Abs difference should increase", absDiffOriginal < absDiffMore);
|
||||
assertTrue(absDiffOriginal < absDiffMore, "Abs difference should increase");
|
||||
// assertEquals("Difference should not change", diffSharpened, diffMore);
|
||||
assertTrue("Abs difference should increase", absDiffSharpened < absDiffMore);
|
||||
assertTrue(absDiffSharpened < absDiffMore, "Abs difference should increase");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -466,7 +466,7 @@ public class ImageUtilTest {
|
||||
if (original != notBlurred) { // Don't care to test if images are same
|
||||
for (int y = 0; y < original.getHeight(); y++) {
|
||||
for (int x = 0; x < original.getWidth(); x++) {
|
||||
assertEquals("0 blur should not change image", original.getRGB(x, y), notBlurred.getRGB(x, y));
|
||||
assertEquals(original.getRGB(x, y), notBlurred.getRGB(x, y), "0 blur should not change image");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -512,13 +512,13 @@ public class ImageUtilTest {
|
||||
}
|
||||
|
||||
// assertEquals("Difference should not change", diffOriginal, diffBlurred);
|
||||
assertTrue(String.format("Abs difference should decrease: %s <= %s", absDiffOriginal, absDiffBlurred), absDiffOriginal > absDiffBlurred);
|
||||
assertTrue(absDiffOriginal > absDiffBlurred, String.format("Abs difference should decrease: %s <= %s", absDiffOriginal, absDiffBlurred));
|
||||
// assertEquals("Difference should not change", diffOriginal, diffDefault);
|
||||
assertTrue("Abs difference should decrease", absDiffOriginal > absDiffDefault);
|
||||
assertTrue(absDiffOriginal > absDiffDefault, "Abs difference should decrease");
|
||||
// assertEquals("Difference should not change", diffOriginal, diffMore);
|
||||
assertTrue("Abs difference should decrease", absDiffOriginal > absDiffMore);
|
||||
assertTrue(absDiffOriginal > absDiffMore, "Abs difference should decrease");
|
||||
// assertEquals("Difference should not change", diffBlurred, diffMore);
|
||||
assertTrue("Abs difference should decrease", absDiffBlurred > absDiffMore);
|
||||
assertTrue(absDiffBlurred > absDiffMore, "Abs difference should decrease");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -528,7 +528,7 @@ public class ImageUtilTest {
|
||||
assertNotNull(sunflower);
|
||||
|
||||
BufferedImage image = ImageUtil.createIndexed(sunflower);
|
||||
assertNotNull("Image was null", image);
|
||||
assertTrue(image.getColorModel() instanceof IndexColorModel);
|
||||
assertNotNull(image, "Image was null");
|
||||
assertInstanceOf(IndexColorModel.class, image.getColorModel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
package com.twelvemonkeys.image;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
@@ -40,7 +40,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* ResampleOpTestCase
|
||||
@@ -124,7 +124,7 @@ public class ResampleOpTest {
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals("Filter threw exceptions: ", Collections.EMPTY_LIST, exceptions);
|
||||
assertEquals(Collections.EMPTY_LIST, exceptions, "Filter threw exceptions: ");
|
||||
}
|
||||
|
||||
// 1x1
|
||||
@@ -358,7 +358,7 @@ public class ResampleOpTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("Not for general unit testing")
|
||||
@Disabled("Not for general unit testing")
|
||||
@Test
|
||||
public void testTime() {
|
||||
int iterations = 1000;
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
TODO:
|
||||
Remove compile-time dependency on JMagick:
|
||||
- Extract interface for MagickAccelerator
|
||||
- Move implementation to separate module
|
||||
- Instantiate impl via reflection
|
||||
DONE:
|
||||
@@ -4,13 +4,13 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>common-io</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>TwelveMonkeys :: Common :: IO</name>
|
||||
<description>
|
||||
The TwelveMonkeys Common IO support
|
||||
TwelveMonkeys Common I/O support classes.
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
@@ -31,4 +31,12 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -56,8 +56,8 @@ public class CompoundReader extends Reader {
|
||||
|
||||
private int currentReader;
|
||||
private int markedReader;
|
||||
private int mark;
|
||||
private int mNext;
|
||||
private long mark;
|
||||
private long next;
|
||||
|
||||
/**
|
||||
* Create a new compound reader.
|
||||
@@ -76,7 +76,7 @@ public class CompoundReader extends Reader {
|
||||
finalLock = pReaders; // NOTE: It's ok to sync on pReaders, as the
|
||||
// reference can't change, only it's elements
|
||||
|
||||
readers = new ArrayList<Reader>();
|
||||
readers = new ArrayList<>();
|
||||
|
||||
boolean markSupported = true;
|
||||
while (pReaders.hasNext()) {
|
||||
@@ -101,7 +101,7 @@ public class CompoundReader extends Reader {
|
||||
}
|
||||
|
||||
// NOTE: Reset mNext for every reader, and record marked reader in mark/reset methods!
|
||||
mNext = 0;
|
||||
next = 0;
|
||||
return current;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ public class CompoundReader extends Reader {
|
||||
|
||||
synchronized (finalLock) {
|
||||
ensureOpen();
|
||||
mark = mNext;
|
||||
mark = next;
|
||||
markedReader = currentReader;
|
||||
|
||||
current.mark(pReadLimit);
|
||||
@@ -158,7 +158,7 @@ public class CompoundReader extends Reader {
|
||||
}
|
||||
current.reset();
|
||||
|
||||
mNext = mark;
|
||||
next = mark;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,13 +177,13 @@ public class CompoundReader extends Reader {
|
||||
return read(); // In case of 0-length readers
|
||||
}
|
||||
|
||||
mNext++;
|
||||
next++;
|
||||
|
||||
return read;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(char pBuffer[], int pOffset, int pLength) throws IOException {
|
||||
public int read(char[] pBuffer, int pOffset, int pLength) throws IOException {
|
||||
synchronized (finalLock) {
|
||||
int read = current.read(pBuffer, pOffset, pLength);
|
||||
|
||||
@@ -192,7 +192,7 @@ public class CompoundReader extends Reader {
|
||||
return read(pBuffer, pOffset, pLength); // In case of 0-length readers
|
||||
}
|
||||
|
||||
mNext += read;
|
||||
next += read;
|
||||
|
||||
return read;
|
||||
}
|
||||
@@ -213,7 +213,7 @@ public class CompoundReader extends Reader {
|
||||
return skip(pChars); // In case of 0-length readers
|
||||
}
|
||||
|
||||
mNext += skipped;
|
||||
next += skipped;
|
||||
|
||||
return skipped;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* An unsynchronized {@code ByteArrayOutputStream} implementation. This version
|
||||
@@ -42,11 +43,8 @@ import java.io.OutputStream;
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version $Id: FastByteArrayOutputStream.java#2 $
|
||||
*/
|
||||
// TODO: Performance test of a stream impl that uses list of fixed size blocks, rather than contiguous block
|
||||
// TODO: Performance test of a stream impl that uses list of fixed size blocks, rather than contiguous block
|
||||
public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
/** Max grow size (unless if writing more than this amount of bytes) */
|
||||
protected int maxGrowSize = 1024 * 1024; // 1 MB
|
||||
|
||||
/**
|
||||
* Creates a {@code ByteArrayOutputStream} with the given initial buffer
|
||||
* size.
|
||||
@@ -97,10 +95,8 @@ public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
private void growIfNeeded(int pNewCount) {
|
||||
if (pNewCount > buf.length) {
|
||||
int newSize = Math.max(Math.min(buf.length << 1, buf.length + maxGrowSize), pNewCount);
|
||||
byte[] newBuf = new byte[newSize];
|
||||
System.arraycopy(buf, 0, newBuf, 0, count);
|
||||
buf = newBuf;
|
||||
int newSize = Math.max(buf.length << 1, pNewCount);
|
||||
buf = Arrays.copyOf(buf, newSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,10 +109,7 @@ public final class FastByteArrayOutputStream extends ByteArrayOutputStream {
|
||||
// Non-synchronized version of toByteArray
|
||||
@Override
|
||||
public byte[] toByteArray() {
|
||||
byte[] newBuf = new byte[count];
|
||||
System.arraycopy(buf, 0, newBuf, 0, count);
|
||||
|
||||
return newBuf;
|
||||
return Arrays.copyOf(buf, count);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,8 +50,8 @@ public class StringArrayReader extends StringReader {
|
||||
protected final Object finalLock;
|
||||
private int currentSting;
|
||||
private int markedString;
|
||||
private int mark;
|
||||
private int next;
|
||||
private long mark;
|
||||
private long next;
|
||||
|
||||
/**
|
||||
* Create a new string array reader.
|
||||
@@ -151,7 +151,7 @@ public class StringArrayReader extends StringReader {
|
||||
}
|
||||
}
|
||||
|
||||
public int read(char pBuffer[], int pOffset, int pLength) throws IOException {
|
||||
public int read(char[] pBuffer, int pOffset, int pLength) throws IOException {
|
||||
synchronized (finalLock) {
|
||||
int read = current.read(pBuffer, pOffset, pLength);
|
||||
|
||||
|
||||
@@ -41,21 +41,20 @@ import java.io.InputStream;
|
||||
* underlying stream.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/SubStream.java#2 $
|
||||
*/
|
||||
public final class SubStream extends FilterInputStream {
|
||||
private long bytesLeft;
|
||||
private int markLimit;
|
||||
|
||||
/**
|
||||
* Creates a {@code SubStream} of the given {@code pStream}.
|
||||
* Creates a {@code SubStream} of the given {@code stream}.
|
||||
*
|
||||
* @param pStream the underlying input stream
|
||||
* @param pLength maximum number of bytes to read drom this stream
|
||||
* @param stream the underlying input stream
|
||||
* @param length maximum number of bytes to read from this stream
|
||||
*/
|
||||
public SubStream(final InputStream pStream, final long pLength) {
|
||||
super(Validate.notNull(pStream, "stream"));
|
||||
bytesLeft = pLength;
|
||||
public SubStream(final InputStream stream, final long length) {
|
||||
super(Validate.notNull(stream, "stream"));
|
||||
bytesLeft = Validate.isTrue(length >= 0, length, "length < 0: %s");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,22 +63,23 @@ public final class SubStream extends FilterInputStream {
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// NOTE: Do not close the underlying stream
|
||||
// NOTE: Do not close the underlying stream, but consume it
|
||||
while (bytesLeft > 0) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
skip(bytesLeft);
|
||||
if (skip(bytesLeft) <= 0 && read() < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
return (int) Math.min(super.available(), bytesLeft);
|
||||
return (int) findMaxLen(super.available());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mark(int pReadLimit) {
|
||||
super.mark(pReadLimit);// This either succeeds or does nothing...
|
||||
markLimit = pReadLimit;
|
||||
public void mark(int readLimit) {
|
||||
super.mark(readLimit);// This either succeeds or does nothing...
|
||||
markLimit = readLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,44 +93,42 @@ public final class SubStream extends FilterInputStream {
|
||||
if (bytesLeft-- <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return super.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int read(byte[] pBytes) throws IOException {
|
||||
return read(pBytes, 0, pBytes.length);
|
||||
public int read(byte[] bytes) throws IOException {
|
||||
return read(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final byte[] pBytes, final int pOffset, final int pLength) throws IOException {
|
||||
public int read(final byte[] bytes, final int off, final int len) throws IOException {
|
||||
if (bytesLeft <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int read = super.read(pBytes, pOffset, (int) findMaxLen(pLength));
|
||||
int read = super.read(bytes, off, (int) findMaxLen(len));
|
||||
bytesLeft = read < 0 ? 0 : bytesLeft - read;
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long length) throws IOException {
|
||||
long skipped = super.skip(findMaxLen(length)); // Skips 0 or more, never -1
|
||||
bytesLeft -= skipped;
|
||||
|
||||
return skipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the maximum number of bytes we can read or skip, from this stream.
|
||||
*
|
||||
* @param pLength the requested length
|
||||
* @param length the requested length
|
||||
* @return the maximum number of bytes to read
|
||||
*/
|
||||
private long findMaxLen(long pLength) {
|
||||
if (bytesLeft < pLength) {
|
||||
return (int) Math.max(bytesLeft, 0);
|
||||
}
|
||||
else {
|
||||
return pLength;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long pLength) throws IOException {
|
||||
long skipped = super.skip(findMaxLen(pLength));// Skips 0 or more, never -1
|
||||
bytesLeft -= skipped;
|
||||
return skipped;
|
||||
private long findMaxLen(long length) {
|
||||
return bytesLeft < length ? Math.max(bytesLeft, 0) : length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,39 +45,39 @@ import java.nio.ByteBuffer;
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/enc/DecoderStream.java#2 $
|
||||
*/
|
||||
public final class DecoderStream extends FilterInputStream {
|
||||
protected final ByteBuffer buffer;
|
||||
protected final Decoder decoder;
|
||||
private final ByteBuffer buffer;
|
||||
private final Decoder decoder;
|
||||
|
||||
/**
|
||||
* Creates a new decoder stream and chains it to the
|
||||
* input stream specified by the {@code pStream} argument.
|
||||
* input stream specified by the {@code stream} argument.
|
||||
* The stream will use a default decode buffer size.
|
||||
*
|
||||
* @param pStream the underlying input stream.
|
||||
* @param pDecoder the decoder that will be used to decode the underlying stream
|
||||
* @param stream the underlying input stream.
|
||||
* @param decoder the decoder that will be used to decode the underlying stream
|
||||
*
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
public DecoderStream(final InputStream pStream, final Decoder pDecoder) {
|
||||
// TODO: Let the decoder decide preferred buffer size
|
||||
this(pStream, pDecoder, 1024);
|
||||
public DecoderStream(final InputStream stream, final Decoder decoder) {
|
||||
// TODO: Let the decoder decide preferred buffer size
|
||||
this(stream, decoder, 1024);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new decoder stream and chains it to the
|
||||
* input stream specified by the {@code pStream} argument.
|
||||
* input stream specified by the {@code stream} argument.
|
||||
*
|
||||
* @param pStream the underlying input stream.
|
||||
* @param pDecoder the decoder that will be used to decode the underlying stream
|
||||
* @param pBufferSize the size of the decode buffer
|
||||
* @param stream the underlying input stream.
|
||||
* @param decoder the decoder that will be used to decode the underlying stream
|
||||
* @param bufferSize the size of the decode buffer
|
||||
*
|
||||
* @see java.io.FilterInputStream#in
|
||||
*/
|
||||
public DecoderStream(final InputStream pStream, final Decoder pDecoder, final int pBufferSize) {
|
||||
super(pStream);
|
||||
public DecoderStream(final InputStream stream, final Decoder decoder, final int bufferSize) {
|
||||
super(stream);
|
||||
|
||||
decoder = pDecoder;
|
||||
buffer = ByteBuffer.allocate(pBufferSize);
|
||||
this.decoder = decoder;
|
||||
buffer = ByteBuffer.allocate(bufferSize); // TODO: Allow decoder to specify minimum buffer size
|
||||
buffer.flip();
|
||||
}
|
||||
|
||||
@@ -95,15 +95,15 @@ public final class DecoderStream extends FilterInputStream {
|
||||
return buffer.get() & 0xff;
|
||||
}
|
||||
|
||||
public int read(final byte pBytes[], final int pOffset, final int pLength) throws IOException {
|
||||
if (pBytes == null) {
|
||||
public int read(final byte[] bytes, final int offset, final int length) throws IOException {
|
||||
if (bytes == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
else if ((pOffset < 0) || (pOffset > pBytes.length) || (pLength < 0) ||
|
||||
((pOffset + pLength) > pBytes.length) || ((pOffset + pLength) < 0)) {
|
||||
throw new IndexOutOfBoundsException("bytes.length=" + pBytes.length + " offset=" + pOffset + " length=" + pLength);
|
||||
else if ((offset < 0) || (offset > bytes.length) || (length < 0) ||
|
||||
((offset + length) > bytes.length) || ((offset + length) < 0)) {
|
||||
throw new IndexOutOfBoundsException("bytes.length=" + bytes.length + " offset=" + offset + " length=" + length);
|
||||
}
|
||||
else if (pLength == 0) {
|
||||
else if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -114,11 +114,11 @@ public final class DecoderStream extends FilterInputStream {
|
||||
}
|
||||
}
|
||||
|
||||
// Read until we have read pLength bytes, or have reached EOF
|
||||
// Read until we have read length bytes, or have reached EOF
|
||||
int count = 0;
|
||||
int off = pOffset;
|
||||
int off = offset;
|
||||
|
||||
while (pLength > count) {
|
||||
while (length > count) {
|
||||
if (!buffer.hasRemaining()) {
|
||||
if (fill() < 0) {
|
||||
break;
|
||||
@@ -126,8 +126,8 @@ public final class DecoderStream extends FilterInputStream {
|
||||
}
|
||||
|
||||
// Copy as many bytes as possible
|
||||
int dstLen = Math.min(pLength - count, buffer.remaining());
|
||||
buffer.get(pBytes, off, dstLen);
|
||||
int dstLen = Math.min(length - count, buffer.remaining());
|
||||
buffer.get(bytes, off, dstLen);
|
||||
|
||||
// Update offset (rest)
|
||||
off += dstLen;
|
||||
@@ -139,7 +139,7 @@ public final class DecoderStream extends FilterInputStream {
|
||||
return count;
|
||||
}
|
||||
|
||||
public long skip(final long pLength) throws IOException {
|
||||
public long skip(final long length) throws IOException {
|
||||
// End of file?
|
||||
if (!buffer.hasRemaining()) {
|
||||
if (fill() < 0) {
|
||||
@@ -147,10 +147,10 @@ public final class DecoderStream extends FilterInputStream {
|
||||
}
|
||||
}
|
||||
|
||||
// Skip until we have skipped pLength bytes, or have reached EOF
|
||||
// Skip until we have skipped length bytes, or have reached EOF
|
||||
long total = 0;
|
||||
|
||||
while (total < pLength) {
|
||||
while (total < length) {
|
||||
if (!buffer.hasRemaining()) {
|
||||
if (fill() < 0) {
|
||||
break;
|
||||
@@ -158,7 +158,7 @@ public final class DecoderStream extends FilterInputStream {
|
||||
}
|
||||
|
||||
// NOTE: Skipped can never be more than avail, which is an int, so the cast is safe
|
||||
int skipped = (int) Math.min(pLength - total, buffer.remaining());
|
||||
int skipped = (int) Math.min(length - total, buffer.remaining());
|
||||
buffer.position(buffer.position() + skipped);
|
||||
total += skipped;
|
||||
}
|
||||
@@ -174,7 +174,7 @@ public final class DecoderStream extends FilterInputStream {
|
||||
*
|
||||
* @throws IOException if an I/O error occurs
|
||||
*/
|
||||
protected int fill() throws IOException {
|
||||
private int fill() throws IOException {
|
||||
buffer.clear();
|
||||
int read = decoder.decode(in, buffer);
|
||||
|
||||
|
||||
@@ -45,41 +45,39 @@ import java.nio.ByteBuffer;
|
||||
* @version $Id: //depot/branches/personal/haraldk/twelvemonkeys/release-2/twelvemonkeys-core/src/main/java/com/twelvemonkeys/io/enc/EncoderStream.java#2 $
|
||||
*/
|
||||
public final class EncoderStream extends FilterOutputStream {
|
||||
// TODO: This class need a test case ASAP!!!
|
||||
|
||||
protected final Encoder encoder;
|
||||
private final Encoder encoder;
|
||||
private final boolean flushOnWrite;
|
||||
|
||||
protected final ByteBuffer buffer;
|
||||
private final ByteBuffer buffer;
|
||||
|
||||
/**
|
||||
* Creates an output stream filter built on top of the specified
|
||||
* underlying output stream.
|
||||
*
|
||||
* @param pStream the underlying output stream
|
||||
* @param pEncoder the encoder to use
|
||||
* @param stream the underlying output stream
|
||||
* @param encoder the encoder to use
|
||||
*/
|
||||
public EncoderStream(final OutputStream pStream, final Encoder pEncoder) {
|
||||
this(pStream, pEncoder, false);
|
||||
public EncoderStream(final OutputStream stream, final Encoder encoder) {
|
||||
this(stream, encoder, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an output stream filter built on top of the specified
|
||||
* underlying output stream.
|
||||
*
|
||||
* @param pStream the underlying output stream
|
||||
* @param pEncoder the encoder to use
|
||||
* @param pFlushOnWrite if {@code true}, calls to the byte-array
|
||||
* @param stream the underlying output stream
|
||||
* @param encoder the encoder to use
|
||||
* @param flushOnWrite if {@code true}, calls to the byte-array
|
||||
* {@code write} methods will automatically flush the buffer.
|
||||
*/
|
||||
public EncoderStream(final OutputStream pStream, final Encoder pEncoder, final boolean pFlushOnWrite) {
|
||||
super(pStream);
|
||||
public EncoderStream(final OutputStream stream, final Encoder encoder, final boolean flushOnWrite) {
|
||||
super(stream);
|
||||
|
||||
encoder = pEncoder;
|
||||
flushOnWrite = pFlushOnWrite;
|
||||
this.encoder = encoder;
|
||||
this.flushOnWrite = flushOnWrite;
|
||||
|
||||
buffer = ByteBuffer.allocate(1024);
|
||||
buffer.flip();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
@@ -104,33 +102,33 @@ public final class EncoderStream extends FilterOutputStream {
|
||||
}
|
||||
}
|
||||
|
||||
public final void write(final byte[] pBytes) throws IOException {
|
||||
write(pBytes, 0, pBytes.length);
|
||||
public void write(final byte[] bytes) throws IOException {
|
||||
write(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
// TODO: Verify that this works for the general case (it probably won't)...
|
||||
// TODO: We might need a way to explicitly flush the encoder, or specify
|
||||
// that the encoder can't buffer. In that case, the encoder should probably
|
||||
// tell the EncoderStream how large buffer it prefers...
|
||||
public void write(final byte[] pBytes, final int pOffset, final int pLength) throws IOException {
|
||||
if (!flushOnWrite && pLength < buffer.remaining()) {
|
||||
// tell the EncoderStream how large buffer it prefers...
|
||||
public void write(final byte[] values, final int offset, final int length) throws IOException {
|
||||
if (!flushOnWrite && length < buffer.remaining()) {
|
||||
// Buffer data
|
||||
buffer.put(pBytes, pOffset, pLength);
|
||||
buffer.put(values, offset, length);
|
||||
}
|
||||
else {
|
||||
// Encode data already in the buffer
|
||||
encodeBuffer();
|
||||
|
||||
// Encode rest without buffering
|
||||
encoder.encode(out, ByteBuffer.wrap(pBytes, pOffset, pLength));
|
||||
encoder.encode(out, ByteBuffer.wrap(values, offset, length));
|
||||
}
|
||||
}
|
||||
|
||||
public void write(final int pByte) throws IOException {
|
||||
public void write(final int value) throws IOException {
|
||||
if (!buffer.hasRemaining()) {
|
||||
encodeBuffer(); // Resets bufferPos to 0
|
||||
}
|
||||
|
||||
buffer.put((byte) pByte);
|
||||
buffer.put((byte) value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
|
||||
package com.twelvemonkeys.xml;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
import org.w3c.dom.DOMConfiguration;
|
||||
import org.w3c.dom.DOMImplementationList;
|
||||
import org.w3c.dom.Document;
|
||||
@@ -38,9 +41,6 @@ import org.w3c.dom.ls.DOMImplementationLS;
|
||||
import org.w3c.dom.ls.LSOutput;
|
||||
import org.w3c.dom.ls.LSSerializer;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* {@code DOMImplementationLS} backed implementation.
|
||||
*
|
||||
@@ -88,17 +88,6 @@ public final class DOMSerializer {
|
||||
output.setCharacterStream(pStream);
|
||||
}
|
||||
|
||||
/*
|
||||
// TODO: Is it useful?
|
||||
public void setNewLine(final String pNewLine) {
|
||||
serializer.setNewLine(pNewLine);
|
||||
}
|
||||
|
||||
public String getNewLine() {
|
||||
return serializer.getNewLine();
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Specifies wether the serializer should use indentation and optimize for
|
||||
* readability.
|
||||
@@ -169,13 +158,7 @@ public final class DOMSerializer {
|
||||
try {
|
||||
return DOMImplementationRegistry.newInstance();
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
catch (InstantiationException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,16 +30,23 @@
|
||||
|
||||
package com.twelvemonkeys.xml;
|
||||
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.SAXException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Date;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
|
||||
/**
|
||||
* XMLSerializer
|
||||
@@ -290,7 +297,7 @@ public class XMLSerializer {
|
||||
}
|
||||
|
||||
private static int appendAndEscape(final String pString, int pStart, final int pEnd, final StringBuilder pBuilder, final String pEntity) {
|
||||
pBuilder.append(pString.substring(pStart, pEnd));
|
||||
pBuilder.append(pString, pStart, pEnd);
|
||||
pBuilder.append(pEntity);
|
||||
return pEnd + 1;
|
||||
}
|
||||
@@ -527,8 +534,7 @@ public class XMLSerializer {
|
||||
builder = factory.newDocumentBuilder();
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
//noinspection ThrowableInstanceNeverThrown BOGUS
|
||||
throw (IOException) new IOException(e.getMessage()).initCause(e);
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
DOMImplementation dom = builder.getDOMImplementation();
|
||||
|
||||
@@ -32,7 +32,6 @@ package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import com.twelvemonkeys.util.CollectionUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
@@ -40,7 +39,8 @@ import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* CompoundReaderTestCase
|
||||
|
||||
+2
-3
@@ -30,12 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* FastByteArrayOutputStreamTestCase
|
||||
|
||||
@@ -30,11 +30,10 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* MemoryCacheSeekableStreamTestCase
|
||||
@@ -92,13 +91,13 @@ public class FileSeekableStreamTest extends SeekableInputStreamAbstractTest {
|
||||
try {
|
||||
FileUtil.read(stream); // Read until EOF
|
||||
|
||||
assertEquals("EOF not reached (test case broken)", -1, stream.read());
|
||||
assertFalse("Underlying stream closed before close", closed[0]);
|
||||
assertEquals(-1, stream.read(), "EOF not reached (test case broken)");
|
||||
assertFalse(closed[0], "Underlying stream closed before close");
|
||||
}
|
||||
finally {
|
||||
stream.close();
|
||||
}
|
||||
|
||||
assertTrue("Underlying stream not closed", closed[0]);
|
||||
assertTrue(closed[0], "Underlying stream not closed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +46,14 @@
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* InputStreamAbstractTestCase
|
||||
@@ -104,15 +104,15 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
int size = 5;
|
||||
InputStream input = makeInputStream(makeOrderedArray(size));
|
||||
for (int i = 0; i < size; i++) {
|
||||
assertTrue("Check Size [" + i + "]", (size - i) >= input.available());
|
||||
assertEquals("Check Value [" + i + "]", i, input.read());
|
||||
assertTrue((size - i) >= input.available(), "Check Size [" + i + "]");
|
||||
assertEquals(i, input.read(), "Check Value [" + i + "]");
|
||||
}
|
||||
assertEquals("Available after contents all read", 0, input.available());
|
||||
assertEquals(0, input.available(), "Available after contents all read");
|
||||
|
||||
// Test reading after the end of file
|
||||
try {
|
||||
int result = input.read();
|
||||
assertEquals("Wrong value read after end of file", -1, result);
|
||||
assertEquals( -1, result, "Wrong value read after end of file");
|
||||
}
|
||||
catch (IOException e) {
|
||||
fail("Should not have thrown an IOException: " + e.getMessage());
|
||||
@@ -122,12 +122,12 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testAvailable() throws Exception {
|
||||
InputStream input = makeInputStream(1);
|
||||
assertFalse("Unexpected EOF", input.read() < 0);
|
||||
assertEquals("Available after contents all read", 0, input.available());
|
||||
assertFalse(input.read() < 0, "Unexpected EOF");
|
||||
assertEquals(0, input.available(), "Available after contents all read");
|
||||
|
||||
// Check availbale is zero after End of file
|
||||
assertEquals("End of File", -1, input.read());
|
||||
assertEquals("Available after End of File", 0, input.available());
|
||||
assertEquals(-1, input.read(), "End of File");
|
||||
assertEquals( 0, input.available(), "Available after End of File");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -138,26 +138,26 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
// Read into array
|
||||
int count1 = input.read(bytes);
|
||||
assertEquals("Read 1", bytes.length, count1);
|
||||
assertEquals(bytes.length, count1, "Read 1");
|
||||
for (int i = 0; i < count1; i++) {
|
||||
assertEquals("Check Bytes 1", i, bytes[i]);
|
||||
assertEquals(i, bytes[i], "Check Bytes 1");
|
||||
}
|
||||
|
||||
// Read into array
|
||||
int count2 = input.read(bytes);
|
||||
assertEquals("Read 2", 5, count2);
|
||||
assertEquals(5, count2, "Read 2");
|
||||
for (int i = 0; i < count2; i++) {
|
||||
assertEquals("Check Bytes 2", count1 + i, bytes[i]);
|
||||
assertEquals(count1 + i, bytes[i], "Check Bytes 2");
|
||||
}
|
||||
|
||||
// End of File
|
||||
int count3 = input.read(bytes);
|
||||
assertEquals("Read 3 (EOF)", -1, count3);
|
||||
assertEquals(-1, count3, "Read 3 (EOF)");
|
||||
|
||||
// Test reading after the end of file
|
||||
try {
|
||||
int result = input.read(bytes);
|
||||
assertEquals("Wrong value read after end of file", -1, result);
|
||||
assertEquals(-1, result, "Wrong value read after end of file");
|
||||
}
|
||||
catch (IOException e) {
|
||||
fail("Should not have thrown an IOException: " + e.getMessage());
|
||||
@@ -170,20 +170,20 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
int offset = 2;
|
||||
int lth = 4;
|
||||
int count5 = input.read(bytes, offset, lth);
|
||||
assertEquals("Read 5", lth, count5);
|
||||
assertEquals(lth, count5, "Read 5");
|
||||
for (int i = offset; i < lth; i++) {
|
||||
assertEquals("Check Bytes 2", i - offset, bytes[i]);
|
||||
assertEquals(i - offset, bytes[i], "Check Bytes 2");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEOF() throws Exception {
|
||||
InputStream input = makeInputStream(makeOrderedArray(2));
|
||||
assertEquals("Read 1", 0, input.read());
|
||||
assertEquals("Read 2", 1, input.read());
|
||||
assertEquals("Read 3", -1, input.read());
|
||||
assertEquals("Read 4", -1, input.read());
|
||||
assertEquals("Read 5", -1, input.read());
|
||||
assertEquals(0, input.read(), "Read 1");
|
||||
assertEquals(1, input.read(), "Read 2");
|
||||
assertEquals(-1, input.read(), "Read 3");
|
||||
assertEquals(-1, input.read(), "Read 4");
|
||||
assertEquals(-1, input.read(), "Read 5");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -205,7 +205,7 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
fail("Should throw IOException");
|
||||
}
|
||||
catch (IOException e) {
|
||||
assertTrue("Wrong messge: " + e.getMessage(), e.getMessage().contains("reset"));
|
||||
assertTrue(e.getMessage().contains("reset"), "Wrong messge: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,10 +223,10 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
// No mark may either throw exception, or reset to beginning of stream.
|
||||
try {
|
||||
input.reset();
|
||||
assertEquals("Re-read of reset data should be same", 0, input.read());
|
||||
assertEquals(0, input.read(), "Re-read of reset data should be same");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertTrue("Wrong no mark IOException message", e.getMessage().contains("mark"));
|
||||
assertTrue(e.getMessage().contains("mark"), "Wrong no mark IOException message");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
// Read further
|
||||
for (int i = 0; i < 3; i++) {
|
||||
assertEquals("Read After Mark [" + i + "]", (position + i), input.read());
|
||||
assertEquals((position + i), input.read(), "Read After Mark [" + i + "]");
|
||||
}
|
||||
|
||||
// Reset
|
||||
@@ -257,7 +257,7 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
// Read from marked position
|
||||
for (int i = 0; i < readlimit + 1; i++) {
|
||||
assertEquals("Read After Reset [" + i + "]", (position + i), input.read());
|
||||
assertEquals((position + i), input.read(), "Read After Reset [" + i + "]");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,16 +280,16 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
// Read past marked position
|
||||
for (int i = 0; i < readlimit + 1; i++) {
|
||||
assertEquals("Read After Reset [" + i + "]", (position + i), input.read());
|
||||
assertEquals((position + i), input.read(), "Read After Reset [" + i + "]");
|
||||
}
|
||||
|
||||
// Reset after read limit passed, may either throw exception, or reset to last mark
|
||||
try {
|
||||
input.reset();
|
||||
assertEquals("Re-read of reset data should be same", 1, input.read());
|
||||
assertEquals(1, input.read(), "Re-read of reset data should be same");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertTrue("Wrong read-limit IOException message", e.getMessage().contains("mark"));
|
||||
assertTrue(e.getMessage().contains("mark"), "Wrong read-limit IOException message");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,29 +302,29 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
}
|
||||
|
||||
int first = input.read();
|
||||
assertTrue("Expected to read positive value", first >= 0);
|
||||
assertTrue(first >= 0, "Expected to read positive value");
|
||||
|
||||
int readlimit = 5;
|
||||
|
||||
// Mark
|
||||
input.mark(readlimit);
|
||||
int read = input.read();
|
||||
assertTrue("Expected to read positive value", read >= 0);
|
||||
assertTrue(read >= 0, "Expected to read positive value");
|
||||
|
||||
assertTrue(input.read() >= 0);
|
||||
assertTrue(input.read() >= 0);
|
||||
|
||||
input.reset();
|
||||
assertEquals("Expected value read differs from actual", read, input.read());
|
||||
assertEquals(read, input.read(), "Expected value read differs from actual");
|
||||
|
||||
// Reset after read limit passed, may either throw exception, or reset to last good mark
|
||||
try {
|
||||
input.reset();
|
||||
int reRead = input.read();
|
||||
assertTrue("Re-read of reset data should be same as initially marked or first", reRead == read || reRead == first);
|
||||
assertTrue(reRead == read || reRead == first, "Re-read of reset data should be same as initially marked or first");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertTrue("Wrong read-limit IOException message", e.getMessage().contains("mark"));
|
||||
assertTrue(e.getMessage().contains("mark"), "Wrong read-limit IOException message");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,17 +332,17 @@ public abstract class InputStreamAbstractTest extends ObjectAbstractTest {
|
||||
public void testSkip() throws Exception {
|
||||
InputStream input = makeInputStream(makeOrderedArray(10));
|
||||
|
||||
assertEquals("Unexpected value read", 0, input.read());
|
||||
assertEquals("Unexpected value read", 1, input.read());
|
||||
assertEquals("Unexpected number of bytes skipped", 5, input.skip(5));
|
||||
assertEquals("Unexpected value read", 7, input.read());
|
||||
assertEquals(0, input.read(), "Unexpected value read");
|
||||
assertEquals(1, input.read(), "Unexpected value read");
|
||||
assertEquals(5, input.skip(5), "Unexpected number of bytes skipped");
|
||||
assertEquals(7, input.read(), "Unexpected value read");
|
||||
|
||||
assertEquals("Unexpected number of bytes skipped", 2, input.skip(5)); // only 2 left to skip
|
||||
assertEquals("Unexpected value read after EOF", -1, input.read());
|
||||
assertEquals(2, input.skip(5), "Unexpected number of bytes skipped"); // only 2 left to skip
|
||||
assertEquals(-1, input.read(), "Unexpected value read after EOF");
|
||||
|
||||
// Spec says skip might return 0 or negative after EOF...
|
||||
assertTrue("Positive value skipped after EOF", input.skip(5) <= 0); // End of file
|
||||
assertEquals("Unexpected value read after EOF", -1, input.read());
|
||||
assertTrue(input.skip(5) <= 0, "Positive value skipped after EOF"); // End of file
|
||||
assertEquals(-1, input.read(), "Unexpected value read after EOF");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+2
-3
@@ -30,12 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* LittleEndianDataInputStreamTest
|
||||
|
||||
@@ -31,13 +31,12 @@
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* InputStreamAbstractTestCase
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* ReaderAbstractTestCase
|
||||
@@ -112,7 +112,7 @@ public abstract class ReaderAbstractTest extends ObjectAbstractTest {
|
||||
int toSkip = mInput.length();
|
||||
while (toSkip > 0) {
|
||||
long skipped = reader.skip(toSkip);
|
||||
assertFalse("Skipped < 0", skipped < 0);
|
||||
assertFalse(skipped < 0, "Skipped < 0");
|
||||
toSkip -= skipped;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,8 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* SeekableAbstractTestCase
|
||||
|
||||
+22
-23
@@ -30,14 +30,13 @@
|
||||
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* SeekableInputStreamAbstractTest
|
||||
@@ -79,25 +78,25 @@ public abstract class SeekableInputStreamAbstractTest extends InputStreamAbstrac
|
||||
return; // Not supported, skip test
|
||||
}
|
||||
|
||||
assertTrue("Expected to read positive value", input.read() >= 0);
|
||||
assertTrue(input.read() >= 0, "Expected to read positive value");
|
||||
|
||||
int readlimit = 5;
|
||||
|
||||
// Mark
|
||||
input.mark(readlimit);
|
||||
int read = input.read();
|
||||
assertTrue("Expected to read positive value", read >= 0);
|
||||
assertTrue(read >= 0, "Expected to read positive value");
|
||||
|
||||
input.reset();
|
||||
assertEquals("Expected value read differs from actual", read, input.read());
|
||||
assertEquals(read, input.read(), "Expected value read differs from actual");
|
||||
|
||||
// Reset after read limit passed, may either throw exception, or reset to last good mark
|
||||
try {
|
||||
input.reset();
|
||||
assertEquals("Re-read of reset data should be first", 0, input.read());
|
||||
assertEquals(0, input.read(), "Re-read of reset data should be first");
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertTrue("Wrong read-limit IOException message", e.getMessage().contains("mark"));
|
||||
assertTrue(e.getMessage().contains("mark"), "Wrong read-limit IOException message");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +126,7 @@ public abstract class SeekableInputStreamAbstractTest extends InputStreamAbstrac
|
||||
|
||||
seekable.seek(pos);
|
||||
long streamPos = seekable.getStreamPosition();
|
||||
assertEquals("Stream positon should match seeked position", pos, streamPos);
|
||||
assertEquals(pos, streamPos, "Stream positon should match seeked position");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -137,7 +136,7 @@ public abstract class SeekableInputStreamAbstractTest extends InputStreamAbstrac
|
||||
seekable.seek(pos);
|
||||
seekable.flushBefore(pos);
|
||||
long flushedPos = seekable.getFlushedPosition();
|
||||
assertEquals("Flushed positon should match position", pos, flushedPos);
|
||||
assertEquals(pos, flushedPos, "Flushed positon should match position");
|
||||
|
||||
try {
|
||||
seekable.seek(pos - 1);
|
||||
@@ -382,13 +381,13 @@ public abstract class SeekableInputStreamAbstractTest extends InputStreamAbstrac
|
||||
int val;
|
||||
|
||||
val = stream.read();
|
||||
assertFalse("Unexepected EOF", val == -1);
|
||||
assertFalse(val == -1, "Unexepected EOF");
|
||||
val = stream.read();
|
||||
assertFalse("Unexepected EOF", val == -1);
|
||||
assertFalse(val == -1, "Unexepected EOF");
|
||||
val = stream.read();
|
||||
assertFalse("Unexepected EOF", val == -1);
|
||||
assertFalse(val == -1, "Unexepected EOF");
|
||||
val = stream.read();
|
||||
assertFalse("Unexepected EOF", val == -1);
|
||||
assertFalse(val == -1, "Unexepected EOF");
|
||||
|
||||
stream.seek(0);
|
||||
|
||||
@@ -422,19 +421,19 @@ public abstract class SeekableInputStreamAbstractTest extends InputStreamAbstrac
|
||||
|
||||
stream.seek(0);
|
||||
for (int i = 0; i < bytes.length; i += 2) {
|
||||
assertEquals("Wrong stream position", i, stream.getStreamPosition());
|
||||
assertEquals(i, stream.getStreamPosition(), "Wrong stream position");
|
||||
int count = stream.read(buffer, 0, 2);
|
||||
assertEquals(2, count);
|
||||
assertEquals(String.format("Wrong value read at pos %d", stream.getStreamPosition()), bytes[i], buffer[0]);
|
||||
assertEquals(String.format("Wrong value read at pos %d", stream.getStreamPosition()), bytes[i + 1], buffer[1]);
|
||||
assertEquals(bytes[i], buffer[0], String.format("Wrong value read at pos %d", stream.getStreamPosition()));
|
||||
assertEquals(bytes[i + 1], buffer[1], String.format("Wrong value read at pos %d", stream.getStreamPosition()));
|
||||
}
|
||||
|
||||
stream.seek(0);
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
assertEquals("Wrong stream position", i, stream.getStreamPosition());
|
||||
assertEquals(i, stream.getStreamPosition(), "Wrong stream position");
|
||||
int actual = stream.read();
|
||||
assertEquals(String.format("Wrong value read at pos %d", stream.getStreamPosition()), bytes[i] & 0xff, actual);
|
||||
assertEquals(String.format("Wrong value read at pos %d", stream.getStreamPosition()), bytes[i], (byte) actual);
|
||||
assertEquals(bytes[i] & 0xff, actual, String.format("Wrong value read at pos %d", stream.getStreamPosition()));
|
||||
assertEquals(bytes[i], (byte) actual, String.format("Wrong value read at pos %d", stream.getStreamPosition()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -456,14 +455,14 @@ public abstract class SeekableInputStreamAbstractTest extends InputStreamAbstrac
|
||||
try {
|
||||
FileUtil.read(stream); // Read until EOF
|
||||
|
||||
assertEquals("EOF not reached (test case broken)", -1, stream.read());
|
||||
assertFalse("Underlying stream closed before close", closed[0]);
|
||||
assertEquals(-1, stream.read(), "EOF not reached (test case broken)");
|
||||
assertFalse(closed[0], "Underlying stream closed before close");
|
||||
}
|
||||
finally {
|
||||
stream.close();
|
||||
}
|
||||
|
||||
assertTrue("Underlying stream not closed", closed[0]);
|
||||
assertTrue(closed[0], "Underlying stream not closed");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* StringArrayReaderTestCase
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.twelvemonkeys.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* SubStreamTest.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: SubStreamTest.java,v 1.0 07/11/2023 haraldk Exp$
|
||||
*/
|
||||
public class SubStreamTest {
|
||||
|
||||
private final Random rng = new Random(2918475687L);
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
public void testCreateNullStream() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SubStream(null, 42);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateNegativeLength() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new SubStream(new ByteArrayInputStream(new byte[1]), -1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadAll() throws IOException {
|
||||
byte[] buf = new byte[128];
|
||||
rng.nextBytes(buf);
|
||||
|
||||
try (InputStream stream = new SubStream(new ByteArrayInputStream(buf), buf.length)) {
|
||||
for (byte b : buf) {
|
||||
assertEquals(b, (byte) stream.read());
|
||||
}
|
||||
|
||||
assertEquals(-1, stream.read());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadAllArray() throws IOException {
|
||||
byte[] buf = new byte[128];
|
||||
rng.nextBytes(buf);
|
||||
|
||||
try (InputStream stream = new SubStream(new ByteArrayInputStream(buf), buf.length)) {
|
||||
byte[] temp = new byte[buf.length / 4];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
assertEquals(temp.length, stream.read(temp)); // Depends on ByteArrayInputStream specifics...
|
||||
assertArrayEquals(Arrays.copyOfRange(buf, i * temp.length, (i + 1) * temp.length), temp);
|
||||
}
|
||||
|
||||
assertEquals(-1, stream.read());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSkipAll() throws IOException {
|
||||
byte[] buf = new byte[128];
|
||||
|
||||
try (InputStream stream = new SubStream(new ByteArrayInputStream(buf), buf.length)) {
|
||||
assertEquals(128, stream.skip(buf.length)); // Depends on ByteArrayInputStream specifics...
|
||||
assertEquals(-1, stream.read());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyTryBlock")
|
||||
@Test
|
||||
public void testCloseConsumesAll() throws IOException {
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(new byte[128]);
|
||||
|
||||
try (InputStream ignore = new SubStream(stream, 128)) {
|
||||
// Nothing here...
|
||||
}
|
||||
|
||||
assertEquals(0, stream.available());
|
||||
assertEquals(-1, stream.read());
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyTryBlock")
|
||||
@Test
|
||||
public void testCloseConsumesAllLongStream() throws IOException {
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(new byte[256]);
|
||||
|
||||
try (InputStream ignore = new SubStream(stream, 128)) {
|
||||
// Nothing here...
|
||||
}
|
||||
|
||||
assertEquals(128, stream.available());
|
||||
assertEquals(0, stream.read());
|
||||
}
|
||||
|
||||
@SuppressWarnings("EmptyTryBlock")
|
||||
@Test
|
||||
public void testCloseConsumesAllShortStream() throws IOException {
|
||||
assertTimeoutPreemptively(Duration.ofMillis(500), () -> {
|
||||
ByteArrayInputStream stream = new ByteArrayInputStream(new byte[13]);
|
||||
|
||||
try (InputStream ignore = new SubStream(stream, 42)) {
|
||||
// Nothing here...
|
||||
}
|
||||
|
||||
assertEquals(0, stream.available());
|
||||
assertEquals(-1, stream.read());
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -31,15 +31,13 @@
|
||||
package com.twelvemonkeys.io.enc;
|
||||
|
||||
import com.twelvemonkeys.io.FileUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
/**
|
||||
* Base64DecoderTest
|
||||
* <p/>
|
||||
@@ -66,7 +64,7 @@ public class Base64DecoderTest extends DecoderAbstractTest {
|
||||
|
||||
FileUtil.copy(in, bytes);
|
||||
|
||||
assertEquals("Strings does not match", "", new String(bytes.toByteArray()));
|
||||
assertEquals("", new String(bytes.toByteArray()), "Strings does not match");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,7 +76,7 @@ public class Base64DecoderTest extends DecoderAbstractTest {
|
||||
|
||||
FileUtil.copy(in, bytes);
|
||||
|
||||
assertEquals("Strings does not match", "test", new String(bytes.toByteArray()));
|
||||
assertEquals("test", new String(bytes.toByteArray()), "Strings does not match");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,11 +91,12 @@ public class Base64DecoderTest extends DecoderAbstractTest {
|
||||
|
||||
FileUtil.copy(in, bytes);
|
||||
|
||||
assertEquals("Strings does not match",
|
||||
assertEquals(
|
||||
"Lorem ipsum dolor sit amet, consectetuer adipiscing " +
|
||||
"elit. Fusce est. Morbi luctus consectetuer justo. Vivamus " +
|
||||
"dapibus laoreet purus. Nunc viverra dictum nisl. Integer " +
|
||||
"ullamcorper, nisi in dictum amet.",
|
||||
new String(bytes.toByteArray()));
|
||||
new String(bytes.toByteArray()),
|
||||
"Strings does not match");
|
||||
}
|
||||
}
|
||||
@@ -30,13 +30,12 @@
|
||||
|
||||
package com.twelvemonkeys.io.enc;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Base64EncoderTest
|
||||
@@ -63,7 +62,7 @@ public class Base64EncoderTest extends EncoderAbstractTest {
|
||||
OutputStream out = new EncoderStream(bytes, createEncoder(), true);
|
||||
out.write(data.getBytes());
|
||||
|
||||
assertEquals("Strings does not match", "", new String(bytes.toByteArray()));
|
||||
assertEquals("", new String(bytes.toByteArray()), "Strings does not match");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -74,7 +73,7 @@ public class Base64EncoderTest extends EncoderAbstractTest {
|
||||
OutputStream out = new EncoderStream(bytes, createEncoder(), true);
|
||||
out.write(data.getBytes());
|
||||
|
||||
assertEquals("Strings does not match", "dGVzdA==", new String(bytes.toByteArray()));
|
||||
assertEquals("dGVzdA==", new String(bytes.toByteArray()), "Strings does not match");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -88,11 +87,12 @@ public class Base64EncoderTest extends EncoderAbstractTest {
|
||||
OutputStream out = new EncoderStream(bytes, createEncoder(), true);
|
||||
out.write(data.getBytes());
|
||||
|
||||
assertEquals("Strings does not match",
|
||||
assertEquals(
|
||||
"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVlciBhZGlwaXNjaW5nIGVsaXQuIEZ1" +
|
||||
"c2NlIGVzdC4gTW9yYmkgbHVjdHVzIGNvbnNlY3RldHVlciBqdXN0by4gVml2YW11cyBkYXBpYnVzIGxh" +
|
||||
"b3JlZXQgcHVydXMuIE51bmMgdml2ZXJyYSBkaWN0dW0gbmlzbC4gSW50ZWdlciB1bGxhbWNvcnBlciwg" +
|
||||
"bmlzaSBpbiBkaWN0dW0gYW1ldC4=",
|
||||
new String(bytes.toByteArray()));
|
||||
new String(bytes.toByteArray()),
|
||||
"Strings does not match");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,12 +32,13 @@ package com.twelvemonkeys.io.enc;
|
||||
|
||||
import com.twelvemonkeys.io.FileUtil;
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* AbstractDecoderTest
|
||||
@@ -55,13 +56,13 @@ public abstract class DecoderAbstractTest extends ObjectAbstractTest {
|
||||
return createDecoder();
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
@Test
|
||||
public final void testNullDecode() throws IOException {
|
||||
Decoder decoder = createDecoder();
|
||||
ByteArrayInputStream bytes = new ByteArrayInputStream(new byte[20]);
|
||||
|
||||
decoder.decode(bytes, null);
|
||||
fail("null should throw NullPointerException");
|
||||
assertThrows(NullPointerException.class, () -> {
|
||||
decoder.decode(bytes, null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -71,7 +72,7 @@ public abstract class DecoderAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
try {
|
||||
int count = decoder.decode(bytes, ByteBuffer.allocate(128));
|
||||
assertEquals("Should not be able to read any bytes", 0, count);
|
||||
assertEquals( 0, count, "Should not be able to read any bytes");
|
||||
}
|
||||
catch (EOFException allowed) {
|
||||
// Okay
|
||||
@@ -94,7 +95,7 @@ public abstract class DecoderAbstractTest extends ObjectAbstractTest {
|
||||
byte[] encoded = outBytes.toByteArray();
|
||||
|
||||
byte[] decoded = FileUtil.read(new DecoderStream(new ByteArrayInputStream(encoded), createDecoder()));
|
||||
assertArrayEquals(String.format("Data %d", pLength), data, decoded);
|
||||
assertArrayEquals(data, decoded, String.format("Data %d", pLength));
|
||||
|
||||
InputStream in = new DecoderStream(new ByteArrayInputStream(encoded), createDecoder());
|
||||
outBytes = new ByteArrayOutputStream();
|
||||
@@ -103,7 +104,7 @@ public abstract class DecoderAbstractTest extends ObjectAbstractTest {
|
||||
in.close();
|
||||
|
||||
decoded = outBytes.toByteArray();
|
||||
assertArrayEquals(String.format("Data %d", pLength), data, decoded);
|
||||
assertArrayEquals(data, decoded, String.format("Data %d", pLength));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.io.enc;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class DecoderStreamTest {
|
||||
|
||||
private final Random rng = new Random(5467809876546L);
|
||||
|
||||
private byte[] createData(final int length) {
|
||||
byte[] data = new byte[length];
|
||||
rng.nextBytes(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecodeSingleBytes() throws IOException {
|
||||
byte[] data = createData(1327);
|
||||
|
||||
InputStream source = new ByteArrayInputStream(data);
|
||||
try (InputStream stream = new DecoderStream(source, new NullDecoder())) {
|
||||
for (byte datum : data) {
|
||||
int read = stream.read();
|
||||
assertNotEquals(-1, read);
|
||||
assertEquals(datum, (byte) read);
|
||||
}
|
||||
|
||||
assertEquals(-1, stream.read());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecodeArray() throws IOException {
|
||||
int length = 793;
|
||||
byte[] data = createData(length * 10);
|
||||
|
||||
InputStream source = new ByteArrayInputStream(data);
|
||||
byte[] result = new byte[477];
|
||||
|
||||
try (InputStream stream = new DecoderStream(source, new NullDecoder())) {
|
||||
int dataOffset = 0;
|
||||
while (dataOffset < data.length) {
|
||||
int count = stream.read(result);
|
||||
|
||||
assertFalse(count <= 0);
|
||||
assertArrayEquals(Arrays.copyOfRange(data, dataOffset, dataOffset + count), Arrays.copyOfRange(result, 0, count));
|
||||
|
||||
dataOffset += count;
|
||||
}
|
||||
|
||||
assertEquals(-1, stream.read());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDecodeArrayOffset() throws IOException {
|
||||
int length = 793;
|
||||
byte[] data = createData(length * 10);
|
||||
|
||||
InputStream source = new ByteArrayInputStream(data);
|
||||
byte[] result = new byte[477];
|
||||
|
||||
try (InputStream stream = new DecoderStream(source, new NullDecoder())) {
|
||||
int dataOffset = 0;
|
||||
while (dataOffset < data.length) {
|
||||
int resultOffset = dataOffset % result.length;
|
||||
int count = stream.read(result, resultOffset, result.length - resultOffset);
|
||||
|
||||
assertFalse(count <= 0);
|
||||
assertArrayEquals(Arrays.copyOfRange(data, dataOffset + resultOffset, dataOffset + count), Arrays.copyOfRange(result, resultOffset, count));
|
||||
|
||||
dataOffset += count;
|
||||
}
|
||||
|
||||
assertEquals(-1, stream.read());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NullDecoder implements Decoder {
|
||||
@Override
|
||||
public int decode(InputStream stream, ByteBuffer buffer) throws IOException {
|
||||
int read = stream.read(buffer.array(), buffer.arrayOffset(), buffer.remaining());
|
||||
|
||||
if (read > 0) {
|
||||
// Set position, should be equivalent to using buffer.put(stream.read()) until EOF or buffer full
|
||||
buffer.position(read);
|
||||
}
|
||||
|
||||
return read;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,13 +33,12 @@ package com.twelvemonkeys.io.enc;
|
||||
import com.twelvemonkeys.io.FileUtil;
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* AbstractEncoderTest
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.io.enc;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class EncoderStreamTest {
|
||||
|
||||
private final Random rng = new Random(5467809876546L);
|
||||
|
||||
private byte[] createData(final int length) {
|
||||
byte[] data = new byte[length];
|
||||
rng.nextBytes(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeSingleBytes() throws IOException {
|
||||
byte[] data = createData(1327);
|
||||
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
try (OutputStream stream = new EncoderStream(result, new NullEncoder())) {
|
||||
for (byte datum : data) {
|
||||
stream.write(datum);
|
||||
}
|
||||
}
|
||||
|
||||
assertArrayEquals(data, result.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeArray() throws IOException {
|
||||
byte[] data = createData(1793);
|
||||
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
try (OutputStream stream = new EncoderStream(result, new NullEncoder())) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
stream.write(data);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] encoded = result.toByteArray();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertArrayEquals(data, Arrays.copyOfRange(encoded, i * data.length, (i + 1) * data.length));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeArrayOffset() throws IOException {
|
||||
byte[] data = createData(87);
|
||||
|
||||
ByteArrayOutputStream result = new ByteArrayOutputStream();
|
||||
try (OutputStream stream = new EncoderStream(result, new NullEncoder())) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
stream.write(data, 13, 59);
|
||||
}
|
||||
}
|
||||
|
||||
byte[] original = Arrays.copyOfRange(data, 13, 13 + 59);
|
||||
byte[] encoded = result.toByteArray();
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
assertArrayEquals(original, Arrays.copyOfRange(encoded, i * original.length, (i + 1) * original.length));
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NullEncoder implements Encoder {
|
||||
@Override
|
||||
public void encode(OutputStream stream, ByteBuffer buffer) throws IOException {
|
||||
stream.write(buffer.array(), buffer.arrayOffset(), buffer.remaining());
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-16
@@ -31,9 +31,9 @@
|
||||
package com.twelvemonkeys.io.ole2;
|
||||
|
||||
import com.twelvemonkeys.io.MemoryCacheSeekableStream;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.stream.MemoryCacheImageInputStream;
|
||||
import java.awt.image.ImageProducer;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -43,8 +43,8 @@ import java.nio.ByteOrder;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
/**
|
||||
* CompoundDocumentTestCase
|
||||
*
|
||||
@@ -59,8 +59,8 @@ public class CompoundDocumentTest {
|
||||
protected final CompoundDocument createTestDocument() throws IOException {
|
||||
URL input = getClass().getResource(SAMPLE_DATA);
|
||||
|
||||
assertNotNull("Missing test resource!", input);
|
||||
assertEquals("Test resource not a file:// resource", "file", input.getProtocol());
|
||||
assertNotNull(input, "Missing test resource!");
|
||||
assertEquals( "file", input.getProtocol(), "Test resource not a file:// resource");
|
||||
|
||||
try {
|
||||
return new CompoundDocument(new File(input.toURI()));
|
||||
@@ -103,7 +103,7 @@ public class CompoundDocumentTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedOperationException.class)
|
||||
@Test
|
||||
public void testChildEntriesUnmodifiable() throws IOException {
|
||||
try (CompoundDocument document = createTestDocument()) {
|
||||
Entry root = document.getRootEntry();
|
||||
@@ -111,9 +111,10 @@ public class CompoundDocumentTest {
|
||||
assertNotNull(root);
|
||||
|
||||
SortedSet<Entry> children = root.getChildEntries();
|
||||
|
||||
// Should not be allowed, as it modifies the internal structure
|
||||
children.remove(children.first());
|
||||
assertThrows(UnsupportedOperationException.class, () -> {
|
||||
// Should not be allowed, as it modifies the internal structure
|
||||
children.remove(children.first());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +129,7 @@ public class CompoundDocumentTest {
|
||||
Entry catalog = root.getChildEntry("Catalog");
|
||||
|
||||
assertNotNull(catalog);
|
||||
assertNotNull("Input stream may not be null", catalog.getInputStream());
|
||||
assertNotNull(catalog.getInputStream(), "Input stream may not be null");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +137,7 @@ public class CompoundDocumentTest {
|
||||
public void testReadCatalogInputStream() throws IOException {
|
||||
InputStream input = getClass().getResourceAsStream(SAMPLE_DATA);
|
||||
|
||||
assertNotNull("Missing test resource!", input);
|
||||
assertNotNull(input, "Missing test resource!");
|
||||
|
||||
CompoundDocument document = new CompoundDocument(input);
|
||||
Entry root = document.getRootEntry();
|
||||
@@ -145,14 +146,14 @@ public class CompoundDocumentTest {
|
||||
|
||||
Entry catalog = root.getChildEntry("Catalog");
|
||||
assertNotNull(catalog);
|
||||
assertNotNull("Input stream may not be null", catalog.getInputStream());
|
||||
assertNotNull(catalog.getInputStream(), "Input stream may not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadCatalogSeekableStream() throws IOException {
|
||||
InputStream input = getClass().getResourceAsStream(SAMPLE_DATA);
|
||||
|
||||
assertNotNull("Missing test resource!", input);
|
||||
assertNotNull(input, "Missing test resource!");
|
||||
|
||||
CompoundDocument document = new CompoundDocument(new MemoryCacheSeekableStream(input));
|
||||
Entry root = document.getRootEntry();
|
||||
@@ -161,14 +162,14 @@ public class CompoundDocumentTest {
|
||||
|
||||
Entry catalog = root.getChildEntry("Catalog");
|
||||
assertNotNull(catalog);
|
||||
assertNotNull("Input stream may not be null", catalog.getInputStream());
|
||||
assertNotNull(catalog.getInputStream(), "Input stream may not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadCatalogImageInputStream() throws IOException {
|
||||
InputStream input = getClass().getResourceAsStream(SAMPLE_DATA);
|
||||
|
||||
assertNotNull("Missing test resource!", input);
|
||||
assertNotNull(input, "Missing test resource!");
|
||||
|
||||
MemoryCacheImageInputStream stream = new MemoryCacheImageInputStream(input);
|
||||
stream.setByteOrder(ByteOrder.LITTLE_ENDIAN);
|
||||
@@ -183,6 +184,6 @@ public class CompoundDocumentTest {
|
||||
Entry catalog = root.getChildEntry("Catalog");
|
||||
|
||||
assertNotNull(catalog);
|
||||
assertNotNull("Input stream may not be null", catalog.getInputStream());
|
||||
assertNotNull(catalog.getInputStream(), "Input stream may not be null");
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
package com.twelvemonkeys.io.ole2;
|
||||
|
||||
import com.twelvemonkeys.io.*;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
|
||||
+4
-4
@@ -33,7 +33,6 @@ package com.twelvemonkeys.io.ole2;
|
||||
import com.twelvemonkeys.io.InputStreamAbstractTest;
|
||||
import com.twelvemonkeys.io.LittleEndianDataOutputStream;
|
||||
import com.twelvemonkeys.io.MemoryCacheSeekableStream;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -42,7 +41,8 @@ import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* CompoundDocument_StreamTestCase
|
||||
@@ -165,8 +165,8 @@ public class CompoundDocument_StreamTest extends InputStreamAbstractTest {
|
||||
count++;
|
||||
}
|
||||
|
||||
assertFalse("Short stream", count < 32);
|
||||
assertFalse("Stream overrun", count > 32);
|
||||
assertFalse(count < 32, "Short stream");
|
||||
assertFalse(count > 32, "Stream overrun");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -30,9 +30,8 @@
|
||||
|
||||
package com.twelvemonkeys.net;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* HTTPUtilTest
|
||||
|
||||
@@ -4,17 +4,25 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>common-lang</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>TwelveMonkeys :: Common :: Language support</name>
|
||||
<description>
|
||||
The TwelveMonkeys Common Language support
|
||||
TwelveMonkeys Common language support classes.
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<project.jpms.module.name>com.twelvemonkeys.common.lang</project.jpms.module.name>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -904,7 +904,7 @@ public final class StringUtil {
|
||||
}
|
||||
catch (ParseException pe) {
|
||||
// Wrap in RuntimeException
|
||||
throw new IllegalArgumentException(pe.getMessage());
|
||||
throw new IllegalArgumentException(pe.getMessage() + " at pos " + pe.getErrorOffset());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,14 +30,13 @@
|
||||
|
||||
package com.twelvemonkeys.lang;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* BeanUtilTestCase
|
||||
@@ -161,10 +160,8 @@ public class BeanUtilTest {
|
||||
}
|
||||
|
||||
assertNotNull(bean.getAmbiguous());
|
||||
assertEquals("String converted rather than invoking setAmbiguous(String), ordering not predictable",
|
||||
"one", bean.getAmbiguous());
|
||||
assertSame("String converted rather than invoking setAmbiguous(String), ordering not predictable",
|
||||
value, bean.getAmbiguous());
|
||||
assertEquals("one", bean.getAmbiguous(), "String converted rather than invoking setAmbiguous(String), ordering not predictable");
|
||||
assertSame(value, bean.getAmbiguous(), "String converted rather than invoking setAmbiguous(String), ordering not predictable");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -184,10 +181,10 @@ public class BeanUtilTest {
|
||||
}
|
||||
|
||||
assertNotNull(bean.getAmbiguous());
|
||||
assertEquals("Integer converted rather than invoking setAmbiguous(Integer), ordering not predictable",
|
||||
2, bean.getAmbiguous());
|
||||
assertSame("Integer converted rather than invoking setAmbiguous(Integer), ordering not predictable",
|
||||
value, bean.getAmbiguous());
|
||||
assertEquals(2, bean.getAmbiguous(),
|
||||
"Integer converted rather than invoking setAmbiguous(Integer), ordering not predictable");
|
||||
assertSame(value, bean.getAmbiguous(),
|
||||
"Integer converted rather than invoking setAmbiguous(Integer), ordering not predictable");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -207,10 +204,8 @@ public class BeanUtilTest {
|
||||
}
|
||||
|
||||
assertNotNull(bean.getAmbiguous());
|
||||
assertEquals("Object converted rather than invoking setAmbiguous(Object), ordering not predictable",
|
||||
value.getClass(), bean.getAmbiguous().getClass());
|
||||
assertSame("Object converted rather than invoking setAmbiguous(Object), ordering not predictable",
|
||||
value, bean.getAmbiguous());
|
||||
assertEquals(value.getClass(), bean.getAmbiguous().getClass(), "Object converted rather than invoking setAmbiguous(Object), ordering not predictable");
|
||||
assertSame(value, bean.getAmbiguous(), "Object converted rather than invoking setAmbiguous(Object), ordering not predictable");
|
||||
}
|
||||
|
||||
static class TestBean {
|
||||
|
||||
@@ -30,16 +30,16 @@
|
||||
|
||||
package com.twelvemonkeys.lang;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* DateUtilTest
|
||||
@@ -48,12 +48,9 @@ import static org.junit.Assert.assertEquals;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: DateUtilTest.java,v 1.0 11.04.12 16:21 haraldk Exp$
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
|
||||
public class DateUtilTest {
|
||||
|
||||
private final TimeZone timeZone;
|
||||
|
||||
@Parameterized.Parameters
|
||||
public static List<Object[]> timeZones() {
|
||||
return Arrays.asList(new Object[][] {
|
||||
{TimeZone.getTimeZone("UTC")},
|
||||
@@ -62,10 +59,6 @@ public class DateUtilTest {
|
||||
});
|
||||
}
|
||||
|
||||
public DateUtilTest(final TimeZone timeZone) {
|
||||
this.timeZone = timeZone;
|
||||
}
|
||||
|
||||
private Calendar getCalendar(long time) {
|
||||
return getCalendar(time, TimeZone.getDefault());
|
||||
}
|
||||
@@ -101,8 +94,9 @@ public class DateUtilTest {
|
||||
assertEquals(0, calendar.get(Calendar.MINUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoundToHourTZ() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("timeZones")
|
||||
public void testRoundToHourTZ(TimeZone timeZone) {
|
||||
Calendar calendar = getCalendar(DateUtil.roundToHour(System.currentTimeMillis(), timeZone), timeZone);
|
||||
|
||||
assertEquals(0, calendar.get(Calendar.MILLISECOND));
|
||||
@@ -120,8 +114,9 @@ public class DateUtilTest {
|
||||
assertEquals(0, calendar.get(Calendar.HOUR_OF_DAY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoundToDayTZ() {
|
||||
@ParameterizedTest
|
||||
@MethodSource("timeZones")
|
||||
public void testRoundToDayTZ(TimeZone timeZone) {
|
||||
Calendar calendar = getCalendar(DateUtil.roundToDay(System.currentTimeMillis(), timeZone), timeZone);
|
||||
|
||||
assertEquals(0, calendar.get(Calendar.MILLISECOND));
|
||||
|
||||
@@ -30,12 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.lang;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* AbstractObjectTestCase
|
||||
@@ -79,10 +78,10 @@ public abstract class ObjectAbstractTest {
|
||||
|
||||
Class cl = obj.getClass();
|
||||
if (isEqualsOverriden(cl)) {
|
||||
assertTrue("Class " + cl.getName() + " implements equals but not hashCode", isHashCodeOverriden(cl));
|
||||
assertTrue(isHashCodeOverriden(cl), "Class " + cl.getName() + " implements equals but not hashCode");
|
||||
}
|
||||
else if (isHashCodeOverriden(cl)) {
|
||||
assertTrue("Class " + cl.getName() + " implements hashCode but not equals", isEqualsOverriden(cl));
|
||||
assertTrue(isEqualsOverriden(cl), "Class " + cl.getName() + " implements hashCode but not equals");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -107,7 +106,7 @@ public abstract class ObjectAbstractTest {
|
||||
@Test
|
||||
public void testObjectEqualsSelf() {
|
||||
Object obj = makeObject();
|
||||
assertEquals("An Object should equal itself", obj, obj);
|
||||
assertEquals(obj, obj, "An Object should equal itself");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -115,32 +114,26 @@ public abstract class ObjectAbstractTest {
|
||||
Object obj = makeObject();
|
||||
// NOTE: Makes sure this doesn't throw NPE either
|
||||
//noinspection ObjectEqualsNull
|
||||
assertFalse("An object should never equal null", obj.equals(null));
|
||||
assertFalse(obj.equals(null), "An object should never equal null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectHashCodeEqualsSelfHashCode() {
|
||||
Object obj = makeObject();
|
||||
assertEquals("hashCode should be repeatable", obj.hashCode(), obj.hashCode());
|
||||
assertEquals(obj.hashCode(), obj.hashCode(), "hashCode should be repeatable");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectHashCodeEqualsContract() {
|
||||
Object obj1 = makeObject();
|
||||
if (obj1.equals(obj1)) {
|
||||
assertEquals(
|
||||
"[1] When two objects are equal, their hashCodes should be also.",
|
||||
obj1.hashCode(), obj1.hashCode());
|
||||
assertEquals(obj1.hashCode(), obj1.hashCode(), "[1] When two objects are equal, their hashCodes should be also.");
|
||||
}
|
||||
// TODO: Make sure we create at least one equal object, and one different object
|
||||
Object obj2 = makeObject();
|
||||
if (obj1.equals(obj2)) {
|
||||
assertEquals(
|
||||
"[2] When two objects are equal, their hashCodes should be also.",
|
||||
obj1.hashCode(), obj2.hashCode());
|
||||
assertTrue(
|
||||
"When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true",
|
||||
obj2.equals(obj1));
|
||||
assertEquals(obj1.hashCode(), obj2.hashCode(), "[2] When two objects are equal, their hashCodes should be also.");
|
||||
assertTrue(obj2.equals(obj1), "When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,14 +162,14 @@ public abstract class ObjectAbstractTest {
|
||||
|
||||
Object cloned = clone.invoke(obj);
|
||||
|
||||
assertNotNull("Cloned object should never be null", cloned);
|
||||
assertNotNull(cloned, "Cloned object should never be null");
|
||||
|
||||
// TODO: This can only be asserted if equals() test is based on
|
||||
// value equality, not reference (identity) equality
|
||||
// Maybe it's possible to do a reflective introspection of
|
||||
// the objects fields?
|
||||
if (isHashCodeOverriden(cl)) {
|
||||
assertEquals("Cloned object not equal", obj, cloned);
|
||||
assertEquals(obj, cloned, "Cloned object not equal");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +228,7 @@ public abstract class ObjectAbstractTest {
|
||||
// Maybe it's possible to do a reflective introspection of
|
||||
// the objects fields?
|
||||
if (isEqualsOverriden(obj.getClass())) {
|
||||
assertEquals("obj != deserialize(serialize(obj))", obj, dest);
|
||||
assertEquals(obj, dest, "obj != deserialize(serialize(obj))");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,13 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.lang;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* PlatformTest
|
||||
@@ -121,7 +119,7 @@ public class PlatformTest {
|
||||
assertEquals(Platform.Architecture.X86, platform.getArchitecture());
|
||||
}
|
||||
|
||||
@Ignore("Known issue, needs resolve")
|
||||
@Disabled("Known issue, needs resolve")
|
||||
@Test
|
||||
public void testCreateWindows686() {
|
||||
Platform platform = new Platform(createProperties("Windows", "5.1", "686"));
|
||||
@@ -129,7 +127,7 @@ public class PlatformTest {
|
||||
assertEquals(Platform.Architecture.X86, platform.getArchitecture());
|
||||
}
|
||||
|
||||
@Ignore("Known issue, needs resolve")
|
||||
@Disabled("Known issue, needs resolve")
|
||||
@Test
|
||||
public void testCreateLinuxX86() {
|
||||
Platform platform = new Platform(createProperties("Linux", "3.0.18", "x86"));
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
package com.twelvemonkeys.lang;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
@@ -41,8 +39,8 @@ import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
/**
|
||||
* StringUtilTestCase
|
||||
*
|
||||
@@ -165,10 +163,10 @@ public class StringUtilTest {
|
||||
// Test all alpha-chars
|
||||
for (int i = 'a'; i < 'z'; i++) {
|
||||
if (TEST_STRING.indexOf(i) < 0) {
|
||||
assertFalse(TEST_STRING + " seems to contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i), StringUtil.contains(TEST_STRING, i));
|
||||
assertFalse(StringUtil.contains(TEST_STRING, i), TEST_STRING + " seems to contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i));
|
||||
}
|
||||
else {
|
||||
assertTrue(TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i), StringUtil.contains(TEST_STRING, i));
|
||||
assertTrue(StringUtil.contains(TEST_STRING, i), TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,10 +197,10 @@ public class StringUtilTest {
|
||||
// Test all alpha-chars
|
||||
for (int i = 'a'; i < 'z'; i++) {
|
||||
if ((TEST_STRING.indexOf(i) < 0) && (TEST_STRING.indexOf(Character.toUpperCase((char) i)) < 0)) {
|
||||
assertFalse(TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))), StringUtil.containsIgnoreCase(TEST_STRING, i));
|
||||
assertFalse(StringUtil.containsIgnoreCase(TEST_STRING, i), TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))));
|
||||
}
|
||||
else {
|
||||
assertTrue(TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i), StringUtil.containsIgnoreCase(TEST_STRING, i));
|
||||
assertTrue(StringUtil.containsIgnoreCase(TEST_STRING, i), TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,10 +348,10 @@ public class StringUtilTest {
|
||||
// Test all alpha-chars
|
||||
for (int i = 'a'; i < 'z'; i++) {
|
||||
if ((TEST_STRING.indexOf(i) < 0) && (TEST_STRING.indexOf(Character.toUpperCase((char) i)) < 0)) {
|
||||
assertEquals(TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))), -1, StringUtil.indexOfIgnoreCase(TEST_STRING, i));
|
||||
assertEquals(-1, StringUtil.indexOfIgnoreCase(TEST_STRING, i), TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))));
|
||||
}
|
||||
else {
|
||||
assertTrue(TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i), 0 <= StringUtil.indexOfIgnoreCase(TEST_STRING, i));
|
||||
assertTrue(0 <= StringUtil.indexOfIgnoreCase(TEST_STRING, i), TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,10 +383,10 @@ public class StringUtilTest {
|
||||
// Test all alpha-chars
|
||||
for (int i = 'a'; i < 'z'; i++) {
|
||||
if ((TEST_STRING.indexOf(i) < 0) && (TEST_STRING.indexOf(Character.toUpperCase((char) i)) < 0)) {
|
||||
assertEquals(TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))), -1, StringUtil.indexOfIgnoreCase(TEST_STRING, i, 0));
|
||||
assertEquals(-1, StringUtil.indexOfIgnoreCase(TEST_STRING, i, 0), TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))));
|
||||
}
|
||||
else {
|
||||
assertTrue(TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i), 0 <= StringUtil.indexOfIgnoreCase(TEST_STRING, i, 0));
|
||||
assertTrue(0 <= StringUtil.indexOfIgnoreCase(TEST_STRING, i, 0), TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -420,10 +418,10 @@ public class StringUtilTest {
|
||||
// Test all alpha-chars
|
||||
for (int i = 'a'; i < 'z'; i++) {
|
||||
if ((TEST_STRING.indexOf(i) < 0) && (TEST_STRING.indexOf(Character.toUpperCase((char) i)) < 0)) {
|
||||
assertEquals(TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))), -1, StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i));
|
||||
assertEquals(-1, StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i), TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))));
|
||||
}
|
||||
else {
|
||||
assertTrue(TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i), 0 <= StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i));
|
||||
assertTrue(0 <= StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i), TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -455,10 +453,10 @@ public class StringUtilTest {
|
||||
// Test all alpha-chars
|
||||
for (int i = 'a'; i < 'z'; i++) {
|
||||
if ((TEST_STRING.indexOf(i) < 0) && (TEST_STRING.indexOf(Character.toUpperCase((char) i)) < 0)) {
|
||||
assertEquals(TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))), -1, StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i, TEST_STRING.length()));
|
||||
assertEquals(-1, StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i, TEST_STRING.length()), TEST_STRING + " seems to contain '" + (char) i + "', at index " + Math.max(TEST_STRING.indexOf(i), TEST_STRING.indexOf(Character.toUpperCase((char) i))));
|
||||
}
|
||||
else {
|
||||
assertTrue(TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i), 0 <= StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i, TEST_STRING.length()));
|
||||
assertTrue(0 <= StringUtil.lastIndexOfIgnoreCase(TEST_STRING, i, TEST_STRING.length()), TEST_STRING + " seems to not contain '" + (char) i + "', at index " + TEST_STRING.indexOf(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -593,8 +591,8 @@ public class StringUtilTest {
|
||||
cal.clear();
|
||||
cal.set(Calendar.HOUR, 1);
|
||||
cal.set(Calendar.MINUTE, 2);
|
||||
date = StringUtil.toDate("1:02 am",
|
||||
DateFormat.getTimeInstance(DateFormat.SHORT, Locale.US));
|
||||
format = new SimpleDateFormat("HH:mm");
|
||||
date = StringUtil.toDate("1:02", format);
|
||||
assertNotNull(date);
|
||||
assertEquals(cal.getTime(), date);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
package com.twelvemonkeys.lang;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
|
||||
/**
|
||||
* SystemUtilTest
|
||||
@@ -39,6 +39,6 @@ import org.junit.Ignore;
|
||||
* @author last modified by $Author: haraldk$
|
||||
* @version $Id: SystemUtilTest.java,v 1.0 11.04.12 16:21 haraldk Exp$
|
||||
*/
|
||||
@Ignore
|
||||
@Disabled
|
||||
public class SystemUtilTest {
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+91
-137
@@ -45,12 +45,11 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Abstract test class for {@link java.util.Collection} methods and contracts.
|
||||
@@ -251,11 +250,8 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
*/
|
||||
public void verifyAll() {
|
||||
int confirmedSize = confirmed.size();
|
||||
assertEquals("Collection size should match confirmed collection's",
|
||||
confirmedSize, collection.size());
|
||||
assertEquals("Collection isEmpty() result should match confirmed " +
|
||||
" collection's",
|
||||
confirmed.isEmpty(), collection.isEmpty());
|
||||
assertEquals(confirmedSize, collection.size(), "Collection size should match confirmed collection's");
|
||||
assertEquals(confirmed.isEmpty(), collection.isEmpty(), "Collection isEmpty() result should match confirmed collection's");
|
||||
|
||||
// verify the collections are the same by attempting to match each
|
||||
// object in the collection and confirmed collection. To account for
|
||||
@@ -521,8 +517,8 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
boolean r = collection.add(elements[i]);
|
||||
confirmed.add(elements[i]);
|
||||
verifyAll();
|
||||
assertTrue("Empty collection changed after add", r);
|
||||
assertEquals("Collection size is 1 after first add", 1, collection.size());
|
||||
assertTrue(r, "Empty collection changed after add");
|
||||
assertEquals(1, collection.size(), "Collection size is 1 after first add");
|
||||
}
|
||||
|
||||
resetEmpty();
|
||||
@@ -532,10 +528,8 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
confirmed.add(elements[i]);
|
||||
verifyAll();
|
||||
if (r) size++;
|
||||
assertEquals("Collection size should grow after add",
|
||||
size, collection.size());
|
||||
assertTrue("Collection should contain added element",
|
||||
collection.contains(elements[i]));
|
||||
assertEquals(size, collection.size(), "Collection size should grow after add");
|
||||
assertTrue(collection.contains(elements[i]), "Collection should contain added element");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,10 +546,9 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
boolean r = collection.addAll(Arrays.asList(elements));
|
||||
confirmed.addAll(Arrays.asList(elements));
|
||||
verifyAll();
|
||||
assertTrue("Empty collection should change after addAll", r);
|
||||
assertTrue(r, "Empty collection should change after addAll");
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
assertTrue("Collection should contain added element",
|
||||
collection.contains(elements[i]));
|
||||
assertTrue(collection.contains(elements[i]), "Collection should contain added element");
|
||||
}
|
||||
|
||||
resetFull();
|
||||
@@ -564,13 +557,11 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
r = collection.addAll(Arrays.asList(elements));
|
||||
confirmed.addAll(Arrays.asList(elements));
|
||||
verifyAll();
|
||||
assertTrue("Full collection should change after addAll", r);
|
||||
assertTrue(r, "Full collection should change after addAll");
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
assertTrue("Full collection should contain added element",
|
||||
collection.contains(elements[i]));
|
||||
assertTrue(collection.contains(elements[i]), "Full collection should contain added element");
|
||||
}
|
||||
assertEquals("Size should increase after addAll",
|
||||
size + elements.length, collection.size());
|
||||
assertEquals(size + elements.length, collection.size(), "Size should increase after addAll");
|
||||
|
||||
resetFull();
|
||||
size = collection.size();
|
||||
@@ -578,11 +569,9 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
confirmed.addAll(Arrays.asList(getFullElements()));
|
||||
verifyAll();
|
||||
if (r) {
|
||||
assertTrue("Size should increase if addAll returns true",
|
||||
size < collection.size());
|
||||
assertTrue(size < collection.size(), "Size should increase if addAll returns true");
|
||||
} else {
|
||||
assertEquals("Size should not change if addAll returns false",
|
||||
size, collection.size());
|
||||
assertEquals(size, collection.size(), "Size should not change if addAll returns false");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,16 +655,14 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
resetEmpty();
|
||||
elements = getFullElements();
|
||||
for(int i = 0; i < elements.length; i++) {
|
||||
assertTrue("Empty collection shouldn't contain element[" + i + "]",
|
||||
!collection.contains(elements[i]));
|
||||
assertTrue(!collection.contains(elements[i]), "Empty collection shouldn't contain element[" + i + "]");
|
||||
}
|
||||
// make sure calls to "contains" don't change anything
|
||||
verifyAll();
|
||||
|
||||
elements = getOtherElements();
|
||||
for(int i = 0; i < elements.length; i++) {
|
||||
assertTrue("Empty collection shouldn't contain element[" + i + "]",
|
||||
!collection.contains(elements[i]));
|
||||
assertTrue(!collection.contains(elements[i]), "Empty collection shouldn't contain element[" + i + "]");
|
||||
}
|
||||
// make sure calls to "contains" don't change anything
|
||||
verifyAll();
|
||||
@@ -683,8 +670,7 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
resetFull();
|
||||
elements = getFullElements();
|
||||
for(int i = 0; i < elements.length; i++) {
|
||||
assertTrue("Full collection should contain element[" + i + "]",
|
||||
collection.contains(elements[i]));
|
||||
assertTrue(collection.contains(elements[i]), "Full collection should contain element[" + i + "]");
|
||||
}
|
||||
// make sure calls to "contains" don't change anything
|
||||
verifyAll();
|
||||
@@ -692,8 +678,7 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
resetFull();
|
||||
elements = getOtherElements();
|
||||
for(int i = 0; i < elements.length; i++) {
|
||||
assertTrue("Full collection shouldn't contain element",
|
||||
!collection.contains(elements[i]));
|
||||
assertTrue(!collection.contains(elements[i]), "Full collection shouldn't contain element");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,22 +690,22 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
public void testCollectionContainsAll() {
|
||||
resetEmpty();
|
||||
Collection col = new HashSet();
|
||||
assertTrue("Every Collection should contain all elements of an " +
|
||||
"empty Collection.", collection.containsAll(col));
|
||||
assertTrue(collection.containsAll(col),
|
||||
"Every Collection should contain all elements of an " +
|
||||
"empty Collection.");
|
||||
col.addAll(Arrays.asList(getOtherElements()));
|
||||
assertTrue("Empty Collection shouldn't contain all elements of " +
|
||||
"a non-empty Collection.", !collection.containsAll(col));
|
||||
assertTrue(!collection.containsAll(col),
|
||||
"Empty Collection shouldn't contain all elements of " +
|
||||
"a non-empty Collection.");
|
||||
// make sure calls to "containsAll" don't change anything
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertTrue("Full collection shouldn't contain other elements",
|
||||
!collection.containsAll(col));
|
||||
assertTrue(!collection.containsAll(col), "Full collection shouldn't contain other elements");
|
||||
|
||||
col.clear();
|
||||
col.addAll(Arrays.asList(getFullElements()));
|
||||
assertTrue("Full collection should containAll full elements",
|
||||
collection.containsAll(col));
|
||||
assertTrue(collection.containsAll(col), "Full collection should containAll full elements");
|
||||
// make sure calls to "containsAll" don't change anything
|
||||
verifyAll();
|
||||
|
||||
@@ -728,18 +713,17 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
int max = (getFullElements().length == 1 ? 1 :
|
||||
(getFullElements().length <= 5 ? getFullElements().length - 1 : 5));
|
||||
col = Arrays.asList(getFullElements()).subList(min, max);
|
||||
assertTrue("Full collection should containAll partial full " +
|
||||
"elements", collection.containsAll(col));
|
||||
assertTrue("Full collection should containAll itself",
|
||||
collection.containsAll(collection));
|
||||
assertTrue(collection.containsAll(col), "Full collection should containAll partial full " +
|
||||
"elements");
|
||||
assertTrue(collection.containsAll(collection), "Full collection should containAll itself");
|
||||
// make sure calls to "containsAll" don't change anything
|
||||
verifyAll();
|
||||
|
||||
col = new ArrayList();
|
||||
col.addAll(Arrays.asList(getFullElements()));
|
||||
col.addAll(Arrays.asList(getFullElements()));
|
||||
assertTrue("Full collection should containAll duplicate full " +
|
||||
"elements", collection.containsAll(col));
|
||||
assertTrue(collection.containsAll(col), "Full collection should containAll duplicate full " +
|
||||
"elements");
|
||||
|
||||
// make sure calls to "containsAll" don't change anything
|
||||
verifyAll();
|
||||
@@ -751,14 +735,12 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testCollectionIsEmpty() {
|
||||
resetEmpty();
|
||||
assertEquals("New Collection should be empty.",
|
||||
true, collection.isEmpty());
|
||||
assertEquals(true, collection.isEmpty(), "New Collection should be empty.");
|
||||
// make sure calls to "isEmpty() don't change anything
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertEquals("Full collection shouldn't be empty",
|
||||
false, collection.isEmpty());
|
||||
assertEquals(false, collection.isEmpty(), "Full collection shouldn't be empty");
|
||||
// make sure calls to "isEmpty() don't change anything
|
||||
verifyAll();
|
||||
}
|
||||
@@ -771,8 +753,7 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
public void testCollectionIterator() {
|
||||
resetEmpty();
|
||||
Iterator it1 = collection.iterator();
|
||||
assertEquals("Iterator for empty Collection shouldn't have next.",
|
||||
false, it1.hasNext());
|
||||
assertEquals(false, it1.hasNext(), "Iterator for empty Collection shouldn't have next.");
|
||||
try {
|
||||
it1.next();
|
||||
fail("Iterator at end of Collection should throw " +
|
||||
@@ -786,18 +767,17 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
resetFull();
|
||||
it1 = collection.iterator();
|
||||
for (int i = 0; i < collection.size(); i++) {
|
||||
assertTrue("Iterator for full collection should haveNext",
|
||||
it1.hasNext());
|
||||
assertTrue(it1.hasNext(), "Iterator for full collection should haveNext");
|
||||
it1.next();
|
||||
}
|
||||
assertTrue("Iterator should be finished", !it1.hasNext());
|
||||
assertTrue(!it1.hasNext(), "Iterator should be finished");
|
||||
|
||||
ArrayList list = new ArrayList();
|
||||
it1 = collection.iterator();
|
||||
for (int i = 0; i < collection.size(); i++) {
|
||||
Object next = it1.next();
|
||||
assertTrue("Collection should contain element returned by " +
|
||||
"its iterator", collection.contains(next));
|
||||
assertTrue(collection.contains(next), "Collection should contain element returned by " +
|
||||
"its iterator");
|
||||
list.add(next);
|
||||
}
|
||||
try {
|
||||
@@ -865,11 +845,10 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
}
|
||||
|
||||
size--;
|
||||
assertEquals("Collection should shrink by one after " +
|
||||
"iterator.remove", size, collection.size());
|
||||
assertEquals(size, collection.size(), "Collection should shrink by one after " +
|
||||
"iterator.remove");
|
||||
}
|
||||
assertTrue("Collection should be empty after iterator purge",
|
||||
collection.isEmpty());
|
||||
assertTrue(collection.isEmpty(), "Collection should be empty after iterator purge");
|
||||
|
||||
resetFull();
|
||||
iter = collection.iterator();
|
||||
@@ -894,8 +873,7 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
resetEmpty();
|
||||
Object[] elements = getFullElements();
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
assertTrue("Shouldn't remove nonexistent element",
|
||||
!collection.remove(elements[i]));
|
||||
assertTrue(!collection.remove(elements[i]), "Shouldn't remove nonexistent element");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -903,16 +881,14 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
resetFull();
|
||||
for (int i = 0; i < other.length; i++) {
|
||||
assertTrue("Shouldn't remove nonexistent other element",
|
||||
!collection.remove(other[i]));
|
||||
assertTrue(!collection.remove(other[i]), "Shouldn't remove nonexistent other element");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
int size = collection.size();
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
resetFull();
|
||||
assertTrue("Collection should remove extant element: " + elements[i],
|
||||
collection.remove(elements[i]));
|
||||
assertTrue(collection.remove(elements[i]), "Collection should remove extant element: " + elements[i]);
|
||||
|
||||
// if the elements aren't distinguishable, we can just remove a
|
||||
// matching element from the confirmed collection and verify
|
||||
@@ -927,8 +903,7 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
assertEquals("Collection should shrink after remove",
|
||||
size - 1, collection.size());
|
||||
assertEquals(size - 1, collection.size(), "Collection should shrink after remove");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -941,28 +916,28 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
if (!isRemoveSupported()) return;
|
||||
|
||||
resetEmpty();
|
||||
assertTrue("Emtpy collection removeAll should return false for " +
|
||||
"empty input",
|
||||
!collection.removeAll(Collections.EMPTY_SET));
|
||||
assertTrue(!collection.removeAll(Collections.EMPTY_SET),
|
||||
"Emtpy collection removeAll should return false for " +
|
||||
"empty input");
|
||||
verifyAll();
|
||||
|
||||
assertTrue("Emtpy collection removeAll should return false for " +
|
||||
"nonempty input",
|
||||
!collection.removeAll(new ArrayList(collection)));
|
||||
assertTrue(!collection.removeAll(new ArrayList(collection)),
|
||||
"Emtpy collection removeAll should return false for " +
|
||||
"nonempty input");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertTrue("Full collection removeAll should return false for " +
|
||||
"empty input",
|
||||
!collection.removeAll(Collections.EMPTY_SET));
|
||||
assertTrue(!collection.removeAll(Collections.EMPTY_SET),
|
||||
"Full collection removeAll should return false for " +
|
||||
"empty input");
|
||||
verifyAll();
|
||||
|
||||
assertTrue("Full collection removeAll should return false for other elements",
|
||||
!collection.removeAll(Arrays.asList(getOtherElements())));
|
||||
assertTrue(!collection.removeAll(Arrays.asList(getOtherElements())),
|
||||
"Full collection removeAll should return false for other elements");
|
||||
verifyAll();
|
||||
|
||||
assertTrue("Full collection removeAll should return true for full elements",
|
||||
collection.removeAll(new HashSet(collection)));
|
||||
assertTrue(collection.removeAll(new HashSet(collection)),
|
||||
"Full collection removeAll should return true for full elements");
|
||||
confirmed.removeAll(new HashSet(confirmed));
|
||||
verifyAll();
|
||||
|
||||
@@ -972,17 +947,14 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
int max = (getFullElements().length == 1 ? 1 :
|
||||
(getFullElements().length <= 5 ? getFullElements().length - 1 : 5));
|
||||
Collection all = Arrays.asList(getFullElements()).subList(min, max);
|
||||
assertTrue("Full collection removeAll should work",
|
||||
collection.removeAll(all));
|
||||
assertTrue(collection.removeAll(all), "Full collection removeAll should work");
|
||||
confirmed.removeAll(all);
|
||||
verifyAll();
|
||||
|
||||
assertTrue("Collection should shrink after removeAll",
|
||||
collection.size() < size);
|
||||
assertTrue(collection.size() < size, "Collection should shrink after removeAll");
|
||||
Iterator iter = all.iterator();
|
||||
while (iter.hasNext()) {
|
||||
assertTrue("Collection shouldn't contain removed element",
|
||||
!collection.contains(iter.next()));
|
||||
assertTrue(!collection.contains(iter.next()), "Collection shouldn't contain removed element");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -998,59 +970,51 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
List elements = Arrays.asList(getFullElements());
|
||||
List other = Arrays.asList(getOtherElements());
|
||||
|
||||
assertTrue("Empty retainAll() should return false",
|
||||
!collection.retainAll(Collections.EMPTY_SET));
|
||||
assertTrue(!collection.retainAll(Collections.EMPTY_SET), "Empty retainAll() should return false");
|
||||
verifyAll();
|
||||
|
||||
assertTrue("Empty retainAll() should return false",
|
||||
!collection.retainAll(elements));
|
||||
assertTrue(!collection.retainAll(elements), "Empty retainAll() should return false");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertTrue("Collection should change from retainAll empty",
|
||||
collection.retainAll(Collections.EMPTY_SET));
|
||||
assertTrue(collection.retainAll(Collections.EMPTY_SET), "Collection should change from retainAll empty");
|
||||
confirmed.retainAll(Collections.EMPTY_SET);
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertTrue("Collection changed from retainAll other",
|
||||
collection.retainAll(other));
|
||||
assertTrue(collection.retainAll(other), "Collection changed from retainAll other");
|
||||
confirmed.retainAll(other);
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
int size = collection.size();
|
||||
assertTrue("Collection shouldn't change from retainAll elements",
|
||||
!collection.retainAll(elements));
|
||||
assertTrue(!collection.retainAll(elements), "Collection shouldn't change from retainAll elements");
|
||||
verifyAll();
|
||||
assertEquals("Collection size shouldn't change", size,
|
||||
collection.size());
|
||||
assertEquals(size, collection.size(), "Collection size shouldn't change");
|
||||
|
||||
if (getFullElements().length > 1) {
|
||||
resetFull();
|
||||
size = collection.size();
|
||||
int min = (getFullElements().length < 2 ? 0 : 2);
|
||||
int max = (getFullElements().length <= 5 ? getFullElements().length - 1 : 5);
|
||||
assertTrue("Collection should changed by partial retainAll",
|
||||
collection.retainAll(elements.subList(min, max)));
|
||||
assertTrue(collection.retainAll(elements.subList(min, max)), "Collection should changed by partial retainAll");
|
||||
confirmed.retainAll(elements.subList(min, max));
|
||||
verifyAll();
|
||||
|
||||
Iterator iter = collection.iterator();
|
||||
while (iter.hasNext()) {
|
||||
assertTrue("Collection only contains retained element",
|
||||
elements.subList(min, max).contains(iter.next()));
|
||||
assertTrue(elements.subList(min, max).contains(iter.next()), "Collection only contains retained element");
|
||||
}
|
||||
}
|
||||
|
||||
resetFull();
|
||||
HashSet set = new HashSet(elements);
|
||||
size = collection.size();
|
||||
assertTrue("Collection shouldn't change from retainAll without " +
|
||||
"duplicate elements", !collection.retainAll(set));
|
||||
assertTrue(!collection.retainAll(set),
|
||||
"Collection shouldn't change from retainAll without duplicate elements");
|
||||
verifyAll();
|
||||
assertEquals("Collection size didn't change from nonduplicate " +
|
||||
"retainAll", size, collection.size());
|
||||
assertEquals( size, collection.size(),
|
||||
"Collection size didn't change from nonduplicate retainAll");
|
||||
}
|
||||
|
||||
|
||||
@@ -1060,11 +1024,10 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testCollectionSize() {
|
||||
resetEmpty();
|
||||
assertEquals("Size of new Collection is 0.", 0, collection.size());
|
||||
assertEquals(0, collection.size(), "Size of new Collection is 0.");
|
||||
|
||||
resetFull();
|
||||
assertTrue("Size of full collection should be greater than zero",
|
||||
collection.size() > 0);
|
||||
assertTrue(collection.size() > 0, "Size of full collection should be greater than zero");
|
||||
}
|
||||
|
||||
|
||||
@@ -1073,22 +1036,18 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
*/
|
||||
public void testCollectionToArray() {
|
||||
resetEmpty();
|
||||
assertEquals("Empty Collection should return empty array for toArray",
|
||||
0, collection.toArray().length);
|
||||
assertEquals(0, collection.toArray().length, "Empty Collection should return empty array for toArray");
|
||||
|
||||
resetFull();
|
||||
Object[] array = collection.toArray();
|
||||
assertEquals("Full collection toArray should be same size as " +
|
||||
"collection", array.length, collection.size());
|
||||
assertEquals(array.length, collection.size(), "Full collection toArray should be same size as collection");
|
||||
Object[] confirmedArray = confirmed.toArray();
|
||||
assertEquals("length of array from confirmed collection should " +
|
||||
"match the length of the collection's array",
|
||||
confirmedArray.length, array.length);
|
||||
assertEquals(confirmedArray.length, array.length,
|
||||
"length of array from confirmed collection should match the length of the collection's array");
|
||||
boolean[] matched = new boolean[array.length];
|
||||
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
assertTrue("Collection should contain element in toArray",
|
||||
collection.contains(array[i]));
|
||||
assertTrue(collection.contains(array[i]), "Collection should contain element in toArray");
|
||||
|
||||
boolean match = false;
|
||||
// find a match in the confirmed array
|
||||
@@ -1108,8 +1067,7 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < matched.length; i++) {
|
||||
assertEquals("Collection should return all its elements in " +
|
||||
"toArray", true, matched[i]);
|
||||
assertEquals(true, matched[i], "Collection should return all its elements in toArray");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1123,8 +1081,8 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
resetEmpty();
|
||||
Object[] a = new Object[] { new Object(), null, null };
|
||||
Object[] array = collection.toArray(a);
|
||||
assertArrayEquals("Given array shouldn't shrink", array, a);
|
||||
assertNull("Last element should be set to null", a[0]);
|
||||
assertArrayEquals(array, a, "Given array shouldn't shrink");
|
||||
assertNull(a[0], "Last element should be set to null");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
@@ -1146,8 +1104,7 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
array = collection.toArray(new Object[0]);
|
||||
a = collection.toArray();
|
||||
assertEquals("toArrays should be equal",
|
||||
Arrays.asList(array), Arrays.asList(a));
|
||||
assertEquals(Arrays.asList(array), Arrays.asList(a), "toArrays should be equal");
|
||||
|
||||
// Figure out if they're all the same class
|
||||
// TODO: It'd be nicer to detect a common superclass
|
||||
@@ -1163,11 +1120,10 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
}
|
||||
a = (Object[])Array.newInstance(cl, 0);
|
||||
array = collection.toArray(a);
|
||||
assertEquals("toArray(Object[]) should return correct array type",
|
||||
a.getClass(), array.getClass());
|
||||
assertEquals("type-specific toArrays should be equal",
|
||||
Arrays.asList(array),
|
||||
Arrays.asList(collection.toArray()));
|
||||
assertEquals(a.getClass(), array.getClass(), "toArray(Object[]) should return correct array type");
|
||||
assertEquals(Arrays.asList(array),
|
||||
Arrays.asList(collection.toArray()),
|
||||
"type-specific toArrays should be equal");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -1178,12 +1134,10 @@ public abstract class CollectionAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testCollectionToString() {
|
||||
resetEmpty();
|
||||
assertTrue("toString shouldn't return null",
|
||||
collection.toString() != null);
|
||||
assertTrue(collection.toString() != null, "toString shouldn't return null");
|
||||
|
||||
resetFull();
|
||||
assertTrue("toString shouldn't return null",
|
||||
collection.toString() != null);
|
||||
assertTrue(collection.toString() != null, "toString shouldn't return null");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,13 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
/**
|
||||
* CollectionUtilTest
|
||||
*
|
||||
@@ -61,44 +59,60 @@ public class CollectionUtilTest {
|
||||
assertArrayEquals(new Object[] {"bar", "baz", 3}, merged);
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectBadOffset() {
|
||||
CollectionUtil.mergeArrays(stringObjects, 4, 2, integerObjects, 2, 1);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, 4, 2, integerObjects, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectBadSecondOffset() {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 4, 1);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 4, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectBadLength() {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 4, integerObjects, 2, 1);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 4, integerObjects, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectBadSecondLength() {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 2, 2);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 2, 2);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectNegativeOffset() {
|
||||
CollectionUtil.mergeArrays(stringObjects, -1, 2, integerObjects, 2, 1);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, -1, 2, integerObjects, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectNegativeSecondOffset() {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, -1, 1);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, -1, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectNegativeLength() {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, -1, integerObjects, 2, 1);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, -1, integerObjects, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IndexOutOfBoundsException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectNegativeSecondLength() {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 2, -1);
|
||||
assertThrows(IndexOutOfBoundsException.class, () -> {
|
||||
CollectionUtil.mergeArrays(stringObjects, 1, 2, integerObjects, 2, -1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -109,20 +123,24 @@ public class CollectionUtilTest {
|
||||
assertArrayEquals(new Object[] {"foo", "bar", "baz", 1, 2, 3}, merged);
|
||||
}
|
||||
|
||||
@Test(expected = ArrayStoreException.class)
|
||||
@Test
|
||||
public void testMergeArraysObjectIllegalType() {
|
||||
String[] strings = {"foo", "bar", "baz"};
|
||||
Integer[] integers = {1, 2, 3}; // Integer not assignable to String
|
||||
|
||||
CollectionUtil.mergeArrays(strings, integers);
|
||||
assertThrows(ArrayStoreException.class, () -> {
|
||||
CollectionUtil.mergeArrays(strings, integers);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = ArrayStoreException.class)
|
||||
@Test
|
||||
public void testMergeArraysNativeIllegalType() {
|
||||
char[] chars = {'a', 'b', 'c'};
|
||||
int[] integers = {1, 2, 3}; // Integer not assignable to String
|
||||
|
||||
CollectionUtil.mergeArrays(chars, integers);
|
||||
assertThrows(ArrayStoreException.class, () -> {
|
||||
CollectionUtil.mergeArrays(chars, integers);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -147,9 +165,11 @@ public class CollectionUtilTest {
|
||||
assertArrayEquals(new int[] {2, 3, 4}, numbers);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testEnumIteratorNull() {
|
||||
CollectionUtil.iterator((Enumeration<Object>) null);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
CollectionUtil.iterator((Enumeration<Object>) null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,9 +203,11 @@ public class CollectionUtilTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testArrayIteratorNull() {
|
||||
CollectionUtil.iterator((Object[]) null);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
CollectionUtil.iterator((Object[]) null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -262,7 +284,7 @@ public class CollectionUtilTest {
|
||||
|
||||
int count = 0;
|
||||
for (Object element : elements) {
|
||||
assertTrue("No next element for element '" + element + "' at index: " + count, iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "No next element for element '" + element + "' at index: " + count);
|
||||
assertEquals(count > 0, iterator.hasPrevious());
|
||||
assertEquals(count, iterator.nextIndex());
|
||||
assertEquals(count - 1, iterator.previousIndex());
|
||||
@@ -318,7 +340,7 @@ public class CollectionUtilTest {
|
||||
assertEquals(elements.length, iterator.nextIndex());
|
||||
|
||||
for (int i = count; i > 0; i--) {
|
||||
assertTrue("No previous element for element '" + elements[i - 1] + "' at index: " + (i - 1), iterator.hasPrevious());
|
||||
assertTrue(iterator.hasPrevious(), "No previous element for element '" + elements[i - 1] + "' at index: " + (i - 1));
|
||||
assertEquals(i < elements.length, iterator.hasNext());
|
||||
assertEquals(i - 1, iterator.previousIndex());
|
||||
assertEquals(i, iterator.nextIndex());
|
||||
@@ -339,18 +361,24 @@ public class CollectionUtilTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testArrayIteratorRangeNull() {
|
||||
CollectionUtil.iterator(null, 0, 0);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
CollectionUtil.iterator(null, 0, 0);
|
||||
});
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testArrayIteratorRangeBadStart() {
|
||||
CollectionUtil.iterator(stringObjects, stringObjects.length + 1, 2);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
CollectionUtil.iterator(stringObjects, stringObjects.length + 1, 2);
|
||||
});
|
||||
}
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testArrayIteratorRangeBadLength() {
|
||||
CollectionUtil.iterator(stringObjects, 1, stringObjects.length);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
CollectionUtil.iterator(stringObjects, 1, stringObjects.length);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -379,9 +407,11 @@ public class CollectionUtilTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testReverseOrderNull() {
|
||||
CollectionUtil.reverseOrder(null);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
CollectionUtil.reverseOrder(null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -431,7 +461,7 @@ public class CollectionUtilTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore("For development only")
|
||||
@Disabled("For development only")
|
||||
@Test
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public void testGenerify() {
|
||||
|
||||
@@ -45,11 +45,10 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests LRUMap.
|
||||
@@ -81,8 +80,8 @@ public class LRUMapTest extends LinkedMapTest {
|
||||
map2.put(4,"foo"); // removes 1 since max size exceeded
|
||||
map2.removeLRU(); // should be Integer(2)
|
||||
|
||||
assertTrue("Second to last value should exist",map2.get(new Integer(3)).equals("foo"));
|
||||
assertTrue("First value inserted should not exist", map2.get(new Integer(1)) == null);
|
||||
assertTrue(map2.get(new Integer(3)).equals("foo"), "Second to last value should exist");
|
||||
assertTrue(map2.get(new Integer(1)) == null, "First value inserted should not exist");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -93,8 +92,8 @@ public class LRUMapTest extends LinkedMapTest {
|
||||
map2.put(3,"foo");
|
||||
map2.put(4,"bar");
|
||||
|
||||
assertTrue("last value should exist",map2.get(new Integer(4)).equals("bar"));
|
||||
assertTrue("LRU should not exist", map2.get(new Integer(1)) == null);
|
||||
assertTrue(map2.get(new Integer(4)).equals("bar"), "last value should exist");
|
||||
assertTrue(map2.get(new Integer(1)) == null, "LRU should not exist");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,10 +112,8 @@ public class LRUMapTest extends LinkedMapTest {
|
||||
|
||||
map2.putAll(hashMap);
|
||||
|
||||
assertTrue("max size is 3, but actual size is " + map2.size(),
|
||||
map2.size() == 3);
|
||||
assertTrue("map should contain the Integer(4) object",
|
||||
map2.containsKey(new Integer(4)));
|
||||
assertTrue(map2.size() == 3, "max size is 3, but actual size is " + map2.size());
|
||||
assertTrue(map2.containsKey(new Integer(4)), "map should contain the Integer(4) object");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -134,8 +131,7 @@ public class LRUMapTest extends LinkedMapTest {
|
||||
map.put("6","6");
|
||||
map.setMaxSize(3);
|
||||
|
||||
assertTrue("map should have size = 3, but actually = " + map.size(),
|
||||
map.size() == 3);
|
||||
assertTrue(map.size() == 3, "map should have size = 3, but actually = " + map.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -160,9 +156,9 @@ public class LRUMapTest extends LinkedMapTest {
|
||||
keys[i] = keyIterator.next();
|
||||
}
|
||||
|
||||
assertTrue("first evicted should be 3, was " + keys[0], keys[0].equals("3"));
|
||||
assertTrue("second evicted should be 1, was " + keys[1], keys[1].equals("1"));
|
||||
assertTrue("third evicted should be 4, was " + keys[2], keys[2].equals("4"));
|
||||
assertTrue(keys[0].equals("3"), "first evicted should be 3, was " + keys[0]);
|
||||
assertTrue(keys[1].equals("1"), "second evicted should be 1, was " + keys[1]);
|
||||
assertTrue(keys[2].equals("4"), "third evicted should be 4, was " + keys[2]);
|
||||
|
||||
}
|
||||
|
||||
@@ -192,13 +188,12 @@ public class LRUMapTest extends LinkedMapTest {
|
||||
// 4 2
|
||||
counter.remove("5");
|
||||
|
||||
assertTrue("size should be 2, but was " + counter.size(), counter.size() == 2);
|
||||
assertTrue("removedCount should be 3 but was " + counter.removedCount,
|
||||
counter.removedCount == 3);
|
||||
assertTrue(counter.size() == 2, "size should be 2, but was " + counter.size());
|
||||
assertTrue(counter.removedCount == 3, "removedCount should be 3 but was " + counter.removedCount);
|
||||
|
||||
assertTrue("first removed was '2'",counter.list.get(0).equals("2"));
|
||||
assertTrue("second removed was '3'",counter.list.get(1).equals("3"));
|
||||
assertTrue("third removed was '1'",counter.list.get(2).equals("1"));
|
||||
assertTrue(counter.list.get(0).equals("2"), "first removed was '2'");
|
||||
assertTrue(counter.list.get(1).equals("3"), "second removed was '3'");
|
||||
assertTrue(counter.list.get(2).equals("1"), "third removed was '1'");
|
||||
|
||||
//assertTrue("oldest key is '4'",counter.get(0).equals("4"));
|
||||
//assertTrue("newest key is '2'",counter.get(1).equals("2"));
|
||||
|
||||
@@ -45,15 +45,11 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Unit tests
|
||||
@@ -74,7 +70,7 @@ public class LinkedMapTest extends MapAbstractTest {
|
||||
*/
|
||||
protected LinkedMap labRat;
|
||||
|
||||
@Before
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception {
|
||||
// use makeMap and cast the result to a SeqHashMap
|
||||
// so that subclasses of SeqHashMap can share these tests
|
||||
@@ -103,27 +99,21 @@ public class LinkedMapTest extends MapAbstractTest {
|
||||
}
|
||||
|
||||
// Test size().
|
||||
assertEquals("size() does not match expected size",
|
||||
expectedSize, labRat.size());
|
||||
assertEquals(expectedSize, labRat.size(), "size() does not match expected size");
|
||||
|
||||
// Test clone(), iterator(), and get(Object).
|
||||
LinkedMap clone = (LinkedMap) labRat.clone();
|
||||
assertEquals("Size of clone does not match original",
|
||||
labRat.size(), clone.size());
|
||||
assertEquals(labRat.size(), clone.size(), "Size of clone does not match original");
|
||||
Iterator origEntries = labRat.entrySet().iterator();
|
||||
Iterator copiedEntries = clone.entrySet().iterator();
|
||||
while (origEntries.hasNext()) {
|
||||
Map.Entry origEntry = (Map.Entry)origEntries.next();
|
||||
Map.Entry copiedEntry = (Map.Entry)copiedEntries.next();
|
||||
assertEquals("Cloned key does not match original",
|
||||
origEntry.getKey(), copiedEntry.getKey());
|
||||
assertEquals("Cloned value does not match original",
|
||||
origEntry.getValue(), copiedEntry.getValue());
|
||||
assertEquals("Cloned entry does not match original",
|
||||
origEntry, copiedEntry);
|
||||
assertEquals(origEntry.getKey(), copiedEntry.getKey(), "Cloned key does not match original");
|
||||
assertEquals(origEntry.getValue(), copiedEntry.getValue(), "Cloned value does not match original");
|
||||
assertEquals(origEntry, copiedEntry, "Cloned entry does not match original");
|
||||
}
|
||||
assertTrue("iterator() returned different number of elements than keys()",
|
||||
!copiedEntries.hasNext());
|
||||
assertTrue(!copiedEntries.hasNext(), "iterator() returned different number of elements than keys()");
|
||||
|
||||
// Test sequence()
|
||||
/*
|
||||
@@ -207,7 +197,7 @@ public class LinkedMapTest extends MapAbstractTest {
|
||||
}
|
||||
*/
|
||||
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() throws Exception {
|
||||
labRat = null;
|
||||
}
|
||||
|
||||
@@ -45,12 +45,10 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Abstract test class for {@link java.util.Map} methods and contracts.
|
||||
@@ -390,19 +388,19 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
m.put(keys[i], values[i]);
|
||||
}
|
||||
catch (NullPointerException exception) {
|
||||
assertTrue("NullPointerException only allowed to be thrown if either the key or value is null.",
|
||||
keys[i] == null || values[i] == null);
|
||||
assertTrue(keys[i] == null || values[i] == null,
|
||||
"NullPointerException only allowed to be thrown if either the key or value is null.");
|
||||
|
||||
assertTrue("NullPointerException on null key, but isAllowNullKey is not overridden to return false.",
|
||||
keys[i] == null || !isAllowNullKey());
|
||||
assertTrue(keys[i] == null || !isAllowNullKey(),
|
||||
"NullPointerException on null key, but isAllowNullKey is not overridden to return false.");
|
||||
|
||||
assertTrue("NullPointerException on null value, but isAllowNullValue is not overridden to return false.",
|
||||
values[i] == null || !isAllowNullValue());
|
||||
assertTrue(values[i] == null || !isAllowNullValue(),
|
||||
"NullPointerException on null value, but isAllowNullValue is not overridden to return false.");
|
||||
|
||||
assertTrue("Unknown reason for NullPointer.", false);
|
||||
fail("Unknown reason for NullPointer.");
|
||||
}
|
||||
}
|
||||
assertEquals("size must reflect number of mappings added.", keys.length, m.size());
|
||||
assertEquals(keys.length, m.size(), "size must reflect number of mappings added.");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -481,27 +479,26 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
Object[] values = getSampleValues();
|
||||
Object[] newValues = getNewSampleValues();
|
||||
|
||||
assertTrue("failure in test: Must have keys returned from getSampleKeys.", keys != null);
|
||||
assertTrue("failure in test: Must have values returned from getSampleValues.", values != null);
|
||||
assertTrue(keys != null, "failure in test: Must have keys returned from getSampleKeys.");
|
||||
assertTrue(values != null, "failure in test: Must have values returned from getSampleValues.");
|
||||
|
||||
// verify keys and values have equivalent lengths (in case getSampleX are
|
||||
// overridden)
|
||||
assertEquals("failure in test: not the same number of sample keys and values.", keys.length, values.length);
|
||||
assertEquals("failure in test: not the same number of values and new values.", values.length, newValues.length);
|
||||
assertEquals(keys.length, values.length, "failure in test: not the same number of sample keys and values.");
|
||||
assertEquals(values.length, newValues.length, "failure in test: not the same number of values and new values.");
|
||||
|
||||
// verify there aren't duplicate keys, and check values
|
||||
for (int i = 0; i < keys.length - 1; i++) {
|
||||
for (int j = i + 1; j < keys.length; j++) {
|
||||
assertTrue("failure in test: duplicate null keys.", (keys[i] != null || keys[j] != null));
|
||||
assertTrue("failure in test: duplicate non-null key.",
|
||||
(keys[i] == null || keys[j] == null || (!keys[i].equals(keys[j]) && !keys[j].equals(keys[i]))));
|
||||
assertTrue((keys[i] != null || keys[j] != null), "failure in test: duplicate null keys.");
|
||||
assertTrue((keys[i] == null || keys[j] == null || (!keys[i].equals(keys[j]) && !keys[j].equals(keys[i]))),
|
||||
"failure in test: duplicate non-null key.");
|
||||
}
|
||||
|
||||
assertTrue("failure in test: found null key, but isNullKeySupported is false.", keys[i] != null || isAllowNullKey());
|
||||
assertTrue("failure in test: found null value, but isNullValueSupported is false.", values[i] != null || isAllowNullValue());
|
||||
assertTrue("failure in test: found null new value, but isNullValueSupported is false.", newValues[i] != null || isAllowNullValue());
|
||||
assertTrue("failure in test: values should not be the same as new value",
|
||||
values[i] != newValues[i] && (values[i] == null || !values[i].equals(newValues[i])));
|
||||
assertTrue(keys[i] != null || isAllowNullKey(),"failure in test: found null key, but isNullKeySupported is false.");
|
||||
assertTrue(values[i] != null || isAllowNullValue(),"failure in test: found null value, but isNullValueSupported is false.");
|
||||
assertTrue(newValues[i] != null || isAllowNullValue(), "failure in test: found null new value, but isNullValueSupported is false.");
|
||||
assertTrue(values[i] != newValues[i] && (values[i] == null || !values[i].equals(newValues[i])), "failure in test: values should not be the same as new value");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,18 +514,18 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testMakeMap() {
|
||||
Map em = makeEmptyMap();
|
||||
assertTrue("failure in test: makeEmptyMap must return a non-null map.", em != null);
|
||||
assertTrue(em != null, "failure in test: makeEmptyMap must return a non-null map.");
|
||||
|
||||
Map em2 = makeEmptyMap();
|
||||
assertTrue("failure in test: makeEmptyMap must return a non-null map.", em2 != null);
|
||||
assertTrue("failure in test: makeEmptyMap must return a new map with each invocation.", em != em2);
|
||||
assertTrue(em2 != null, "failure in test: makeEmptyMap must return a non-null map.");
|
||||
assertTrue(em != em2, "failure in test: makeEmptyMap must return a new map with each invocation.");
|
||||
|
||||
Map fm = makeFullMap();
|
||||
assertTrue("failure in test: makeFullMap must return a non-null map.", fm != null);
|
||||
assertTrue(fm != null, "failure in test: makeFullMap must return a non-null map.");
|
||||
|
||||
Map fm2 = makeFullMap();
|
||||
assertTrue("failure in test: makeFullMap must return a non-null map.", fm2 != null);
|
||||
assertTrue("failure in test: makeFullMap must return a new map with each invocation.", fm != fm2);
|
||||
assertTrue(fm2 != null, "failure in test: makeFullMap must return a non-null map.");
|
||||
assertTrue(fm != fm2, "failure in test: makeFullMap must return a new map with each invocation.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -537,11 +534,11 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testMapIsEmpty() {
|
||||
resetEmpty();
|
||||
assertEquals("Map.isEmpty() should return true with an empty map", true, map.isEmpty());
|
||||
assertEquals(true, map.isEmpty(), "Map.isEmpty() should return true with an empty map");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertEquals("Map.isEmpty() should return false with a non-empty map", false, map.isEmpty());
|
||||
assertEquals(false, map.isEmpty(), "Map.isEmpty() should return false with a non-empty map");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -551,11 +548,11 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testMapSize() {
|
||||
resetEmpty();
|
||||
assertEquals("Map.size() should be 0 with an empty map", 0, map.size());
|
||||
assertEquals(0, map.size(), "Map.size() should be 0 with an empty map");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertEquals("Map.size() should equal the number of entries in the map", getSampleKeys().length, map.size());
|
||||
assertEquals(getSampleKeys().length, map.size(), "Map.size() should equal the number of entries in the map");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -602,13 +599,13 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
resetEmpty();
|
||||
for (Object key : keys) {
|
||||
assertTrue("Map must not contain key when map is empty", !map.containsKey(key));
|
||||
assertTrue(!map.containsKey(key), "Map must not contain key when map is empty");
|
||||
}
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
for (Object key : keys) {
|
||||
assertTrue("Map must contain key for a mapping in the map. Missing: " + key, map.containsKey(key));
|
||||
assertTrue(map.containsKey(key), "Map must contain key for a mapping in the map. Missing: " + key);
|
||||
}
|
||||
verifyAll();
|
||||
}
|
||||
@@ -624,13 +621,13 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
|
||||
resetEmpty();
|
||||
for (Object value : values) {
|
||||
assertTrue("Empty map must not contain value", !map.containsValue(value));
|
||||
assertTrue(!map.containsValue(value), "Empty map must not contain value");
|
||||
}
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
for (Object value : values) {
|
||||
assertTrue("Map must contain value for a mapping in the map.", map.containsValue(value));
|
||||
assertTrue(map.containsValue(value), "Map must contain value for a mapping in the map.");
|
||||
}
|
||||
verifyAll();
|
||||
}
|
||||
@@ -641,11 +638,11 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testMapEquals() {
|
||||
resetEmpty();
|
||||
assertTrue("Empty maps unequal.", map.equals(confirmed));
|
||||
assertTrue(map.equals(confirmed), "Empty maps unequal.");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertTrue("Full maps unequal.", map.equals(confirmed));
|
||||
assertTrue(map.equals(confirmed), "Full maps unequal.");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
@@ -654,11 +651,11 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
Iterator iter = confirmed.keySet().iterator();
|
||||
iter.next();
|
||||
iter.remove();
|
||||
assertTrue("Different maps equal.", !map.equals(confirmed));
|
||||
assertTrue(!map.equals(confirmed), "Different maps equal.");
|
||||
|
||||
resetFull();
|
||||
assertTrue("equals(null) returned true.", !map.equals(null));
|
||||
assertTrue("equals(new Object()) returned true.", !map.equals(new Object()));
|
||||
assertTrue(!map.equals(null), "equals(null) returned true.");
|
||||
assertTrue(!map.equals(new Object()), "equals(new Object()) returned true.");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -673,14 +670,14 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
Object[] values = getSampleValues();
|
||||
|
||||
for (Object key : keys) {
|
||||
assertTrue("Empty map.get() should return null.", map.get(key) == null);
|
||||
assertTrue(map.get(key) == null, "Empty map.get() should return null.");
|
||||
}
|
||||
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
assertEquals("Full map.get() should return value from mapping.", values[i], map.get(keys[i]));
|
||||
assertEquals(values[i], map.get(keys[i]), "Full map.get() should return value from mapping.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -690,10 +687,10 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testMapHashCode() {
|
||||
resetEmpty();
|
||||
assertTrue("Empty maps have different hashCodes.", map.hashCode() == confirmed.hashCode());
|
||||
assertTrue(map.hashCode() == confirmed.hashCode(), "Empty maps have different hashCodes.");
|
||||
|
||||
resetFull();
|
||||
assertTrue("Equal maps have different hashCodes.", map.hashCode() == confirmed.hashCode());
|
||||
assertTrue(map.hashCode() == confirmed.hashCode(), "Equal maps have different hashCodes.");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -708,11 +705,11 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
@Test
|
||||
public void testMapToString() {
|
||||
resetEmpty();
|
||||
assertTrue("Empty map toString() should not return null", map.toString() != null);
|
||||
assertTrue(map.toString() != null, "Empty map toString() should not return null");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertTrue("Empty map toString() should not return null", map.toString() != null);
|
||||
assertTrue(map.toString() != null, "Empty map toString() should not return null");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -776,29 +773,23 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
Object o = map.put(keys[i], values[i]);
|
||||
confirmed.put(keys[i], values[i]);
|
||||
verifyAll();
|
||||
assertTrue("First map.put should return null", o == null);
|
||||
assertTrue("Map should contain key after put",
|
||||
map.containsKey(keys[i]));
|
||||
assertTrue("Map should contain value after put",
|
||||
map.containsValue(values[i]));
|
||||
assertTrue(o == null, "First map.put should return null");
|
||||
assertTrue(map.containsKey(keys[i]), "Map should contain key after put");
|
||||
assertTrue(map.containsValue(values[i]), "Map should contain value after put");
|
||||
}
|
||||
if (isPutChangeSupported()) {
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
Object o = map.put(keys[i], newValues[i]);
|
||||
confirmed.put(keys[i], newValues[i]);
|
||||
verifyAll();
|
||||
assertEquals("Map.put should return previous value when changed",
|
||||
values[i], o);
|
||||
assertTrue("Map should still contain key after put when changed",
|
||||
map.containsKey(keys[i]));
|
||||
assertTrue("Map should contain new value after put when changed",
|
||||
map.containsValue(newValues[i]));
|
||||
assertEquals(values[i], o, "Map.put should return previous value when changed");
|
||||
assertTrue(map.containsKey(keys[i]), "Map should still contain key after put when changed");
|
||||
assertTrue(map.containsValue(newValues[i]), "Map should contain new value after put when changed");
|
||||
|
||||
// if duplicates are allowed, we're not guaranteed that the value
|
||||
// no longer exists, so don't try checking that.
|
||||
if (!isAllowDuplicateValues()) {
|
||||
assertTrue("Map should not contain old value after put when changed",
|
||||
!map.containsValue(values[i]));
|
||||
assertTrue(!map.containsValue(values[i]), "Map should not contain old value after put when changed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -832,18 +823,14 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
Object o = map.put(key, newValues[i]);
|
||||
Object value = confirmed.put(key, newValues[i]);
|
||||
verifyAll();
|
||||
assertEquals("Map.put should return previous value when changed",
|
||||
value, o);
|
||||
assertTrue("Map should still contain key after put when changed",
|
||||
map.containsKey(key));
|
||||
assertTrue("Map should contain new value after put when changed",
|
||||
map.containsValue(newValues[i]));
|
||||
assertEquals(value, o, "Map.put should return previous value when changed");
|
||||
assertTrue(map.containsKey(key), "Map should still contain key after put when changed");
|
||||
assertTrue(map.containsValue(newValues[i]), "Map should contain new value after put when changed");
|
||||
|
||||
// if duplicates are allowed, we're not guaranteed that the value
|
||||
// no longer exists, so don't try checking that.
|
||||
if (!isAllowDuplicateValues()) {
|
||||
assertTrue("Map should not contain old value after put when changed",
|
||||
!map.containsValue(values[i]));
|
||||
assertTrue(!map.containsValue(values[i]), "Map should not contain old value after put when changed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -970,7 +957,7 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
Object[] values = getSampleValues();
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
Object o = map.remove(keys[i]);
|
||||
assertTrue("First map.remove should return null", o == null);
|
||||
assertTrue(o == null, "First map.remove should return null");
|
||||
}
|
||||
verifyAll();
|
||||
|
||||
@@ -981,8 +968,7 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
confirmed.remove(keys[i]);
|
||||
verifyAll();
|
||||
|
||||
assertEquals("map.remove with valid key should return value",
|
||||
values[i], o);
|
||||
assertEquals(values[i], o, "map.remove with valid key should return value");
|
||||
}
|
||||
|
||||
Object[] other = getOtherKeys();
|
||||
@@ -991,10 +977,8 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
int size = map.size();
|
||||
for (int i = 0; i < other.length; i++) {
|
||||
Object o = map.remove(other[i]);
|
||||
assertEquals("map.remove for nonexistent key should return null",
|
||||
o, null);
|
||||
assertEquals("map.remove for nonexistent key should not " +
|
||||
"shrink map", size, map.size());
|
||||
assertEquals(o, null, "map.remove for nonexistent key should return null");
|
||||
assertEquals(size, map.size(), "map.remove for nonexistent key should not shrink map");
|
||||
}
|
||||
verifyAll();
|
||||
}
|
||||
@@ -1204,10 +1188,9 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
}
|
||||
j++;
|
||||
}
|
||||
assertTrue("values().remove(obj) is broken", j < 10000);
|
||||
assertTrue(
|
||||
"Value should have been removed from the underlying map.",
|
||||
!map.containsValue(sampleValues[i]));
|
||||
assertTrue(j < 10000, "values().remove(obj) is broken");
|
||||
assertTrue(!map.containsValue(sampleValues[i]),
|
||||
"Value should have been removed from the underlying map.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1230,9 +1213,8 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
// if key.remove is unsupported, just skip this test
|
||||
return;
|
||||
}
|
||||
assertTrue(
|
||||
"Key should have been removed from the underlying map.",
|
||||
!map.containsKey(sampleKeys[i]));
|
||||
assertTrue(!map.containsKey(sampleKeys[i]),
|
||||
"Key should have been removed from the underlying map.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1413,7 +1395,7 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertNotNull("No matching entry in map for key '" + key + "'", entry);
|
||||
assertNotNull(entry, "No matching entry in map for key '" + key + "'");
|
||||
return entry;
|
||||
}
|
||||
|
||||
@@ -1638,14 +1620,14 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
public void verifyMap() {
|
||||
int size = confirmed.size();
|
||||
boolean empty = confirmed.isEmpty();
|
||||
assertEquals("Map should be same size as HashMap", size, map.size());
|
||||
assertEquals("Map should be empty if HashMap is", empty, map.isEmpty());
|
||||
assertEquals("hashCodes should be the same", confirmed.hashCode(), map.hashCode());
|
||||
assertEquals(size, map.size(), "Map should be same size as HashMap");
|
||||
assertEquals(empty, map.isEmpty(), "Map should be empty if HashMap is");
|
||||
assertEquals(confirmed.hashCode(), map.hashCode(), "hashCodes should be the same");
|
||||
// this fails for LRUMap because confirmed.equals() somehow modifies
|
||||
// map, causing concurrent modification exceptions.
|
||||
//assertEquals("Map should still equal HashMap", confirmed, map);
|
||||
// this works though and performs the same verification:
|
||||
assertTrue("Map should still equal HashMap", map.equals(confirmed));
|
||||
assertTrue(map.equals(confirmed), "Map should still equal HashMap");
|
||||
// TODO: this should really be reexamined to figure out why LRU map
|
||||
// behaves like it does (the equals shouldn't modify since all accesses
|
||||
// by the confirmed collection should be through an iterator, thus not
|
||||
@@ -1655,29 +1637,29 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
public void verifyEntrySet() {
|
||||
int size = confirmed.size();
|
||||
boolean empty = confirmed.isEmpty();
|
||||
assertEquals("entrySet should be same size as HashMap's\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(),
|
||||
size, entrySet.size());
|
||||
assertEquals("entrySet should be empty if HashMap is\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(),
|
||||
empty, entrySet.isEmpty());
|
||||
assertTrue("entrySet should contain all HashMap's elements\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(),
|
||||
entrySet.containsAll(confirmed.entrySet()));
|
||||
assertEquals("entrySet hashCodes should be the same\nTest: " + entrySet + "\nReal: " + confirmed.entrySet(),
|
||||
confirmed.entrySet().hashCode(), entrySet.hashCode());
|
||||
assertEquals("Map's entry set should still equal HashMap's", confirmed.entrySet(), entrySet);
|
||||
assertEquals(size, entrySet.size(),
|
||||
"entrySet should be same size as HashMap's\nTest: " + entrySet + "\nReal: " + confirmed.entrySet());
|
||||
assertEquals(empty, entrySet.isEmpty(),
|
||||
"entrySet should be empty if HashMap is\nTest: " + entrySet + "\nReal: " + confirmed.entrySet());
|
||||
assertTrue(entrySet.containsAll(confirmed.entrySet()),
|
||||
"entrySet should contain all HashMap's elements\nTest: " + entrySet + "\nReal: " + confirmed.entrySet());
|
||||
assertEquals(confirmed.entrySet().hashCode(), entrySet.hashCode(),
|
||||
"entrySet hashCodes should be the same\nTest: " + entrySet + "\nReal: " + confirmed.entrySet());
|
||||
assertEquals(confirmed.entrySet(), entrySet,"Map's entry set should still equal HashMap's");
|
||||
}
|
||||
|
||||
public void verifyKeySet() {
|
||||
int size = confirmed.size();
|
||||
boolean empty = confirmed.isEmpty();
|
||||
assertEquals("keySet should be same size as HashMap's\nTest: " + keySet + "\nReal: " + confirmed.keySet(),
|
||||
size, keySet.size());
|
||||
assertEquals("keySet should be empty if HashMap is\nTest: " + keySet + "\nReal: " + confirmed.keySet(),
|
||||
empty, keySet.isEmpty());
|
||||
assertTrue("keySet should contain all HashMap's elements\nTest: " + keySet + "\nReal: " + confirmed.keySet(),
|
||||
keySet.containsAll(confirmed.keySet()));
|
||||
assertEquals("keySet hashCodes should be the same\nTest: " + keySet + "\nReal: " + confirmed.keySet(),
|
||||
confirmed.keySet().hashCode(), keySet.hashCode());
|
||||
assertEquals("Map's key set should still equal HashMap's", confirmed.keySet(), keySet);
|
||||
assertEquals(size, keySet.size(),
|
||||
"keySet should be same size as HashMap's\nTest: " + keySet + "\nReal: " + confirmed.keySet());
|
||||
assertEquals(empty, keySet.isEmpty(),
|
||||
"keySet should be empty if HashMap is\nTest: " + keySet + "\nReal: " + confirmed.keySet());
|
||||
assertTrue(keySet.containsAll(confirmed.keySet()),
|
||||
"keySet should contain all HashMap's elements\nTest: " + keySet + "\nReal: " + confirmed.keySet());
|
||||
assertEquals(confirmed.keySet().hashCode(), keySet.hashCode(),
|
||||
"keySet hashCodes should be the same\nTest: " + keySet + "\nReal: " + confirmed.keySet());
|
||||
assertEquals(confirmed.keySet(), keySet, "Map's key set should still equal HashMap's");
|
||||
}
|
||||
|
||||
public void verifyValues() {
|
||||
@@ -1687,23 +1669,23 @@ public abstract class MapAbstractTest extends ObjectAbstractTest {
|
||||
int size = confirmed.size();
|
||||
boolean empty = confirmed.isEmpty();
|
||||
|
||||
assertEquals("values should be same size as HashMap's\nTest: " + test + "\nReal: " + known, size, values.size());
|
||||
assertEquals("values should be empty if HashMap is\nTest: " + test + "\nReal: " + known, empty, values.isEmpty());
|
||||
assertTrue("values should contain all HashMap's elements\nTest: " + test + "\nReal: " + known, test.containsAll(known));
|
||||
assertTrue("values should contain all HashMap's elements\nTest: " + test + "\nReal: " + known, known.containsAll(test));
|
||||
assertEquals(size, values.size(), "values should be same size as HashMap's\nTest: " + test + "\nReal: " + known);
|
||||
assertEquals(empty, values.isEmpty(), "values should be empty if HashMap is\nTest: " + test + "\nReal: " + known);
|
||||
assertTrue(test.containsAll(known), "values should contain all HashMap's elements\nTest: " + test + "\nReal: " + known);
|
||||
assertTrue(known.containsAll(test), "values should contain all HashMap's elements\nTest: " + test + "\nReal: " + known);
|
||||
|
||||
for (Object aKnown : known) {
|
||||
boolean removed = test.remove(aKnown);
|
||||
assertTrue("Map's values should still equal HashMap's", removed);
|
||||
assertTrue(removed, "Map's values should still equal HashMap's");
|
||||
}
|
||||
|
||||
assertTrue("Map's values should still equal HashMap's", test.isEmpty());
|
||||
assertTrue(test.isEmpty(), "Map's values should still equal HashMap's");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erases any leftover instance variables by setting them to null.
|
||||
*/
|
||||
@After
|
||||
@AfterEach
|
||||
public void tearDown() throws Exception {
|
||||
map = null;
|
||||
keySet = null;
|
||||
|
||||
@@ -30,13 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* NOTE: This TestCase is written especially for NullMap, and is full of dirty
|
||||
@@ -83,12 +81,12 @@ public class NullMapTest extends MapAbstractTest {
|
||||
@Override
|
||||
public void testMapIsEmpty() {
|
||||
resetEmpty();
|
||||
assertEquals("Map.isEmpty() should return true with an empty map",
|
||||
true, map.isEmpty());
|
||||
assertEquals(true, map.isEmpty(),
|
||||
"Map.isEmpty() should return true with an empty map");
|
||||
verifyAll();
|
||||
resetFull();
|
||||
assertEquals("Map.isEmpty() should return true with a full map",
|
||||
true, map.isEmpty());
|
||||
assertEquals(true, map.isEmpty(),
|
||||
"Map.isEmpty() should return true with a full map");
|
||||
}
|
||||
|
||||
// Overriden, as this map is always empty
|
||||
@@ -96,13 +94,13 @@ public class NullMapTest extends MapAbstractTest {
|
||||
@Override
|
||||
public void testMapSize() {
|
||||
resetEmpty();
|
||||
assertEquals("Map.size() should be 0 with an empty map",
|
||||
0, map.size());
|
||||
assertEquals(0, map.size(),
|
||||
"Map.size() should be 0 with an empty map");
|
||||
verifyAll();
|
||||
|
||||
resetFull();
|
||||
assertEquals("Map.size() should equal the number of entries " +
|
||||
"in the map", 0, map.size());
|
||||
assertEquals(0, map.size(),
|
||||
"Map.size() should equal the number of entries in the map");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,7 +110,7 @@ public class NullMapTest extends MapAbstractTest {
|
||||
|
||||
resetEmpty();
|
||||
for (Object key : keys) {
|
||||
assertTrue("Map must not contain key when map is empty", !map.containsKey(key));
|
||||
assertTrue(!map.containsKey(key),"Map must not contain key when map is empty");
|
||||
}
|
||||
verifyAll();
|
||||
}
|
||||
@@ -124,7 +122,7 @@ public class NullMapTest extends MapAbstractTest {
|
||||
|
||||
resetEmpty();
|
||||
for (Object value : values) {
|
||||
assertTrue("Empty map must not contain value", !map.containsValue(value));
|
||||
assertTrue(!map.containsValue(value), "Empty map must not contain value");
|
||||
}
|
||||
verifyAll();
|
||||
}
|
||||
@@ -133,7 +131,7 @@ public class NullMapTest extends MapAbstractTest {
|
||||
@Override
|
||||
public void testMapEquals() {
|
||||
resetEmpty();
|
||||
assertTrue("Empty maps unequal.", map.equals(confirmed));
|
||||
assertTrue(map.equals(confirmed), "Empty maps unequal.");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -141,8 +139,7 @@ public class NullMapTest extends MapAbstractTest {
|
||||
@Override
|
||||
public void testMapHashCode() {
|
||||
resetEmpty();
|
||||
assertTrue("Empty maps have different hashCodes.",
|
||||
map.hashCode() == confirmed.hashCode());
|
||||
assertTrue(map.hashCode() == confirmed.hashCode(), "Empty maps have different hashCodes.");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,7 +150,7 @@ public class NullMapTest extends MapAbstractTest {
|
||||
Object[] keys = getSampleKeys();
|
||||
|
||||
for (Object key : keys) {
|
||||
assertTrue("Empty map.get() should return null.", map.get(key) == null);
|
||||
assertTrue(map.get(key) == null, "Empty map.get() should return null.");
|
||||
}
|
||||
verifyAll();
|
||||
}
|
||||
@@ -170,7 +167,7 @@ public class NullMapTest extends MapAbstractTest {
|
||||
Object o = map.put(keys[i], values[i]);
|
||||
//confirmed.put(keys[i], values[i]);
|
||||
verifyAll();
|
||||
assertTrue("First map.put should return null", o == null);
|
||||
assertTrue(o == null, "First map.put should return null");
|
||||
}
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
map.put(keys[i], newValues[i]);
|
||||
@@ -183,8 +180,8 @@ public class NullMapTest extends MapAbstractTest {
|
||||
@Override
|
||||
public void testMapToString() {
|
||||
resetEmpty();
|
||||
assertTrue("Empty map toString() should not return null",
|
||||
map.toString() != null);
|
||||
assertTrue(map.toString() != null,
|
||||
"Empty map toString() should not return null");
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -202,7 +199,7 @@ public class NullMapTest extends MapAbstractTest {
|
||||
Object[] keys = getSampleKeys();
|
||||
for(int i = 0; i < keys.length; i++) {
|
||||
Object o = map.remove(keys[i]);
|
||||
assertTrue("First map.remove should return null", o == null);
|
||||
assertTrue(o == null, "First map.remove should return null");
|
||||
}
|
||||
verifyAll();
|
||||
}
|
||||
|
||||
@@ -44,12 +44,10 @@
|
||||
*/
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Abstract test class for {@link Object} methods and contracts.
|
||||
@@ -119,7 +117,7 @@ public abstract class ObjectAbstractTest {
|
||||
@Test
|
||||
public void testObjectEqualsSelf() {
|
||||
Object obj = makeObject();
|
||||
assertEquals("A Object should equal itself", obj, obj);
|
||||
assertEquals(obj, obj, "A Object should equal itself");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,25 +129,24 @@ public abstract class ObjectAbstractTest {
|
||||
@Test
|
||||
public void testObjectHashCodeEqualsSelfHashCode() {
|
||||
Object obj = makeObject();
|
||||
assertEquals("hashCode should be repeatable", obj.hashCode(), obj.hashCode());
|
||||
assertEquals(obj.hashCode(), obj.hashCode(), "hashCode should be repeatable");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testObjectHashCodeEqualsContract() {
|
||||
Object obj1 = makeObject();
|
||||
if (obj1.equals(obj1)) {
|
||||
assertEquals(
|
||||
"[1] When two objects are equal, their hashCodes should be also.",
|
||||
obj1.hashCode(), obj1.hashCode());
|
||||
assertEquals(obj1.hashCode(), obj1.hashCode(),
|
||||
"[1] When two objects are equal, their hashCodes should be also.");
|
||||
}
|
||||
Object obj2 = makeObject();
|
||||
if (obj1.equals(obj2)) {
|
||||
assertEquals(
|
||||
"[2] When two objects are equal, their hashCodes should be also.",
|
||||
obj1.hashCode(), obj2.hashCode());
|
||||
obj1.hashCode(), obj2.hashCode(),
|
||||
"[2] When two objects are equal, their hashCodes should be also.");
|
||||
assertTrue(
|
||||
"When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true",
|
||||
obj2.equals(obj1));
|
||||
obj2.equals(obj1),
|
||||
"When obj1.equals(obj2) is true, then obj2.equals(obj1) should also be true");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,7 +163,7 @@ public abstract class ObjectAbstractTest {
|
||||
Object dest = in.readObject();
|
||||
in.close();
|
||||
if (isEqualsCheckable()) {
|
||||
assertEquals("obj != deserialize(serialize(obj))", obj, dest);
|
||||
assertEquals(obj, dest, "obj != deserialize(serialize(obj))");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,8 +196,8 @@ public abstract class ObjectAbstractTest {
|
||||
if (object instanceof Serializable) {
|
||||
String name = getCanonicalEmptyCollectionName(object);
|
||||
assertTrue(
|
||||
"Canonical empty collection (" + name + ") is not in CVS",
|
||||
new File(name).exists());
|
||||
new File(name).exists(),
|
||||
"Canonical empty collection (" + name + ") is not in CVS");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,8 +213,8 @@ public abstract class ObjectAbstractTest {
|
||||
if (object instanceof Serializable) {
|
||||
String name = getCanonicalFullCollectionName(object);
|
||||
assertTrue(
|
||||
"Canonical full collection (" + name + ") is not in CVS",
|
||||
new File(name).exists());
|
||||
new File(name).exists(),
|
||||
"Canonical full collection (" + name + ") is not in CVS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,12 +44,10 @@
|
||||
*/
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Abstract test class for {@link Set} methods and contracts.
|
||||
@@ -79,14 +77,12 @@ public abstract class SetAbstractTest extends CollectionAbstractTest {
|
||||
public void verifyAll() {
|
||||
super.verifyAll();
|
||||
|
||||
assertEquals("Sets should be equal", confirmed, collection);
|
||||
assertEquals("Sets should have equal hashCodes",
|
||||
confirmed.hashCode(), collection.hashCode());
|
||||
assertEquals(confirmed, collection, "Sets should be equal");
|
||||
assertEquals(confirmed.hashCode(), collection.hashCode(), "Sets should have equal hashCodes");
|
||||
Collection set = makeConfirmedCollection();
|
||||
Iterator iterator = collection.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
assertTrue("Set.iterator should only return unique elements",
|
||||
set.add(iterator.next()));
|
||||
assertTrue(set.add(iterator.next()), "Set.iterator should only return unique elements");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,23 +176,20 @@ public abstract class SetAbstractTest extends CollectionAbstractTest {
|
||||
@Test
|
||||
public void testSetEquals() {
|
||||
resetEmpty();
|
||||
assertEquals("Empty sets should be equal",
|
||||
getSet(), getConfirmedSet());
|
||||
assertEquals(getSet(), getConfirmedSet(), "Empty sets should be equal");
|
||||
verifyAll();
|
||||
|
||||
Collection set2 = makeConfirmedCollection();
|
||||
set2.add("foo");
|
||||
assertTrue("Empty set shouldn't equal nonempty set",
|
||||
!getSet().equals(set2));
|
||||
assertTrue(!getSet().equals(set2), "Empty set shouldn't equal nonempty set");
|
||||
|
||||
resetFull();
|
||||
assertEquals("Full sets should be equal", getSet(), getConfirmedSet());
|
||||
assertEquals(getSet(), getConfirmedSet(), "Full sets should be equal");
|
||||
verifyAll();
|
||||
|
||||
set2.clear();
|
||||
set2.addAll(Arrays.asList(getOtherElements()));
|
||||
assertTrue("Sets with different contents shouldn't be equal",
|
||||
!getSet().equals(set2));
|
||||
assertTrue(!getSet().equals(set2), "Sets with different contents shouldn't be equal");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,11 +198,9 @@ public abstract class SetAbstractTest extends CollectionAbstractTest {
|
||||
@Test
|
||||
public void testSetHashCode() {
|
||||
resetEmpty();
|
||||
assertEquals("Empty sets have equal hashCodes",
|
||||
getSet().hashCode(), getConfirmedSet().hashCode());
|
||||
assertEquals(getSet().hashCode(), getConfirmedSet().hashCode(), "Empty sets have equal hashCodes");
|
||||
|
||||
resetFull();
|
||||
assertEquals("Equal sets have equal hashCodes",
|
||||
getSet().hashCode(), getConfirmedSet().hashCode());
|
||||
assertEquals(getSet().hashCode(), getConfirmedSet().hashCode(), "Equal sets have equal hashCodes");
|
||||
}
|
||||
}
|
||||
|
||||
+30
-32
@@ -30,12 +30,10 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* StringTokenIteratorTestCase
|
||||
@@ -56,88 +54,88 @@ public class StringTokenIteratorTest extends TokenIteratorAbstractTest {
|
||||
@Test
|
||||
public void testEmptyDelimiter() {
|
||||
Iterator iterator = createTokenIterator("", "");
|
||||
assertFalse("Empty string has elements", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "Empty string has elements");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleToken() {
|
||||
Iterator iterator = createTokenIterator("A");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleTokenEmptyDelimiter() {
|
||||
Iterator iterator = createTokenIterator("A", "");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleTokenSingleDelimiter() {
|
||||
Iterator iterator = createTokenIterator("A", ",");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleSeparatorDefaultDelimiter() {
|
||||
Iterator iterator = createTokenIterator("A B C D");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("D", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleSeparator() {
|
||||
Iterator iterator = createTokenIterator("A,B,C", ",");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleSeparatorDefaultDelimiter() {
|
||||
Iterator iterator = createTokenIterator("A B C\nD\t\t \nE");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("D", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("E", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleSeparator() {
|
||||
Iterator iterator = createTokenIterator("A,B,;,C...D, ., ,E", " ,.;:");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("D", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("E", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,12 +30,10 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
/**
|
||||
* TimeoutMapTest
|
||||
* <p/>
|
||||
@@ -541,7 +539,7 @@ public class TimeoutMapTest extends MapAbstractTest {
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Elements expired too early, test did not run as expected.", count > 0);
|
||||
assertTrue(count > 0, "Elements expired too early, test did not run as expected.");
|
||||
//assertEquals("Elements did not expire as expected.", 1, count);
|
||||
}
|
||||
|
||||
@@ -573,7 +571,7 @@ public class TimeoutMapTest extends MapAbstractTest {
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Elements expired too early, test did not run as expected.", count > 0);
|
||||
assertTrue(count > 0, "Elements expired too early, test did not run as expected.");
|
||||
//assertEquals("Elements did not expire as expected.", 1, count);
|
||||
}
|
||||
|
||||
@@ -613,7 +611,7 @@ public class TimeoutMapTest extends MapAbstractTest {
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue("Elements expired too early, test did not run as expected.", count > 0);
|
||||
assertTrue(count > 0, "Elements expired too early, test did not run as expected.");
|
||||
//assertEquals("Elements did not expire as expected.", 1, count);
|
||||
}
|
||||
|
||||
@@ -630,7 +628,7 @@ public class TimeoutMapTest extends MapAbstractTest {
|
||||
Object removedKey = null;
|
||||
Object otherKey = null;
|
||||
Iterator iterator = map.entrySet().iterator();
|
||||
assertTrue("Iterator was empty", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "Iterator was empty");
|
||||
try {
|
||||
Map.Entry entry = (Map.Entry) iterator.next();
|
||||
assertNotNull(entry);
|
||||
@@ -648,8 +646,8 @@ public class TimeoutMapTest extends MapAbstractTest {
|
||||
fail("Elements expired between Interator.hasNext() and Iterator.remove()");
|
||||
}
|
||||
|
||||
assertTrue("Wrong entry removed, keySet().iterator() is broken.", !map.containsKey(removedKey));
|
||||
assertTrue("Wrong entry removed, keySet().iterator() is broken.", map.containsKey(otherKey));
|
||||
assertTrue(!map.containsKey(removedKey), "Wrong entry removed, keySet().iterator() is broken.");
|
||||
assertTrue(map.containsKey(otherKey), "Wrong entry removed, keySet().iterator() is broken.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-5
@@ -30,12 +30,10 @@
|
||||
|
||||
package com.twelvemonkeys.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
import org.junit.jupiter.api.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* TokenIteratorAbstractTestCase
|
||||
@@ -80,7 +78,7 @@ public abstract class TokenIteratorAbstractTest {
|
||||
@Test
|
||||
public void testEmptyString() {
|
||||
Iterator iterator = createTokenIterator("");
|
||||
assertFalse("Empty string has elements", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "Empty string has elements");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
|
||||
package com.twelvemonkeys.util.convert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* ConverterTest
|
||||
@@ -43,7 +43,7 @@ import org.junit.Test;
|
||||
*/
|
||||
public class ConverterTest {
|
||||
|
||||
@Ignore("Not implemented")
|
||||
@Disabled("Not implemented")
|
||||
@Test
|
||||
public void testMe() {
|
||||
// TODO: Implement tests
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
package com.twelvemonkeys.util.convert;
|
||||
|
||||
import com.twelvemonkeys.lang.DateUtil;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
+4
-4
@@ -31,13 +31,13 @@
|
||||
package com.twelvemonkeys.util.convert;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* DefaultConverterTest
|
||||
@@ -138,7 +138,7 @@ public class DefaultConverterTest extends PropertyConverterAbstractTest {
|
||||
assertEquals(-2.3456, (Double) converter.toObject("-2.3456", Double.TYPE, null), 0);
|
||||
}
|
||||
|
||||
@Ignore("Known issue. Why would anyone do something like this?")
|
||||
@Disabled("Known issue. Why would anyone do something like this?")
|
||||
@Test
|
||||
public void testConvertCharPrimitive() {
|
||||
PropertyConverter converter = makePropertyConverter();
|
||||
|
||||
+16
-16
@@ -32,11 +32,11 @@ package com.twelvemonkeys.util.convert;
|
||||
|
||||
import com.twelvemonkeys.lang.ObjectAbstractTest;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* PropertyConverterAbstractTest
|
||||
@@ -66,26 +66,26 @@ public abstract class PropertyConverterAbstractTest extends ObjectAbstractTest {
|
||||
try {
|
||||
obj = converter.toObject(test.original(), test.type(), test.format());
|
||||
|
||||
assertEquals(String.format("'%s' converted to incorrect type", test.original()), test.type(), obj.getClass());
|
||||
assertEquals(test.type(), obj.getClass(), String.format("'%s' converted to incorrect type", test.original()));
|
||||
if (test.type().isArray()) {
|
||||
assertArrayEquals0(String.format("'%s' not converted", test.original()), test.value(), obj);
|
||||
}
|
||||
else {
|
||||
assertEquals(String.format("'%s' not converted", test.original()), test.value(), obj);
|
||||
assertEquals(test.value(), obj, String.format("'%s' not converted", test.original()));
|
||||
}
|
||||
|
||||
String result = converter.toString(test.value(), test.format());
|
||||
|
||||
assertEquals(String.format("'%s' does not match", test.converted()), test.converted(), result);
|
||||
assertEquals(test.converted(), result, String.format("'%s' does not match", test.converted()));
|
||||
|
||||
obj = converter.toObject(result, test.type(), test.format());
|
||||
assertEquals(String.format("'%s' converted to incorrect type", test.original()), test.type(), obj.getClass());
|
||||
assertEquals(test.type(), obj.getClass(), String.format("'%s' converted to incorrect type", test.original()));
|
||||
|
||||
if (test.type().isArray()) {
|
||||
assertArrayEquals0(String.format("'%s' did not survive round trip conversion", test.original()), test.value(), obj);
|
||||
}
|
||||
else {
|
||||
assertEquals(String.format("'%s' did not survive round trip conversion", test.original()), test.value(), obj);
|
||||
assertEquals(test.value(), obj, String.format("'%s' did not survive round trip conversion", test.original()));
|
||||
}
|
||||
}
|
||||
catch (ConversionException e) {
|
||||
@@ -98,35 +98,35 @@ public abstract class PropertyConverterAbstractTest extends ObjectAbstractTest {
|
||||
Class<?> componentType = left.getClass().getComponentType();
|
||||
if (componentType.isPrimitive()) {
|
||||
if (int.class == componentType) {
|
||||
assertArrayEquals(message, (int[]) left, (int[]) right);
|
||||
assertArrayEquals((int[]) left, (int[]) right, message);
|
||||
}
|
||||
else if (short.class == componentType) {
|
||||
assertArrayEquals(message, (short[]) left, (short[]) right);
|
||||
assertArrayEquals((short[]) left, (short[]) right, message);
|
||||
}
|
||||
else if (long.class == componentType) {
|
||||
assertArrayEquals(message, (long[]) left, (long[]) right);
|
||||
assertArrayEquals((long[]) left, (long[]) right, message);
|
||||
}
|
||||
else if (float.class == componentType) {
|
||||
assertArrayEquals(message, (float[]) left, (float[]) right, 0f);
|
||||
assertArrayEquals((float[]) left, (float[]) right, 0f, message);
|
||||
}
|
||||
else if (double.class == componentType) {
|
||||
assertArrayEquals(message, (double[]) left, (double[]) right, 0d);
|
||||
assertArrayEquals((double[]) left, (double[]) right, 0d, message);
|
||||
}
|
||||
else if (boolean.class == componentType) {
|
||||
assertTrue(message, Arrays.equals((boolean[]) left, (boolean[]) right));
|
||||
assertTrue(Arrays.equals((boolean[]) left, (boolean[]) right), message);
|
||||
}
|
||||
else if (byte.class == componentType) {
|
||||
assertArrayEquals(message, (byte[]) left, (byte[]) right);
|
||||
assertArrayEquals((byte[]) left, (byte[]) right, message);
|
||||
}
|
||||
else if (char.class == componentType) {
|
||||
assertArrayEquals(message, (char[]) left, (char[]) right);
|
||||
assertArrayEquals((char[]) left, (char[]) right, message);
|
||||
}
|
||||
else {
|
||||
fail(String.format("Unknown primitive type: %s", componentType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
assertArrayEquals(message, (Object[]) left, (Object[]) right);
|
||||
assertArrayEquals((Object[]) left, (Object[]) right, message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-28
@@ -32,12 +32,11 @@ package com.twelvemonkeys.util.regex;
|
||||
|
||||
import com.twelvemonkeys.util.TokenIterator;
|
||||
import com.twelvemonkeys.util.TokenIteratorAbstractTest;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
/**
|
||||
* StringTokenIteratorTestCase
|
||||
* <p/>
|
||||
@@ -68,9 +67,9 @@ public class RegExTokenIteratorTest extends TokenIteratorAbstractTest {
|
||||
@Test
|
||||
public void testSingleToken() {
|
||||
Iterator iterator = createTokenIterator("A");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -87,67 +86,67 @@ public class RegExTokenIteratorTest extends TokenIteratorAbstractTest {
|
||||
@Test
|
||||
public void testSingleTokenSingleDelimiter() {
|
||||
Iterator iterator = createTokenIterator("A", "[^,]+");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleSeparatorDefaultDelimiter() {
|
||||
Iterator iterator = createTokenIterator("A B C D");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("D", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleSeparator() {
|
||||
Iterator iterator = createTokenIterator("A,B,C", "[^,]+");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleSeparatorDefaultDelimiter() {
|
||||
Iterator iterator = createTokenIterator("A B C\nD\t\t \nE");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("A", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("D", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("E", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleSeparator() {
|
||||
Iterator iterator = createTokenIterator("A,B,;,C...D, ., ,E", "[^ ,.;:]+");
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
Object o = iterator.next();
|
||||
assertEquals("A", o);
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("B", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("C", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("D", iterator.next());
|
||||
assertTrue("String has no elements", iterator.hasNext());
|
||||
assertTrue(iterator.hasNext(), "String has no elements");
|
||||
assertEquals("E", iterator.next());
|
||||
assertFalse("String has more than one element", iterator.hasNext());
|
||||
assertFalse(iterator.hasNext(), "String has more than one element");
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -30,12 +30,13 @@
|
||||
|
||||
package com.twelvemonkeys.util.service;
|
||||
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
import com.twelvemonkeys.util.CollectionUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* ServiceRegistryTest
|
||||
@@ -48,9 +49,11 @@ public class ServiceRegistryTest {
|
||||
|
||||
private final TestRegistry registry = new TestRegistry();
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
@Test
|
||||
public void testCreateNull() {
|
||||
new ServiceRegistry(null);
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
new ServiceRegistry(null);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -64,11 +67,12 @@ public class ServiceRegistryTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = ServiceConfigurationError.class)
|
||||
@Test
|
||||
public void testCreateBadConfig() {
|
||||
@SuppressWarnings("unchecked")
|
||||
ServiceRegistry registry = new ServiceRegistry(Arrays.asList(BadSPI.class).iterator());
|
||||
registry.registerApplicationClasspathSPIs();
|
||||
assertThrows(ServiceConfigurationError.class, () -> {
|
||||
ServiceRegistry registry = new ServiceRegistry(Arrays.asList(BadSPI.class).iterator());
|
||||
registry.registerApplicationClasspathSPIs();
|
||||
});
|
||||
|
||||
// DONE: Test non-class
|
||||
|
||||
|
||||
+15
-4
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys</groupId>
|
||||
<artifactId>twelvemonkeys</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
@@ -20,6 +20,10 @@
|
||||
<module>common-image</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<junit.jupiter.version>5.13.0</junit.jupiter.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -43,11 +47,18 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
+25
-6
@@ -4,15 +4,20 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys</groupId>
|
||||
<artifactId>twelvemonkeys</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<groupId>com.twelvemonkeys.contrib</groupId>
|
||||
<artifactId>contrib</artifactId>
|
||||
<name>TwelveMonkeys :: Contrib</name>
|
||||
<description>
|
||||
Contributions to TwelveMonkeys which are not matching into the ImageIO plug-ins.
|
||||
Contributions to TwelveMonkeys and code that doesn't fit anywhere else.
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<junit.jupiter.version>5.13.0</junit.jupiter.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.twelvemonkeys.common</groupId>
|
||||
@@ -61,12 +66,26 @@
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -30,9 +30,14 @@ import static com.twelvemonkeys.contrib.tiff.TIFFUtilities.applyOrientation;
|
||||
public class EXIFUtilities {
|
||||
/**
|
||||
* Reads image and metadata, applies Exif orientation to image, and returns everything as an {@code IIOImage}.
|
||||
* The returned {@code IIOImage} will always contain an image and no raster, and
|
||||
* the {@code RenderedImage} may be safely cast to a {@code BufferedImage}.
|
||||
*
|
||||
* If no registered {@code ImageReader} claims to be able to read the input, {@code null} is returned.
|
||||
*
|
||||
* @param input a {@code URL}
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info.
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info, or
|
||||
* {@code null}.
|
||||
* @throws IOException if an error occurs during reading.
|
||||
*/
|
||||
public static IIOImage readWithOrientation(final URL input) throws IOException {
|
||||
@@ -43,9 +48,14 @@ public class EXIFUtilities {
|
||||
|
||||
/**
|
||||
* Reads image and metadata, applies Exif orientation to image, and returns everything as an {@code IIOImage}.
|
||||
* The returned {@code IIOImage} will always contain an image and no raster, and
|
||||
* the {@code RenderedImage} may be safely cast to a {@code BufferedImage}.
|
||||
*
|
||||
* If no registered {@code ImageReader} claims to be able to read the input, {@code null} is returned.
|
||||
*
|
||||
* @param input an {@code InputStream}
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info.
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info, or
|
||||
* {@code null}.
|
||||
* @throws IOException if an error occurs during reading.
|
||||
*/
|
||||
public static IIOImage readWithOrientation(final InputStream input) throws IOException {
|
||||
@@ -56,9 +66,14 @@ public class EXIFUtilities {
|
||||
|
||||
/**
|
||||
* Reads image and metadata, applies Exif orientation to image, and returns everything as an {@code IIOImage}.
|
||||
* The returned {@code IIOImage} will always contain an image and no raster, and
|
||||
* the {@code RenderedImage} may be safely cast to a {@code BufferedImage}.
|
||||
*
|
||||
* If no registered {@code ImageReader} claims to be able to read the input, {@code null} is returned.
|
||||
*
|
||||
* @param input a {@code File}
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info.
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info or
|
||||
* {@code null}.
|
||||
* @throws IOException if an error occurs during reading.
|
||||
*/
|
||||
public static IIOImage readWithOrientation(final File input) throws IOException {
|
||||
@@ -69,9 +84,14 @@ public class EXIFUtilities {
|
||||
|
||||
/**
|
||||
* Reads image and metadata, applies Exif orientation to image, and returns everything as an {@code IIOImage}.
|
||||
* The returned {@code IIOImage} will always contain an image and no raster, and
|
||||
* the {@code RenderedImage} may be safely cast to a {@code BufferedImage}.
|
||||
*
|
||||
* If no registered {@code ImageReader} claims to be able to read the input, {@code null} is returned.
|
||||
*
|
||||
* @param input an {@code ImageInputStream}
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info.
|
||||
* @return an {@code IIOImage} containing the correctly oriented image and metadata including rotation info, or
|
||||
* {@code null}.
|
||||
* @throws IOException if an error occurs during reading.
|
||||
*/
|
||||
public static IIOImage readWithOrientation(final ImageInputStream input) throws IOException {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.twelvemonkeys.contrib.exif;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.twelvemonkeys.contrib.exif.Orientation.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* OrientationTest.
|
||||
|
||||
@@ -34,8 +34,6 @@ import com.twelvemonkeys.contrib.tiff.TIFFUtilities.TIFFExtension;
|
||||
import com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadataFormat;
|
||||
import com.twelvemonkeys.io.FileUtil;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
@@ -54,6 +52,9 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* TIFFUtilitiesTest
|
||||
*
|
||||
@@ -95,7 +96,7 @@ public class TIFFUtilitiesTest {
|
||||
ImageInputStream iis = ImageIO.createImageInputStream(output);
|
||||
ImageReader reader = ImageIO.getImageReaders(iis).next();
|
||||
reader.setInput(iis);
|
||||
Assert.assertEquals(3, reader.getNumImages(true));
|
||||
assertEquals(3, reader.getNumImages(true));
|
||||
|
||||
iis.close();
|
||||
output.delete();
|
||||
@@ -119,11 +120,11 @@ public class TIFFUtilitiesTest {
|
||||
ImageReader reader = ImageIO.getImageReadersByFormatName("TIF").next();
|
||||
|
||||
File[] outputFiles = outputDirectory.listFiles();
|
||||
Assert.assertEquals(3, outputFiles.length);
|
||||
assertEquals(3, outputFiles.length);
|
||||
for (File outputFile : outputFiles) {
|
||||
ImageInputStream iis = ImageIO.createImageInputStream(outputFile);
|
||||
reader.setInput(iis);
|
||||
Assert.assertEquals(1, reader.getNumImages(true));
|
||||
assertEquals(1, reader.getNumImages(true));
|
||||
iis.close();
|
||||
outputFile.delete();
|
||||
}
|
||||
@@ -157,7 +158,7 @@ public class TIFFUtilitiesTest {
|
||||
Node metaData = reader.getImageMetadata(i)
|
||||
.getAsTree(TIFFImageMetadataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME);
|
||||
short orientation = ((Number) expression.evaluate(metaData, XPathConstants.NUMBER)).shortValue();
|
||||
Assert.assertEquals(orientation, TIFFExtension.ORIENTATION_RIGHTTOP);
|
||||
assertEquals(orientation, TIFFExtension.ORIENTATION_RIGHTTOP);
|
||||
}
|
||||
checkTest1.close();
|
||||
|
||||
@@ -174,7 +175,7 @@ public class TIFFUtilitiesTest {
|
||||
Node metaData = reader.getImageMetadata(i)
|
||||
.getAsTree(TIFFImageMetadataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME);
|
||||
short orientation = ((Number) expression.evaluate(metaData, XPathConstants.NUMBER)).shortValue();
|
||||
Assert.assertEquals(orientation, i == 1
|
||||
assertEquals(orientation, i == 1
|
||||
? TIFFExtension.ORIENTATION_BOTRIGHT
|
||||
: TIFFExtension.ORIENTATION_RIGHTTOP);
|
||||
}
|
||||
@@ -199,7 +200,7 @@ public class TIFFUtilitiesTest {
|
||||
byte[] original = ((DataBufferByte) image.getData().getDataBuffer()).getData();
|
||||
byte[] rotated = ((DataBufferByte) image360.getData().getDataBuffer()).getData();
|
||||
|
||||
Assert.assertArrayEquals(original, rotated);
|
||||
assertArrayEquals(original, rotated);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>imageio-batik</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: Batik Plugin</name>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<properties>
|
||||
<project.jpms.module.name>com.twelvemonkeys.imageio.batik</project.jpms.module.name>
|
||||
<batik.version>1.14</batik.version>
|
||||
<batik.version>1.19</batik.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
@@ -27,12 +27,24 @@
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<com.twelvemonkeys.imageio.plugins.svg.allowexternalresources>
|
||||
<com.twelvemonkeys.imageio.plugins.svg.allowExternalResources>
|
||||
true
|
||||
</com.twelvemonkeys.imageio.plugins.svg.allowexternalresources>
|
||||
</com.twelvemonkeys.imageio.plugins.svg.allowExternalResources>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Provide-Capability>
|
||||
osgi.serviceloader;
|
||||
osgi.serviceloader=javax.imageio.spi.ImageReaderSpi
|
||||
</Provide-Capability>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -48,6 +60,13 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.19.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.xmlgraphics</groupId>
|
||||
<artifactId>batik-rasterizer-ext</artifactId>
|
||||
|
||||
+140
-132
@@ -30,21 +30,11 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.svg;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import com.twelvemonkeys.image.ImageUtil;
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
|
||||
import org.apache.batik.anim.dom.SVGDOMImplementation;
|
||||
import org.apache.batik.anim.dom.SVGOMDocument;
|
||||
@@ -68,10 +58,19 @@ import org.w3c.dom.DOMImplementation;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.svg.SVGSVGElement;
|
||||
|
||||
import com.twelvemonkeys.image.ImageUtil;
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import com.twelvemonkeys.lang.StringUtil;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import java.awt.*;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Image reader for SVG document fragments.
|
||||
@@ -79,12 +78,13 @@ import com.twelvemonkeys.lang.StringUtil;
|
||||
* @author Harald Kuhr
|
||||
* @author Inpspired by code from the Batik Team
|
||||
* @version $Id: $
|
||||
* @see <A href="http://www.mail-archive.com/batik-dev@xml.apache.org/msg00992.html">batik-dev</A>
|
||||
* @see <a href="http://www.mail-archive.com/batik-dev@xml.apache.org/msg00992.html">batik-dev</a>
|
||||
*/
|
||||
public class SVGImageReader extends ImageReaderBase {
|
||||
|
||||
final static boolean DEFAULT_ALLOW_EXTERNAL_RESOURCES =
|
||||
"true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.plugins.svg.allowexternalresources"));
|
||||
"true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.plugins.svg.allowExternalResources",
|
||||
System.getProperty("com.twelvemonkeys.imageio.plugins.svg.allowexternalresources")));
|
||||
|
||||
private Rasterizer rasterizer;
|
||||
private boolean allowExternalResources = DEFAULT_ALLOW_EXTERNAL_RESOURCES;
|
||||
@@ -92,10 +92,10 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
/**
|
||||
* Creates an {@code SVGImageReader}.
|
||||
*
|
||||
* @param pProvider the provider
|
||||
* @param provider the provider
|
||||
*/
|
||||
public SVGImageReader(final ImageReaderSpi pProvider) {
|
||||
super(pProvider);
|
||||
public SVGImageReader(final ImageReaderSpi provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
protected void resetMembers() {
|
||||
@@ -109,20 +109,20 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInput(Object pInput, boolean seekForwardOnly, boolean ignoreMetadata) {
|
||||
super.setInput(pInput, seekForwardOnly, ignoreMetadata);
|
||||
public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
|
||||
super.setInput(input, seekForwardOnly, ignoreMetadata);
|
||||
|
||||
if (imageInput != null) {
|
||||
TranscoderInput input = new TranscoderInput(IIOUtil.createStreamAdapter(imageInput));
|
||||
rasterizer.setInput(input);
|
||||
TranscoderInput transcoderInput = new TranscoderInput(IIOUtil.createStreamAdapter(imageInput));
|
||||
rasterizer.setInput(transcoderInput);
|
||||
}
|
||||
}
|
||||
|
||||
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
|
||||
checkBounds(pIndex);
|
||||
public BufferedImage read(int imageIndex, ImageReadParam param) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
if (pParam instanceof SVGReadParam) {
|
||||
SVGReadParam svgParam = (SVGReadParam) pParam;
|
||||
if (param instanceof SVGReadParam) {
|
||||
SVGReadParam svgParam = (SVGReadParam) param;
|
||||
|
||||
// set the external-resource-resolution preference
|
||||
allowExternalResources = svgParam.isAllowExternalResources();
|
||||
@@ -140,39 +140,33 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
Dimension size = null;
|
||||
if (pParam != null) {
|
||||
size = pParam.getSourceRenderSize();
|
||||
if (param != null) {
|
||||
size = param.getSourceRenderSize();
|
||||
}
|
||||
if (size == null) {
|
||||
size = new Dimension(getWidth(pIndex), getHeight(pIndex));
|
||||
size = new Dimension(getWidth(imageIndex), getHeight(imageIndex));
|
||||
}
|
||||
|
||||
BufferedImage destination = getDestination(pParam, getImageTypes(pIndex), size.width, size.height);
|
||||
BufferedImage destination = getDestination(param, getImageTypes(imageIndex), size.width, size.height);
|
||||
|
||||
// Read in the image, using the Batik Transcoder
|
||||
processImageStarted(imageIndex);
|
||||
|
||||
BufferedImage image = rasterizer.getImage();
|
||||
|
||||
Graphics2D g = destination.createGraphics();
|
||||
try {
|
||||
processImageStarted(pIndex);
|
||||
|
||||
BufferedImage image = rasterizer.getImage();
|
||||
|
||||
Graphics2D g = destination.createGraphics();
|
||||
try {
|
||||
g.setComposite(AlphaComposite.Src);
|
||||
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
|
||||
g.drawImage(image, 0, 0, null); // TODO: Dest offset?
|
||||
}
|
||||
finally {
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
processImageComplete();
|
||||
|
||||
return destination;
|
||||
g.setComposite(AlphaComposite.Src);
|
||||
g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
|
||||
g.drawImage(image, 0, 0, null); // TODO: Dest offset?
|
||||
}
|
||||
catch (TranscoderException e) {
|
||||
Throwable cause = unwrapException(e);
|
||||
throw new IIOException(cause.getMessage(), cause);
|
||||
finally {
|
||||
g.dispose();
|
||||
}
|
||||
|
||||
processImageComplete();
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
private static Throwable unwrapException(TranscoderException ex) {
|
||||
@@ -180,18 +174,18 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
return ex.getException() != null ? ex.getException() : ex;
|
||||
}
|
||||
|
||||
private TranscodingHints paramsToHints(SVGReadParam pParam) throws IOException {
|
||||
private TranscodingHints paramsToHints(SVGReadParam param) throws IOException {
|
||||
TranscodingHints hints = new TranscodingHints();
|
||||
// Note: We must allow generic ImageReadParams, so converting to
|
||||
// TanscodingHints should be done outside the SVGReadParam class.
|
||||
|
||||
// Set dimensions
|
||||
Dimension size = pParam.getSourceRenderSize();
|
||||
Dimension origSize = new Dimension(getWidth(0), getHeight(0));
|
||||
Dimension size = param.getSourceRenderSize();
|
||||
Rectangle viewBox = rasterizer.getViewBox();
|
||||
if (size == null) {
|
||||
// SVG is not a pixel based format, but we'll scale it, according to
|
||||
// the subsampling for compatibility
|
||||
size = getSourceRenderSizeFromSubsamping(pParam, origSize);
|
||||
size = getSourceRenderSizeFromSubsamping(param, viewBox.getSize());
|
||||
}
|
||||
|
||||
if (size != null) {
|
||||
@@ -200,7 +194,7 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
// Set area of interest
|
||||
Rectangle region = pParam.getSourceRegion();
|
||||
Rectangle region = param.getSourceRegion();
|
||||
if (region != null) {
|
||||
hints.put(ImageTranscoder.KEY_AOI, region);
|
||||
|
||||
@@ -211,8 +205,8 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
else {
|
||||
// Need to resize here...
|
||||
double xScale = size.getWidth() / origSize.getWidth();
|
||||
double yScale = size.getHeight() / origSize.getHeight();
|
||||
double xScale = size.getWidth() / viewBox.getWidth();
|
||||
double yScale = size.getHeight() / viewBox.getHeight();
|
||||
|
||||
hints.put(ImageTranscoder.KEY_WIDTH, (float) (region.getWidth() * xScale));
|
||||
hints.put(ImageTranscoder.KEY_HEIGHT, (float) (region.getHeight() * yScale));
|
||||
@@ -220,11 +214,11 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
else if (size != null) {
|
||||
// Allow non-uniform scaling
|
||||
hints.put(ImageTranscoder.KEY_AOI, new Rectangle(origSize));
|
||||
hints.put(ImageTranscoder.KEY_AOI, viewBox);
|
||||
}
|
||||
|
||||
// Background color
|
||||
Paint bg = pParam.getBackgroundColor();
|
||||
Paint bg = param.getBackgroundColor();
|
||||
if (bg != null) {
|
||||
hints.put(ImageTranscoder.KEY_BACKGROUND_COLOR, bg);
|
||||
}
|
||||
@@ -232,10 +226,10 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
return hints;
|
||||
}
|
||||
|
||||
private Dimension getSourceRenderSizeFromSubsamping(ImageReadParam pParam, Dimension pOrigSize) {
|
||||
if (pParam.getSourceXSubsampling() > 1 || pParam.getSourceYSubsampling() > 1) {
|
||||
return new Dimension((int) (pOrigSize.width / (float) pParam.getSourceXSubsampling()),
|
||||
(int) (pOrigSize.height / (float) pParam.getSourceYSubsampling()));
|
||||
private Dimension getSourceRenderSizeFromSubsamping(ImageReadParam param, Dimension origSize) {
|
||||
if (param.getSourceXSubsampling() > 1 || param.getSourceYSubsampling() > 1) {
|
||||
return new Dimension((int) (origSize.width / (float) param.getSourceXSubsampling()),
|
||||
(int) (origSize.height / (float) param.getSourceYSubsampling()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -244,28 +238,19 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
return new SVGReadParam();
|
||||
}
|
||||
|
||||
public int getWidth(int pIndex) throws IOException {
|
||||
checkBounds(pIndex);
|
||||
try {
|
||||
return rasterizer.getDefaultWidth();
|
||||
}
|
||||
catch (TranscoderException e) {
|
||||
throw new IIOException(e.getMessage(), e);
|
||||
}
|
||||
public int getWidth(int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
return rasterizer.getDefaultWidth();
|
||||
}
|
||||
|
||||
public int getHeight(int pIndex) throws IOException {
|
||||
checkBounds(pIndex);
|
||||
try {
|
||||
return rasterizer.getDefaultHeight();
|
||||
}
|
||||
catch (TranscoderException e) {
|
||||
throw new IIOException(e.getMessage(), e);
|
||||
}
|
||||
public int getHeight(int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
return rasterizer.getDefaultHeight();
|
||||
}
|
||||
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) {
|
||||
return Collections.singleton(ImageTypeSpecifier.createFromRenderedImage(rasterizer.createImage(1, 1))).iterator();
|
||||
return Collections.singleton(ImageTypeSpecifiers.createFromRenderedImage(rasterizer.createImage(1, 1))).iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,12 +260,11 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
* and needs major refactoring!
|
||||
* </p>
|
||||
*/
|
||||
private class Rasterizer extends SVGAbstractTranscoder /*ImageTranscoder*/ {
|
||||
|
||||
private class Rasterizer extends SVGAbstractTranscoder {
|
||||
private BufferedImage image;
|
||||
private TranscoderInput transcoderInput;
|
||||
private float defaultWidth;
|
||||
private float defaultHeight;
|
||||
private final Rectangle2D viewBox = new Rectangle2D.Float();
|
||||
private final Dimension defaultSize = new Dimension();
|
||||
private boolean initialized = false;
|
||||
private SVGOMDocument document;
|
||||
private String uri;
|
||||
@@ -341,54 +325,66 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
// ----
|
||||
SVGSVGElement rootElement = svgDoc.getRootElement();
|
||||
|
||||
// get the 'width' and 'height' attributes of the SVG document
|
||||
UnitProcessor.Context uctx
|
||||
= UnitProcessor.createContext(ctx, rootElement);
|
||||
// Get the viewBox
|
||||
String viewBoxStr = rootElement.getAttributeNS(null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE);
|
||||
if (viewBoxStr.length() != 0) {
|
||||
float[] rect = ViewBox.parseViewBoxAttribute(rootElement, viewBoxStr, null);
|
||||
viewBox.setFrame(rect[0], rect[1], rect[2], rect[3]);
|
||||
}
|
||||
|
||||
// Get the 'width' and 'height' attributes of the SVG document
|
||||
double width = 0;
|
||||
double height = 0;
|
||||
UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, rootElement);
|
||||
String widthStr = rootElement.getAttributeNS(null, SVGConstants.SVG_WIDTH_ATTRIBUTE);
|
||||
String heightStr = rootElement.getAttributeNS(null, SVGConstants.SVG_HEIGHT_ATTRIBUTE);
|
||||
if (!StringUtil.isEmpty(widthStr)) {
|
||||
defaultWidth = UnitProcessor.svgToUserSpace(widthStr, SVGConstants.SVG_WIDTH_ATTRIBUTE, UnitProcessor.HORIZONTAL_LENGTH, uctx);
|
||||
width = UnitProcessor.svgToUserSpace(widthStr, SVGConstants.SVG_WIDTH_ATTRIBUTE, UnitProcessor.HORIZONTAL_LENGTH, uctx);
|
||||
}
|
||||
if(!StringUtil.isEmpty(heightStr)){
|
||||
defaultHeight = UnitProcessor.svgToUserSpace(heightStr, SVGConstants.SVG_HEIGHT_ATTRIBUTE, UnitProcessor.VERTICAL_LENGTH, uctx);
|
||||
if (!StringUtil.isEmpty(heightStr)) {
|
||||
height = UnitProcessor.svgToUserSpace(heightStr, SVGConstants.SVG_HEIGHT_ATTRIBUTE, UnitProcessor.VERTICAL_LENGTH, uctx);
|
||||
}
|
||||
|
||||
boolean hasWidth = defaultWidth > 0.0;
|
||||
boolean hasHeight = defaultHeight > 0.0;
|
||||
boolean hasWidth = width > 0.0;
|
||||
boolean hasHeight = height > 0.0;
|
||||
|
||||
if (!hasWidth || !hasHeight) {
|
||||
String viewBoxStr = rootElement.getAttributeNS
|
||||
(null, SVGConstants.SVG_VIEW_BOX_ATTRIBUTE);
|
||||
if (viewBoxStr.length() != 0) {
|
||||
float[] rect = ViewBox.parseViewBoxAttribute(rootElement, viewBoxStr, null);
|
||||
// if one dimension is given, calculate other by aspect ratio in viewBox
|
||||
// or use viewBox if no dimension is given
|
||||
if (!viewBox.isEmpty()) {
|
||||
// If one dimension is given, calculate other by aspect ratio in viewBox
|
||||
if (hasWidth) {
|
||||
defaultHeight = defaultWidth * rect[3] / rect[2];
|
||||
height = width * viewBox.getHeight() / viewBox.getWidth();
|
||||
}
|
||||
else if (hasHeight) {
|
||||
defaultWidth = defaultHeight * rect[2] / rect[3];
|
||||
width = height * viewBox.getWidth() / viewBox.getHeight();
|
||||
}
|
||||
else {
|
||||
defaultWidth = rect[2];
|
||||
defaultHeight = rect[3];
|
||||
// ...or use viewBox if no dimension is given
|
||||
width = viewBox.getWidth();
|
||||
height = viewBox.getHeight();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No viewBox, just assume square size
|
||||
if (hasHeight) {
|
||||
defaultWidth = defaultHeight;
|
||||
width = height;
|
||||
}
|
||||
else if (hasWidth) {
|
||||
defaultHeight = defaultWidth;
|
||||
height = width;
|
||||
}
|
||||
else {
|
||||
// fallback to batik default sizes
|
||||
defaultWidth = 400;
|
||||
defaultHeight = 400;
|
||||
// ...or finally fall back to Batik default sizes
|
||||
width = 400;
|
||||
height = 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We now have a size, in the rare case we don't have a viewBox; set it to this size
|
||||
defaultSize.setSize(width, height);
|
||||
if (viewBox.isEmpty()) {
|
||||
viewBox.setRect(0, 0, width, height);
|
||||
}
|
||||
|
||||
// Hack to work around exception above
|
||||
if (root != null) {
|
||||
gvtRoot = root;
|
||||
@@ -401,7 +397,7 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
ctx = null;
|
||||
}
|
||||
|
||||
private BufferedImage readImage() throws TranscoderException {
|
||||
private BufferedImage readImage() throws IOException {
|
||||
init();
|
||||
|
||||
if (abortRequested()) {
|
||||
@@ -426,7 +422,8 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
if (gvtRoot == null) {
|
||||
throw exception;
|
||||
Throwable cause = unwrapException(exception);
|
||||
throw new IIOException(cause.getMessage(), cause);
|
||||
}
|
||||
}
|
||||
ctx = context;
|
||||
@@ -444,7 +441,7 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
|
||||
|
||||
// ----
|
||||
setImageSize(defaultWidth, defaultHeight);
|
||||
setImageSize(defaultSize.width, defaultSize.height);
|
||||
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
@@ -458,18 +455,17 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
|
||||
try {
|
||||
Px = ViewBox.getViewTransform(ref, root, width, height, null);
|
||||
|
||||
}
|
||||
catch (BridgeException ex) {
|
||||
throw new TranscoderException(ex);
|
||||
throw new IIOException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
if (Px.isIdentity() && (width != defaultWidth || height != defaultHeight)) {
|
||||
if (Px.isIdentity() && (width != defaultSize.width || height != defaultSize.height)) {
|
||||
// The document has no viewBox, we need to resize it by hand.
|
||||
// we want to keep the document size ratio
|
||||
float xscale, yscale;
|
||||
xscale = width / defaultWidth;
|
||||
yscale = height / defaultHeight;
|
||||
xscale = width / defaultSize.width;
|
||||
yscale = height / defaultSize.height;
|
||||
float scale = Math.min(xscale, yscale);
|
||||
Px = AffineTransform.getScaleInstance(scale, scale);
|
||||
}
|
||||
@@ -519,7 +515,7 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
catch (BridgeException ex) {
|
||||
throw new TranscoderException(ex);
|
||||
throw new IIOException(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
this.root = gvtRoot;
|
||||
@@ -588,7 +584,7 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
return dest;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new TranscoderException(ex.getMessage(), ex);
|
||||
throw new IIOException(ex.getMessage(), ex);
|
||||
}
|
||||
finally {
|
||||
if (context != null) {
|
||||
@@ -597,7 +593,7 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void init() throws TranscoderException {
|
||||
private synchronized void init() throws IIOException {
|
||||
if (!initialized) {
|
||||
if (transcoderInput == null) {
|
||||
throw new IllegalStateException("input == null");
|
||||
@@ -605,11 +601,18 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
|
||||
initialized = true;
|
||||
|
||||
super.transcode(transcoderInput, null);
|
||||
try {
|
||||
super.addTranscodingHint(SVGAbstractTranscoder.KEY_ALLOW_EXTERNAL_RESOURCES, allowExternalResources);
|
||||
super.transcode(transcoderInput, null);
|
||||
}
|
||||
catch (TranscoderException e) {
|
||||
Throwable cause = unwrapException(e);
|
||||
throw new IIOException(cause.getMessage(), cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BufferedImage getImage() throws TranscoderException {
|
||||
private BufferedImage getImage() throws IOException {
|
||||
if (image == null) {
|
||||
image = readImage();
|
||||
}
|
||||
@@ -617,18 +620,23 @@ public class SVGImageReader extends ImageReaderBase {
|
||||
return image;
|
||||
}
|
||||
|
||||
int getDefaultWidth() throws TranscoderException {
|
||||
int getDefaultWidth() throws IOException {
|
||||
init();
|
||||
return (int) Math.ceil(defaultWidth);
|
||||
return defaultSize.width;
|
||||
}
|
||||
|
||||
int getDefaultHeight() throws TranscoderException {
|
||||
int getDefaultHeight() throws IOException {
|
||||
init();
|
||||
return (int) Math.ceil(defaultHeight);
|
||||
return defaultSize.height;
|
||||
}
|
||||
|
||||
void setInput(final TranscoderInput pInput) {
|
||||
transcoderInput = pInput;
|
||||
Rectangle getViewBox() throws IOException {
|
||||
init();
|
||||
return viewBox.getBounds();
|
||||
}
|
||||
|
||||
void setInput(final TranscoderInput input) {
|
||||
transcoderInput = input;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+14
-14
@@ -60,22 +60,22 @@ public final class SVGImageReaderSpi extends ImageReaderSpiBase {
|
||||
super(new SVGProviderInfo());
|
||||
}
|
||||
|
||||
public boolean canDecodeInput(final Object pSource) throws IOException {
|
||||
return pSource instanceof ImageInputStream && canDecode((ImageInputStream) pSource);
|
||||
public boolean canDecodeInput(final Object source) throws IOException {
|
||||
return source instanceof ImageInputStream && canDecode((ImageInputStream) source);
|
||||
}
|
||||
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
private static boolean canDecode(final ImageInputStream pInput) throws IOException {
|
||||
private static boolean canDecode(final ImageInputStream input) throws IOException {
|
||||
// NOTE: This test is quite quick as it does not involve any parsing,
|
||||
// however it may not recognize all kinds of SVG documents.
|
||||
try {
|
||||
pInput.mark();
|
||||
input.mark();
|
||||
|
||||
// TODO: This is not ok for UTF-16 and other wide encodings
|
||||
// TODO: Use an XML (encoding) aware Reader instance instead
|
||||
// Need to figure out pretty fast if this is XML or not
|
||||
int b;
|
||||
while (Character.isWhitespace((char) (b = pInput.read()))) {
|
||||
while (Character.isWhitespace((char) (b = input.read()))) {
|
||||
// Skip over leading WS
|
||||
}
|
||||
|
||||
@@ -95,30 +95,30 @@ public final class SVGImageReaderSpi extends ImageReaderSpiBase {
|
||||
|
||||
byte[] buffer = new byte[4];
|
||||
while (true) {
|
||||
pInput.readFully(buffer);
|
||||
input.readFully(buffer);
|
||||
|
||||
if (buffer[0] == '?') {
|
||||
// This is the XML declaration or a processing instruction
|
||||
while (!((pInput.readByte() & 0xFF) == '?' && pInput.read() == '>')) {
|
||||
while (!((input.readByte() & 0xFF) == '?' && input.read() == '>')) {
|
||||
// Skip until end of XML declaration or processing instruction or EOF
|
||||
}
|
||||
}
|
||||
else if (buffer[0] == '!') {
|
||||
if (buffer[1] == '-' && buffer[2] == '-') {
|
||||
// This is a comment
|
||||
while (!((pInput.readByte() & 0xFF) == '-' && pInput.read() == '-' && pInput.read() == '>')) {
|
||||
while (!((input.readByte() & 0xFF) == '-' && input.read() == '-' && input.read() == '>')) {
|
||||
// Skip until end of comment or EOF
|
||||
}
|
||||
}
|
||||
else if (buffer[1] == 'D' && buffer[2] == 'O' && buffer[3] == 'C'
|
||||
&& pInput.read() == 'T' && pInput.read() == 'Y'
|
||||
&& pInput.read() == 'P' && pInput.read() == 'E') {
|
||||
&& input.read() == 'T' && input.read() == 'Y'
|
||||
&& input.read() == 'P' && input.read() == 'E') {
|
||||
// This is the DOCTYPE declaration
|
||||
while (Character.isWhitespace((char) (b = pInput.read()))) {
|
||||
while (Character.isWhitespace((char) (b = input.read()))) {
|
||||
// Skip over WS
|
||||
}
|
||||
|
||||
if (b == 's' && pInput.read() == 'v' && pInput.read() == 'g') {
|
||||
if (b == 's' && input.read() == 'v' && input.read() == 'g') {
|
||||
// It's SVG, identified by DOCTYPE
|
||||
return true;
|
||||
}
|
||||
@@ -142,7 +142,7 @@ public final class SVGImageReaderSpi extends ImageReaderSpiBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
while ((pInput.readByte() & 0xFF) != '<') {
|
||||
while ((input.readByte() & 0xFF) != '<') {
|
||||
// Skip over, until next begin tag or EOF
|
||||
}
|
||||
}
|
||||
@@ -153,7 +153,7 @@ public final class SVGImageReaderSpi extends ImageReaderSpiBase {
|
||||
}
|
||||
finally {
|
||||
//noinspection ThrowFromFinallyBlock
|
||||
pInput.reset();
|
||||
input.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -51,16 +51,16 @@ public class SVGReadParam extends ImageReadParam {
|
||||
return background;
|
||||
}
|
||||
|
||||
public void setBackgroundColor(Paint pColor) {
|
||||
background = pColor;
|
||||
public void setBackgroundColor(Paint color) {
|
||||
background = color;
|
||||
}
|
||||
|
||||
public String getBaseURI() {
|
||||
return baseURI;
|
||||
}
|
||||
|
||||
public void setBaseURI(String pBaseURI) {
|
||||
baseURI = pBaseURI;
|
||||
public void setBaseURI(String baseURI) {
|
||||
this.baseURI = baseURI;
|
||||
}
|
||||
|
||||
public void setAllowExternalResources(boolean allow) {
|
||||
|
||||
+143
-141
@@ -1,141 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.wmf;
|
||||
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.plugins.svg.SVGImageReader;
|
||||
import com.twelvemonkeys.imageio.plugins.svg.SVGReadParam;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
import org.apache.batik.transcoder.TranscoderException;
|
||||
import org.apache.batik.transcoder.TranscoderInput;
|
||||
import org.apache.batik.transcoder.TranscoderOutput;
|
||||
import org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* WMFImageReader class description.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haku $
|
||||
* @version $Id: WMFImageReader.java,v 1.0 29.jul.2004 13:00:59 haku Exp $
|
||||
*/
|
||||
// TODO: Probably possible to do less wrapping/unwrapping of data...
|
||||
// TODO: Consider using temp file instead of in-memory stream
|
||||
public final class WMFImageReader extends ImageReaderBase {
|
||||
|
||||
private SVGImageReader reader = null;
|
||||
|
||||
public WMFImageReader(final ImageReaderSpi pProvider) {
|
||||
super(pProvider);
|
||||
}
|
||||
|
||||
protected void resetMembers() {
|
||||
if (reader != null) {
|
||||
reader.dispose();
|
||||
}
|
||||
|
||||
reader = null;
|
||||
}
|
||||
|
||||
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
|
||||
init();
|
||||
|
||||
processImageStarted(pIndex);
|
||||
|
||||
BufferedImage image = reader.read(pIndex, pParam);
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return image;
|
||||
}
|
||||
processImageProgress(100f);
|
||||
|
||||
processImageComplete();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private synchronized void init() throws IOException {
|
||||
// Need the extra test, to avoid throwing an IOException from the Transcoder
|
||||
if (imageInput == null) {
|
||||
throw new IllegalStateException("input == null");
|
||||
}
|
||||
|
||||
if (reader == null) {
|
||||
WMFTranscoder transcoder = new WMFTranscoder();
|
||||
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
Writer writer = new OutputStreamWriter(output, "UTF8");
|
||||
try {
|
||||
TranscoderInput in = new TranscoderInput(IIOUtil.createStreamAdapter(imageInput));
|
||||
TranscoderOutput out = new TranscoderOutput(writer);
|
||||
|
||||
// TODO: Transcodinghints?
|
||||
|
||||
transcoder.transcode(in, out);
|
||||
}
|
||||
catch (TranscoderException e) {
|
||||
throw new IIOException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
reader = new SVGImageReader(getOriginatingProvider());
|
||||
reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(output.toByteArray())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageReadParam getDefaultReadParam() {
|
||||
return new SVGReadParam();
|
||||
}
|
||||
|
||||
public int getWidth(int pIndex) throws IOException {
|
||||
init();
|
||||
return reader.getWidth(pIndex);
|
||||
}
|
||||
|
||||
public int getHeight(int pIndex) throws IOException {
|
||||
init();
|
||||
return reader.getHeight(pIndex);
|
||||
}
|
||||
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(final int pImageIndex) throws IOException {
|
||||
init();
|
||||
return reader.getImageTypes(pImageIndex);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2008, Harald Kuhr
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.wmf;
|
||||
|
||||
import com.twelvemonkeys.imageio.ImageReaderBase;
|
||||
import com.twelvemonkeys.imageio.plugins.svg.SVGImageReader;
|
||||
import com.twelvemonkeys.imageio.plugins.svg.SVGReadParam;
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||
import com.twelvemonkeys.imageio.util.IIOUtil;
|
||||
|
||||
import org.apache.batik.transcoder.TranscoderException;
|
||||
import org.apache.batik.transcoder.TranscoderInput;
|
||||
import org.apache.batik.transcoder.TranscoderOutput;
|
||||
import org.apache.batik.transcoder.wmf.tosvg.WMFTranscoder;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import java.awt.image.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* WMFImageReader class description.
|
||||
*
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @author last modified by $Author: haku $
|
||||
* @version $Id: WMFImageReader.java,v 1.0 29.jul.2004 13:00:59 haku Exp $
|
||||
*/
|
||||
// TODO: Probably possible to do less wrapping/unwrapping of data...
|
||||
public final class WMFImageReader extends ImageReaderBase {
|
||||
|
||||
private SVGImageReader reader = null;
|
||||
|
||||
public WMFImageReader(final ImageReaderSpi pProvider) {
|
||||
super(pProvider);
|
||||
}
|
||||
|
||||
protected void resetMembers() {
|
||||
if (reader != null) {
|
||||
reader.dispose();
|
||||
}
|
||||
|
||||
reader = null;
|
||||
}
|
||||
|
||||
public BufferedImage read(int pIndex, ImageReadParam pParam) throws IOException {
|
||||
init();
|
||||
|
||||
processImageStarted(pIndex);
|
||||
|
||||
BufferedImage image = reader.read(pIndex, pParam);
|
||||
if (abortRequested()) {
|
||||
processReadAborted();
|
||||
return image;
|
||||
}
|
||||
processImageProgress(100f);
|
||||
|
||||
processImageComplete();
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private void init() throws IOException {
|
||||
// Need the extra test, to avoid throwing an IOException from the Transcoder
|
||||
if (imageInput == null) {
|
||||
throw new IllegalStateException("input == null");
|
||||
}
|
||||
|
||||
if (reader == null) {
|
||||
WMFTranscoder transcoder = new WMFTranscoder();
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream(8192);
|
||||
|
||||
try (Writer writer = new OutputStreamWriter(output, StandardCharsets.UTF_8)) {
|
||||
TranscoderInput in = new TranscoderInput(IIOUtil.createStreamAdapter(imageInput));
|
||||
TranscoderOutput out = new TranscoderOutput(writer);
|
||||
|
||||
// TODO: Transcodinghints?
|
||||
|
||||
transcoder.transcode(in, out);
|
||||
}
|
||||
catch (TranscoderException e) {
|
||||
throw new IIOException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
reader = new SVGImageReader(getOriginatingProvider());
|
||||
reader.setInput(new ByteArrayImageInputStream(output.toByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageReadParam getDefaultReadParam() {
|
||||
return new SVGReadParam();
|
||||
}
|
||||
|
||||
public int getWidth(int pIndex) throws IOException {
|
||||
init();
|
||||
return reader.getWidth(pIndex);
|
||||
}
|
||||
|
||||
public int getHeight(int pIndex) throws IOException {
|
||||
init();
|
||||
return reader.getHeight(pIndex);
|
||||
}
|
||||
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(final int pImageIndex) throws IOException {
|
||||
init();
|
||||
return reader.getImageTypes(pImageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-9
@@ -32,16 +32,16 @@ package com.twelvemonkeys.imageio.plugins.svg;
|
||||
|
||||
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
|
||||
import com.twelvemonkeys.imageio.stream.URLImageInputStreamSpi;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.spi.IIORegistry;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* SVGImageReaderSpiTest.
|
||||
@@ -83,18 +83,20 @@ public class SVGImageReaderSpiTest {
|
||||
public void canDecodeInput() throws Exception {
|
||||
for (String validInput : VALID_INPUTS) {
|
||||
try (ImageInputStream input = ImageIO.createImageInputStream(getClass().getResource(validInput))) {
|
||||
assertTrue("Can't read valid input: " + validInput, provider.canDecodeInput(input));
|
||||
assertTrue(provider.canDecodeInput(input), "Can't read valid input: " + validInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test will time out, if EOFs are not properly detected, see #275
|
||||
@Test(timeout = 5000)
|
||||
@Test
|
||||
public void canDecodeInputInvalid() throws Exception {
|
||||
for (String invalidInput : INVALID_INPUTS) {
|
||||
try (ImageInputStream input = new ByteArrayImageInputStream(invalidInput.getBytes(StandardCharsets.UTF_8))) {
|
||||
assertFalse("Claims to read invalid input:" + invalidInput, provider.canDecodeInput(input));
|
||||
assertTimeoutPreemptively(Duration.ofMillis(5000), () -> {
|
||||
for (String invalidInput : INVALID_INPUTS) {
|
||||
try (ImageInputStream input = new ByteArrayImageInputStream(invalidInput.getBytes(StandardCharsets.UTF_8))) {
|
||||
assertFalse(provider.canDecodeInput(input), "Claims to read invalid input:" + invalidInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+81
-16
@@ -32,9 +32,6 @@ package com.twelvemonkeys.imageio.plugins.svg;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
@@ -43,8 +40,7 @@ import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ImagingOpException;
|
||||
import java.awt.image.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URISyntaxException;
|
||||
@@ -53,7 +49,9 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
@@ -126,18 +124,18 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
int current = image.getRGB(x, y);
|
||||
if (x < quadPoint) {
|
||||
if (y < quadPoint) {
|
||||
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF0000FF, current);
|
||||
assertEquals( 0xFF0000FF, current, "x=" + x + " y=" + y + " q=" + quadPoint);
|
||||
}
|
||||
else {
|
||||
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFFFF0000, current);
|
||||
assertEquals(0xFFFF0000, current, "x=" + x + " y=" + y + " q=" + quadPoint);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (y < quadPoint) {
|
||||
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF00FF00, current);
|
||||
assertEquals(0xFF00FF00, current, "x=" + x + " y=" + y + " q=" + quadPoint);
|
||||
}
|
||||
else {
|
||||
assertEquals("x=" + x + " y=" + y + " q=" + quadPoint, 0xFF000000, current);
|
||||
assertEquals(0xFF000000, current, "x=" + x + " y=" + y + " q=" + quadPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,14 +167,14 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Known issue: Source region reading not supported")
|
||||
@Disabled("Known issue: Source region reading not supported")
|
||||
@Override
|
||||
public void testReadWithSourceRegionParamEqualImage() throws IOException {
|
||||
super.testReadWithSourceRegionParamEqualImage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Known issue: Subsampled reading not supported")
|
||||
@Disabled("Known issue: Subsampled reading not supported")
|
||||
@Override
|
||||
public void testReadWithSubsampleParamPixels() throws IOException {
|
||||
super.testReadWithSubsampleParamPixels();
|
||||
@@ -192,12 +190,12 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
TestData redSquare = new TestData(getClassLoaderResource("/svg/red-square.svg"), dim);
|
||||
reader.setInput(redSquare.getInputStream());
|
||||
BufferedImage imageRed = reader.read(0, param);
|
||||
assertEquals(0xFF0000, imageRed.getRGB(50, 50) & 0xFFFFFF);
|
||||
assertRGBEquals("Expected all red", 0xFF0000, imageRed.getRGB(50, 50) & 0xFFFFFF, 0);
|
||||
|
||||
TestData blueSquare = new TestData(getClassLoaderResource("/svg/blue-square.svg"), dim);
|
||||
reader.setInput(blueSquare.getInputStream());
|
||||
BufferedImage imageBlue = reader.read(0, param);
|
||||
assertEquals(0x0000FF, imageBlue.getRGB(50, 50) & 0xFFFFFF);
|
||||
assertRGBEquals("Expected all blue", 0x0000FF, imageBlue.getRGB(50, 50) & 0xFFFFFF, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -314,7 +312,7 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = SecurityException.class)
|
||||
@Test
|
||||
public void testDisallowedExternalResources() throws URISyntaxException, IOException {
|
||||
// system-property set to true in surefire-plugin-settings in the pom
|
||||
URL resource = getClassLoaderResource("/svg/barChart.svg");
|
||||
@@ -331,7 +329,74 @@ public class SVGImageReaderTest extends ImageReaderAbstractTest<SVGImageReader>
|
||||
// `reader.read` for `/svg/barChart.svg` should raise
|
||||
// a SecurityException when External Resources are blocked
|
||||
// because the API invocation gets preference
|
||||
reader.read(0, param);
|
||||
assertThrows(SecurityException.class, () -> {
|
||||
reader.read(0, param);
|
||||
});
|
||||
}
|
||||
finally {
|
||||
reader.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWitSourceRenderSize() throws IOException {
|
||||
URL resource = getClassLoaderResource("/svg/circle.svg");
|
||||
|
||||
SVGImageReader reader = createReader();
|
||||
|
||||
TestData data = new TestData(resource, (Dimension) null);
|
||||
try (ImageInputStream stream = data.getInputStream()) {
|
||||
reader.setInput(stream);
|
||||
|
||||
SVGReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceRenderSize(new Dimension(100, 100));
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
assertEquals(100, image.getWidth());
|
||||
assertEquals(100, image.getHeight());
|
||||
|
||||
// Some quick samples
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(0, 0), 0);
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(99, 0), 0);
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(0, 99), 0);
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(99, 99), 0);
|
||||
assertRGBEquals("Expected red center", 0xffff0000, image.getRGB(50, 50), 0);
|
||||
}
|
||||
finally {
|
||||
reader.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWitSourceRenderSizeViewBoxNegativeXY() throws IOException {
|
||||
URL resource = getClassLoaderResource("/svg/Android_robot.svg");
|
||||
|
||||
SVGImageReader reader = createReader();
|
||||
|
||||
TestData data = new TestData(resource, (Dimension) null);
|
||||
try (ImageInputStream stream = data.getInputStream()) {
|
||||
reader.setInput(stream);
|
||||
|
||||
SVGReadParam param = reader.getDefaultReadParam();
|
||||
param.setSourceRenderSize(new Dimension(219, 256)); // Aspect scaled to 256 boxed
|
||||
BufferedImage image = reader.read(0, param);
|
||||
|
||||
assertNotNull(image);
|
||||
assertEquals(219, image.getWidth());
|
||||
assertEquals(256, image.getHeight());
|
||||
|
||||
// Some quick samples
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(0, 0), 0);
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(218, 0), 0);
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(0, 255), 0);
|
||||
assertRGBEquals("Expected transparent corner", 0, image.getRGB(218, 255), 0);
|
||||
assertRGBEquals("Expected green head", 0xffa4c639, image.getRGB(109, 20), 25);
|
||||
assertRGBEquals("Expected green center", 0xffa4c639, image.getRGB(109, 128), 25);
|
||||
assertRGBEquals("Expected green feet", 0xffa4c639, image.getRGB(80, 246), 25);
|
||||
assertRGBEquals("Expected green feet", 0xffa4c639, image.getRGB(130, 246), 25);
|
||||
assertRGBEquals("Expected white edge", 0xffffffff, image.getRGB(0, 128), 0);
|
||||
assertRGBEquals("Expected white edge", 0xffffffff, image.getRGB(218, 128), 0);
|
||||
}
|
||||
finally {
|
||||
reader.dispose();
|
||||
|
||||
+4
-5
@@ -32,9 +32,6 @@ package com.twelvemonkeys.imageio.plugins.wmf;
|
||||
|
||||
import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
@@ -42,6 +39,8 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
/**
|
||||
* WMFImageReaderTest
|
||||
*
|
||||
@@ -77,14 +76,14 @@ public class WMFImageReaderTest extends ImageReaderAbstractTest<WMFImageReader>
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Known issue: Source region reading not supported")
|
||||
@Disabled("Known issue: Source region reading not supported")
|
||||
@Override
|
||||
public void testReadWithSourceRegionParamEqualImage() throws IOException {
|
||||
super.testReadWithSourceRegionParamEqualImage();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("Known issue: Subsampled reading not supported")
|
||||
@Disabled("Known issue: Subsampled reading not supported")
|
||||
@Override
|
||||
public void testReadWithSubsampleParamPixels() throws IOException {
|
||||
super.testReadWithSubsampleParamPixels();
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2">
|
||||
<circle cx="25" cy="25" r="25" fill="red"/></svg>
|
||||
|
After Width: | Height: | Size: 436 B |
@@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.twelvemonkeys.imageio</groupId>
|
||||
<artifactId>imageio</artifactId>
|
||||
<version>3.8.0-SNAPSHOT</version>
|
||||
<version>3.12.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>imageio-bmp</artifactId>
|
||||
<name>TwelveMonkeys :: ImageIO :: BMP plugin</name>
|
||||
@@ -26,4 +26,23 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Provide-Capability>
|
||||
osgi.serviceloader;
|
||||
osgi.serviceloader=javax.imageio.spi.ImageReaderSpi,
|
||||
osgi.serviceloader;
|
||||
osgi.serviceloader=javax.imageio.spi.ImageWriterSpi
|
||||
</Provide-Capability>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
+29
-21
@@ -39,7 +39,11 @@ import com.twelvemonkeys.io.LittleEndianDataInputStream;
|
||||
import com.twelvemonkeys.io.enc.DecoderStream;
|
||||
import com.twelvemonkeys.xml.XMLSerializer;
|
||||
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.IIOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReadParam;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.ImageTypeSpecifier;
|
||||
import javax.imageio.event.IIOReadUpdateListener;
|
||||
import javax.imageio.event.IIOReadWarningListener;
|
||||
import javax.imageio.metadata.IIOMetadata;
|
||||
@@ -47,7 +51,7 @@ import javax.imageio.metadata.IIOMetadataFormatImpl;
|
||||
import javax.imageio.spi.ImageReaderSpi;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.color.*;
|
||||
import java.awt.image.*;
|
||||
import java.io.DataInput;
|
||||
import java.io.File;
|
||||
@@ -77,8 +81,8 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
super(new BMPImageReaderSpi());
|
||||
}
|
||||
|
||||
protected BMPImageReader(final ImageReaderSpi pProvider) {
|
||||
super(pProvider);
|
||||
BMPImageReader(final ImageReaderSpi provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,6 +129,7 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
|
||||
// Read DIB header
|
||||
header = DIBHeader.read(imageInput);
|
||||
// System.out.println("header = " + header);
|
||||
|
||||
if (pixelOffset < header.size + DIB.BMP_FILE_HEADER_SIZE) {
|
||||
throw new IIOException("Invalid pixel offset: " + pixelOffset);
|
||||
@@ -182,30 +187,30 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWidth(int pImageIndex) throws IOException {
|
||||
checkBounds(pImageIndex);
|
||||
public int getWidth(int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
return header.getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHeight(int pImageIndex) throws IOException {
|
||||
checkBounds(pImageIndex);
|
||||
public int getHeight(int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
return header.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int pImageIndex) throws IOException {
|
||||
checkBounds(pImageIndex);
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
// TODO: Better implementation, include INT_RGB types for 3BYTE_BGR and 4BYTE_ABGR for INT_ARGB
|
||||
return Collections.singletonList(getRawImageType(pImageIndex)).iterator();
|
||||
return Collections.singletonList(getRawImageType(imageIndex)).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageTypeSpecifier getRawImageType(int pImageIndex) throws IOException {
|
||||
checkBounds(pImageIndex);
|
||||
public ImageTypeSpecifier getRawImageType(int imageIndex) throws IOException {
|
||||
checkBounds(imageIndex);
|
||||
|
||||
if (header.getPlanes() != 1) {
|
||||
throw new IIOException("Multiple planes not supported");
|
||||
@@ -358,14 +363,18 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
|
||||
processImageStarted(imageIndex);
|
||||
for (int y = 0; y < height; y++) {
|
||||
switch (header.getBitCount()) {
|
||||
int bitCount = header.getBitCount();
|
||||
switch (bitCount) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
case 24:
|
||||
byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData();
|
||||
readRowByte(input, height, srcRegion, xSub, ySub, rowDataByte, destRaster, clippedRow, y);
|
||||
int bitsPerSample = bitCount == 24 ? 8 : bitCount;
|
||||
int samplesPerPixel = bitCount == 24 ? 3 : 1;
|
||||
|
||||
readRowByte(input, height, srcRegion, xSub, ySub, bitsPerSample, samplesPerPixel, rowDataByte, destRaster, clippedRow, y);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
@@ -379,7 +388,7 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new AssertionError("Unsupported pixel depth: " + header.getBitCount());
|
||||
throw new AssertionError("Unsupported pixel depth: " + bitCount);
|
||||
}
|
||||
|
||||
processImageProgress(100f * y / height);
|
||||
@@ -476,6 +485,7 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
private void readRowByte(final DataInput input, final int height, final Rectangle srcRegion, final int xSub, final int ySub,
|
||||
int bitsPerSample, int samplesPerPixel,
|
||||
final byte[] rowDataByte, final WritableRaster destChannel, final Raster srcChannel, final int y) throws IOException {
|
||||
// Flip into position?
|
||||
int srcY = !header.topDown ? height - 1 - y : y;
|
||||
@@ -492,9 +502,7 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
|
||||
// Subsample horizontal
|
||||
if (xSub != 1) {
|
||||
for (int x = 0; x < srcRegion.width / xSub; x++) {
|
||||
rowDataByte[srcRegion.x + x] = rowDataByte[srcRegion.x + x * xSub];
|
||||
}
|
||||
IIOUtil.subsampleRow(rowDataByte, srcRegion.x, srcRegion.width, rowDataByte, 0, samplesPerPixel, bitsPerSample, xSub);
|
||||
}
|
||||
|
||||
destChannel.setDataElements(0, dstY, srcChannel);
|
||||
@@ -678,8 +686,8 @@ public final class BMPImageReader extends ImageReaderBase {
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "UnusedDeclaration", "SameParameterValue" })
|
||||
static <T extends Throwable> void throwAs(final Class<T> pType, final Throwable pThrowable) throws T {
|
||||
throw (T) pThrowable;
|
||||
static <T extends Throwable> void throwAs(final Class<T> type, final Throwable throwable) throws T {
|
||||
throw (T) throwable;
|
||||
}
|
||||
|
||||
private class ListenerDelegator extends ProgressListenerBase implements IIOReadUpdateListener, IIOReadWarningListener {
|
||||
|
||||
+8
-8
@@ -65,16 +65,16 @@ public final class BMPImageReaderSpi extends ImageReaderSpiBase {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canDecodeInput(final Object pSource) throws IOException {
|
||||
return pSource instanceof ImageInputStream && canDecode((ImageInputStream) pSource);
|
||||
public boolean canDecodeInput(final Object source) throws IOException {
|
||||
return source instanceof ImageInputStream && canDecode((ImageInputStream) source);
|
||||
}
|
||||
|
||||
private static boolean canDecode(final ImageInputStream pInput) throws IOException {
|
||||
private static boolean canDecode(final ImageInputStream input) throws IOException {
|
||||
byte[] fileHeader = new byte[18]; // Strictly: file header (14 bytes) + BMP header size field (4 bytes)
|
||||
|
||||
try {
|
||||
pInput.mark();
|
||||
pInput.readFully(fileHeader);
|
||||
input.mark();
|
||||
input.readFully(fileHeader);
|
||||
|
||||
// Magic: BM
|
||||
if (fileHeader[0] != 'B' || fileHeader[1] != 'M') {
|
||||
@@ -112,15 +112,15 @@ public final class BMPImageReaderSpi extends ImageReaderSpiBase {
|
||||
}
|
||||
}
|
||||
finally {
|
||||
pInput.reset();
|
||||
input.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public ImageReader createReaderInstance(final Object pExtension) throws IOException {
|
||||
public ImageReader createReaderInstance(final Object extension) {
|
||||
return new BMPImageReader(this);
|
||||
}
|
||||
|
||||
public String getDescription(final Locale pLocale) {
|
||||
public String getDescription(final Locale locale) {
|
||||
return "Windows Device Independent Bitmap Format (BMP) Reader";
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ import java.nio.ByteOrder;
|
||||
* BMPImageWriter
|
||||
*/
|
||||
public final class BMPImageWriter extends DIBImageWriter {
|
||||
protected BMPImageWriter(ImageWriterSpi provider) {
|
||||
BMPImageWriter(ImageWriterSpi provider) {
|
||||
super(provider);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -32,6 +32,7 @@ package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import com.twelvemonkeys.imageio.AbstractMetadata;
|
||||
import com.twelvemonkeys.lang.Validate;
|
||||
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import javax.imageio.metadata.IIOMetadataNode;
|
||||
@@ -141,7 +142,7 @@ final class BMPMetadata extends AbstractMetadata {
|
||||
@Override
|
||||
protected IIOMetadataNode getStandardChromaNode() {
|
||||
// NOTE: BMP files may contain a color map, even if true color...
|
||||
// Not sure if this is a good idea to expose to the meta data,
|
||||
// Not sure if this is a good idea to expose to the metadata,
|
||||
// as it might be unexpected... Then again...
|
||||
if (colorMap != null) {
|
||||
IIOMetadataNode chroma = new IIOMetadataNode("Chroma");
|
||||
|
||||
+7
-7
@@ -29,11 +29,11 @@
|
||||
*/
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.*;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
|
||||
/**
|
||||
* Describes a bitmap structure.
|
||||
*
|
||||
@@ -47,9 +47,9 @@ abstract class BitmapDescriptor {
|
||||
protected BufferedImage image;
|
||||
protected BitmapMask mask;
|
||||
|
||||
public BitmapDescriptor(final DirectoryEntry pEntry, final DIBHeader pHeader) {
|
||||
entry = notNull(pEntry, "entry");;
|
||||
header = notNull(pHeader, "header");
|
||||
public BitmapDescriptor(final DirectoryEntry entry, final DIBHeader header) {
|
||||
this.entry = notNull(entry, "entry");
|
||||
this.header = notNull(header, "header");
|
||||
}
|
||||
|
||||
abstract public BufferedImage getImage() throws IOException;
|
||||
@@ -75,7 +75,7 @@ abstract class BitmapDescriptor {
|
||||
return getClass().getSimpleName() + "[" + entry + ", " + header + "]";
|
||||
}
|
||||
|
||||
public final void setMask(final BitmapMask mask) {
|
||||
final void setMask(final BitmapMask mask) {
|
||||
this.mask = mask;
|
||||
}
|
||||
|
||||
|
||||
+14
-22
@@ -29,10 +29,7 @@
|
||||
*/
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.*;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
@@ -41,12 +38,13 @@ import java.util.Hashtable;
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version $Id: BitmapIndexed.java,v 1.0 25.feb.2006 00:29:44 haku Exp$
|
||||
*/
|
||||
class BitmapIndexed extends BitmapDescriptor {
|
||||
protected final int[] bits;
|
||||
protected final int[] colors;
|
||||
final class BitmapIndexed extends BitmapDescriptor {
|
||||
final int[] bits;
|
||||
final int[] colors;
|
||||
|
||||
public BitmapIndexed(final DirectoryEntry entry, final DIBHeader header) {
|
||||
super(entry, header);
|
||||
|
||||
public BitmapIndexed(final DirectoryEntry pEntry, final DIBHeader pHeader) {
|
||||
super(pEntry, pHeader);
|
||||
bits = new int[getWidth() * getHeight()];
|
||||
|
||||
// NOTE: We're adding space for one extra color, for transparency
|
||||
@@ -59,20 +57,16 @@ class BitmapIndexed extends BitmapDescriptor {
|
||||
|
||||
IndexColorModel icm = createColorModel();
|
||||
|
||||
// This is slightly obscure, and should probably be moved..
|
||||
// We add cursor hotspot as a property to images created from CUR format.
|
||||
// This is slightly obscure, and should probably be moved...
|
||||
Hashtable<String, Object> properties = null;
|
||||
if (entry instanceof DirectoryEntry.CUREntry) {
|
||||
properties = new Hashtable<>(1);
|
||||
properties.put("cursor_hotspot", ((DirectoryEntry.CUREntry) this.entry).getHotspot());
|
||||
}
|
||||
|
||||
BufferedImage image = new BufferedImage(
|
||||
icm,
|
||||
icm.createCompatibleWritableRaster(getWidth(), getHeight()),
|
||||
icm.isAlphaPremultiplied(), properties
|
||||
);
|
||||
|
||||
WritableRaster raster = image.getRaster();
|
||||
WritableRaster raster = icm.createCompatibleWritableRaster(getWidth(), getHeight());
|
||||
BufferedImage image = new BufferedImage(icm, raster, icm.isAlphaPremultiplied(), properties);
|
||||
|
||||
// Make pixels transparent according to mask
|
||||
final int trans = icm.getTransparentPixel();
|
||||
@@ -105,7 +99,7 @@ class BitmapIndexed extends BitmapDescriptor {
|
||||
int index = findTransparentIndexMaybeRemap(this.colors, this.bits);
|
||||
|
||||
if (index == -1) {
|
||||
// No duplicate found, increase bitcount
|
||||
// No duplicate found, increase bit count
|
||||
bits++;
|
||||
transparent = this.colors.length - 1;
|
||||
}
|
||||
@@ -117,10 +111,8 @@ class BitmapIndexed extends BitmapDescriptor {
|
||||
}
|
||||
|
||||
// NOTE: Setting hasAlpha to true, makes things work on 1.2
|
||||
return new IndexColorModel(
|
||||
bits, colors, this.colors, 0, true, transparent,
|
||||
bits <= 8 ? DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT
|
||||
);
|
||||
return new IndexColorModel(bits, colors, this.colors, 0, true, transparent,
|
||||
bits <= 8 ? DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT);
|
||||
}
|
||||
|
||||
private static int findTransparentIndexMaybeRemap(final int[] colors, final int[] bits) {
|
||||
|
||||
+8
-8
@@ -30,7 +30,7 @@
|
||||
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.*;
|
||||
|
||||
|
||||
/**
|
||||
@@ -39,17 +39,17 @@ import java.awt.image.BufferedImage;
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version $Id: BitmapMask.java,v 1.0 25.feb.2006 00:29:44 haku Exp$
|
||||
*/
|
||||
class BitmapMask extends BitmapDescriptor {
|
||||
protected final BitmapIndexed bitMask;
|
||||
final class BitmapMask extends BitmapDescriptor {
|
||||
final BitmapIndexed bitMask;
|
||||
|
||||
public BitmapMask(final DirectoryEntry pParent, final DIBHeader pHeader) {
|
||||
super(pParent, pHeader);
|
||||
bitMask = new BitmapIndexed(pParent, pHeader);
|
||||
public BitmapMask(final DirectoryEntry parent, final DIBHeader header) {
|
||||
super(parent, header);
|
||||
bitMask = new BitmapIndexed(parent, header);
|
||||
}
|
||||
|
||||
boolean isTransparent(final int pX, final int pY) {
|
||||
boolean isTransparent(final int x, final int y) {
|
||||
// NOTE: 1: Fully transparent, 0: Opaque...
|
||||
return bitMask.bits[pX + pY * getWidth()] != 0;
|
||||
return bitMask.bits[x + y * getWidth()] != 0;
|
||||
}
|
||||
|
||||
public BufferedImage getImage() {
|
||||
|
||||
+5
-6
@@ -31,8 +31,7 @@
|
||||
package com.twelvemonkeys.imageio.plugins.bmp;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.WritableRaster;
|
||||
import java.awt.image.*;
|
||||
|
||||
/**
|
||||
* Describes an RGB/true color bitmap structure (16, 24 and 32 bits per pixel).
|
||||
@@ -40,10 +39,10 @@ import java.awt.image.WritableRaster;
|
||||
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
|
||||
* @version $Id: BitmapRGB.java,v 1.0 25.feb.2006 00:29:44 haku Exp$
|
||||
*/
|
||||
class BitmapRGB extends BitmapDescriptor {
|
||||
final class BitmapRGB extends BitmapDescriptor {
|
||||
|
||||
public BitmapRGB(final DirectoryEntry pEntry, final DIBHeader pHeader) {
|
||||
super(pEntry, pHeader);
|
||||
public BitmapRGB(final DirectoryEntry entry, final DIBHeader header) {
|
||||
super(entry, header);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,7 +70,7 @@ class BitmapRGB extends BitmapDescriptor {
|
||||
|
||||
WritableRaster alphaRaster = masked.getAlphaRaster();
|
||||
|
||||
byte[] trans = {0x0};
|
||||
byte[] trans = {0x00};
|
||||
for (int y = 0; y < getHeight(); y++) {
|
||||
for (int x = 0; x < getWidth(); x++) {
|
||||
if (mask.isTransparent(x, y)) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user