From 371a2ef5b82f3c784049a91a5ef200b79a6e978d Mon Sep 17 00:00:00 2001 From: Simon Honegger Date: Sun, 9 Feb 2014 17:06:25 +0100 Subject: [PATCH 1/3] Extract Persistance Layer into separate Project (https://github.com/Hoene84/perzist). Allows to use it for other Projects. --- ext/perzist-android-0.1-sources.jar | Bin 0 -> 5629 bytes ext/perzist-android-0.1.jar | Bin 0 -> 14090 bytes ext/perzist-core-0.1-sources.jar | Bin 0 -> 29929 bytes ext/perzist-core-0.1.jar | Bin 0 -> 58711 bytes src/com/turtleplayer/Player.java | 17 +- .../common/MatchFilterVisitor.java | 17 +- .../turtleplayer/controller/TouchHandler.java | 7 +- .../turtleplayer/dirchooser/DirChooser.java | 6 +- src/com/turtleplayer/model/AlbumDigest.java | 2 +- src/com/turtleplayer/model/ArtistDigest.java | 2 +- src/com/turtleplayer/model/FSobject.java | 2 +- src/com/turtleplayer/model/GenreDigest.java | 2 +- .../turtleplayer/model/InstanceCreator.java | 2 +- src/com/turtleplayer/model/SongDigest.java | 2 +- .../framework/UniqueFieldGetter.java | 25 -- .../framework/creator/Creator.java | 23 -- .../framework/creator/CreatorForList.java | 51 ----- .../framework/creator/ResultCreator.java | 23 -- .../persistance/framework/db/Database.java | 39 ---- .../framework/executor/OperationExecutor.java | 57 ----- .../framework/filter/FieldFilter.java | 85 ------- .../persistance/framework/filter/Filter.java | 25 -- .../framework/filter/FilterSet.java | 80 ------- .../framework/filter/FilterVisitor.java | 30 --- .../filter/FilterVisitorGenerified.java | 31 --- .../framework/filter/NotFilter.java | 64 ------ .../framework/filter/Operator.java | 30 --- .../framework/filter/ResultFilter.java | 28 --- .../framework/mapping/Mapping.java | 32 --- .../framework/mapping/QueryGenerator.java | 23 -- .../persistance/framework/paging/Paging.java | 39 ---- .../framework/paging/PagingFilterBuilder.java | 118 ---------- .../framework/query/OperationDelete.java | 23 -- .../framework/query/OperationInsert.java | 27 --- .../framework/query/OperationRead.java | 30 --- .../persistance/framework/query/Query.java | 69 ------ .../framework/sort/FieldOrder.java | 75 ------ .../persistance/framework/sort/Order.java | 26 --- .../persistance/framework/sort/OrderSet.java | 71 ------ .../framework/sort/OrderVisitor.java | 27 --- .../sort/OrderVisitorGenerified.java | 31 --- .../framework/sort/RandomOrder.java | 27 --- .../persistance/framework/sort/SortOrder.java | 24 -- .../persistance/source/relational/Field.java | 54 ----- .../source/relational/FieldPersistable.java | 45 ---- .../persistance/source/relational/Table.java | 42 ---- .../persistance/source/relational/View.java | 29 --- .../fieldtype/FieldPersistableAsDouble.java | 41 ---- .../fieldtype/FieldPersistableAsInteger.java | 41 ---- .../fieldtype/FieldPersistableAsString.java | 41 ---- .../relational/fieldtype/FieldVisitor.java | 31 --- .../fieldtype/ToStringFieldVisitor.java | 43 ---- .../persistance/source/sql/Counter.java | 39 ---- .../persistance/source/sql/First.java | 57 ----- .../persistance/source/sql/Limited.java | 53 ----- .../source/sql/MappingDistinct.java | 54 ----- .../persistance/source/sql/MappingTable.java | 48 ---- .../source/sql/QueryGeneratorTable.java | 37 --- .../source/sql/query/BoolOperator.java | 37 --- .../source/sql/query/FieldsPart.java | 43 ---- .../persistance/source/sql/query/Helper.java | 49 ---- .../persistance/source/sql/query/Limit.java | 33 --- .../source/sql/query/Operator.java | 43 ---- .../source/sql/query/OrderClause.java | 26 --- .../source/sql/query/OrderClauseFields.java | 42 ---- .../source/sql/query/OrderClausePart.java | 22 -- .../sql/query/OrderClausePartField.java | 50 ---- .../source/sql/query/OrderClauseRandom.java | 31 --- .../persistance/source/sql/query/Select.java | 105 --------- .../persistance/source/sql/query/Sql.java | 27 --- .../source/sql/query/SqlFragment.java | 23 -- .../source/sql/query/SqlOrder.java | 37 --- .../persistance/source/sql/query/SqlPart.java | 25 -- .../source/sql/query/TablesPart.java | 43 ---- .../source/sql/query/WhereClause.java | 65 ------ .../source/sql/query/WhereClauseField.java | 50 ---- .../source/sql/query/WhereClausePart.java | 22 -- .../source/sqlite/CounterSqlite.java | 36 --- .../source/sqlite/CreatorForListSqlite.java | 46 ---- .../sqlite/DeleteTableContentSqlLite.java | 31 --- .../source/sqlite/InsertOperationSqlLite.java | 40 ---- .../source/sqlite/QuerySqlite.java | 216 ------------------ .../persistance/turtle/FileBase.java | 8 +- .../persistance/turtle/FsReader.java | 33 ++- .../db/ObservableDatabase.java | 3 +- .../persistance/turtle/db/TurtleDatabase.java | 48 ++-- .../turtle/db/TurtleDatabaseImpl.java | 2 +- .../turtle/db/structure/Tables.java | 24 +- .../turtle/db/structure/Views.java | 4 +- .../persistance/turtle/filter/DirFilter.java | 4 +- .../turtle/filter/TurtleFilterVisitor.java | 2 +- .../mapping/AlbumArtLoactionToDbMapper.java | 14 +- .../mapping/AlbumArtLocationCreator.java | 4 +- .../turtle/mapping/AlbumCreator.java | 2 +- .../turtle/mapping/ArtistCreator.java | 2 +- .../turtle/mapping/DirCreator.java | 2 +- .../turtle/mapping/FsObjectToDbMapper.java | 14 +- .../turtle/mapping/GenreCreator.java | 2 +- .../turtle/mapping/SongCreator.java | 2 +- .../turtle/mapping/StringCreator.java | 2 +- .../turtle/mapping/TrackCreator.java | 8 +- .../turtle/mapping/TrackToDbMapper.java | 14 +- .../turtleplayer/player/PlayerService.java | 7 +- .../player/PlayerServiceConnector.java | 12 +- src/com/turtleplayer/playlist/Playlist.java | 39 ++-- .../playlist/playorder/DefaultOrder.java | 6 +- .../playlist/playorder/PlayOrderRandom.java | 10 +- .../playlist/playorder/PlayOrderSorted.java | 14 +- src/com/turtleplayer/preferences/Keys.java | 2 +- .../turtleplayer/preferences/ObjectKey.java | 6 +- .../presentation/AlbumArtResolver.java | 14 +- .../presentation/OverAllFormatter.java | 9 +- .../presentation/ShortInstanceFormatter.java | 7 +- .../ShortWithNumberInstanceFormatter.java | 2 +- src/com/turtleplayer/util/DefaultAdapter.java | 9 +- .../util/FormattedInstanceComparator.java | 9 +- src/com/turtleplayer/util/Shorty.java | 73 ------ src/com/turtleplayer/util/TurtleUtil.java | 1 + src/com/turtleplayer/view/AlbumArtView.java | 2 +- src/com/turtleplayer/view/FileChooser.java | 28 ++- .../turtleplayer/view/FilterListAdapter.java | 10 +- 121 files changed, 294 insertions(+), 3249 deletions(-) create mode 100644 ext/perzist-android-0.1-sources.jar create mode 100644 ext/perzist-android-0.1.jar create mode 100644 ext/perzist-core-0.1-sources.jar create mode 100644 ext/perzist-core-0.1.jar delete mode 100644 src/com/turtleplayer/persistance/framework/UniqueFieldGetter.java delete mode 100644 src/com/turtleplayer/persistance/framework/creator/Creator.java delete mode 100644 src/com/turtleplayer/persistance/framework/creator/CreatorForList.java delete mode 100644 src/com/turtleplayer/persistance/framework/creator/ResultCreator.java delete mode 100644 src/com/turtleplayer/persistance/framework/db/Database.java delete mode 100644 src/com/turtleplayer/persistance/framework/executor/OperationExecutor.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/FieldFilter.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/Filter.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/FilterSet.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/FilterVisitor.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/FilterVisitorGenerified.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/NotFilter.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/Operator.java delete mode 100644 src/com/turtleplayer/persistance/framework/filter/ResultFilter.java delete mode 100644 src/com/turtleplayer/persistance/framework/mapping/Mapping.java delete mode 100644 src/com/turtleplayer/persistance/framework/mapping/QueryGenerator.java delete mode 100644 src/com/turtleplayer/persistance/framework/paging/Paging.java delete mode 100644 src/com/turtleplayer/persistance/framework/paging/PagingFilterBuilder.java delete mode 100644 src/com/turtleplayer/persistance/framework/query/OperationDelete.java delete mode 100644 src/com/turtleplayer/persistance/framework/query/OperationInsert.java delete mode 100644 src/com/turtleplayer/persistance/framework/query/OperationRead.java delete mode 100644 src/com/turtleplayer/persistance/framework/query/Query.java delete mode 100644 src/com/turtleplayer/persistance/framework/sort/FieldOrder.java delete mode 100644 src/com/turtleplayer/persistance/framework/sort/Order.java delete mode 100644 src/com/turtleplayer/persistance/framework/sort/OrderSet.java delete mode 100644 src/com/turtleplayer/persistance/framework/sort/OrderVisitor.java delete mode 100644 src/com/turtleplayer/persistance/framework/sort/OrderVisitorGenerified.java delete mode 100644 src/com/turtleplayer/persistance/framework/sort/RandomOrder.java delete mode 100644 src/com/turtleplayer/persistance/framework/sort/SortOrder.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/Field.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/FieldPersistable.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/Table.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/View.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsDouble.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsInteger.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsString.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/fieldtype/FieldVisitor.java delete mode 100644 src/com/turtleplayer/persistance/source/relational/fieldtype/ToStringFieldVisitor.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/Counter.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/First.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/Limited.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/MappingDistinct.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/MappingTable.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/QueryGeneratorTable.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/BoolOperator.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/FieldsPart.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/Helper.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/Limit.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/Operator.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/OrderClause.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/OrderClauseFields.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/OrderClausePart.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/OrderClausePartField.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/OrderClauseRandom.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/Select.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/Sql.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/SqlFragment.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/SqlOrder.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/SqlPart.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/TablesPart.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/WhereClause.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/WhereClauseField.java delete mode 100644 src/com/turtleplayer/persistance/source/sql/query/WhereClausePart.java delete mode 100644 src/com/turtleplayer/persistance/source/sqlite/CounterSqlite.java delete mode 100644 src/com/turtleplayer/persistance/source/sqlite/CreatorForListSqlite.java delete mode 100644 src/com/turtleplayer/persistance/source/sqlite/DeleteTableContentSqlLite.java delete mode 100644 src/com/turtleplayer/persistance/source/sqlite/InsertOperationSqlLite.java delete mode 100644 src/com/turtleplayer/persistance/source/sqlite/QuerySqlite.java rename src/com/turtleplayer/persistance/{framework => turtle}/db/ObservableDatabase.java (94%) delete mode 100644 src/com/turtleplayer/util/Shorty.java diff --git a/ext/perzist-android-0.1-sources.jar b/ext/perzist-android-0.1-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..b83913659a1df6f10f3439a9288dd7aae1cabf25 GIT binary patch literal 5629 zcmai22{@GN`=0EwWZxAUTgJYHvJWx#?E5yxSSO9OY!zan5Xrt1$4<5p*=5TvQIurg z$(H`3b2{YL@&D$U`M&F#=egf^?&q2JxvyIbf{k+?aCFh!Q&If+@XrS!=B^IbmE%>> zP~zA6CyW38@bdMMKzOh8boG|$ z2n-5OesKe-_Oyc_yz&J2)0z5DX?PldUe$>x9ZHDKO=QxQ0;)%kwz}M-iHWI24p0=) zw{@r!H&Ex-Q528>V^QyFuWG=rtpEU~Avb>8F*ar^HunGS6##&q3OM>nm;ifMs0;K& znDePH@{?f*sGAS`Hu6L`-re7cqW@F4m5Z&LE8OI6kXb*-$OpbD-oNT>_)<}D{RI1E=c!s>bkZH3u89kumU1 zaty0INGK021BiHXia-TftU4k#zkhs8Tk49mE2c#&l0G8JxsXE5T}4&L7{0ba5#7j_ zdO0gp$i}>d=kwf`66rQGX8%Qh?1C?ew|EmjtX1b_N(WyiT9DC=U^i-QE`6u68pH8I zwjfLG6R%-fVj8YtEH?*7*jI)QhKNzc2IELL_`cEZ~Zh zWIGNCXsN=6KOm`BC>&MNY7lMjX&hzxxptwUc3-8 z?WIbuY{&Xg;i5|uG5$A+P93qA`|70H56VEJJcL|j+yKpZz+wl*2&5ej;P2l$ha8s|q z<6t8M*j!m|9*o<9wx(0A_Z>Mc0)1Pllxa1J3B9UYa{QSEnhf@-QXgqHe|_r89jc|+ z1X8#{{y_D?=Z?=lTlRcS~#z_Dc`nCZAlnJPAf^ zL>As*uh(fs?tDZ9Xgop(Gi5N7mxQTN&>rNQX3yG3o3d5VHvoz_?*iY-Zv$BUSirb) zmsGd0H;38e4N5wCxjKVJ(j;ye@YNTQXVHYkFIXh-t0EsLX7;# ztr}#M98lKZ@0^D$g|8bEjM*&H2it*xdZC1audE>+$vYWKn@Y1e7q~jOnN_A`Ijn;v z+9_`2hwX>n(J6>rFJ5QsXNoZ~rn{$xok`+%gSj)nD!ELNK}%F`Upsz!ZgGGV9Jwbr z%vf9@Wo>Ai54(|f!0}1#Fu5^4!2An(G7#Q+s|O4C=KiCQdvDr@jRSqSow*!y5N*#_ zX9KPQVmNJ7(2?85Ks*7FJ3jm=_yIvzH5;zQT@R;j(I4G`ngX6pv_pxI(hKrEFqg?} z%Bovfv`G}SE}^IpnVPhFtxM@cGbz%DQo8%dd5mnq}3ZlZk?~*I=E%=RC(#{L-KKH zy+M+TDN-ddc-SUglA2c~K9yFWDOLEeEk1N1i1&x3%w&+>_l9a=lI7be{ZC$++wzRK ztBh63QPB_gVU6X>s1=x%rH+`|N%q8SZ}Pv=r{?L^GwIY%y+{JD;2R-<_q2Blrrzxw z6lLQ{Uyq$h#@l41Dtc**W?WO%=nl;`6#I7G_gR2AI(u(hJ$9fiGJR0craYKQXVtWa znxLb2J`Sa5OWj2jjw+Gwp{Aa(EG*VGpe{VDXia101<^<}#LT64kgi5o3L^pl1ry)J z4o)43Gn^ts=P=U)j0FH(IqOJNg1g=RZD<5(c55^V5Wo7y?dHTjO*>oO3CvVUwB(=6 z4hGw*IC2ui?JbwX$EeRWh8*nduYD!m;(7I?A9nSQ8xHeYP9$K~cssiQ)o3c&EB6Jj zoUT}o^{OIG@7BE^$hYx|vcguY#38$f3H;Kf9G0bYk38+C9)xH4F`Y{CF!;r~y7Lf|B?wA4W zc4E2&MbsaS-;l4<+(NM}*8J8IgrU^SxZ{KK;OS4p9%TN=6^)440amR4<5@^s{+a1*oP9?jedSI zXCeEHSgNokx5K2{y`4KaPFvLJ{#SO+3|UttC_2+~0rKr|pf-H3;-jw&+2Xh>+R;SA zvGzlO%F0BCMSEMTI*|3em4bo0;gybkN_h86`a+7U>pV-ltf9u9!xF6dI)&VE?eR6W zX1z%Vw7-wtX#yXKO$;S`m>v^6iyCz+1On~?`zcdS>XR7lPE4zjq4#;V4Kv@!JjtU7 z!@|N1(`oYk{FgD2xJO-tZ0ezu%7VNXRr5usr3jdv=yvXk~upM1fX92Hz=5xs+J|f&rrWek1c=_Dp zdZ-090|V51epx-x3PjXDC4xG7Fz$MgLhkJV1J=}{^4<#xYTG2uQ;Xgy{olcRO>Dkh zMy|LosumRDfgP8Vm!^`)q}K3$r!X4DVkL^{ta%KDLT6E^;0Coqy1FU3x~XAQ=7}Z? z*IIJG5+plF$r(M2ya|+U2-RzjZS1>ee#x@iS#(paM_pqtaOK0M^d$PcC>f219n7v$ zb}K>(tK!)mNU*KkK~~Z;d!d(-sGzqYjin*ktiqdBU}ZO>(lVyX9Shv7c8M2pZ%tx5 zYorY|uzWT~<4vFM+g;5hw-#a`qIvXU7n4Fz*%qwjhTmVk&H!Ge z3g$@Xs;t&ebwiT!U3QMB-WE}(U1-yj4Ay@peeL;Qn#+ByS{4}v!fU)N=+@f%cfofgx-VyVD?-Jla#f5Q8Ddzc+n+%p4tG%fp;VV)DeFWLaLq4TQ~5< zl)!ALM|l=sM}o0K$$MxECPEUl%bnN!5En1X$_5FnzFRfrF`$>Vxg+z~Huf3!qHUpps=`2DB6ghqSZHY9R7IrwBA_e%p8FlSS`+w;N8mc-Mx3(>lUS( z4MXqXJcU~b=c=73r}`!3#xW&7OMZ;k_8QRvx-BgcfINb7<1wA=JsZ{lrpJxh{0y+6>#*Tc~@`=r0Ie|Hx`I zl#J(`OP2Q~z}-rvmQ?_1xu2kprJpD!^%4FAdDz1sUA|_tw>90~1Lc;U$1^TvicZ%f zI2^P&Y=VM~5@-lrL0K+@z|NB?`bGj>H&Ly~u&F@+wa^gr!1g-2- zy<*adp`8_Zpem;jlvapX$EQHzO^LH4^FuLB`SQjV}K^O?p0H2R858O7{G zbRHA3f$kz|$SgLtbEwHy%XT3LZOT+jIWXzrAh6slz~p=`g}j`)^n0>{2gPIseo6|$ zkFXG41h~ACxYm7Mh76z8t6X#!^&~C-158XdVx9%!GsG&XXrTo;hed_`-@XZ^oiP^~ zU`g)ie!@lhmG);J!aoV5kk>j+zlWE6h$#MFh?2_YjZcHcsYsvgdKQ>Q(!Ti}i`5WelFUzxF&Nfqy zDgCqQaJZQ~8r-%PBeh={(_-9Cg(<_`FV8<&sk)E-_ nAI8~fbIw=y1MI;kpPE)1^YfQeZ_#kefZA{4Cq}_NP(YLOiGwu=09T4U>G1V zNC_TPW6;+gpnvqgib?WIi3tnIE6_;_UrLUSyp^D(n?jJFr5YcdsFh=wW%|5rMK4sAs467-EYlf8K72KJq6 z@qQn2G`ePGoJG|6j@yfK;es}eHVv>pCic(ygM%ifZ}R8N|0(eO0YL&L)`nJwzYs(D ztC)?Uotvq>!!N|K|C_k3m4ThLsllIW(7&zra(?)h^>Z*VM+h)5nqR5OIvU!!%G+9) zIvA1w==3dg?d{{`Ev08<&^@i#K3XCce+dis>=_;>pOTuTQBR$0cb@kwz)tgV32U>yoaD-in z(Q$3DrKKS|4cNIN&EgZy+oRTKaJ&*T*PK6^aFyD&*f+IN(muh==~&)IBl8dm@g_`z zKFZS^*#sbmQIWMu%`^*RA!q9D=|iDj{E_fPbgTl`kGU1fG$CMWps@#56;FWvTo(XK zDc9LbkG%ZpA~VZli~JgU-{JbrG#qW}>*cv>&c(L_Mnebqsl=(r3*4&u(pS%J+`Hk9 zoHux7%sKG7Y#p+Z1hL2nvOn3xxWGEwBsPVS&ITR2K)he*Bh%Y}s5}p37rNssxR#Y* z7k9}lxj`Y!ZOL-`Fsq;*zg)7WWTj4OdEHRnw1yQ1#VMt8PA_wZUsUQjJZXap-fNmh z)CRQ9_>V z@b4a69Sxcf%eEs$mNFk z%U*6UeOnTRFd_VeCz(EXt!BxjfVf`DDwF+=hNu0`+uPmKQ(mwzeI8hRVw5_fIau&q zoc3ud6Lc~>zADZ!%9G}{Z2}?5@rJfYe21eb4Hh> zd{YHV64pcsU<`Rky_EHqDne($>Lb0p^7ErD0o=kwjmzc0d_xw%IPabJ;$D7Lytma{Y@cc8i^1 zY@$+={*Y^yLOaWdA(nX*k@x6Qg-si&+AZ%Sc`l;}x}9feZnq5row z?D$H?z{cbwVEdSYA0IjXrjiglm+2VYXc#B1>$r|qgq=Z#lqpd_fNo)jNo?~6M zrl9Zu$sTK8iX|StG()-mi&}V(!kefF^CW#N3#*sYEs{>>F(M)s6ZscTK z9z{bE!Z)S9Z7ure!XCv_8$_Rw2M{hYc~`|>$pYVuTpBsUXa6-kg0~OM z1Il5NHoH(FgLeq=YYfF6aByBT%a+X)mINbas#m$H_v|G_rU_=ZkXvIk#9i?g#_LRi zlxu}@TbRUWUJBu!+k;DUOKQfn_VnR9_c(IpTZ2lN> zCif=E_(5&%NVHcdB`qQZB@>v}_Sc`u3}ZE5rseB!lws#>{Q$$VymNxDCDJq0>k2=V z72}lFwMe#bFQxm0CgV&MSoTDknO zSRsr(i8tgP7$b^-MYlIUzXk0S3s7KSw7&|tx2Be$05kYo zpw%mCeh;)aGYJ)%YDKSvvM56MJ{X{UFcpgO&l8I_5tAfLJcbUHfNNC;e|)C>K-i(D z_bR&g%xJ?J(9hMX&XYHXBba(Jy25e0Vt=}_==pTFP3>*U9h)_%lN5u}pN`DQNV`dQ zBGyE|?gI~lM9LjA^r+Gu=1(KYP^j$ap0KW%lT}WA$fC79jLG(CKcQTuzNOf3P znMiA#XyE2HUp8?_kU1alj0%mI$f4t`zqR0%3Q2<3r(JfIWusjNe~-d1#hu~L7+Q$B z)7=z7A~?U;A`^$!(`H)I+D(PGi~Uty6hna+9?epVByft=tVgCLC^2ns_vMq&JMj{E z-P;I(`poe>5Y&ZCP-h5) zolisj!uynHF*h(C$sK&deYsHWh}!7NlOkz)n1UbPcZ58={5NUuGEd zXcEqF*vm*kV*Y9xR>(sfwI(uv;wzDC9fT)9MfiDI1Onh*N64OE7I_iEF)Xa{N#D?R z_$%4@dzd#N>i#@aXt!5Q?)nC}&PpAGSaA%DBD~VNM4a@TX)gZVhBeSnGE^S^lRR7P zn*xyOL_j=BtEkE9IOKR*$$LL3nd z-Fg8ZEq2Qz#hQ3?G+m5yGcdyWF{UcdR@?DF#O`g2dBr6QWx2B*;*gZFPELc zmQ5B_IxTU9$`&bfR=e@xoGn$FjMqB?5a3eb^YJmL+DD?CaYWz)+6NQiB`RRIyY}+P zHuA92t1>808gkjNDPPZ8>@T`+VnUzbiB2h3fFzHypnF1UcwLPCA7PgboHvbBHP#I#vl9k$(iPw2FDk{Qq1XudSQt;R{PqjKy1 z%EH1=pIt$a7~J>w7qbYB3R#& zg^6^v;k1f9V<&uoApdlh^<3KRa~B)wyAeO3rZGS3O-lL>zruEx7oWDb+)+DD`;pEB zVR$#%cyB(FH>r0^zcJ~ZAbHT}rYCur_A_ptH9k*+lKc`6C2?kssiGJuDCPvd!X;LwCc$bSAPG~N9M+9G{yZR_ zF&$4zD4x$vo4d+dMGPO-KduRNjQM?IT|mQ&p0O^`9Nze_YpAcp$)egMWar zP9{Ib5c&FG*s+GOm5a#^7n@igtG$LRea0Cp5s-`v2~ln1h}Pc zH}xKqXqU}jtFC(~^#zg9#sYZ`hjXqzV75${!cQP-Xgw$qaLTJsJ!8H~2?oD8$ z0pHM>fMv}fddyqDqR1|5d4u@X_ehm06yT^v&3-SFmWI=)nO zLvGlM*jX#RFoUL)X^k zJvk|gQ5HkZp;6m;N@qR0ssNw?2IFWL=?!&pUCw+{PV}6}vVcc**Nx^0Euarr%(+&x zzE~caae|&$8KfJosC9WUWYZH|^fAF)A@`d+$JkxaRciz)+1O8L%cXbzyddK?$6 zQ64bC&5=^@F^Umpf(c$FY`~oUyieIk|C(XZodc1sny9ZyCP|cIV#jF&*qeqkb8?VU z++Gm2ZInLt(Z>|fvH%=j^+|$Ou`EQF#Gg>AGg#LJOwHlK#UdRzEtD~%*NH$THsMv< z5>>0FS$4PXxr%(K9a6XEe*HS(vv93f!g_yUv;#b z2{ly+_g(Usu$s|!TH5Fkp45&VATstYEzOs?r<+D zXTPLIp`D~b#fYUWLARJzn^i~-JNZsEz4xH_m1?u<747yo>w=>akk)dDr-#CdkXE%} z0NN7OeCrjwjeDX^je?#eK)pXf!UB>%*X3?2Ta}X7rzcILODsk@*E8@AlB^;O>&B+v zoP(othy|X9I@(ahAlqM6Qa(1{^d*2`ex#7V1xwuQOJC@xgLX_~EsOn%XnUvh!9zgy z(#9P6amNevZ(n50ow5}^k1zDyzlV-Lq*>|+*Iq_%AxueD0xXB`c9WqM&(LwN90D$c zmYbBNH^s*tkJPBesLb3OZJEr5oHnT_Dvon0NxQo~ZNcFO8Rq!Ky-uOydEH+ad|sSz zH{1EOCd%>1g4{;!Q`XdD@_;y@wleo+;Bv9=-mt!5lu06i1aL#|F)BEsVeD$5uXxj! zRjM24d$k4MV4YV`R?5{T;o$($VNbIsMkVeC`PKAicYNaU9sv`lr*h28Z2r@-KP{dHn%FZ$CDdJ9%5nmV}(9-;|`| z99zy9{WK`(D}=panL((<-<$D*s&^tQa%q_N<`{Xz&9cPam(9(RAt=he=n zJ$cJsbE@0dB1f6S^GKh&!;^qbD>v#cvK*#jNX+hFA)B7}V^^%w+x?jSVCQ+_NW1Tr zOT6F?QW{~}ms#4OingcQA6ppXz8p%T&u5|6ll0P~E0-L#=+Qf6y$4>9TloqmMQtyY z*k2!L@NdY4FH(lN`Xw_;$?M|`C4qe*G)}^`N1 zO)^g1h5Fh)qyEwTGuHdi_1B{OPZYxhU1^+aUkBEmWGap0^f+Nv4-<>MUYurfgv1`4 z5TQt|&lYbXPKIHtNS4t1Z^r!awE+4tDOE26&G zogrV^GPhkVd%ZeRUV%G619dXpbAT$x3BMFJ)Q*0RXBkVW=vSNgb+0YEME5uf7!nbt zMhz$#Tns=e`bBs564{yIJq6UrQ^mJR)wc6B7 zI5V6~6#N@okmNlH1*z0mhXqFlghtIYZ@V4h=V}ZLCi8rTMBrrW{F1Mj)1d}yQ zf+Kp15SY=e9S`UQ@RT$&W0b^#NZSg$wnOO-c(>2+rhYH9;0&1A|j3>M)(LOp`$@% z(h08PdyXgd`l5;Vm!yNJYh>%k12VMh_#(2N3YBk9(WltUgfYvK8cE(?91MX@v$x(1Kuy|@ldsPKH{zo*j9i;B#IPvZZl3_ zu?ua%_>ROvBo-C{dBWk&!=BM8<{a2J)$Q5rPkJ17IyPx_ZVS9aCLH#Wh%b7Q3I~P7 z(>iz43Ij}HBwpVUjRp^AX}qs(Zo^xM`r?BNd76|)=8#|C zZ5qX>mq~QgWNk?&iD_ACUUWQ<$!!vgU4bR*h@a+c>er~^Y*IkO8{e1h>$9mPt59c} zJ+5?zHW#s7b7*LBR9`hXB)7M4#LYRQtfi<^i|oFJ+`Kns8agbK;8BpdFdikTY^1vj zN;dG=yi{EwT2eQy@otz#EE&fYwa2!E?)#wp?C)n+pByb$%NJl^(rEu5eFDbc&lK&- zhstQm$WN=#s;HQdz=K?>xgzAwSF}8^`HHaU2ryC5MCDFmm^CbT?+mBHv(ZI{TBYcT!j0Tud>Jj6hPSh2D@7s|$PsLVx(&o+kn@*iOCTcSTi=be zv5Sjs!X3!MB=#|2?9Z~zfnx}%hNWcdw_TAuAZO?38WMXZ4eb)sW!j6rI@4LTNEm#l z2csJAA*RYzycZ}fm#Zca{MAjq#)*g-QyIQFS*nhrM6V7otFX)^H!~qKnGiG#Kk^Vl z1tm8SXh=(gFko7^k{Kj=?kOh!#onma8@CVaMYV*YVL2_`e#={~8)mnL=;U}N$V^cw zm_~Aa>O@)gioK978>&yqqQH-ipMp@?494cO2hUC3H(OfU>cJ6sml(S3P!w$jRU*fN1SdjAZgk- zdwygAb9)7O+t3)$>g%&(qwQ|;fp_JImndAKqbV=qt8b6UR?yUnxSsnyn~7+97D1`Gn+$C5naZ zyo{71kZZQwi(q7urw#iolSjU(rD3( zD*J3AXd%Q{XvGhKh;@VG*+i(zGx`uvl_~G@@*GwR;~Xain6|OSOkQb!@q*mi?gEqC zc(S*O6RLndA7_}c*@K9P+%*qdNmireN&%2O3D2P>lpxs-*?iErzp*eugL3-0EXdh5 zBJ&OXXWyV(8`(}$l+#Us;!705&w?m~>v%n6>I4|)j65hdLcN7w!tVP9#K_5MXCapk zD~poo=s5OBb!v^XKH6B_8J{gMM(OTl&V3mDHaD=*!ASR!4LO!2d1*3kyfuq-uC1_s zw^TS#SbDEX52!aQ7j;K)8Afj3udljYU3RfG$radAG>;n}zM^D#Ex<|lI$H>X>PI>x1#995JZu~GnqkAzACxUKlJ*_P3;NSjvpP6WO2PzIH#MioFYu{nGCcG4Gpdi>S?_lL~XqjAKjRoDa$Gy8?{Z zt|-k}+^C$mu%5U$ef5}LN9X5W$aLupMfa@LhS!p7(0FB;Hlfkh&!}QeLPmK-fKS%-~D#TEO+1y2^29XFac{A%}5XD*22`=&9&O1b_(u&V;sa|5;s3u~iu{ z+Z%(OU^ckv&{cGf1W1GP#^lL1Rg<(s-Hi?Jko6|;M(>+XL5sfAx&r&7e2dc38e*^c zRqZ{L2-a9>OY5*|l+ZU&hVe&2R;;fVKiy1QCzN>Pw~EE{#@>RHq^eW7m>-ha-dY$c zO{?3Y)(k^{4xkm!w^1U^Pl%us)a1n&a(gqIHKYhq>+c*@gt=-t)AICTqevGyB<-Ym zh7OM;)?%drkjr+m^j}9gfQu8(x4D_m2WNWu4ST=h=4r-ZeuMe@wndn&^(7m0<%$Pt zS}^_UB23WEP}jlQPT1P+EvUB+x^DfmN0_ew>JiE!KT4^$SgCI1#O1gs)1a&HWmwEC zAfFiq_*W$9=-IWrneLkoSfzdD72?H5=rZ{-oChoOn`}QvD;#utRKG_Old;kG?O1a1 zn-5P9Utn}lBq)oLjzkCvB%#Je0|m7`+yguBXoIRXv3tQI_@bs5c7SlV}j0w-_% z@7HeLrK=~Laj)7z-r_5NLe{E1p?}}{FiR$=w^$4t$lqfXRKH^-)I?S}I|R^U$E>ur zn@_kOOgb}f7|3dTZKj|(P;r2AQ?iL;KzBNCslA0AN8xv4+)6qW#gjQSwI;@zzcx*g zWMsN|7n01zrZh~Cz@$xbHs78vpVSVmmnNgsJVCvJ_SJ6Yn!+}?BH{S>#ce8`;eElt z%@vSTy?C~%kqprzFxX;XvY0mT@mqmSqyQlBJfa#N+%Qx9RO_rg_L1%RLq6RX%}KJ_ zenj5SZs}|d*Vn@lRqsNq85w&KcelYB&chn~vZy_%{OjG84iH1<`(@ke2zLvM3_Uru z>JQ)M4NJ|`_m>8Bd$W5}0>htIBdiSEyFoZeseYAmVWHDeEXIP%m?qZl% z$Hp?E%iQwHOv*dP*2oAo_S>&*pH|my%BHP9#DkuRwhwi`Dl3lCCLHwh?9H083jK&x zKD58WRz;uJ$H)i3Pve>U@APqUg;bQ(uCUppxgs(dQ`q*6Ej`Y z=Fp1NQB{*-X>IdpH|;~9!}4y*NjJ}8(y?seP)!AMp>(+^h&XcI!g**%a}z_;=Qx6W zkSI4r%INxr_<8vJ$wyveAr;C6t1R;Ir@r_ts^1X=$m5?tz42cXIs~m9L9GS5zq)#O zti<=m!obrZ_X>Mp16^L6GbK8CHp@l|st=JOY)BEXgvfT8L;}=Uh`r`~&V!-hZO4~( zClgeCn1GI2+`zoHntV5A{_XJgmJlpMXQcbNRlIEHF>s~Y=H(&Ti7G?2?nXy26nq~( zw&<$Cf*selXf{}(S8dJ$9&yn(ISfi3>y+#Ev_0PUYdoiSIkInb1{=G5bX1N8`P#xF z-30PEUlgL3>?O1f$HQfIH8a!ZEdf+kWwo2Ly`_Q*W2zIhEk^#om~ z(wXAxS3D*zJ%%-2sTM{-`GaBIPRBBe8Dsmy(EdkLWv88;8IrU)Nqi^6rAPbl6{(zM zimsaK;PG=M24d}XH`#}QV(XNS4WHx@G&%Odp1&+p{-&!BAV$8;ZFL=27lPdFyt`J z7GI-Fu_}MJuEb!a5W7*K^a;2Q7vg0r1bE$tUg8i)rHe5yYOO!B+6V}1uZBn4Z zQa(?9K}vQTUMt=JICN;I^JQB3!ju-peg^)9@ByKhT}l8>Ofj>{@H91fH<_)K`02~_ zF_$-aleRE{bLaxq20@RUq^aQ{d}f2D*Wml?*_g<@yDXxSTn5&TE#Vj4B{HGj&hhVd zA0*H_=yQYag<)}V)=ao@~9^7sQqRByeV zmSCBp5_B)$5ub|87^$hY7P+p?+*}syx>PQgCyoW)<~VM-92@P1A96UBsB+-y1TmFV z98bW$jcJkR_s|uR2F9@Ip#>P(zKWJjDbQ6pDe}Q&Wt~0UJ+8fY3~extFu3si2s&}J zUx_|MXRhZeSk1k`EcAsEKyoQ{rtvtOeOVAB<@-V8b9e2BGv?uR+iAi0(Up%6L!6?$ ziZY!TFEVVYux|iYK2U>GNR-W3s|wLaq%}OKbdzdJtL{xt7)NmH+#y$VXy7WZ-yx6+ zv{E9Cpm$+u3I*7angp;nGpdnl6PWLQIb?e55A*Wq|G@u{>Tkc0M=sQ8D^^whU#cJL0q1hf*RYFy96beA{CU7Z_Zy8O$cTD+9p^ z)8jDH*zDd3F0weJCrrTgy2lI&rV{^))bf&(uS|o~Y5}oOxGu2YCw~1LI}9Q&o7;gF zzAv?NcU5Aqe%++;#@Wnq_|i;85@WJ$baqF95-DIV$T!MGfvk2L&s9VC8UNtZWal$5 zP;(z&;Ok+2N5=LJ4DV*bNIS9l?HO<(X5q3h8hZQ|h}9gUn{Ca|qatB<|IK_&GQ$0w zP#j{kO0I==A@=pPuKa2b0he{7lh%q>H&w>X2@wlU3Y7Bmrvri0)SbWz zZv+*{xBC5^M$h0}1{vnbiw{3{-Gbp4As@W(IrkR!`?&aD63u-v&_0`H(1E zM2=7p!Vl|O1F>j|6E5y}jJsfbER)q}2i70m2hneGL*bMg50l>CNm4)&pE4C3bxSiA z$|>%;D%MtTy@WR=pG5A(nE-4N%)Ovf`as-w2D2GYFB%&yw(hGrDJ2{mX1o00#i ztsvMjM44G=rN?8q0t+^!B#D7LNFqZL8IxSQq(3@TU_lajRQ&p-a0ijQt)iEb@sPGW zQ|0Vi&hUI(Gou_Q)qQ>Lsm+-WfA`sD1(b+EP{um|HR%Dr^4b4nyx+R?e{0XzD~ws8 zF(N;%6s)q=<)K3dpsk1(o6YL8hWO{8`@HpwA!S1x?-$pgJ)Au}yXD~qBPT)R28-IKlL3^j$5%-Tg%6CosHCEsWA8G#&a*&A{sdsd{t9wzZe%{?cLM z7@1V}vc?g{Mn?L5<>GlWWbrVOTMV-6pWb2*P>r})#5?p~I8|q0Q4iws;4vsH8RcP_ z2^1bU+!z&EWQ6J}C#jHuo7R7t2*+TX!tR;!72hAkd9y*ksF~z#({H9Cgq$)oQoQXv?!k+1F5i+bO)ReYnsQ#)HOO?~ z^ynrt8Z2llu@dM6SfM^KxD{g_&zlww9vpXd<@V6)WWrPsWm(5V^M#9YExdC0kfj^T zJvhZ;Axjn6V4J?c(tXW6T_t1Gao4sYa!%qmmLCN5xCJSdu>akv>0b8dI7)M+Lx{rqWwW z1UmHG3QWff<8>^3b64SJkO*lnjfc#$Q*X1O~Ynane>#N1YP06Ty26WPXfN+1JtjdbP9r8MD_Wv(CP^bPwkd~5Hzsc*At}dD zrNF>k`fmTLf_{YQxZ0rTH!{C@!D`B?o5<}dW0KS=#Q*73jdtbZVr zgLcS&Jl`J^{1xl^XA?g&OMjS10$tnutBL={GyNI*XUg3V=p~Sk{wwtVK*0Oi%FlGG zA69?}zp(O`)&IRw@-yzwO_v|I2_Rqj*V+FCm*hV!n4ghUN!RDSh`?r*8O_n*rDrG)u+ zwC_dC@8kPao`cxqKTYKyX#Xr}{y>KY`)@_fANYAbGXDqk|CBgCR`d7N_wy$F!w4k( g|NkR=H}YdkmXUx2byGnL5Bj43Ww}uhA{f~J1JITzAOHXW literal 0 HcmV?d00001 diff --git a/ext/perzist-core-0.1-sources.jar b/ext/perzist-core-0.1-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..68193b0f6f21b9f7eb99f5f5385720bedb5f3d65 GIT binary patch literal 29929 zcmb@u1yojB*9J;=cSx6XcSv`4N=tWlcQ?{VcXtUQ(kzcBnIgunmgkKdpHf69m`3(!i)iqgyf@fZ{kI^Z$r z(n9pF)5(aQ$qWxkOVQFzz)R6mjSi31DKbnmuWj4YNRIZ? zNYM&HL2l)%CSp*(Cv|Pfh)_h8QdDxxq^dxRjJz0jN`QkyXSt6+NpMg^&p3;KIgLP( z^3`N@YjJG>`co7jAgNICzex-V5XI2+KeGPwfoGKf5185*TO0rM7`W%(HAnvWFh)Cd70=p zFB`iW8#+1K{O)za-@I<6Z)5cX?NPG6NS(}p&w z#K=cxU82x%6<|Hq1+}j{7VXMz@%>I#jLCGl+%h<_EhBQR8ho5|4s+ESdDR_;Hm0Z5< zqOo4Hi(BS_R9VT-F4=wOL7)$FF{oySku&C&-Y7GAbzjK~actZa?RYrRY=w4Pyu6Ka z5+kO=HOKAc#+%+<6HgY3r!U->g+x6s_BNr)b;Wt*o8goThz`Uo!`t`l zwoj}lOnX>}cVS4{v)*+(*$ODwBJt4<5;>u47tND5aHd_sL9%Pw>o^TX{9KR+e9)5~Sj%%&1IqGeu}|f(>_*Hzo%%-BZW+zOi3uW{YFd zO}(M_vE-EMlZ^$rSf)5IJ_+Ko_iE^*p}iFt$Q%!sx_l{rG;2zebR$a~x7qyCMKM2C z(wf$_H%~3Ag1t;`DCF?d=P59@p&k0{Ce%4^9ePZDJTiQRmhkZpbQ`O7%26`#5bHyqkq*?C`chx>;_FW{Uy&~>}i#kVBF0}5tngSG7kq9PvH3N8of#t z{=MiEIj;iUK7JYM&eF-7ba2ZYoar92^?Thwbg(?I>#5uYt>&~U@C=Zg9ZE~4C)v_X zoLPid<+7%cbB0sr^VqovYmVyYo{c8GrZ>GYXaq-V=nqF}NYXmTE-^-PwnYuXl|Vj; z+6zVvccP%stw+>MC&Bu%E_}fY!OXA6)x^Rea(CaTgmdj9>^FCtcE&Hp7lI_(Ksvv38{I}58=w3k=LSTU3kI9Gfb_oLP@stq2ET^304=pJ>+sV$d+XO zVq%HUBKO7C(icSc)nTg!lkwz9olf={!NS+gbe$fsRrKSdR!^wzvFyE8Eof&lv}+Dv zg>v@MPydNdelV?uJ)}1Sz_8DNMfKk>?fDGahDtH%a-?n5?7RlvxbhEyjMd?|Q&J3BR2+t&f-}a@p`^YPm-<^Ebh*)ehMInt{{K6rUjIZ?PY*&rT`zz_}}WNYUW@D zIP<@&>J-y$-ouX+Ja(jXF9uJ<=c`Yh2y-Yv29MERkuJfMdKA1I6%u~DB9pWr$o=W< zQ+iC7+HEn8zjfVAd~P|#RX3lJq{S&;SqtnI2JtA51Q-g9$M!V$so+M13UDsj!JI=i zf|f}ck$tMUu`OXn3SK&ib8;DMb8tI7e%sSe`Os-kN(HV>1%O!feR5El8V}I-T%6)(30Js}( zq~-&LOw7Fi5zhXLU_G2u=uGutHh8ujSXT%7R!hY z6p)PwaTTa|HbTA^#gBr12A^=_jLo60G%n<=!_C2szn$N|w7F=dH5w97bmh^LW9(C)ju=hA;wOGr7lgCOHp6nUqyZ)B>b^zzlqFDstul6`+k&N#sn- z$|%F*eⅇnb{u75Pj%7eM6yukp*@ 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 literal 0 HcmV?d00001 diff --git a/src/com/turtleplayer/Player.java b/src/com/turtleplayer/Player.java index 5a1cdd9..efcd50a 100644 --- a/src/com/turtleplayer/Player.java +++ b/src/com/turtleplayer/Player.java @@ -32,17 +32,27 @@ import android.util.Log; import android.view.View; import android.view.View.OnClickListener; -import android.widget.*; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; +import android.widget.Toast; +import ch.hoene.perzist.access.filter.Filter; +import ch.hoene.perzist.util.Shorty; import com.turtleplayer.common.MatchFilterVisitor; import com.turtleplayer.controller.BroadcastsHandler; import com.turtleplayer.controller.PhoneStateHandler; import com.turtleplayer.dirchooser.DirChooserConstants; import com.turtleplayer.model.Instance; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.framework.db.ObservableDatabase; -import com.turtleplayer.persistance.framework.filter.Filter; +import com.turtleplayer.persistance.turtle.db.ObservableDatabase; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.player.ObservableOutput; @@ -57,7 +67,6 @@ import com.turtleplayer.preferences.Keys; import com.turtleplayer.preferences.Preferences; import com.turtleplayer.preferences.PreferencesObserver; -import com.turtleplayer.util.Shorty; import com.turtleplayer.view.AlbumArtView; import com.turtleplayer.view.FileChooser; diff --git a/src/com/turtleplayer/common/MatchFilterVisitor.java b/src/com/turtleplayer/common/MatchFilterVisitor.java index b68cb57..8d3b2d6 100644 --- a/src/com/turtleplayer/common/MatchFilterVisitor.java +++ b/src/com/turtleplayer/common/MatchFilterVisitor.java @@ -1,11 +1,16 @@ package com.turtleplayer.common; -import com.turtleplayer.persistance.framework.filter.*; -import com.turtleplayer.persistance.source.relational.FieldPersistable; -import com.turtleplayer.persistance.source.relational.fieldtype.FieldPersistableAsDouble; -import com.turtleplayer.persistance.source.relational.fieldtype.FieldPersistableAsInteger; -import com.turtleplayer.persistance.source.relational.fieldtype.FieldPersistableAsString; -import com.turtleplayer.persistance.source.relational.fieldtype.FieldVisitor; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.Filter; +import ch.hoene.perzist.access.filter.FilterSet; +import ch.hoene.perzist.access.filter.FilterVisitorGenerified; +import ch.hoene.perzist.access.filter.NotFilter; +import ch.hoene.perzist.access.filter.Operator; +import ch.hoene.perzist.source.relational.FieldPersistable; +import ch.hoene.perzist.source.relational.fieldtype.FieldPersistableAsDouble; +import ch.hoene.perzist.source.relational.fieldtype.FieldPersistableAsInteger; +import ch.hoene.perzist.source.relational.fieldtype.FieldPersistableAsString; +import ch.hoene.perzist.source.relational.fieldtype.FieldVisitor; import java.util.regex.Pattern; diff --git a/src/com/turtleplayer/controller/TouchHandler.java b/src/com/turtleplayer/controller/TouchHandler.java index d164c8b..fb80dd7 100644 --- a/src/com/turtleplayer/controller/TouchHandler.java +++ b/src/com/turtleplayer/controller/TouchHandler.java @@ -8,9 +8,14 @@ import android.view.View; import android.widget.ImageView; import android.widget.TextView; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.Filter; +import ch.hoene.perzist.access.filter.FilterSet; +import ch.hoene.perzist.access.filter.FilterVisitor; +import ch.hoene.perzist.access.filter.NotFilter; +import ch.hoene.perzist.access.filter.Operator; import com.turtleplayer.R; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.framework.filter.*; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.filter.DirFilter; import com.turtleplayer.persistance.turtle.filter.TurtleFilterVisitor; diff --git a/src/com/turtleplayer/dirchooser/DirChooser.java b/src/com/turtleplayer/dirchooser/DirChooser.java index ec9450a..46f46e6 100644 --- a/src/com/turtleplayer/dirchooser/DirChooser.java +++ b/src/com/turtleplayer/dirchooser/DirChooser.java @@ -22,7 +22,11 @@ import android.content.Intent; import android.os.Bundle; import android.view.View; -import android.widget.*; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; import com.turtleplayer.R; import java.io.File; diff --git a/src/com/turtleplayer/model/AlbumDigest.java b/src/com/turtleplayer/model/AlbumDigest.java index 4645433..b89bc20 100644 --- a/src/com/turtleplayer/model/AlbumDigest.java +++ b/src/com/turtleplayer/model/AlbumDigest.java @@ -18,7 +18,7 @@ package com.turtleplayer.model; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.util.Shorty; public class AlbumDigest implements Album { diff --git a/src/com/turtleplayer/model/ArtistDigest.java b/src/com/turtleplayer/model/ArtistDigest.java index 5457c56..8152b57 100644 --- a/src/com/turtleplayer/model/ArtistDigest.java +++ b/src/com/turtleplayer/model/ArtistDigest.java @@ -18,7 +18,7 @@ package com.turtleplayer.model; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.util.Shorty; public class ArtistDigest implements Artist { diff --git a/src/com/turtleplayer/model/FSobject.java b/src/com/turtleplayer/model/FSobject.java index d666366..1e06ba6 100644 --- a/src/com/turtleplayer/model/FSobject.java +++ b/src/com/turtleplayer/model/FSobject.java @@ -18,7 +18,7 @@ package com.turtleplayer.model; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.util.Shorty; import java.io.File; diff --git a/src/com/turtleplayer/model/GenreDigest.java b/src/com/turtleplayer/model/GenreDigest.java index 3bcb0b0..cf2c8b0 100644 --- a/src/com/turtleplayer/model/GenreDigest.java +++ b/src/com/turtleplayer/model/GenreDigest.java @@ -18,7 +18,7 @@ package com.turtleplayer.model; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.util.Shorty; import com.turtleplayer.util.TurtleUtil; public class GenreDigest implements Genre diff --git a/src/com/turtleplayer/model/InstanceCreator.java b/src/com/turtleplayer/model/InstanceCreator.java index 644f8e2..b112924 100644 --- a/src/com/turtleplayer/model/InstanceCreator.java +++ b/src/com/turtleplayer/model/InstanceCreator.java @@ -1,6 +1,6 @@ package com.turtleplayer.model; -import com.turtleplayer.persistance.framework.creator.Creator; +import ch.hoene.perzist.access.creator.Creator; /** * TURTLE PLAYER diff --git a/src/com/turtleplayer/model/SongDigest.java b/src/com/turtleplayer/model/SongDigest.java index 51e2ab0..ede2b70 100644 --- a/src/com/turtleplayer/model/SongDigest.java +++ b/src/com/turtleplayer/model/SongDigest.java @@ -19,7 +19,7 @@ package com.turtleplayer.model; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.util.Shorty; public class SongDigest implements Song { diff --git a/src/com/turtleplayer/persistance/framework/UniqueFieldGetter.java b/src/com/turtleplayer/persistance/framework/UniqueFieldGetter.java deleted file mode 100644 index 1ec809c..0000000 --- a/src/com/turtleplayer/persistance/framework/UniqueFieldGetter.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.turtleplayer.persistance.framework; - -import com.turtleplayer.persistance.source.relational.Field; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface UniqueFieldGetter -{ - Field getUniqueFields(); -} diff --git a/src/com/turtleplayer/persistance/framework/creator/Creator.java b/src/com/turtleplayer/persistance/framework/creator/Creator.java deleted file mode 100644 index 9a687bc..0000000 --- a/src/com/turtleplayer/persistance/framework/creator/Creator.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.turtleplayer.persistance.framework.creator; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface Creator -{ - RESULT create(SOURCE source); -} \ No newline at end of file diff --git a/src/com/turtleplayer/persistance/framework/creator/CreatorForList.java b/src/com/turtleplayer/persistance/framework/creator/CreatorForList.java deleted file mode 100644 index bf71375..0000000 --- a/src/com/turtleplayer/persistance/framework/creator/CreatorForList.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.turtleplayer.persistance.framework.creator; - -import java.util.*; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param Instance type - * @param Source type of row - * @param Source type of table - */ -public abstract class CreatorForList implements ResultCreator, M> -{ - private final Creator creator; - - protected CreatorForList(Creator creator) - { - this.creator = creator; - } - - public List create(M queryResult) - { - List result = new ArrayList(); - - while(hasNext(queryResult)) - { - result.add(creator.create(next(queryResult))); - } - - return result; - } - - protected abstract boolean hasNext(M queryResult); - - protected abstract S next(M queryResult); -} diff --git a/src/com/turtleplayer/persistance/framework/creator/ResultCreator.java b/src/com/turtleplayer/persistance/framework/creator/ResultCreator.java deleted file mode 100644 index d4f4838..0000000 --- a/src/com/turtleplayer/persistance/framework/creator/ResultCreator.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.turtleplayer.persistance.framework.creator; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface ResultCreator extends Creator -{ - -} diff --git a/src/com/turtleplayer/persistance/framework/db/Database.java b/src/com/turtleplayer/persistance/framework/db/Database.java deleted file mode 100644 index 65ddf2b..0000000 --- a/src/com/turtleplayer/persistance/framework/db/Database.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.turtleplayer.persistance.framework.db; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param eg Cursor - * @param eg sql as String - * @param DB object for write operations - */ -public interface Database -{ - abstract I read(Q query, DbReadOp readOp); - abstract int write(DbWriteOp writer, I instance); - - interface DbReadOp - { - public I read(C db); - } - - interface DbWriteOp - { - public int write(D target, I instance); - } -} diff --git a/src/com/turtleplayer/persistance/framework/executor/OperationExecutor.java b/src/com/turtleplayer/persistance/framework/executor/OperationExecutor.java deleted file mode 100644 index dee96e1..0000000 --- a/src/com/turtleplayer/persistance/framework/executor/OperationExecutor.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.turtleplayer.persistance.framework.executor; - -import com.turtleplayer.persistance.framework.db.Database; -import com.turtleplayer.persistance.framework.query.OperationDelete; -import com.turtleplayer.persistance.framework.query.OperationRead; -import com.turtleplayer.persistance.framework.query.OperationInsert; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class OperationExecutor -{ - public static I execute(Database db, final OperationRead operation){ - return db.read(operation.get(), new Database.DbReadOp(){ - public I read(C c) - { - return operation.map(c); - } - }); - } - - public static int execute(Database db, final OperationInsert operation, final I instance){ - return db.write(new Database.DbWriteOp() - { - public int write(D target, - I instance) - { - return operation.insert(target, instance); - } - }, instance); - } - - public static void execute(Database db, final OperationDelete operation, T target){ - db.write(new Database.DbWriteOp() - { - public int write(D target, - T instance) - { - return operation.delete(target, instance); - } - }, target); - } -} diff --git a/src/com/turtleplayer/persistance/framework/filter/FieldFilter.java b/src/com/turtleplayer/persistance/framework/filter/FieldFilter.java deleted file mode 100644 index 2f2621c..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/FieldFilter.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class FieldFilter implements Filter -{ - protected final FieldPersistable field; - protected final Operator operator; - protected final TYPE value; - - public FieldFilter(FieldPersistable field, - Operator operator, - TYPE value) - { - this.field = field; - this.operator = operator; - this.value = value; - } - - public FieldPersistable getField() - { - return field; - } - - public TYPE getValue() - { - return value; - } - - public Operator getOperator() - { - return operator; - } - public R accept(FilterVisitor visitor) - { - return visitor.visit(this); - } - - @Override - public String toString() - { - return getField().getName() + " " + operator.name() + " " + value; - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (!(o instanceof FieldFilter)) return false; - - FieldFilter that = (FieldFilter) o; - - if (!field.equals(that.field)) return false; - if (operator != that.operator) return false; - if (value != null ? !value.equals(that.value) : that.value != null) return false; - - return true; - } - - @Override - public int hashCode() - { - int result = field.hashCode(); - result = 31 * result + operator.hashCode(); - result = 31 * result + (value != null ? value.hashCode() : 0); - return result; - } -} diff --git a/src/com/turtleplayer/persistance/framework/filter/Filter.java b/src/com/turtleplayer/persistance/framework/filter/Filter.java deleted file mode 100644 index ea9a23b..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/Filter.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -import java.io.Serializable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface Filter extends Serializable -{ - public abstract R accept(FilterVisitor visitor); -} diff --git a/src/com/turtleplayer/persistance/framework/filter/FilterSet.java b/src/com/turtleplayer/persistance/framework/filter/FilterSet.java deleted file mode 100644 index fe0b790..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/FilterSet.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class FilterSet implements Filter -{ - private final Set> filters; - - public FilterSet(Filter... filter) - { - this.filters = new HashSet>(Arrays.asList(filter)); - } - - public FilterSet(Set> filters) - { - this.filters = new HashSet>(filters); - } - - public R accept(FilterVisitor visitor) - { - return visitor.visit(this); - } - - /** - * @return never null, Set can be empty - */ - public Set> getFilters() - { - return filters; - } - - public boolean makesObsolete(Filter filter) - { - return false; //Not implemented yet - } - - @Override - public String toString() - { - return Arrays.deepToString(filters.toArray()); - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (!(o instanceof FilterSet)) return false; - - FilterSet filterSet = (FilterSet) o; - - if (filters != null ? !filters.equals(filterSet.filters) : filterSet.filters != null) return false; - - return true; - } - - @Override - public int hashCode() - { - return filters != null ? filters.hashCode() : 0; - } -} diff --git a/src/com/turtleplayer/persistance/framework/filter/FilterVisitor.java b/src/com/turtleplayer/persistance/framework/filter/FilterVisitor.java deleted file mode 100644 index 87c583b..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/FilterVisitor.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param What the Visitor Produces (can be {@link Void} if nothing gets produced) - */ -public interface FilterVisitor -{ - R visit(FieldFilter fieldFilter); - - R visit(FilterSet filterSet); - - R visit(NotFilter notFilter); -} diff --git a/src/com/turtleplayer/persistance/framework/filter/FilterVisitorGenerified.java b/src/com/turtleplayer/persistance/framework/filter/FilterVisitorGenerified.java deleted file mode 100644 index f69c7c0..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/FilterVisitorGenerified.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class FilterVisitorGenerified implements FilterVisitor -{ - public abstract R visit(FieldFilter fieldFilter, - FieldPersistable field); - - final public R visit(FieldFilter fieldFilter) - { - return visit((FieldFilter) fieldFilter, (FieldPersistable) fieldFilter.getField()); - } -} diff --git a/src/com/turtleplayer/persistance/framework/filter/NotFilter.java b/src/com/turtleplayer/persistance/framework/filter/NotFilter.java deleted file mode 100644 index 032f685..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/NotFilter.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class NotFilter implements Filter -{ - private final Filter filter; - - public NotFilter(Filter filter) - { - this.filter = filter; - } - - public R accept(FilterVisitor visitor) - { - return visitor.visit(this); - } - - public Filter getFilter() - { - return filter; - } - - @Override - public String toString() - { - return " NOT (" + filter.toString() + ") "; - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (!(o instanceof NotFilter)) return false; - - NotFilter notFilter = (NotFilter) o; - - if (filter != null ? !filter.equals(notFilter.filter) : notFilter.filter != null) return false; - - return true; - } - - @Override - public int hashCode() - { - return filter != null ? filter.hashCode() : 0; - } - -} diff --git a/src/com/turtleplayer/persistance/framework/filter/Operator.java b/src/com/turtleplayer/persistance/framework/filter/Operator.java deleted file mode 100644 index b3f1c4e..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/Operator.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public enum Operator -{ - GT, - LT, - GE, - LE, - EQ, - NEQ, - LIKE, - NOT_LIKE -} diff --git a/src/com/turtleplayer/persistance/framework/filter/ResultFilter.java b/src/com/turtleplayer/persistance/framework/filter/ResultFilter.java deleted file mode 100644 index ffce02b..0000000 --- a/src/com/turtleplayer/persistance/framework/filter/ResultFilter.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.turtleplayer.persistance.framework.filter; - -import java.util.Set; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param eg Instance - */ -public interface ResultFilter -{ - Set apply(Set results); -} diff --git a/src/com/turtleplayer/persistance/framework/mapping/Mapping.java b/src/com/turtleplayer/persistance/framework/mapping/Mapping.java deleted file mode 100644 index 3fe30f1..0000000 --- a/src/com/turtleplayer/persistance/framework/mapping/Mapping.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.turtleplayer.persistance.framework.mapping; - -import com.turtleplayer.persistance.framework.creator.Creator; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - * - * Knows how to create I's from C's which are dependent from Q - * Eg: Knows How to create an Instance I from Query result Cursor C from Sql Q - * - * @param eg sql String - * @param resulting instance - * @param eg cursor - */ -public interface Mapping extends Creator, QueryGenerator -{ - Q get(); - I create(C queryResult); -} diff --git a/src/com/turtleplayer/persistance/framework/mapping/QueryGenerator.java b/src/com/turtleplayer/persistance/framework/mapping/QueryGenerator.java deleted file mode 100644 index 8a1ed84..0000000 --- a/src/com/turtleplayer/persistance/framework/mapping/QueryGenerator.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.turtleplayer.persistance.framework.mapping; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface QueryGenerator -{ - Q get(); -} diff --git a/src/com/turtleplayer/persistance/framework/paging/Paging.java b/src/com/turtleplayer/persistance/framework/paging/Paging.java deleted file mode 100644 index 8acd2f9..0000000 --- a/src/com/turtleplayer/persistance/framework/paging/Paging.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.turtleplayer.persistance.framework.paging; - -import com.turtleplayer.persistance.framework.filter.*; -import com.turtleplayer.persistance.framework.sort.*; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class Paging -{ - - public static Filter getFilter(Filter oldFilters, - RESULT instance, - Order order) - { - if(instance != null) - { - return new FilterSet(order.accept(new PagingFilterBuilder(instance)), oldFilters); - } - else - { - return oldFilters; - } - } -} diff --git a/src/com/turtleplayer/persistance/framework/paging/PagingFilterBuilder.java b/src/com/turtleplayer/persistance/framework/paging/PagingFilterBuilder.java deleted file mode 100644 index dbdf428..0000000 --- a/src/com/turtleplayer/persistance/framework/paging/PagingFilterBuilder.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.turtleplayer.persistance.framework.paging; - -import com.turtleplayer.persistance.framework.filter.FieldFilter; -import com.turtleplayer.persistance.framework.filter.Filter; -import com.turtleplayer.persistance.framework.filter.FilterSet; -import com.turtleplayer.persistance.framework.filter.Operator; -import com.turtleplayer.persistance.framework.sort.*; -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class PagingFilterBuilder extends OrderVisitorGenerified> -{ - final RESULT instance; - - public PagingFilterBuilder(RESULT instance) - { - this.instance = instance; - } - - @Override - public Filter visit(FieldOrder fieldOrder, - FieldPersistable field) - { - final Operator op; - - switch(fieldOrder.getOrder()){ - case ASC: - op = Operator.GT; - break; - case DESC: - op = Operator.LT; - break; - default: - throw new IllegalArgumentException(); - } - return new FieldFilter(field, op, field.get(instance)); - } - -// public Filter visit(FieldOrder fieldOrder) -// { -// FieldPersistable field = fieldOrder.getField(); -// -// final Operator op; -// -// switch(fieldOrder.getOrder()){ -// case ASC: -// op = Operator.GT; -// break; -// case DESC: -// op = Operator.LT; -// break; -// default: -// throw new IllegalArgumentException(); -// } -// return new FieldFilter(field, op, field.get(instance)); -// } - - public Filter visit(RandomOrder orderFilter) - { - return null; - } - - public Filter visit(OrderSet orderFilter) - { - if(!orderFilter.isEmpty()){ - Filter filterSet = new FilterSet(); - for( int i = 0; i < orderFilter.getOrders().size() -1; i++) - { - final Filter finalFilterSet = filterSet; - filterSet = orderFilter.getOrders().get(i).accept(new OrderVisitorGenerified>() - { - public Filter visit(RandomOrder orderFilter) - { - // :-) - return null; - } - - @Override - public Filter visit(FieldOrder fieldOrder, - FieldPersistable field) - { - return new FilterSet( - finalFilterSet, - new FieldFilter(fieldOrder.getField(), Operator.EQ, field.get(instance))); - } - - public Filter visit(OrderSet orderFilter) - { - return this.visit(orderFilter); - } - }); - } - - return new FilterSet(filterSet, orderFilter.getOrders().get(orderFilter.getOrders().size()-1).accept(this)); - } - else - { - return null; - } - } - -} diff --git a/src/com/turtleplayer/persistance/framework/query/OperationDelete.java b/src/com/turtleplayer/persistance/framework/query/OperationDelete.java deleted file mode 100644 index 5655c42..0000000 --- a/src/com/turtleplayer/persistance/framework/query/OperationDelete.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.turtleplayer.persistance.framework.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface OperationDelete -{ - int delete(D db, T target); -} diff --git a/src/com/turtleplayer/persistance/framework/query/OperationInsert.java b/src/com/turtleplayer/persistance/framework/query/OperationInsert.java deleted file mode 100644 index f341200..0000000 --- a/src/com/turtleplayer/persistance/framework/query/OperationInsert.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.turtleplayer.persistance.framework.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param write target eg SQLiteDb - * @param Object Type of the write information - */ -public interface OperationInsert -{ - int insert(D db, I instance); -} diff --git a/src/com/turtleplayer/persistance/framework/query/OperationRead.java b/src/com/turtleplayer/persistance/framework/query/OperationRead.java deleted file mode 100644 index 21b857c..0000000 --- a/src/com/turtleplayer/persistance/framework/query/OperationRead.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.turtleplayer.persistance.framework.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param write target eg SQLiteDb - * @param Object type that knows how to do the operation - * @param Object Type of the write information - */ -public interface OperationRead -{ - I map(R dbResult); - - Q get(); -} diff --git a/src/com/turtleplayer/persistance/framework/query/Query.java b/src/com/turtleplayer/persistance/framework/query/Query.java deleted file mode 100644 index f7df6eb..0000000 --- a/src/com/turtleplayer/persistance/framework/query/Query.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.turtleplayer.persistance.framework.query; - -import com.turtleplayer.persistance.framework.filter.Filter; -import com.turtleplayer.persistance.framework.filter.FilterVisitor; -import com.turtleplayer.persistance.framework.sort.Order; -import com.turtleplayer.persistance.framework.sort.OrderVisitor; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class Query implements FilterVisitor, OperationRead, OrderVisitor -{ - private final Filter filter; - private final Order order; - - protected Query() - { - this.filter = null; - order = null; - } - - protected Query(Filter filter) - { - this.filter = filter; - order = null; - } - - protected Query(Order order) - { - this.order = order; - this.filter = null; - } - - public Query(Filter filter, Order order) - { - this.filter = filter; - this.order = order; - } - - /** - * @return can be null - */ - public Filter getFilter() - { - return filter; - } - - /** - * @return can be null - */ - public Order getOrder() - { - return order; - } -} diff --git a/src/com/turtleplayer/persistance/framework/sort/FieldOrder.java b/src/com/turtleplayer/persistance/framework/sort/FieldOrder.java deleted file mode 100644 index 899daea..0000000 --- a/src/com/turtleplayer/persistance/framework/sort/FieldOrder.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.turtleplayer.persistance.framework.sort; - -import com.turtleplayer.persistance.framework.filter.FieldFilter; -import com.turtleplayer.persistance.framework.filter.Filter; -import com.turtleplayer.persistance.framework.filter.Operator; -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -import java.util.ArrayList; -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class FieldOrder implements Order -{ - private final FieldPersistable field; - private final SortOrder order; - - public FieldOrder(FieldPersistable field, - SortOrder order) - { - this.field = field; - this.order = order; - } - - public FieldPersistable getField() - { - return field; - } - - public SortOrder getOrder() - { - return order; - } - - public R accept(OrderVisitor visitor) - { - return visitor.visit(this); - } - - @Override - public String toString() - { - return getField().getName() + " " + order; - } - - public Filter asFilter(TYPE value, Operator op){ - return new FieldFilter(field, op, value); - } - - public static Order getMultiFieldOrder(SortOrder order, - FieldPersistable... fields) - { - List> orders = new ArrayList>(); - for(FieldPersistable field : fields) - { - orders.add(new FieldOrder(field, order)); - } - return new OrderSet(orders); - } -} diff --git a/src/com/turtleplayer/persistance/framework/sort/Order.java b/src/com/turtleplayer/persistance/framework/sort/Order.java deleted file mode 100644 index 735d519..0000000 --- a/src/com/turtleplayer/persistance/framework/sort/Order.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.turtleplayer.persistance.framework.sort; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param eg sql as String - */ -public interface Order -{ - R accept(OrderVisitor visitor); -} diff --git a/src/com/turtleplayer/persistance/framework/sort/OrderSet.java b/src/com/turtleplayer/persistance/framework/sort/OrderSet.java deleted file mode 100644 index ba974ab..0000000 --- a/src/com/turtleplayer/persistance/framework/sort/OrderSet.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.turtleplayer.persistance.framework.sort; - -import java.util.*; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class OrderSet implements Order -{ - private final List> orders = new ArrayList>(); - - public OrderSet(Order... order) - { - Collections.addAll(orders, order); - } - - public OrderSet(List> orders) - { - this.orders.addAll(orders); - } - - /** - * @return never null, Set can be empty - */ - public List> getOrders() - { - return orders; - } - - public R accept(OrderVisitor visitor) - { - return visitor.visit(this); - } - - public OrderSet removeLast() - { - if(orders.size() > 1) - { - return new OrderSet(orders.subList(0, orders.size()-1)); - } - else - { - return new OrderSet(new ArrayList>()); - } - } - - public boolean isEmpty() - { - return orders.isEmpty(); - } - - @Override - public String toString() - { - return Arrays.deepToString(orders.toArray()); - } -} diff --git a/src/com/turtleplayer/persistance/framework/sort/OrderVisitor.java b/src/com/turtleplayer/persistance/framework/sort/OrderVisitor.java deleted file mode 100644 index 2448aa5..0000000 --- a/src/com/turtleplayer/persistance/framework/sort/OrderVisitor.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.turtleplayer.persistance.framework.sort; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface OrderVisitor -{ - R visit(FieldOrder fieldOrder); - - R visit(RandomOrder orderFilter); - - R visit(OrderSet orderFilter); -} diff --git a/src/com/turtleplayer/persistance/framework/sort/OrderVisitorGenerified.java b/src/com/turtleplayer/persistance/framework/sort/OrderVisitorGenerified.java deleted file mode 100644 index 0f73bd7..0000000 --- a/src/com/turtleplayer/persistance/framework/sort/OrderVisitorGenerified.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.turtleplayer.persistance.framework.sort; - -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class OrderVisitorGenerified implements OrderVisitor -{ - public abstract R visit(FieldOrder fieldOrder, - FieldPersistable field); - - final public R visit(FieldOrder fieldOrder) - { - return visit((FieldOrder)fieldOrder, (FieldPersistable)fieldOrder.getField()); - } -} diff --git a/src/com/turtleplayer/persistance/framework/sort/RandomOrder.java b/src/com/turtleplayer/persistance/framework/sort/RandomOrder.java deleted file mode 100644 index 2930744..0000000 --- a/src/com/turtleplayer/persistance/framework/sort/RandomOrder.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.turtleplayer.persistance.framework.sort; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class RandomOrder implements Order -{ - - public R accept(OrderVisitor visitor) - { - return visitor.visit(this); - } -} diff --git a/src/com/turtleplayer/persistance/framework/sort/SortOrder.java b/src/com/turtleplayer/persistance/framework/sort/SortOrder.java deleted file mode 100644 index 63e0150..0000000 --- a/src/com/turtleplayer/persistance/framework/sort/SortOrder.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.turtleplayer.persistance.framework.sort; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public enum SortOrder -{ - ASC, - DESC -} diff --git a/src/com/turtleplayer/persistance/source/relational/Field.java b/src/com/turtleplayer/persistance/source/relational/Field.java deleted file mode 100644 index 7e8b334..0000000 --- a/src/com/turtleplayer/persistance/source/relational/Field.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.turtleplayer.persistance.source.relational; - -import java.io.Serializable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class Field implements Serializable -{ - private final String name; - - public Field(String name) - { - this.name = name; - } - - public String getName() - { - return name; - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Field field = (Field) o; - - if (!name.equals(field.name)) return false; - - return true; - } - - @Override - public int hashCode() - { - return name.hashCode(); - } -} diff --git a/src/com/turtleplayer/persistance/source/relational/FieldPersistable.java b/src/com/turtleplayer/persistance/source/relational/FieldPersistable.java deleted file mode 100644 index 979f19d..0000000 --- a/src/com/turtleplayer/persistance/source/relational/FieldPersistable.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.turtleplayer.persistance.source.relational; - -import com.turtleplayer.persistance.framework.creator.Creator; -import com.turtleplayer.persistance.source.relational.fieldtype.FieldVisitor; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class FieldPersistable extends Field -{ - private final Creator mapping; - - protected FieldPersistable(String name, - Creator mapping) - { - super(name); - this.mapping = mapping; - } - - public FieldPersistable(FieldPersistable fieldPersistable) - { - this(fieldPersistable.getName(), fieldPersistable.mapping); - } - - public TYPE get(RESULT type) - { - return mapping.create(type); - } - - public abstract R accept(FieldVisitor visitor); -} diff --git a/src/com/turtleplayer/persistance/source/relational/Table.java b/src/com/turtleplayer/persistance/source/relational/Table.java deleted file mode 100644 index ff57df8..0000000 --- a/src/com/turtleplayer/persistance/source/relational/Table.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.turtleplayer.persistance.source.relational; - -import com.turtleplayer.util.Shorty; - -import java.util.Set; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class Table implements View -{ - final String name; - - public Table(String name) - { - this.name = name; - } - - public String getName() - { - return name; - } - - public Set getTables() - { - return Shorty.oneElementSet(this); - } -} diff --git a/src/com/turtleplayer/persistance/source/relational/View.java b/src/com/turtleplayer/persistance/source/relational/View.java deleted file mode 100644 index 084b839..0000000 --- a/src/com/turtleplayer/persistance/source/relational/View.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.turtleplayer.persistance.source.relational; - -import java.io.Serializable; -import java.util.List; -import java.util.Set; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface View extends Serializable -{ - public Set getTables(); - - public List getFields(); -} diff --git a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsDouble.java b/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsDouble.java deleted file mode 100644 index abeaa6e..0000000 --- a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsDouble.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.turtleplayer.persistance.source.relational.fieldtype; - -import com.turtleplayer.persistance.framework.creator.Creator; -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class FieldPersistableAsDouble extends FieldPersistable -{ - public FieldPersistableAsDouble(String name, - Creator mapping) - { - super(name, mapping); - } - - public FieldPersistableAsDouble(FieldPersistable fieldPersistable) - { - super(fieldPersistable); - } - - @Override - public R accept(FieldVisitor visitor) - { - return visitor.visit(this); - } -} diff --git a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsInteger.java b/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsInteger.java deleted file mode 100644 index f141b23..0000000 --- a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsInteger.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.turtleplayer.persistance.source.relational.fieldtype; - -import com.turtleplayer.persistance.framework.creator.Creator; -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class FieldPersistableAsInteger extends FieldPersistable -{ - public FieldPersistableAsInteger(String name, - Creator mapping) - { - super(name, mapping); - } - - public FieldPersistableAsInteger(FieldPersistable fieldPersistable) - { - super(fieldPersistable); - } - - @Override - public R accept(FieldVisitor visitor) - { - return visitor.visit(this); - } -} diff --git a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsString.java b/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsString.java deleted file mode 100644 index 29f0612..0000000 --- a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldPersistableAsString.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.turtleplayer.persistance.source.relational.fieldtype; - -import com.turtleplayer.persistance.framework.creator.Creator; -import com.turtleplayer.persistance.source.relational.FieldPersistable; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class FieldPersistableAsString extends FieldPersistable -{ - public FieldPersistableAsString(String name, - Creator mapping) - { - super(name, mapping); - } - - public FieldPersistableAsString(FieldPersistable fieldPersistable) - { - super(fieldPersistable); - } - - @Override - public R accept(FieldVisitor visitor) - { - return visitor.visit(this); - } -} diff --git a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldVisitor.java b/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldVisitor.java deleted file mode 100644 index f724cf7..0000000 --- a/src/com/turtleplayer/persistance/source/relational/fieldtype/FieldVisitor.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.turtleplayer.persistance.source.relational.fieldtype; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param What the Visitor Produces (can be {@link Void} if nothing gets produced) - */ -public interface FieldVisitor -{ - R visit(FieldPersistableAsString field); - - R visit(FieldPersistableAsDouble field); - - R visit(FieldPersistableAsInteger field); - -} diff --git a/src/com/turtleplayer/persistance/source/relational/fieldtype/ToStringFieldVisitor.java b/src/com/turtleplayer/persistance/source/relational/fieldtype/ToStringFieldVisitor.java deleted file mode 100644 index 2907d1a..0000000 --- a/src/com/turtleplayer/persistance/source/relational/fieldtype/ToStringFieldVisitor.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.turtleplayer.persistance.source.relational.fieldtype; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class ToStringFieldVisitor implements FieldVisitor -{ - final RESULT result; - - public ToStringFieldVisitor(RESULT result) - { - this.result = result; - } - - public String visit(FieldPersistableAsString field) - { - return field.get(result); - } - - public String visit(FieldPersistableAsDouble field) - { - return field.get(result).toString(); - } - - public String visit(FieldPersistableAsInteger field) - { - return field.get(result).toString(); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/Counter.java b/src/com/turtleplayer/persistance/source/sql/Counter.java deleted file mode 100644 index 58089c8..0000000 --- a/src/com/turtleplayer/persistance/source/sql/Counter.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.turtleplayer.persistance.source.sql; - -import android.database.Cursor; -import com.turtleplayer.persistance.framework.mapping.Mapping; -import com.turtleplayer.persistance.source.relational.Table; -import com.turtleplayer.persistance.source.sql.query.Select; -import com.turtleplayer.persistance.source.sql.query.Sql; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class Counter implements Mapping -{ - private final Table table; - - public Counter(Table table) - { - this.table = table; - } - - public Select get() - { - return new Select(table, Select.SelectMethod.COUNT, Sql.FIELD_PSEUDO_STAR); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/First.java b/src/com/turtleplayer/persistance/source/sql/First.java deleted file mode 100644 index fc03bcf..0000000 --- a/src/com/turtleplayer/persistance/source/sql/First.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.turtleplayer.persistance.source.sql; - -import android.database.Cursor; -import com.turtleplayer.persistance.framework.creator.Creator; -import com.turtleplayer.persistance.framework.mapping.Mapping; -import com.turtleplayer.persistance.source.relational.Table; -import com.turtleplayer.persistance.source.sql.query.Limit; -import com.turtleplayer.persistance.source.sql.query.Select; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class First implements Mapping -{ - private final Table table; - private final Creator creator; - - public First(Table table, - Creator creator) - { - this.table = table; - this.creator = creator; - } - - public Select get() - { - Select select = new Select(table); - select.setLimit(new Limit(1)); - return select; - } - - public I create(Cursor queryResult) - { - if(queryResult.moveToFirst()){ - return creator.create(queryResult); - } - else - { - return null; - } - - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/Limited.java b/src/com/turtleplayer/persistance/source/sql/Limited.java deleted file mode 100644 index a29af42..0000000 --- a/src/com/turtleplayer/persistance/source/sql/Limited.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.turtleplayer.persistance.source.sql; - -import android.database.Cursor; -import com.turtleplayer.persistance.framework.creator.Creator; -import com.turtleplayer.persistance.source.relational.Table; -import com.turtleplayer.persistance.source.sql.query.Limit; -import com.turtleplayer.persistance.source.sql.query.Select; - -import java.util.ArrayList; -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class Limited extends First> -{ - private final int limit; - - public Limited(Table table, - Creator, Cursor> creator, - int limit) - { - super(table, creator); - this.limit = limit; - } - - public Select get() - { - Select select = super.get(); - select.setLimit(new Limit(limit)); - return select; - } - - public List create(Cursor queryResult) - { - List result = super.create(queryResult); - return result == null ? new ArrayList() : result; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/MappingDistinct.java b/src/com/turtleplayer/persistance/source/sql/MappingDistinct.java deleted file mode 100644 index 388e84a..0000000 --- a/src/com/turtleplayer/persistance/source/sql/MappingDistinct.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.turtleplayer.persistance.source.sql; - -import android.database.Cursor; -import com.turtleplayer.persistance.framework.creator.CreatorForList; -import com.turtleplayer.persistance.framework.mapping.Mapping; -import com.turtleplayer.persistance.source.relational.Field; -import com.turtleplayer.persistance.source.relational.View; -import com.turtleplayer.persistance.source.sql.query.Select; - -import java.util.Collection; -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class MappingDistinct implements Mapping, Cursor> -{ - private final PROJECTION view; - private final List fields; - private final CreatorForList creator; - - public MappingDistinct(PROJECTION view, - CreatorForList creator, - TARGET target) - { - this.view = view; - this.fields = target.getFields(); - this.creator = creator; - } - - public Select get() - { - return new Select(view, Select.SelectMethod.DISTINCT, fields.toArray(new Field[fields.size()])); - } - - public List create(Cursor queryResult) - { - return creator.create(queryResult); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/MappingTable.java b/src/com/turtleplayer/persistance/source/sql/MappingTable.java deleted file mode 100644 index c7ccc7e..0000000 --- a/src/com/turtleplayer/persistance/source/sql/MappingTable.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.turtleplayer.persistance.source.sql; - -import android.database.Cursor; -import com.turtleplayer.persistance.framework.creator.CreatorForList; -import com.turtleplayer.persistance.framework.mapping.Mapping; -import com.turtleplayer.persistance.source.relational.Table; -import com.turtleplayer.persistance.source.sql.query.Select; - -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class MappingTable implements Mapping, Cursor> -{ - private final Table table; - private final CreatorForList creator; - - public MappingTable(Table table, CreatorForList creator) - { - this.table = table; - this.creator = creator; - } - - public Select get() - { - return new Select(table); - } - - public List create(Cursor queryResult) - { - return creator.create(queryResult); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/QueryGeneratorTable.java b/src/com/turtleplayer/persistance/source/sql/QueryGeneratorTable.java deleted file mode 100644 index 954f174..0000000 --- a/src/com/turtleplayer/persistance/source/sql/QueryGeneratorTable.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.turtleplayer.persistance.source.sql; - -import android.content.ContentValues; -import com.turtleplayer.persistance.framework.mapping.Mapping; -import com.turtleplayer.persistance.source.relational.Table; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class QueryGeneratorTable implements Mapping -{ - final Table table; - - public QueryGeneratorTable(Table table) - { - this.table = table; - } - - public Table get() - { - return table; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/BoolOperator.java b/src/com/turtleplayer/persistance/source/sql/query/BoolOperator.java deleted file mode 100644 index 166956f..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/BoolOperator.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public enum BoolOperator implements SqlFragment -{ - AND(" and "), - OR(" and "); - - private final String sql; - - private BoolOperator(String sql) - { - this.sql = sql; - } - - - public String toSql() - { - return sql; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/FieldsPart.java b/src/com/turtleplayer/persistance/source/sql/query/FieldsPart.java deleted file mode 100644 index a8cb7b1..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/FieldsPart.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import com.turtleplayer.persistance.source.relational.Field; - -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class FieldsPart implements SqlFragment -{ - private final List fields; - - public FieldsPart(List fields) - { - this.fields = fields; - } - - public String toSql() - { - String[] fieldNames = new String[fields.size()]; - int i = 0; - for(Field field : fields) - { - fieldNames[i++] = field.getName(); - } - return Helper.getSeparatedList(", ", fieldNames); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/Helper.java b/src/com/turtleplayer/persistance/source/sql/query/Helper.java deleted file mode 100644 index 58f9740..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/Helper.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public abstract class Helper -{ - public static String getSeparatedList(String separator, String... values){ - - String result = ""; - - for(String value : values) - { - result += value + separator; - } - return removeLast(result, separator); - } - - public static String getSeparatedList(String separator, SqlFragment... fragments){ - - String result = ""; - - for(SqlFragment fragment : fragments) - { - result += fragment.toSql() + separator; - } - return removeLast(result, separator); - } - - public static String removeLast(String s, String pattern){ - return s.endsWith(pattern) ? - s.substring(0, s.length() - pattern.length()) : - s; //cut off last pattern - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/Limit.java b/src/com/turtleplayer/persistance/source/sql/query/Limit.java deleted file mode 100644 index eb8307a..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/Limit.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class Limit implements SqlFragment -{ - final int limit; - - public Limit(int limit) - { - this.limit = limit; - } - - public String toSql() - { - return " LIMIT " + limit + " "; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/Operator.java b/src/com/turtleplayer/persistance/source/sql/query/Operator.java deleted file mode 100644 index 5a75cd9..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/Operator.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public enum Operator -{ - GT(" > "), - LT(" < "), - GE(" >= "), - LE(" <= "), - EQ(" = "), - NEQ(" != "), - LIKE(" LIKE "), - NOT_LIKE(" NOT LIKE "); - - final String string; - - private Operator(String op) - { - this.string = op; - } - - @Override - public String toString() - { - return string; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/OrderClause.java b/src/com/turtleplayer/persistance/source/sql/query/OrderClause.java deleted file mode 100644 index 51dbf1b..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/OrderClause.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * Marker Interface - */ -public interface OrderClause extends SqlFragment, OrderClausePart -{ - OrderClause apply(OrderClause orderClause); -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/OrderClauseFields.java b/src/com/turtleplayer/persistance/source/sql/query/OrderClauseFields.java deleted file mode 100644 index fce87dc..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/OrderClauseFields.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class OrderClauseFields implements OrderClause -{ - private final String sql; - - public OrderClauseFields(OrderClausePart... parts) - { - sql = Helper.getSeparatedList(" , ", parts); - } - - private OrderClauseFields(OrderClause orderClause, OrderClause orderClause2) - { - sql = orderClause.toSql() + " , " + orderClause2.toSql(); - } - - public String toSql(){ - return sql; - } - - public OrderClause apply(OrderClause orderClause) - { - return new OrderClauseFields(this, orderClause); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/OrderClausePart.java b/src/com/turtleplayer/persistance/source/sql/query/OrderClausePart.java deleted file mode 100644 index 9af795b..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/OrderClausePart.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface OrderClausePart extends SqlFragment -{ -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/OrderClausePartField.java b/src/com/turtleplayer/persistance/source/sql/query/OrderClausePartField.java deleted file mode 100644 index f034583..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/OrderClausePartField.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import com.turtleplayer.persistance.framework.sort.SortOrder; -import com.turtleplayer.persistance.source.relational.Field; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class OrderClausePartField implements OrderClausePart -{ - final Field field; - final SqlOrder order; - - public OrderClausePartField(Field field, - SortOrder order) - { - this.field = field; - - switch (order) - { - case ASC: - this.order = SqlOrder.ASC; - break; - case DESC: - this.order = SqlOrder.DESC; - break; - default: - this.order = SqlOrder.ASC; - } - } - - public String toSql() - { - return " " + field.getName() + " " + order.toSql() + " "; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/OrderClauseRandom.java b/src/com/turtleplayer/persistance/source/sql/query/OrderClauseRandom.java deleted file mode 100644 index da3b17f..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/OrderClauseRandom.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPLS - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class OrderClauseRandom implements OrderClause -{ - public String toSql() - { - return " RANDOM() "; - } - - public OrderClause apply(OrderClause orderClause) - { - throw new RuntimeException("random order cant be chained"); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/Select.java b/src/com/turtleplayer/persistance/source/sql/query/Select.java deleted file mode 100644 index 768aaaa..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/Select.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import com.turtleplayer.persistance.source.relational.Field; -import com.turtleplayer.persistance.source.relational.View; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class Select implements Sql -{ - private final String sql; - private WhereClause whereClause; - private OrderClause orderClause; - private Limit limit; - - public enum SelectMethod{ - NORMAL, - COUNT, - DISTINCT - } - - public Select(View view) - { - this.sql = "SELECT * FROM " + getTableList(view); - } - - public Select(View view, Field... fields) - { - this(view, SelectMethod.NORMAL, fields); - } - - public Select(View view, SelectMethod selectMethod, Field... fields) - { - this.sql = "SELECT " + - getFieldsList(selectMethod, fields) + - " FROM " + getTableList(view); - } - - private String getFieldsList(SelectMethod selectMethod, Field... fields) - { - switch (selectMethod) - { - case NORMAL: - return new FieldsPart(Arrays.asList(fields)).toSql(); - case COUNT: - return " COUNT(" + new FieldsPart(Arrays.asList(fields)).toSql() + ")"; - case DISTINCT: - return " DISTINCT " + new FieldsPart(Arrays.asList(fields)).toSql() + " "; - default: - throw new RuntimeException("Implement SelectMethod " + selectMethod.name()); - } - } - - private String getTableList(View view) - { - return new TablesPart(view.getTables()).toSql(); - } - - public String toSql() - { - return sql - + (whereClause != null ? " WHERE " + whereClause.toSql() : "") - + (orderClause != null ? " ORDER BY " + orderClause.toSql() : "") - + (limit != null ? limit.toSql() : ""); - } - - public List getParams() - { - List params = new ArrayList(); - params.addAll(whereClause != null ? whereClause.getParams() : new ArrayList()); - return params; - } - - public void setWhereClause(WhereClause whereClause) - { - this.whereClause = whereClause; - } - - public void setOrderClause(OrderClause orderClause) - { - this.orderClause = orderClause; - } - - public void setLimit(Limit limit){ - this.limit = limit; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/Sql.java b/src/com/turtleplayer/persistance/source/sql/query/Sql.java deleted file mode 100644 index e00b231..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/Sql.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import com.turtleplayer.persistance.source.relational.Field; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - * - * Marker Interface for a complete, executable Sql - */ - -public interface Sql extends SqlPart -{ - public static final Field FIELD_PSEUDO_STAR = new Field("*"); -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/SqlFragment.java b/src/com/turtleplayer/persistance/source/sql/query/SqlFragment.java deleted file mode 100644 index b0427b6..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/SqlFragment.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface SqlFragment -{ - String toSql(); -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/SqlOrder.java b/src/com/turtleplayer/persistance/source/sql/query/SqlOrder.java deleted file mode 100644 index 77efd07..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/SqlOrder.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public enum SqlOrder -{ - ASC(" ASC "), - DESC(" DESC "); - - final String sql; - - private SqlOrder(String sql) - { - this.sql = sql; - } - - - public String toSql() - { - return sql; - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/SqlPart.java b/src/com/turtleplayer/persistance/source/sql/query/SqlPart.java deleted file mode 100644 index beab180..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/SqlPart.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface SqlPart extends SqlFragment -{ - List getParams(); -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/TablesPart.java b/src/com/turtleplayer/persistance/source/sql/query/TablesPart.java deleted file mode 100644 index 864a04c..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/TablesPart.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import com.turtleplayer.persistance.source.relational.Table; - -import java.util.Set; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class TablesPart implements SqlFragment -{ - private final Set tables; - - public TablesPart(Set tables) - { - this.tables = tables; - } - - public String toSql() - { - String[] tableNames = new String[tables.size()]; - int i = 0; - for(Table table : tables) - { - tableNames[i++] = table.getName(); - } - return Helper.getSeparatedList(", ", tableNames); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/WhereClause.java b/src/com/turtleplayer/persistance/source/sql/query/WhereClause.java deleted file mode 100644 index f945358..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/WhereClause.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * Immutable - */ -public class WhereClause implements WhereClausePart -{ - private List params = new ArrayList(); - private final String sql; - - public WhereClause(WhereClauseField part) - { - sql = part.toSql(); - params.addAll(part.getParams()); - } - - private WhereClause(String sql, List params) - { - this.sql = sql; - this.params = params; - } - - public WhereClause apply(BoolOperator op, WhereClausePart part){ - - if(part == null) - { - return this; - } - List newParams = new ArrayList(params); - newParams.addAll(part.getParams()); - - String newSql = " (" + sql + ") " + op + " (" + part.toSql() + ") "; - return new WhereClause(newSql, newParams); - } - - public String toSql(){ - return sql; - } - - public List getParams() - { - return Collections.unmodifiableList(params); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/WhereClauseField.java b/src/com/turtleplayer/persistance/source/sql/query/WhereClauseField.java deleted file mode 100644 index 6ab80cf..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/WhereClauseField.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -import com.turtleplayer.persistance.source.relational.Field; - -import java.util.Arrays; -import java.util.List; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class WhereClauseField implements WhereClausePart -{ - - final Field field; - final Object value; - final Operator op; - - public WhereClauseField(Field field, - Object value, - Operator op) - { - this.field = field; - this.value = value; - this.op = op; - } - - public String toSql() - { - return " " + field.getName() + op + " ? "; - } - - public List getParams() - { - return Arrays.asList(value); - } -} diff --git a/src/com/turtleplayer/persistance/source/sql/query/WhereClausePart.java b/src/com/turtleplayer/persistance/source/sql/query/WhereClausePart.java deleted file mode 100644 index dc54876..0000000 --- a/src/com/turtleplayer/persistance/source/sql/query/WhereClausePart.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.turtleplayer.persistance.source.sql.query; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public interface WhereClausePart extends SqlPart -{ -} diff --git a/src/com/turtleplayer/persistance/source/sqlite/CounterSqlite.java b/src/com/turtleplayer/persistance/source/sqlite/CounterSqlite.java deleted file mode 100644 index 4b8130f..0000000 --- a/src/com/turtleplayer/persistance/source/sqlite/CounterSqlite.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.turtleplayer.persistance.source.sqlite; - -import android.database.Cursor; -import com.turtleplayer.persistance.source.relational.Table; -import com.turtleplayer.persistance.source.sql.Counter; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class CounterSqlite extends Counter -{ - public CounterSqlite(Table table) - { - super(table); - } - - public Integer create(Cursor queryResult) - { - queryResult.moveToFirst(); - return queryResult.getInt(0); - } -} diff --git a/src/com/turtleplayer/persistance/source/sqlite/CreatorForListSqlite.java b/src/com/turtleplayer/persistance/source/sqlite/CreatorForListSqlite.java deleted file mode 100644 index b789815..0000000 --- a/src/com/turtleplayer/persistance/source/sqlite/CreatorForListSqlite.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.turtleplayer.persistance.source.sqlite; - -import android.database.Cursor; -import com.turtleplayer.persistance.framework.creator.CreatorForList; -import com.turtleplayer.persistance.framework.creator.ResultCreator; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -/** - * @param resulting set contains instance I - */ -public class CreatorForListSqlite extends CreatorForList -{ - public CreatorForListSqlite(ResultCreator creator) - { - super(creator); - } - - @Override - public boolean hasNext(Cursor queryResult) - { - return !queryResult.isLast() && !queryResult.isAfterLast(); - } - - @Override - public Cursor next(Cursor queryResult) - { - queryResult.moveToNext(); - return queryResult; - } -} diff --git a/src/com/turtleplayer/persistance/source/sqlite/DeleteTableContentSqlLite.java b/src/com/turtleplayer/persistance/source/sqlite/DeleteTableContentSqlLite.java deleted file mode 100644 index 8cc0cbc..0000000 --- a/src/com/turtleplayer/persistance/source/sqlite/DeleteTableContentSqlLite.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.turtleplayer.persistance.source.sqlite; - -import android.database.sqlite.SQLiteDatabase; -import com.turtleplayer.persistance.framework.query.OperationDelete; -import com.turtleplayer.persistance.source.relational.Table; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class DeleteTableContentSqlLite implements OperationDelete -{ - public int delete(SQLiteDatabase db, - Table target) - { - return db.delete(target.getName(), null, null); - } -} diff --git a/src/com/turtleplayer/persistance/source/sqlite/InsertOperationSqlLite.java b/src/com/turtleplayer/persistance/source/sqlite/InsertOperationSqlLite.java deleted file mode 100644 index 6ef8be4..0000000 --- a/src/com/turtleplayer/persistance/source/sqlite/InsertOperationSqlLite.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.turtleplayer.persistance.source.sqlite; - -import android.content.ContentValues; -import android.database.sqlite.SQLiteDatabase; -import com.turtleplayer.persistance.framework.query.OperationInsert; -import com.turtleplayer.persistance.framework.mapping.Mapping; -import com.turtleplayer.persistance.source.relational.Table; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class InsertOperationSqlLite implements OperationInsert -{ - private final Mapping mapping; - - public InsertOperationSqlLite(Mapping mapping) - { - this.mapping = mapping; - } - - public int insert(final SQLiteDatabase db, I instance) - { - long newRowId = db.insert(mapping.get().getName(), null, mapping.create(instance)); - return (newRowId < 0) ? 0 : 1; - } -} diff --git a/src/com/turtleplayer/persistance/source/sqlite/QuerySqlite.java b/src/com/turtleplayer/persistance/source/sqlite/QuerySqlite.java deleted file mode 100644 index 934c9b2..0000000 --- a/src/com/turtleplayer/persistance/source/sqlite/QuerySqlite.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.turtleplayer.persistance.source.sqlite; - -import android.database.Cursor; -import com.turtleplayer.persistance.framework.filter.*; -import com.turtleplayer.persistance.framework.query.Query; -import com.turtleplayer.persistance.framework.mapping.Mapping; -import com.turtleplayer.persistance.framework.sort.FieldOrder; -import com.turtleplayer.persistance.framework.sort.Order; -import com.turtleplayer.persistance.framework.sort.OrderSet; -import com.turtleplayer.persistance.framework.sort.RandomOrder; -import com.turtleplayer.persistance.source.relational.FieldPersistable; -import com.turtleplayer.persistance.source.sql.query.*; -import com.turtleplayer.persistance.source.sql.query.Operator; - -/** - * TURTLE PLAYER - *

- * Licensed under MIT & GPL - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - *

- * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -public class QuerySqlite extends Query -{ - private final Mapping mapping; - - public QuerySqlite(Mapping mapping) - { - this.mapping = mapping; - } - - public QuerySqlite(Filter filter, Mapping mapping) - { - super(filter); - this.mapping = mapping; - } - - public QuerySqlite(Order order, Mapping mapping) - { - super(order); - this.mapping = mapping; - } - - public QuerySqlite(Filter filter, Order order, Mapping mapping) - { - super(filter, order); - - this.mapping = mapping; - } - - public Select get() - { - Select sql = mapping.get(); - - if(getFilter() != null){ - sql.setWhereClause(getFilter().accept(this)); - } - - if(getOrder() != null){ - sql.setOrderClause(getOrder().accept(this)); - } - - return sql; - } - - public RESULT map(final Cursor cursor) - { - return mapping.create(cursor); - } - - public WhereClause visit(FieldFilter fieldFilter) - { - final Operator operator; - switch (fieldFilter.getOperator()){ - case EQ: - operator = Operator.EQ; - break; - case NEQ: - operator = Operator.NEQ; - break; - case GE: - operator = Operator.GE; - break; - case GT: - operator = Operator.GT; - break; - case LE: - operator = Operator.LE; - break; - case LIKE: - operator = Operator.LIKE; - break; - case NOT_LIKE: - operator = Operator.NOT_LIKE; - break; - case LT: - operator = Operator.LT; - break; - default: - throw new IllegalArgumentException(); - } - - return new WhereClause(new WhereClauseField(fieldFilter.getField(), fieldFilter.getValue(), operator)); - } - - public OrderClause visit(RandomOrder orderFilter) - { - return new OrderClauseRandom(); - } - - public WhereClause visit(FilterSet filterSet) - { - WhereClause whereClause = null; - for(Filter filter : filterSet.getFilters()){ - if(whereClause == null) - { - whereClause = filter.accept(this); - } - else - { - whereClause = whereClause.apply(BoolOperator.AND, filter.accept(this)); - } - } - return whereClause; - } - - - public WhereClause visit(NotFilter notFilter) - { - Filter inversedFilter = notFilter.getFilter().accept(new FilterVisitorGenerified>() - { - - @Override - public Filter visit(FieldFilter fieldFilter, - FieldPersistable field) - { - final com.turtleplayer.persistance.framework.filter.Operator inversedOp; - switch (fieldFilter.getOperator()) - { - case NEQ: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.EQ; - break; - case EQ: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.NEQ; - break; - case GE: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.LT; - break; - case GT: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.LE; - break; - case LE: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.GT; - break; - case LIKE: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.NOT_LIKE; - break; - case NOT_LIKE: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.LIKE; - break; - case LT: - inversedOp = com.turtleplayer.persistance.framework.filter.Operator.GE; - break; - default: - throw new RuntimeException("Not supported Operator"); - } - return new FieldFilter(fieldFilter.getField(), inversedOp, fieldFilter.getValue()); - } - - public Filter visit(FilterSet filterSet) - { - for(Filter f : filterSet.getFilters()) - { - f.accept(this); - } - return null; - } - - public Filter visit(NotFilter notFilter) - { - return notFilter.getFilter(); - } - }); - return inversedFilter.accept(this); - } - - public OrderClause visit(FieldOrder fieldOrder) - { - return new OrderClauseFields(new OrderClausePartField(fieldOrder.getField(), fieldOrder.getOrder())); - } - - public OrderClause visit(OrderSet clauseSet) - { - OrderClause orderClause = null; - for(Order order : clauseSet.getOrders()){ - if(orderClause == null) - { - orderClause = order.accept(this); - } - else - { - orderClause = orderClause.apply(order.accept(this)); - } - } - return orderClause; - } -} diff --git a/src/com/turtleplayer/persistance/turtle/FileBase.java b/src/com/turtleplayer/persistance/turtle/FileBase.java index 68bfd62..ca1548d 100644 --- a/src/com/turtleplayer/persistance/turtle/FileBase.java +++ b/src/com/turtleplayer/persistance/turtle/FileBase.java @@ -1,7 +1,11 @@ package com.turtleplayer.persistance.turtle; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.filter.Filter; +import ch.hoene.perzist.access.filter.Filter; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.Artist; +import com.turtleplayer.model.Genre; +import com.turtleplayer.model.Song; +import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.db.structure.Tables; import java.util.Collection; diff --git a/src/com/turtleplayer/persistance/turtle/FsReader.java b/src/com/turtleplayer/persistance/turtle/FsReader.java index 079be04..2b31bd3 100644 --- a/src/com/turtleplayer/persistance/turtle/FsReader.java +++ b/src/com/turtleplayer/persistance/turtle/FsReader.java @@ -20,25 +20,38 @@ package com.turtleplayer.persistance.turtle; import android.util.Log; +import ch.hoene.perzist.access.executor.OperationExecutor; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.Operator; +import ch.hoene.perzist.android.FirstSqlLite; +import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.util.Shorty; import com.mpatric.mp3agic.ID3v1; import com.mpatric.mp3agic.InvalidDataException; import com.mpatric.mp3agic.Mp3File; import com.mpatric.mp3agic.UnsupportedTagException; import com.turtleplayer.common.filefilter.FileFilters; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.executor.OperationExecutor; -import com.turtleplayer.persistance.framework.filter.FieldFilter; -import com.turtleplayer.persistance.framework.filter.Operator; -import com.turtleplayer.persistance.source.sql.First; -import com.turtleplayer.persistance.source.sqlite.QuerySqlite; +import com.turtleplayer.model.AlbumArtLocation; +import com.turtleplayer.model.AlbumDigest; +import com.turtleplayer.model.ArtistDigest; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.SongDigest; +import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.mapping.AlbumArtLocationCreator; import com.turtleplayer.preferences.Preferences; -import com.turtleplayer.util.Shorty; -import java.io.*; -import java.util.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileFilter; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; public class FsReader { @@ -198,7 +211,7 @@ public static String getAlbumArt(String mediaFileDir, TurtleDatabase db) db, new QuerySqlite( new FieldFilter(Tables.AlbumArtLocations.PATH, Operator.EQ, mediaFileDir), - new First(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()) + new FirstSqlLite(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()) ) ); diff --git a/src/com/turtleplayer/persistance/framework/db/ObservableDatabase.java b/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java similarity index 94% rename from src/com/turtleplayer/persistance/framework/db/ObservableDatabase.java rename to src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java index 2f82fb6..7f2b116 100644 --- a/src/com/turtleplayer/persistance/framework/db/ObservableDatabase.java +++ b/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java @@ -1,5 +1,6 @@ -package com.turtleplayer.persistance.framework.db; +package com.turtleplayer.persistance.turtle.db; +import ch.hoene.perzist.access.db.Database; import com.turtleplayer.controller.Observer; import com.turtleplayer.model.Instance; diff --git a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java index fb83bc0..0cf25c4 100644 --- a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java +++ b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java @@ -23,24 +23,40 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.creator.ResultCreator; -import com.turtleplayer.persistance.framework.db.Database; -import com.turtleplayer.persistance.framework.db.ObservableDatabase; -import com.turtleplayer.persistance.framework.executor.OperationExecutor; -import com.turtleplayer.persistance.framework.filter.Filter; -import com.turtleplayer.persistance.framework.sort.FieldOrder; -import com.turtleplayer.persistance.framework.sort.SortOrder; -import com.turtleplayer.persistance.source.relational.FieldPersistable; -import com.turtleplayer.persistance.source.relational.View; -import com.turtleplayer.persistance.source.sql.MappingDistinct; -import com.turtleplayer.persistance.source.sql.MappingTable; -import com.turtleplayer.persistance.source.sql.query.Select; -import com.turtleplayer.persistance.source.sqlite.*; +import ch.hoene.perzist.access.creator.ResultCreator; +import ch.hoene.perzist.access.db.Database; +import ch.hoene.perzist.access.executor.OperationExecutor; +import ch.hoene.perzist.access.filter.Filter; +import ch.hoene.perzist.access.sort.FieldOrder; +import ch.hoene.perzist.access.sort.SortOrder; +import ch.hoene.perzist.android.CounterSqlite; +import ch.hoene.perzist.android.CreatorForListSqlite; +import ch.hoene.perzist.android.DeleteTableContentSqlLite; +import ch.hoene.perzist.android.InsertOperationSqlLite; +import ch.hoene.perzist.android.MappingDistinctSqlLite; +import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.source.relational.FieldPersistable; +import ch.hoene.perzist.source.relational.View; +import ch.hoene.perzist.source.sql.query.Select; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.AlbumArtLocation; +import com.turtleplayer.model.Artist; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.Genre; +import com.turtleplayer.model.Song; +import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.FileBase; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.db.structure.Views; -import com.turtleplayer.persistance.turtle.mapping.*; +import com.turtleplayer.persistance.turtle.mapping.AlbumArtLoactionToDbMapper; +import com.turtleplayer.persistance.turtle.mapping.AlbumCreator; +import com.turtleplayer.persistance.turtle.mapping.ArtistCreator; +import com.turtleplayer.persistance.turtle.mapping.DirCreator; +import com.turtleplayer.persistance.turtle.mapping.FsObjectToDbMapper; +import com.turtleplayer.persistance.turtle.mapping.GenreCreator; +import com.turtleplayer.persistance.turtle.mapping.SongCreator; +import com.turtleplayer.persistance.turtle.mapping.TrackCreator; +import com.turtleplayer.persistance.turtle.mapping.TrackToDbMapper; import java.util.Arrays; import java.util.List; @@ -158,7 +174,7 @@ private List g new QuerySqlite>( filter, FieldOrder.getMultiFieldOrder(SortOrder.ASC, sortFields), - new MappingDistinct(view, new CreatorForListSqlite(creator), target) + new MappingDistinctSqlLite(view, new CreatorForListSqlite(creator), target) ) ); } diff --git a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java index 4fe6516..2bf2c44 100644 --- a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java +++ b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java @@ -3,7 +3,7 @@ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; -import com.turtleplayer.persistance.source.relational.FieldPersistable; +import ch.hoene.perzist.source.relational.FieldPersistable; import com.turtleplayer.persistance.turtle.db.structure.Tables; import java.util.Arrays; diff --git a/src/com/turtleplayer/persistance/turtle/db/structure/Tables.java b/src/com/turtleplayer/persistance/turtle/db/structure/Tables.java index 98f54d0..e2a4234 100644 --- a/src/com/turtleplayer/persistance/turtle/db/structure/Tables.java +++ b/src/com/turtleplayer/persistance/turtle/db/structure/Tables.java @@ -1,14 +1,20 @@ package com.turtleplayer.persistance.turtle.db.structure; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.creator.Creator; -import com.turtleplayer.persistance.source.relational.Field; -import com.turtleplayer.persistance.source.relational.FieldPersistable; -import com.turtleplayer.persistance.source.relational.Table; -import com.turtleplayer.persistance.source.relational.View; -import com.turtleplayer.persistance.source.relational.fieldtype.FieldPersistableAsInteger; -import com.turtleplayer.persistance.source.relational.fieldtype.FieldPersistableAsString; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.access.creator.Creator; +import ch.hoene.perzist.source.relational.Field; +import ch.hoene.perzist.source.relational.FieldPersistable; +import ch.hoene.perzist.source.relational.Table; +import ch.hoene.perzist.source.relational.View; +import ch.hoene.perzist.source.relational.fieldtype.FieldPersistableAsInteger; +import ch.hoene.perzist.source.relational.fieldtype.FieldPersistableAsString; +import ch.hoene.perzist.util.Shorty; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.AlbumArtLocation; +import com.turtleplayer.model.Artist; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.Genre; +import com.turtleplayer.model.Song; +import com.turtleplayer.model.Track; import java.util.Arrays; import java.util.List; diff --git a/src/com/turtleplayer/persistance/turtle/db/structure/Views.java b/src/com/turtleplayer/persistance/turtle/db/structure/Views.java index 5a68fa4..a3eec4c 100644 --- a/src/com/turtleplayer/persistance/turtle/db/structure/Views.java +++ b/src/com/turtleplayer/persistance/turtle/db/structure/Views.java @@ -1,7 +1,7 @@ package com.turtleplayer.persistance.turtle.db.structure; -import com.turtleplayer.persistance.source.relational.Field; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.source.relational.Field; +import ch.hoene.perzist.util.Shorty; import java.util.Arrays; import java.util.List; diff --git a/src/com/turtleplayer/persistance/turtle/filter/DirFilter.java b/src/com/turtleplayer/persistance/turtle/filter/DirFilter.java index d50003d..079161f 100644 --- a/src/com/turtleplayer/persistance/turtle/filter/DirFilter.java +++ b/src/com/turtleplayer/persistance/turtle/filter/DirFilter.java @@ -1,7 +1,9 @@ package com.turtleplayer.persistance.turtle.filter; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.FilterVisitor; +import ch.hoene.perzist.access.filter.Operator; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.framework.filter.*; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/persistance/turtle/filter/TurtleFilterVisitor.java b/src/com/turtleplayer/persistance/turtle/filter/TurtleFilterVisitor.java index 1b009a3..1184651 100644 --- a/src/com/turtleplayer/persistance/turtle/filter/TurtleFilterVisitor.java +++ b/src/com/turtleplayer/persistance/turtle/filter/TurtleFilterVisitor.java @@ -17,7 +17,7 @@ * @author Simon Honegger (Hoene84) */ -import com.turtleplayer.persistance.framework.filter.FilterVisitor; +import ch.hoene.perzist.access.filter.FilterVisitor; /** * @param What the Visitor Produces (can be {@link Void} if nothing gets produced) diff --git a/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java b/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java index 8f9017f..f81e3cc 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java @@ -1,8 +1,9 @@ package com.turtleplayer.persistance.turtle.mapping; import android.content.ContentValues; +import ch.hoene.perzist.access.mapping.Mapping; +import ch.hoene.perzist.source.relational.Table; import com.turtleplayer.model.AlbumArtLocation; -import com.turtleplayer.persistance.source.sql.QueryGeneratorTable; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** @@ -22,14 +23,13 @@ * @author Simon Honegger (Hoene84) */ -public class AlbumArtLoactionToDbMapper extends QueryGeneratorTable +public class AlbumArtLoactionToDbMapper implements Mapping { - public AlbumArtLoactionToDbMapper() - { - super(Tables.ALBUM_ART_LOCATIONS); - } + public Table get() { + return Tables.ALBUM_ART_LOCATIONS; + } - public ContentValues create(AlbumArtLocation albumArtLocation) + public ContentValues create(AlbumArtLocation albumArtLocation) { final ContentValues values = new ContentValues(); diff --git a/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLocationCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLocationCreator.java index bf2aef8..8ee7951 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLocationCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLocationCreator.java @@ -1,8 +1,8 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.creator.Creator; +import ch.hoene.perzist.access.creator.Creator; +import com.turtleplayer.model.AlbumArtLocation; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java index b3ae8e1..4e9c0c2 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java @@ -1,9 +1,9 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; +import ch.hoene.perzist.access.creator.ResultCreator; import com.turtleplayer.model.Album; import com.turtleplayer.model.AlbumDigest; -import com.turtleplayer.persistance.framework.creator.ResultCreator; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java index 86e4f13..ea34d59 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java @@ -1,8 +1,8 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; +import ch.hoene.perzist.access.creator.ResultCreator; import com.turtleplayer.model.ArtistDigest; -import com.turtleplayer.persistance.framework.creator.ResultCreator; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.db.structure.Views; diff --git a/src/com/turtleplayer/persistance/turtle/mapping/DirCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/DirCreator.java index 3bade09..327973a 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/DirCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/DirCreator.java @@ -1,8 +1,8 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; +import ch.hoene.perzist.access.creator.ResultCreator; import com.turtleplayer.model.FSobject; -import com.turtleplayer.persistance.framework.creator.ResultCreator; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java b/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java index 9e752e3..73d1f8b 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java @@ -1,8 +1,9 @@ package com.turtleplayer.persistance.turtle.mapping; import android.content.ContentValues; +import ch.hoene.perzist.access.mapping.Mapping; +import ch.hoene.perzist.source.relational.Table; import com.turtleplayer.model.FSobject; -import com.turtleplayer.persistance.source.sql.QueryGeneratorTable; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** @@ -22,14 +23,13 @@ * @author Simon Honegger (Hoene84) */ -public class FsObjectToDbMapper extends QueryGeneratorTable +public class FsObjectToDbMapper implements Mapping { - public FsObjectToDbMapper() - { - super(Tables.DIRS); - } + public Table get() { + return Tables.DIRS; + } - public ContentValues create(FSobject fsObject) + public ContentValues create(FSobject fsObject) { final ContentValues values = new ContentValues(); diff --git a/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java index 56ce60d..30cab69 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java @@ -1,8 +1,8 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; +import ch.hoene.perzist.access.creator.ResultCreator; import com.turtleplayer.model.GenreDigest; -import com.turtleplayer.persistance.framework.creator.ResultCreator; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java index c5d2e06..7917ac5 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java @@ -1,8 +1,8 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; +import ch.hoene.perzist.access.creator.ResultCreator; import com.turtleplayer.model.SongDigest; -import com.turtleplayer.persistance.framework.creator.ResultCreator; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/persistance/turtle/mapping/StringCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/StringCreator.java index d51842b..4a46337 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/StringCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/StringCreator.java @@ -1,7 +1,7 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; -import com.turtleplayer.persistance.framework.creator.Creator; +import ch.hoene.perzist.access.creator.Creator; /** * TURTLE PLAYER diff --git a/src/com/turtleplayer/persistance/turtle/mapping/TrackCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/TrackCreator.java index e1d2a79..7af13c9 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/TrackCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/TrackCreator.java @@ -1,8 +1,12 @@ package com.turtleplayer.persistance.turtle.mapping; import android.database.Cursor; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.creator.ResultCreator; +import ch.hoene.perzist.access.creator.ResultCreator; +import com.turtleplayer.model.AlbumDigest; +import com.turtleplayer.model.ArtistDigest; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.SongDigest; +import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java b/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java index 2a73ec7..0e46a81 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java @@ -1,8 +1,9 @@ package com.turtleplayer.persistance.turtle.mapping; import android.content.ContentValues; +import ch.hoene.perzist.access.mapping.Mapping; +import ch.hoene.perzist.source.relational.Table; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.source.sql.QueryGeneratorTable; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** @@ -22,14 +23,13 @@ * @author Simon Honegger (Hoene84) */ -public class TrackToDbMapper extends QueryGeneratorTable +public class TrackToDbMapper implements Mapping { - public TrackToDbMapper() - { - super(Tables.TRACKS); - } + public Table get() { + return Tables.TRACKS; + } - public ContentValues create(Track track) + public ContentValues create(Track track) { final ContentValues values = new ContentValues(); diff --git a/src/com/turtleplayer/player/PlayerService.java b/src/com/turtleplayer/player/PlayerService.java index 499d486..a133037 100644 --- a/src/com/turtleplayer/player/PlayerService.java +++ b/src/com/turtleplayer/player/PlayerService.java @@ -5,7 +5,12 @@ import android.app.Service; import android.content.Intent; import android.media.MediaPlayer; -import android.os.*; +import android.os.Binder; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; import android.util.Log; import com.turtleplayer.Player; import com.turtleplayer.R; diff --git a/src/com/turtleplayer/player/PlayerServiceConnector.java b/src/com/turtleplayer/player/PlayerServiceConnector.java index 2b66a5d..7ed156e 100644 --- a/src/com/turtleplayer/player/PlayerServiceConnector.java +++ b/src/com/turtleplayer/player/PlayerServiceConnector.java @@ -1,7 +1,15 @@ package com.turtleplayer.player; -import android.content.*; -import android.os.*; +import android.content.ComponentName; +import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.AsyncTask; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; import android.util.Log; import com.turtleplayer.model.Track; import com.turtleplayer.preferences.Preferences; diff --git a/src/com/turtleplayer/playlist/Playlist.java b/src/com/turtleplayer/playlist/Playlist.java index 65b9add..2d260f1 100644 --- a/src/com/turtleplayer/playlist/Playlist.java +++ b/src/com/turtleplayer/playlist/Playlist.java @@ -21,18 +21,21 @@ import android.content.Context; import android.util.Log; +import ch.hoene.perzist.access.executor.OperationExecutor; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.Filter; +import ch.hoene.perzist.access.filter.FilterSet; +import ch.hoene.perzist.access.filter.Operator; +import ch.hoene.perzist.access.sort.RandomOrder; +import ch.hoene.perzist.android.FirstSqlLite; +import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.util.Shorty; import com.turtleplayer.Stats; import com.turtleplayer.common.filefilter.FileFilters; import com.turtleplayer.controller.Observer; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.executor.OperationExecutor; -import com.turtleplayer.persistance.framework.filter.FieldFilter; -import com.turtleplayer.persistance.framework.filter.Filter; -import com.turtleplayer.persistance.framework.filter.FilterSet; -import com.turtleplayer.persistance.framework.filter.Operator; -import com.turtleplayer.persistance.framework.sort.RandomOrder; -import com.turtleplayer.persistance.source.sql.First; -import com.turtleplayer.persistance.source.sqlite.QuerySqlite; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.Track; +import com.turtleplayer.model.TrackBundle; import com.turtleplayer.persistance.turtle.FsReader; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; @@ -40,11 +43,19 @@ import com.turtleplayer.playlist.playorder.PlayOrderStrategy; import com.turtleplayer.preferences.Keys; import com.turtleplayer.preferences.Preferences; -import com.turtleplayer.util.Shorty; import java.io.IOException; -import java.util.*; -import java.util.concurrent.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; public class Playlist { @@ -144,7 +155,7 @@ public Track getTrack(String src) getCompressedFilter(), new FieldFilter(Tables.FsObjects.NAME, Operator.EQ, fsObject.getPath()), new FieldFilter(Tables.FsObjects.PATH, Operator.EQ, fsObject.getName())), - new First(Tables.TRACKS, new TrackCreator()) + new FirstSqlLite(Tables.TRACKS, new TrackCreator()) ) ); } @@ -166,7 +177,7 @@ public Track getRandom() new QuerySqlite( getCompressedFilter(), new RandomOrder(), - new First(Tables.TRACKS, new TrackCreator()))); + new FirstSqlLite(Tables.TRACKS, new TrackCreator()))); } /** diff --git a/src/com/turtleplayer/playlist/playorder/DefaultOrder.java b/src/com/turtleplayer/playlist/playorder/DefaultOrder.java index 4dbd974..6c9b700 100644 --- a/src/com/turtleplayer/playlist/playorder/DefaultOrder.java +++ b/src/com/turtleplayer/playlist/playorder/DefaultOrder.java @@ -1,9 +1,9 @@ package com.turtleplayer.playlist.playorder; +import ch.hoene.perzist.access.sort.FieldOrder; +import ch.hoene.perzist.access.sort.OrderSet; +import ch.hoene.perzist.access.sort.SortOrder; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.framework.sort.FieldOrder; -import com.turtleplayer.persistance.framework.sort.OrderSet; -import com.turtleplayer.persistance.framework.sort.SortOrder; import com.turtleplayer.persistance.turtle.db.structure.Tables; /** diff --git a/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java b/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java index 5e2b2c5..c4d0b0e 100644 --- a/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java +++ b/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java @@ -1,10 +1,10 @@ package com.turtleplayer.playlist.playorder; +import ch.hoene.perzist.access.executor.OperationExecutor; +import ch.hoene.perzist.access.sort.RandomOrder; +import ch.hoene.perzist.android.FirstSqlLite; +import ch.hoene.perzist.android.QuerySqlite; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.framework.executor.OperationExecutor; -import com.turtleplayer.persistance.framework.sort.RandomOrder; -import com.turtleplayer.persistance.source.sql.First; -import com.turtleplayer.persistance.source.sqlite.QuerySqlite; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.mapping.TrackCreator; @@ -39,6 +39,6 @@ private Track get() new QuerySqlite( playlist.getCompressedFilter(), new RandomOrder(), - new First(Tables.TRACKS, new TrackCreator()))); + new FirstSqlLite(Tables.TRACKS, new TrackCreator()))); } } diff --git a/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java b/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java index ee0e719..55766a5 100644 --- a/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java +++ b/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java @@ -19,13 +19,13 @@ package com.turtleplayer.playlist.playorder; import android.util.Log; +import ch.hoene.perzist.access.executor.OperationExecutor; +import ch.hoene.perzist.access.paging.Paging; +import ch.hoene.perzist.access.sort.OrderSet; +import ch.hoene.perzist.access.sort.SortOrder; +import ch.hoene.perzist.android.FirstSqlLite; +import ch.hoene.perzist.android.QuerySqlite; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.framework.executor.OperationExecutor; -import com.turtleplayer.persistance.framework.paging.Paging; -import com.turtleplayer.persistance.framework.sort.OrderSet; -import com.turtleplayer.persistance.framework.sort.SortOrder; -import com.turtleplayer.persistance.source.sql.First; -import com.turtleplayer.persistance.source.sqlite.QuerySqlite; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.mapping.TrackCreator; @@ -68,7 +68,7 @@ private Track get(Track ofTrack, OrderSet order) new QuerySqlite( Paging.getFilter(playlist.getCompressedFilter(), ofTrack, currOrder), order, - new First(Tables.TRACKS, new TrackCreator()) + new FirstSqlLite(Tables.TRACKS, new TrackCreator()) ) ); if(nextTrack != null){ diff --git a/src/com/turtleplayer/preferences/Keys.java b/src/com/turtleplayer/preferences/Keys.java index 681d7f7..138e6d2 100644 --- a/src/com/turtleplayer/preferences/Keys.java +++ b/src/com/turtleplayer/preferences/Keys.java @@ -19,7 +19,7 @@ package com.turtleplayer.preferences; import android.os.Environment; -import com.turtleplayer.persistance.framework.filter.Filter; +import ch.hoene.perzist.access.filter.Filter; import com.turtleplayer.persistance.turtle.db.structure.Tables; import java.util.HashSet; diff --git a/src/com/turtleplayer/preferences/ObjectKey.java b/src/com/turtleplayer/preferences/ObjectKey.java index 16e62a8..b04b3c8 100644 --- a/src/com/turtleplayer/preferences/ObjectKey.java +++ b/src/com/turtleplayer/preferences/ObjectKey.java @@ -23,7 +23,11 @@ import android.util.Base64OutputStream; import android.util.Log; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; public class ObjectKey extends AbstractKey { diff --git a/src/com/turtleplayer/presentation/AlbumArtResolver.java b/src/com/turtleplayer/presentation/AlbumArtResolver.java index aa3705f..0121ee7 100644 --- a/src/com/turtleplayer/presentation/AlbumArtResolver.java +++ b/src/com/turtleplayer/presentation/AlbumArtResolver.java @@ -4,22 +4,22 @@ import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.Log; +import ch.hoene.perzist.access.executor.OperationExecutor; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.Operator; +import ch.hoene.perzist.android.FirstSqlLite; +import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.util.Shorty; import com.mpatric.mp3agic.InvalidDataException; import com.mpatric.mp3agic.Mp3File; import com.mpatric.mp3agic.UnsupportedTagException; import com.turtleplayer.model.AlbumArtLocation; import com.turtleplayer.model.Track; -import com.turtleplayer.persistance.framework.executor.OperationExecutor; -import com.turtleplayer.persistance.framework.filter.FieldFilter; -import com.turtleplayer.persistance.framework.filter.Operator; -import com.turtleplayer.persistance.source.sql.First; -import com.turtleplayer.persistance.source.sqlite.QuerySqlite; import com.turtleplayer.persistance.turtle.FsReader; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.mapping.AlbumArtLocationCreator; import com.turtleplayer.preferences.Preferences; -import com.turtleplayer.util.Shorty; import java.io.IOException; @@ -85,7 +85,7 @@ public Bitmap lookup(Track track) AlbumArtLocation albumArtLocation = OperationExecutor.execute( db, new QuerySqlite(new FieldFilter(Tables.AlbumArtLocations.PATH, Operator.EQ, track.getPath()), - new First(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()))); + new FirstSqlLite(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()))); if(albumArtLocation != null) { diff --git a/src/com/turtleplayer/presentation/OverAllFormatter.java b/src/com/turtleplayer/presentation/OverAllFormatter.java index f75b659..22fd513 100644 --- a/src/com/turtleplayer/presentation/OverAllFormatter.java +++ b/src/com/turtleplayer/presentation/OverAllFormatter.java @@ -18,8 +18,13 @@ package com.turtleplayer.presentation; -import com.turtleplayer.model.*; -import com.turtleplayer.util.Shorty; +import ch.hoene.perzist.util.Shorty; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.ArtistDigest; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.SongDigest; +import com.turtleplayer.model.Track; import com.turtleplayer.util.TurtleUtil; class OverAllFormatter extends InstanceFormatter diff --git a/src/com/turtleplayer/presentation/ShortInstanceFormatter.java b/src/com/turtleplayer/presentation/ShortInstanceFormatter.java index b337a1e..d1ae244 100644 --- a/src/com/turtleplayer/presentation/ShortInstanceFormatter.java +++ b/src/com/turtleplayer/presentation/ShortInstanceFormatter.java @@ -18,7 +18,12 @@ package com.turtleplayer.presentation; -import com.turtleplayer.model.*; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.ArtistDigest; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.SongDigest; +import com.turtleplayer.model.Track; class ShortInstanceFormatter extends InstanceFormatter { diff --git a/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java b/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java index 2dd2a3b..66ddcf4 100644 --- a/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java +++ b/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java @@ -18,8 +18,8 @@ package com.turtleplayer.presentation; +import ch.hoene.perzist.util.Shorty; import com.turtleplayer.model.Track; -import com.turtleplayer.util.Shorty; class ShortWithNumberInstanceFormatter extends ShortInstanceFormatter { diff --git a/src/com/turtleplayer/util/DefaultAdapter.java b/src/com/turtleplayer/util/DefaultAdapter.java index 25a3f78..bff6686 100644 --- a/src/com/turtleplayer/util/DefaultAdapter.java +++ b/src/com/turtleplayer/util/DefaultAdapter.java @@ -29,7 +29,14 @@ import android.widget.ImageView; import android.widget.TextView; import com.turtleplayer.R; -import com.turtleplayer.model.*; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.ArtistDigest; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.Instance; +import com.turtleplayer.model.InstanceVisitor; +import com.turtleplayer.model.SongDigest; +import com.turtleplayer.model.Track; import com.turtleplayer.presentation.InstanceFormatter; import java.util.Collections; diff --git a/src/com/turtleplayer/util/FormattedInstanceComparator.java b/src/com/turtleplayer/util/FormattedInstanceComparator.java index fc7011a..bb25c3d 100644 --- a/src/com/turtleplayer/util/FormattedInstanceComparator.java +++ b/src/com/turtleplayer/util/FormattedInstanceComparator.java @@ -18,7 +18,14 @@ package com.turtleplayer.util; -import com.turtleplayer.model.*; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.ArtistDigest; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.Instance; +import com.turtleplayer.model.InstanceVisitor; +import com.turtleplayer.model.SongDigest; +import com.turtleplayer.model.Track; import com.turtleplayer.presentation.InstanceFormatter; import java.text.Collator; diff --git a/src/com/turtleplayer/util/Shorty.java b/src/com/turtleplayer/util/Shorty.java deleted file mode 100644 index c1c02a7..0000000 --- a/src/com/turtleplayer/util/Shorty.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * - * TURTLE PLAYER - * - * Licensed under MIT & GPL - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR - * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE - * OR OTHER DEALINGS IN THE SOFTWARE. - * - * More Information @ www.turtle-player.co.uk - * - * @author Simon Honegger (Hoene84) - */ - -package com.turtleplayer.util; - -import java.util.*; - -public class Shorty -{ - public static boolean isVoid(String string) - { - return string == null || string.length() == 0; - } - - public static boolean isVoid(Integer integer) - { - return integer == null || integer == 0; - } - - public static > boolean isVoid(T collection) - { - return collection == null || collection.size() == 0; - } - - public static String avoidNull(String s) - { - return isVoid(s) ? "" : s; - } - - public static > T avoidNull(T collection, T emptyCollections) - { - return isVoid(collection) ? emptyCollections : collection; - } - - public static Set oneElementSet(E element) - { - final Set result = new HashSet(); - result.add(element); - return result; - } - - @SuppressWarnings({"unchecked"}) - public static List concat(List... lists) - { - List result = new ArrayList(); - for(List list : lists) - { - result.addAll(list); - } - - return result; - } - - public static List concatWith(List arrays, T... elements) - { - return concat(arrays, Arrays.asList(elements)); - } -} diff --git a/src/com/turtleplayer/util/TurtleUtil.java b/src/com/turtleplayer/util/TurtleUtil.java index c0345e8..0acc266 100644 --- a/src/com/turtleplayer/util/TurtleUtil.java +++ b/src/com/turtleplayer/util/TurtleUtil.java @@ -1,5 +1,6 @@ package com.turtleplayer.util; +import ch.hoene.perzist.util.Shorty; import com.turtleplayer.R; import com.turtleplayer.TurtlePlayer; diff --git a/src/com/turtleplayer/view/AlbumArtView.java b/src/com/turtleplayer/view/AlbumArtView.java index 20edbcc..7d89459 100644 --- a/src/com/turtleplayer/view/AlbumArtView.java +++ b/src/com/turtleplayer/view/AlbumArtView.java @@ -3,12 +3,12 @@ import android.app.Activity; import android.os.AsyncTask; import android.view.View; +import ch.hoene.perzist.access.filter.Filter; import com.turtleplayer.R; import com.turtleplayer.TurtlePlayer; import com.turtleplayer.controller.TouchHandler; import com.turtleplayer.model.Track; import com.turtleplayer.model.TrackBundle; -import com.turtleplayer.persistance.framework.filter.Filter; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.player.ObservableOutput; import com.turtleplayer.player.Output; diff --git a/src/com/turtleplayer/view/FileChooser.java b/src/com/turtleplayer/view/FileChooser.java index b54cf45..5dd1621 100644 --- a/src/com/turtleplayer/view/FileChooser.java +++ b/src/com/turtleplayer/view/FileChooser.java @@ -21,15 +21,30 @@ import android.view.View; import android.widget.ImageView; import android.widget.ListView; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.Filter; +import ch.hoene.perzist.access.filter.FilterSet; +import ch.hoene.perzist.access.filter.NotFilter; +import ch.hoene.perzist.access.filter.Operator; import com.turtleplayer.Player; import com.turtleplayer.R; import com.turtleplayer.TurtlePlayer; import com.turtleplayer.common.MatchFilterVisitor; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.filter.*; +import com.turtleplayer.model.Album; +import com.turtleplayer.model.AlbumDigest; +import com.turtleplayer.model.Artist; +import com.turtleplayer.model.ArtistDigest; +import com.turtleplayer.model.FSobject; +import com.turtleplayer.model.Genre; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.Instance; +import com.turtleplayer.model.InstanceVisitor; +import com.turtleplayer.model.SongDigest; +import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; -import com.turtleplayer.persistance.turtle.filter.*; +import com.turtleplayer.persistance.turtle.filter.DirFilter; +import com.turtleplayer.persistance.turtle.filter.TurtleFilterVisitor; import com.turtleplayer.preferences.AbstractKey; import com.turtleplayer.preferences.Keys; import com.turtleplayer.preferences.Preferences; @@ -37,7 +52,12 @@ import com.turtleplayer.presentation.InstanceFormatter; import com.turtleplayer.util.DefaultAdapter; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; public abstract class FileChooser implements TurtleDatabase.DbObserver { diff --git a/src/com/turtleplayer/view/FilterListAdapter.java b/src/com/turtleplayer/view/FilterListAdapter.java index f446d4f..71df2e1 100644 --- a/src/com/turtleplayer/view/FilterListAdapter.java +++ b/src/com/turtleplayer/view/FilterListAdapter.java @@ -26,9 +26,15 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import ch.hoene.perzist.access.filter.FieldFilter; +import ch.hoene.perzist.access.filter.Filter; +import ch.hoene.perzist.access.filter.FilterSet; +import ch.hoene.perzist.access.filter.NotFilter; import com.turtleplayer.R; -import com.turtleplayer.model.*; -import com.turtleplayer.persistance.framework.filter.*; +import com.turtleplayer.model.AlbumDigest; +import com.turtleplayer.model.GenreDigest; +import com.turtleplayer.model.Instance; +import com.turtleplayer.model.SongDigest; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.persistance.turtle.filter.DirFilter; import com.turtleplayer.persistance.turtle.filter.TurtleFilterVisitor; From d1016ba67e52f92f352364811da0c3d9cd610cf2 Mon Sep 17 00:00:00 2001 From: Simon Honegger Date: Sat, 19 Apr 2014 14:00:31 +0200 Subject: [PATCH 2/3] update to new perzist snapshot --- ext/perzist-android-0.1-sources.jar | Bin 5629 -> 0 bytes ext/perzist-android-0.1.jar | Bin 14090 -> 0 bytes ext/perzist-android-0.2-SNAPSHOT-sources.jar | Bin 0 -> 6315 bytes ext/perzist-android-0.2-SNAPSHOT.jar | Bin 0 -> 12244 bytes ext/perzist-core-0.1-sources.jar | Bin 29929 -> 0 bytes ext/perzist-core-0.2-SNAPSHOT-sources.jar | Bin 0 -> 33709 bytes ...-0.1.jar => perzist-core-0.2-SNAPSHOT.jar} | Bin 58711 -> 68709 bytes src/com/turtleplayer/Player.java | 10 +- .../persistance/turtle/FsReader.java | 15 ++- .../turtle/db/ObservableDatabase.java | 12 +- .../persistance/turtle/db/TurtleDatabase.java | 104 +++--------------- .../turtle/db/TurtleDatabaseImpl.java | 4 + src/com/turtleplayer/playlist/Playlist.java | 39 ++++--- .../playlist/playorder/PlayOrderRandom.java | 16 ++- .../playlist/playorder/PlayOrderSorted.java | 18 +-- .../presentation/AlbumArtResolver.java | 34 +++--- 16 files changed, 115 insertions(+), 137 deletions(-) delete mode 100644 ext/perzist-android-0.1-sources.jar delete mode 100644 ext/perzist-android-0.1.jar create mode 100644 ext/perzist-android-0.2-SNAPSHOT-sources.jar create mode 100644 ext/perzist-android-0.2-SNAPSHOT.jar delete mode 100644 ext/perzist-core-0.1-sources.jar create mode 100644 ext/perzist-core-0.2-SNAPSHOT-sources.jar rename ext/{perzist-core-0.1.jar => perzist-core-0.2-SNAPSHOT.jar} (55%) diff --git a/ext/perzist-android-0.1-sources.jar b/ext/perzist-android-0.1-sources.jar deleted file mode 100644 index b83913659a1df6f10f3439a9288dd7aae1cabf25..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5629 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 diff --git a/ext/perzist-android-0.2-SNAPSHOT-sources.jar b/ext/perzist-android-0.2-SNAPSHOT-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..d0f944d9b91eef163a7b8353d35adb74536f4329 GIT binary patch literal 6315 zcmai21zgiz7akpBbPEcKfYJz3(jhoi5tu#M@aBFMeivsR}GtMSsV&N1%_xN<1gn>KUQ5=RlOHM!c8r-hoX#d zg3!dRp@>⪙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 Vg7NT=FeuPJw&;?+M0NDne*o#Z;ynNW literal 0 HcmV?d00001 diff --git a/ext/perzist-android-0.2-SNAPSHOT.jar b/ext/perzist-android-0.2-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..8b8a051f77ba626af2c57a6a5f2a1889fb06fad6 GIT binary patch literal 12244 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 Wtso8a_!}NJ_>Tn~?ZT+P{r7)d>cS=f literal 0 HcmV?d00001 diff --git a/ext/perzist-core-0.1-sources.jar b/ext/perzist-core-0.1-sources.jar deleted file mode 100644 index 68193b0f6f21b9f7eb99f5f5385720bedb5f3d65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29929 zcmb@u1yojB*9J;=cSx6XcSv`4N=tWlcQ?{VcXtUQ(kzcBnIgunmgkKdpHf69m`3(!i)iqgyf@fZ{kI^Z$r z(n9pF)5(aQ$qWxkOVQFzz)R6mjSi31DKbnmuWj4YNRIZ? zNYM&HL2l)%CSp*(Cv|Pfh)_h8QdDxxq^dxRjJz0jN`QkyXSt6+NpMg^&p3;KIgLP( z^3`N@YjJG>`co7jAgNICzex-V5XI2+KeGPwfoGKf5185*TO0rM7`W%(HAnvWFh)Cd70=p zFB`iW8#+1K{O)za-@I<6Z)5cX?NPG6NS(}p&w z#K=cxU82x%6<|Hq1+}j{7VXMz@%>I#jLCGl+%h<_EhBQR8ho5|4s+ESdDR_;Hm0Z5< zqOo4Hi(BS_R9VT-F4=wOL7)$FF{oySku&C&-Y7GAbzjK~actZa?RYrRY=w4Pyu6Ka z5+kO=HOKAc#+%+<6HgY3r!U->g+x6s_BNr)b;Wt*o8goThz`Uo!`t`l zwoj}lOnX>}cVS4{v)*+(*$ODwBJt4<5;>u47tND5aHd_sL9%Pw>o^TX{9KR+e9)5~Sj%%&1IqGeu}|f(>_*Hzo%%-BZW+zOi3uW{YFd zO}(M_vE-EMlZ^$rSf)5IJ_+Ko_iE^*p}iFt$Q%!sx_l{rG;2zebR$a~x7qyCMKM2C z(wf$_H%~3Ag1t;`DCF?d=P59@p&k0{Ce%4^9ePZDJTiQRmhkZpbQ`O7%26`#5bHyqkq*?C`chx>;_FW{Uy&~>}i#kVBF0}5tngSG7kq9PvH3N8of#t z{=MiEIj;iUK7JYM&eF-7ba2ZYoar92^?Thwbg(?I>#5uYt>&~U@C=Zg9ZE~4C)v_X zoLPid<+7%cbB0sr^VqovYmVyYo{c8GrZ>GYXaq-V=nqF}NYXmTE-^-PwnYuXl|Vj; z+6zVvccP%stw+>MC&Bu%E_}fY!OXA6)x^Rea(CaTgmdj9>^FCtcE&Hp7lI_(Ksvv38{I}58=w3k=LSTU3kI9Gfb_oLP@stq2ET^304=pJ>+sV$d+XO zVq%HUBKO7C(icSc)nTg!lkwz9olf={!NS+gbe$fsRrKSdR!^wzvFyE8Eof&lv}+Dv zg>v@MPydNdelV?uJ)}1Sz_8DNMfKk>?fDGahDtH%a-?n5?7RlvxbhEyjMd?|Q&J3BR2+t&f-}a@p`^YPm-<^Ebh*)ehMInt{{K6rUjIZ?PY*&rT`zz_}}WNYUW@D zIP<@&>J-y$-ouX+Ja(jXF9uJ<=c`Yh2y-Yv29MERkuJfMdKA1I6%u~DB9pWr$o=W< zQ+iC7+HEn8zjfVAd~P|#RX3lJq{S&;SqtnI2JtA51Q-g9$M!V$so+M13UDsj!JI=i zf|f}ck$tMUu`OXn3SK&ib8;DMb8tI7e%sSe`Os-kN(HV>1%O!feR5El8V}I-T%6)(30Js}( zq~-&LOw7Fi5zhXLU_G2u=uGutHh8ujSXT%7R!hY z6p)PwaTTa|HbTA^#gBr12A^=_jLo60G%n<=!_C2szn$N|w7F=dH5w97bmh^LW9(C)ju=hA;wOGr7lgCOHp6nUqyZ)B>b^zzlqFDstul6`+k&N#sn- z$|%F*eⅇnb{u75Pj%7eM6yukp*@ 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

wP`~gD`#9bAG&pvk%m0+z zkJRv49oCRjZFC2|oD#z`P@`SS`5=D=0q2!l?zv5&VS3 zK!@=+pT)-Fa0;-)q{3npq6c&i>SpTBkxMer^*-=HHV68yn;6hSpmF!^R1khuTB$iH zz}lSZ$x405Tyom&$1!6Hte(XnXwezu?P1)W7Ix9@0PDB_ml}+piW3K|-Q*{VsA||& zp3Qpq^t0MkCfB290@Q5*Fev{UwR?8x-!)D$iWj<6RC6mEwx@ z)=bm@3vrD|e;ZasaoxiS*FYTibgb-rsa1=v;o{|{KVik9yJ9HRAu>?Q!WgFIkXusI(;+CW5HPnLY`j)hM_ ze~EtM))O=tvlN~@(duw_^lb?x!h;oP3l#Sh^yfvsOBL{311!!KV38UA+eIpw+M5C* zfbVN{jP5q;rAHJvxeH?_9bm(g$paSyIU<0n6eVC4)LItT5LK~5fV;gGlQa=C-EHQu z4zd-)Qxu-?oK%0U!1n6xLNK4H?p|qH zm5p9(@juk7?iS~>K?x)}Ms)}TUT>#Wqy&BTOT0dnU-8Rc;TEQuT+_H7@^gr5B~SZXmnjt>BkL;=Q#<9`H87!bqSnF8Fg!FSjKW4f*U zpJ96pW_@p#*NHZCRdPG zIS6ob#p>JA=e$_vlkS?aFdwAFCQB^YzRlhi>W8OIrt(NyW@sU|uD)9Q*hGO7rdrZS zg`-MefM8K>lW~Td1mek`#n(&K{aP`gE#GBGS+&N8)7{-WvF%31_*{%vj*U|nhjgut zND%|ft`NkY?Rv^YVh@9FR)EOC`^rIhV_OGD>(jS)jenJ1Qsk3SSa^y zlysD}bT>rWmyS(M*ZdxKGaz%&!e6Y0)fJZVb?9KNz>@YiPGv7n^&1b**E+9X3dNSiPn z?&X5%UVM_K5XeL}sA@H8zQoMOrySFT1uhkh3x zsgl2SX{R^2TSj&m)huGw0tNjQ%R}B(H;5Yu8RCu%)%R;h@km!+_DxD#ZWjexQx+4{X8eq@FZNcZbl>@LH79yZq1}s zNdiR(Xqp*LOHy^jo7U&g=A*BpwKs!FR4jZs61HCrD4tY7TqUR-vJ+SYY=h0fYJP#1 zF!bz#tPPk8MO)ERhkCH_el?8wrHdEDGI&1N?h}gvK5*#!97b=+&~>XQ+lx`!rITX+ z>Rivv7-joPAa9i6a_u4J>?hGO{kHsLr;Y&T8D5Ij$E*OP{I4PhT}~j4-s>zGrPCsb zNtMHC+V7J*I9(XBn_}2k91%m^%T$#FZRLf5RpU|PWB zj(QVrXx(4x-R`Mz@JA@fUrN`y*k;&=y``dBj*d5$fSTD?sPX-59Y9_yNap7d_(^tr zL>WJyfL2~1o#2|+rX8nB_>yK-?n@Emw--=mGn(TzpRxrdHFUrjciZhJ8C$}UyWH9C z_aI3NGF#dkMF^nm+>uTcgRF_I@>ihnVwCndSdV7!A$~RhDXZzO1^{y!0T|T(*{n(f zQvBxx^t%>OiAan|Nk}V-j7@y}AU!HROC>^6I!sMFDJ~%;MMFC${&9ptl&1DGu%F*l ze#VGF;7t3J2AFqFZC~6s!b&q*Fnk+?$rsbyGE1vy!@*OPzKBZ*1E*(SgT!ucgZunl zG#WJiWH5e#kDhZyln{ zoX+0yjfQK^r@nt?w2(m0%!4wz*@QOWDB}Z;GV3o^^(XW2+b#gIRKef5i0|9c5HI=c z)&j4&`>8_%JbVQlwrEupD`Hw%jM7vJf|d&Rqnq8~SfGe=lEf~@vaZ)gJVMgKjXQ-A zA>4{(2r6W~#q=pKfFpBnqTbact|1d@ABZgr8pg^G(2TcqA4xCGgI_{)*jKF#i!o47 zRyq|7=QNsYB7A^pf+cW_PnH83kDS$D^B#)yjX!3gmgRRf_K_!FuyI6B3 z4d{;8mXOhWZpCP~%z;yyOlywV#v*krN}AN(Pswq^TGP#{?>@abBk*>5)#~ve{ubkHe-)~Z`>0bLfiFf|Z{4VeFveN+e3>XlO{Oa8N zLH9`hM*Do^efmc^DB*`vPKtVkkRoy+}3>=8}AXqPVZLgu0ufGq<4u z{07MoIQlHI48M*cMkq(i%vJhMm)?t!>cgqng_k+!v`I!iP1a<23%IdSanb76mUN{Q z>+FHLpNZ_IfcWde-x@9jyL`r_pqiEQfY~SljIpJz5)B$ zT%8%ry?>@tbpV6$7f0m}*kzw-tMB38pH>U*BLloYJuKM7YSAgAI4#h@a0XHHoHa6< z-%dbog`4yFmGL`kQJqnO>|#jpr=&Um;&%-;A*v;&x!sk!S_$Gur^)1OTBqYIN#buk zBN6V95Moj8nCQM1Vf`#BaHs^PJwU|gG=}yUqAFUM0;rnriL1I2G%eKy?oSPGUAvF z?)*!9Z~)0m;#Qkr0}%V!+`j&W_RD#JO9IJsR9H=WRzJ3mjGg3I5`;BVn3eF;8ao;Cv0 zjzD1wPuY+SH)rqfQnf#xuKzy)pumlGpZkkW%Y4E5}vOY zbZRD+q7pr~p+-HQn2GZa-4kAvs4x;vK%5wYHW;2z0X+vv#|_Ia17Xy;@y#SMp8m1< zK{(hkzE=0di=d~I!CPWO7{_7NHNQ2~toHb&ST1d81H_ZeY#`sYF~A}?{^F(C9lDQ@Hx_~m3J?J8@tYAnqyrA_c; zU!RL&cr*KUcJA>aTjzop!C;+MEIj$UWw{1e?&68WN*e_P$#0qIr z;Q5slq?uXNfMXx*?Bo*6j-(9{xB8ILcr0SPS!al@QBcImAz44Dp6522N>Vj0M^0f! zPTJ4s1f~vC(6V`ge4k4=cCGDl`yfVrqGr+PjW<};xg4no33Q=r7Q-h&8W~Fa5iQU) z?6%h%Duqfr>|e>sFlm@EzSboip7@7m!Hx?x;;HJU_`UN$;`9}uFX$q%6D8&DM?WHwhtdjzI%rFgoH=$|++2s+qjW!L5Wwp)!{_DQ5OhHNGU|UV~ zP~c6g-3RGQjtGo35z?mZQ0&3eFFVjUhcf<`QR*0&z&8`<8rd!6_D*tU*U|hP*5NDf zoJ6LS@nw@=o9`Z8`jG?c{6#35Rw(m-Wui4-Ev-9;5%>u6#2S&!PnOAA{!H8M#^dmd6kUvpC!HKf3TOV_{}@c7Ire=SYYPMhyqbOz+xNI}Wi`-`(?;c@QeL23YHG?qe*iCHl**IRCY^5aV8suyh_;5E- zHmNYbvxpTH>7y8yyr9imv0^N}MG5y6oGByw3bf;WR*15^_C3Q5!e7?=nYM+RSl&zm zoQ7t=AOnm)D|vsE=zh=ZzpK|@nk5+74gZ1xRq*;Dtj&Nh6CuS&q|Yx$kcpA;~TvKQAqOs`XVTz_3#TqUB#vgMTgUkE}OS;iD9QE^FVVx=K;# z?`kRVL4-hjSB!sbRa*}}A9X0{Qt}jq!eI(+%6o$>&e+CyZ)2C$c?!nYY9Jm7ts3>2 zUqz2oa#GExAy*bPRPmVhbVPg%8aXZ#t9RWR+qNF0j;kv$30WRl?J}1;ox_zOnJ`en z&Ro~*HPf}oR@>s&yYtOYW^NoWFsN(;!+_Vo^2Q-oh9b$?2{@tpNfcTJv)rH?Z3Owq z41inxs55+elugW+QIN>S%qq4T-S@D~RaG)ZK_SJ80Fe zx^jiS5h|`N#Bn$KRw*T}n;P6W+hm9U0fP71htXdFb4N|_4V0n?JLoQ`T%}HwPg%wq z$aS^(ZPQEY7_*sybuMt;ld>wTtwm5HnFzb#{Kn#jj zA0M%@CZIo+++4Gs^Sicr+EH8`GGZBOA*%1qvA~NP0*M6@$fGC2NL0 zM28uM-176o>E)YO)9B(<Mt$$kvNSUt$8Mi!8f?1 zZS(ksU@$lF(H*Lh!}*(1w2mg15{MmTJe;Tf2tzjBuRX1uJnLQ1QdtMD(a7^wr?Iq#fNlyxHkbJQj1m-62^xi<86Z+z)`qe6&Hh`hh2Y4#ke5 z&&Q+zYgGgcD!};VVU`Ef?*2N^|0zYM8l$7E`8h!k)XB;5mK8HY`tHiuz&XD7yriw{ z9{XoDP9gGW{S6=wC%})f{U^D;%k=vm{3{;|;1OM+@pwzmf%z3UsL47ztw$9XR zH)~Yy(y4Vcd)@GfP-mRY&;`&c0(V32UVWh0ttZ<_fV(7s?!2c=io&kxwTa}4X1zn? z@H+c8pZwusJ5cff_zU>m)DNB&J6uK}f+_jd5@2+w0PcqzAp8Gy7=M%dd;a-d+Dy4s zsUCXN&UN_=agvWNK#0sLPw%9lP1>n1fg<(GEREjZ@4CF)iqhn`xm4w{HFJ?Yoc;CXevPy~Vw!Wjs$ zpsnCoga-zkpexSSeAd3KY*QEMyS%p35(p*H0GNo#psPU+z) zG>jPi%e^oAOi>-@8Z4xCoLbyX@*W?`4Wot6SOlu$8!(Ug%!YGy#-3JvogNAY*=eKS ztV*f3%?{_%G|QOCp@A4PNYK}P5<9AmKSn!XVk2E>lxF568zU)z5C9mQA z6)`;bxU@agysHCj6)0fae#IL8P1WQKb$_cDNk)o8_wXPJ07{B#W-%^6B+Va4@k6p< z97r<_zU2>!ip!iGM}_Ip;9Zt-E`l(_E*DnV43_NL*mo2f&|G`Eb=owKNsKUw!Xi_1 zg1ynrGRE|i50W!c>4t0kVhHMbtG#TblIY$D-EpU4C2G58us1mjgrveuiBK}b6Wu>Vs&gPj|a+Z9)XVEvDOZrj86N6P^mNPr&!^kRrAy0@&LLTKH;|0C+ zUjRHiOa9S3-68-0i~rkM6ScB8wEHa;mW=9tc9;Suw_#jnv0p*d!h$uR`H&ubEms<4 z)B7C470%W*`~5-O7g!nTk&eLJfjRaFV#shPxK{dJRTP*`HKk6;k;`ToLcd-Rl3?RA zrEDe}1dS*m13&mwy$(fx)i|GD@5n66ciXec^?s2vIGJ7G+DAy}P3lz5Kxh zGSlnN=JQ_f`U)0#G)szrWAnGUT?{v7!Y*82b`&_~Y8}A+yzIn?bsT&^`u`dJ*SzW< z{Yl^3lzuCe@Hv`V{E==oC`rmM1Bxa0%Ehei^inNxOf&_)xxGxNQ@G6(V{c?-Eux9} z#Rr}`;&!Y#9`_PD1ZteJ*DAA=plj{}ntWC=>tMPd$Uv{enr*7T0PjkLH1(}Z!TBHd z`h@0r;pPIT*bDktRmPn;*nDs~fk5O3Njhgl=Y0a!kTQD|Z+yu^ekQFETussLjVwi+ zZNA?ZBCNwmeT93UuCvY`34vtat;*OUDPx-_#UuN2?KMM3#GTlZS{lTTF_mpMhQ%D$T+Ct3+*zKvG z6?q^{A%+FkQ8z~TI&HuKQ;O0Hv|S=_LOm~J6*Dc(^wN(e;*X7MP>K?a^EruS=C5V_ z6=WHqPT8abXKCIEV^s`K)yU=Z-<2H}3)PCKE+06NA(ev1i$WC%GAG{R?x0598j&rP zcv&Ae%1KX?t)8IEROE2aEO!^TM5G<}1}OCP7o0&dRDkb^fD8^4k14d0t91Y~=gA(> z5a;2^s+q>}Cy!b6)_g%8_fSrAg490bKP#F{e*@{V*v50foBZ}coAR-JnWMoQUyAyjtcPftOiSWuKQ(9-$rhaHvgL@=X zHE|gH1SM z;MCrpNILH{431bi>@5x9RRa*dVn3$+A^%)$N+Vb^9Q3SZ7eq)T6|8 zF79acu$_G|v!kS~A}edBLcBn~p>xLPd~**+O;st%AwyHQ<_zQKL#Olp4Hz`Q&<+8D z!e6ClKOMU79x_pOQVfIv(PLb>+}hb@8{)V;M?oe`dFk$jX=?}gw1$WsB<}Ue=eV@S zcMZoM!HtZJo$_9K>%#%BPilrkmk3=Dl;=g**C(0HLCz)wgmhR%-X}JpP37iB=O#Ys z(M>*3RO9A1EJoCM?px7-K{Pgw(H|Seslr^uBz_I>sR9{%^Vy>eeR}7Mg<_Y7>|1F( zCF#qLpzpjLAsR2djAi_3-z|d4QL!R52v)Zj>cJxpL&#%SVFVp{M==n(V$KxV>ZN|_%xkM+7l*v0mRs+_zHZy){J;Z#4)qtJ&z+Kj70ZXu0bvaQ)n7#%fKEvPT?bt~UHjkSBg?36 zK)U-JR);-7&dzWF%1|{LZfW2UV^Rl>x_NM+NXRB9QOn0Nn4QG6-rkRdwm2w`9nloDS zik?^IV|E>Vpv-~FWAo@<`0Wq8+OwE9)c^u$ zME+|JK_QiMkP01rJu1ETg@s&@q6zsvVK>fGkhz4PhR(UvcSW^}gJ=9-VN)jvr?8Qt ztzt4M_~iDD#gznXlsOX&F|LZ#$io50e+pIeKiFj>WiiV(e(Zy@OWPTot4^{&=?P`p zjNS#9?WjO(rJ31%Ucj4ha3DC=Ju@w`YF zB}EAifHuGboZG)9UjJO=cM4I)(9Rw}ZtLn<{H7t1a(@ycdm^#kIl0&}>;wu0V4+)c ztBvTcDp!TTrH>p=8Q=*CgIap7#>S*y7>c!QrE}oVCuAh2Vjd=<3e45YMARr_9p&}e z#gR2r2hLH$#bWK{RQasR+r!rvqi>*^R!k|IzFCQ^1y9#Gwd$W5E=iW4Z4A^1?ktKq zz`t3DE5Gn)rl6ohFDnXm1pkt}qX++WK*8Ew#ZIg%x#liJqIy~j$t~Ws%NVg}S0?vwm`vqGFvQ+)dh?PN&ceT(L8f2UeJpLDvmT<2rS zK~G8Sr<$78Vy;G%gnmro>%QoTAf?|b)%R6Y&^=*J3%=vm z%EJbZ!>}jEH<+rv!7Xb4u;COkVE8b&@HJz18|AMJ>57sOAUHXBbqopwgpU1xL>m9x zknfp++@IaX-xaVzb=7W@1+{aRVy2_k81rox-&7$*x~Mn-!J(6pwG%cGkESk)s+3du zr`58z%e5rS$f2~rAKvV8yq#jt&d|^Bh;~LKzBkG4MimkkdE{r0JTJ$Gih%565LA7& zHDnS1KNulnZ<#?%Kb}X^gBrJo;^%T9>XFSBepBV;Gb6nLGmJF)0Zv_b0=+x3?1nJU z3!HY*VI&899&d9Csi1Ao`j)-N-l<1rwy=)LhvT=+r)Qk_a$jqOuT3Z%wwoQrKKG6ddP&9Di6Z3w2oQP(ANA&?F31?LqziehWCxc>Ajl*M}Dw3tXLEFgPavb74ho@-dFXqGek})=4i1h z#k#qcU4;hJeu&@fUQ7XR$sllVP`<;KI|?}9dnb);+7$`k@HOE~8Iv%DA91N=-rx|j zXbA?`lvl1YA1QA=X*>q8-q)?qAc}_%p9aBU$o(6QYrY^hEse%c{#j_GD79R|2A)s5(g zM8>MOg+yt&f(XVNE2g$=%rZPxmriMkQJA;0FnFu1jCixGj0mIVbff0ZqxN*^ySOal z)=%ftqjT=twk?mJ!)1nDZZ^=aThv!rZLsRL%*+bi<2rm$JAKq6KG6;+8z^Jzh#9|i z8PcsFtWK;iWwH_Npl$RDM_K0%wtJ23Kld#e6C-Ba{5WV1IxkUFQH{xKZMFJPQ1GH} zqsA9)O=)o^v9c(;w#d>%b29u&voYk&vAR+{_&xKD3W%Vh_i&`y;F2te_+{QenzDW# z)2KX#Uq^NP%qF(m{=Ao9`RzuwuUBGNCAxQnC5yu=TQlQ(!T0dRu-8S+t%BTH9SX>*dtmF?ICQ|Tn&A7plcJyO#OC0@@6m<=m@Ke*18*qM#$ zY!Bj)6mP70HKPdcF0z^hc?Q8GuMyrRv#%JNnO6;sLJ&d)B@dyTnv}3-k6LkRlW09D{%EKE}UJC zGb?M-@=0Awcml32BuAq9GFr}&TQ*#OV!1}^eAiVGV0i^yX4jj4NEFLy^`wN$j86c@V?Dcd*T9oS`Z*^{8#GhpCa~Vj( zJ3BNML&_e*Rd+F!I;liVL-Eyusg#wV8870}rU!}y%a!1dh!ENcL?>iW=Ke8m8=OACT#GoN%c7zlS3lfeMb7++QPn^&gfl$rM3l)m!zhZlBSi67A2!WoPK^6t&mT!Xyw-4Kt(Zu^`CEk4(!T^h42X_m0AT-@Kr8$iF*wFBSOH>6 zLFY`ryt+ML(>lY^%^VJzY8G|X*Tj^9>Nm%^77&u^0r6eq*8-+|*HK))ScixdF`49^ zw&>~lqEQxv(LD?~>sY;8sPW&jX?oTg{f)BU%3Hg1(-2HHGRW_9a&*y(^A+Jnv-iH_ zkj{xIiuE&a(Y>Qz2d~#sr3+F*4#owJ%FkL_mw;JX>2D*^TvU5))5z?z3s<#zn{3eQ z9v3ggZ&%!rqF9Q9F6@2VG(n$xl{2|VP$h$s8FE&&K~Z$(T-HgnmNUo*cj}D76XvSI;zB7yu{n{|+akKW{<(JqG2q7qxOQ zH2%G+9Vxpk*7v=tJ)$2Nhi6g}Mh@vWrMOY-2!RCB15H+YK3^A&ttdJ>ZuUzwk2My;Lk1p235eZqhePk!Bwf_fpN5-3Fzk+ld$ z_95-Il}lP_k(F*Ub9Y7pkG2LO|HiPFNfG9q&M(CCnclCqb8;H{oV?JiF_H?vEDV(J zfZAIl_LgH?0)1TxT4WZXOPMI816yZV(SBlr;s3dK<*ij)<76|3eB2AJkc-2oqZe&p zTPLtob5)qi(eA{r!5(1~Kfm0b@Ge8pk5cX}tjZp=ac%$V;r9SZdj!QVZY8uspC|K@ zo0KiY`md<+Im~B5R|VPzfb0zbTj+lUTfti1!47ck?mOr|*1jrYc*Ox}cHqf9)#qlg zA-rluP&7~ky|Qa2Dd*rq(GL=!iI2|llBi0Yin}S-=beKvONW;}Izr5D4#mI&&U&(k z@=V2qYBbxKjb_3o+S@c6uE})y6(k@7W=0D)4FYz(mNlFx@i)yL?W%8At!aJWyEk8C z(szx>JZ11QI^p4LFUtlsu!ejX5(7ssAn^9TWPH-Aoo}{#ja)|AeZWyiKB#Ip8aN-f zD1C;2$zGM)gkIG={84-(LHVu}ZkqOOEE0*JGBb0|*NR1`1@mmn8`knT7Bz1%e-1J> zop0CBgU3Ha=ijgH^)*5O1C%xZfTP&|isL_(_BUL=`<+PHk5YZ~uz-rP2en)xo{1t4 zq?AYwt<8Ahnx#ORkW=es?t}AEp(gJ~XpfrhR2L)cs;^~BM0;v;G;b1c_j_$(R-E!> zk=4*7z9b}a_%}kI;4%_OY^g(kQ5G{dNJ^6lOxl(_TvUBj+p&^y71+d8Qs)SP`qWmz z{Hk7Yq}o8^f;7hVzP){wbNwxvkM#@922!a2RKoX&*}!*cN!jY@ec)2eDLo0~(Y>ff zqe8Ch2($x{wkI+xm!k1E4uu9pZm3VlPgEd>=mG0Ephk726FP`3~~^@@09Vv!=t9r~o*r8N~bp?5Nm9X?Tv zwSPX*Rvzm?7G7~YifMnOLKE_pOSo?o;}w+&!$`D4U4uQ;Zr)NKjKOM{Yit+L!lgxt2^s z=JL3?fLgbEdCcR4%*=j*sC!`v{9Hj;EIXrMOjj)EKtKuxqDqsCzD0|haJBfIp(2HX zig4yvtTd-Uejn+oUU^g7vfbA1}N-*U~epMAo1Cb`b&8$*-cH=exJR_w4=^ z{UpZy&Zv1p<8hRn!<0+#&2GG=)pYfteyxsgS=WaHT<=UK**e8g2&L_Ddh+zNIR|-5 z+6ZbF+?Mo;kN--ZU1;7(3Awc+i!8KM()?DAIG=b|Mh$sIjatv!Z+><5 zAvv}Hf$KmhWy&9UtWCvb8<17wxfvsAk-9*;nAUz%E`cG%Fu47xWzXw=9;4T25s!Xl)e=9&`%4A+{f9E#AtDEV0lLt+qj)v67hkxIbRC zv0UbD9TX+%RqrjAwylzCNs6;jS-DjrDn2SJxL=??<*>$rloJ#8k)e+?`bCMan;Q)6 zKwh0z+NE%BMNczp3+K36jFazY3Jo1ARxS=LahQW49E78}g*|3qwSpunE2LxMTZ=Ij z_K$6d^Mhau1$6bPRWjM*wf2yO@9Mj-%tf3^d%EcClt|B#>XUjO+aHNGSv`Bt zR4R>4P=sApCk{1UDNzOZ3k9WzMMs!rjqcg%rm?9K;n02{*dWbpy}F_x@^0ke+O&N6 z%Cf-zgJ`gDKW)P)veh2YQF}`5)+6y31o^O@GW|xjskFC)%*!Qh@L)vR^io!F+f>Y> zSf3U3GyLv}223a$P!uPcAD=)9L{*|)!`FTY7N6r6KAur)LcpFc1N<)OFAUW4o(q}U z{oZw(82fyw5kOmeLF1r624yZEzb1!O0$5IGTHczOpgCPho)jYY)kW(Xyoxw%B)>MXA4FN5lCT!GtrzwK`d_vG&_6rMJi8i>_6XCkAnSLGnm7zQ~v zfI@ddrSg``%8CHBaY1ho)HThJQntG!Ngd+L-K#5H+P z%1zCxC%$E`kc~n~@ba4mrLvIMTVq>&kpZ#lHw~=j>~zI-xw0JJY7>=!nC;G*c$3Hj z(Hw44*TWVnIj_Vch_`RT`$GzsC0+eox4WHFvsSSCerQN|MtMK#^8q9PWpn__|5_gS z;bie!I|3r^-)`?D#;iV2z;gkK^GgGm-V{P&6w+f35tRNbPZ-V!Swdc z>a_O5%L7>$xjD#DteW{7W8MruJczGV?Lv`pkMi{3IwNrI6~rN)_;d#4GlZbUhdPiC z6)ds3 zbbRIgX(qCIDGgVRKlR*bc_P{C=NMrqaj+8~pd6S0clWQiX8*CA@BKvl7P^l1hR@6T z9{zrhbu(kTr2^;?gHAldLdjUtxPAKkRWFN4IeD94CoFR5ar7MOPOO>?kp$x-`KNkE zp1hyxzlxnGM&@8GvK`7?iQo;?eYGNvoI+57Cz^7n4KQ^VZcn1Dn7rS>PZDI)Di#=i zN{}|-D_dxmQoS{pNFv|~@mf*M<5l0`5*V8+o!lxTjG}~82&ZvsPYd_=kx7IS5!s~l zeZSPNlLw=*#1K_DvA$Ugwo4jDS9*&kH%9sfp)MP1%g~@_)pgKyZyojvcx~WC+r5IC zYrwspd)pF4Z60g&_@Yao%rzCeBE69^ zF3cT&f)9*Q%#` zkO$pphLs8KxR#&@9TPZsD z?)DhUs%v_OEK{m<2+*=T`?o?d1!52V^X+#{07AbiVm*6@-#c@jJK%p)&EI<8zT>4C z^GBHzx~!-^_^{`NDF&j%5*TTNbWDK~RxDddya{Z*v+)rR>SO%Q_!Hf-Y&t6!eu`}5 z3n)c_$7+f)RA?*(Q#&)t54#nJ>4iuWUH-JLu&|kzzB+i2!7pBJdtI%s&(5btBGzC7 zdgC&rpx{@C-m+^VH>TZfbl>ew5beB`@qlhVSY9@4Wa5Ee-8Sfm!OHGWfk9E2;O^wc z(=vdYb@Iii8B+=LkDAQfX+`n+@^tIEZ3EncQXg1*+3e1WSqDc<)wx>T+-)*!lkv8g zMpt|Gt+__u-!PkxSo`wqQ6&Jj{$IZ_;2&D`{ruYhX`nn~rKJIfxc}q<6-7FRInsFk zZBrzKz66^Un?j1Au()qyd27(gaRM|biY41b>a~|OrkY}V33M*ou)aUIVfdBAnE3qH zMxOmQG;O#?yGoFy%L8|B3(y(R~C9pQ#%--cBO#YwfbR%}UI2?fUg?$t#eNjr*BUjs3j{(KKsgqL*vn z;#Emgxiv#Kpa8!_o)*AFug6e^rmW7!vU*KuJFUK>yd)+kXHqU}tUf+c}mQeJ;NPih1Rk zZwPk4phft%SZYF#z*augFHR9VuH^b&9p}@~cQfJHeYiFkW`Zb(lE_Qv$#NimtQK{E z=E9mPv2XnnDqSGg80ou1nmClZuraxhqZCCO#)T_;t(U1qzh#;zxWmliNriSltO_!q zD^|UYNFa~Xuuan4Xn!EjoAu!;gzwbIp3ow&qKaUC6rG5(1@=y_9OQNT1yTlfQ0zdV zuBeO8;<;mo@9L)MB`jle`b{gTYj;wZE4$g4_sV;Dl5MqqZ*$W9Md`%Kg5JjKFJ{t0 zxCFr#F*TA+5}X~qCr4fe$x_CbKM<&(NDflZ3^fr;TWJnnb~mqCuj-=@O7Up_O?z@ZM+Ja4p+bPSY?t2b>|oM3ybT z=!*A-A&&188Bt-#SCu+c3~3=M9xUq#$r7;h=Ip0WUFvMwPA6qB!|a)NHoZXY`{R+d zpPekvwy6W&)VAJr>oSO(&F%b^oXn1s3=M?DOz346PU?yAD}3s zCRCPQTT0H@IIH7}xwN@na5E|aZi?W~&{)HnZKLngWbTfEmd3VeopIxLG*b5jmBlgV zz~f*?$QmlZSVI~Zqd66K_?Ie^Axpkm2!zCaq}WfMwuJ0KrTGTONnU6ZoJCmj?TC@}X2q^_}dFq=tC8sFohDVz8=ZK zlJJXSJVBb__l#0$Of-Bwax9GYs@!9ksH?uGO9zQCr|k#1!N$B!?0DwN%2PuM`hycbV2HZfpBwc+d-aM->K zpI5HYfHiqy_kM7_zX3-nsf`d$hhejx)!Uw^{_+K7fgwA%BOeoNQa zqNGH4+6}=G?YKrKyN%Pr+nfB5grxZR`}&p(e@h3DEy-uD0m>)~*o*(!t^VdMzMC&k z8NinCz_y<#t8f(%p8J~jLqXZ{08?mJucjCTwk;m|m*zZjkc!R*G~R5^Mj3PBR*eQ* zK}v*M3P(-I-_$bb9@^0d)EFN!2KEYx-nJW>cU4CrY4J;bigk?oY7qJb(rGui$Z=rfzzoix17kO_at(sK;wOOFIW;N z;}}#`-hW{4hZa*wM6qX#i8A~2WqouabDd-b=(tKfO;YEeG%K8WrCUejF2ma|`Efv} zu&XfiB8rCsf)(6#D2-!w?c&p%tapWUZPb;rpJ+woj-Tg}r^4I66#LnVK@(h^5dajs z769hI-pv2U$yPQov@`rIM)@mrj+7gf0yGeJp2$nECF)#(ostdo#Ur7>X9d5R=(lVd z8H>aJw3^wd1})~`o^IXweswP8{Z<%0odr@cp*o6pGdW98ANykSnNxg-v%J2BDnwFv znFMZsAasYP!}fYq1hduT|5Ms|z*F_VaU2~+ODUlE*Dfyp6oa5`_{$Bsv>ng8a=lwkAyU+JL&*#hM*weG;gNUXl zk=FK9VvC{NF%jP`i=eTi)UDptbQzJvA6>U+gl!%sF?!L%)cp7Y3qjG>lZ+q46NK9$ zC~RB!SsDjerCaw2cyYdJ)f^P8b-iYr=--%eLFJhZr; zrx`$XandlI{?z_`;T0;ag%2|ibI5*ud|r=Fh5dvuhXO}@@{dc zYxrW~+-f8vUqiRR_sJyOTZyNQu#Ma_r zuGYK%EfrmD$a7PZS9PHsHzK!nY@=bfu?QNi_M$&{Rw?ck+3)8;${C(J683QMSAA!| zu4B|DW});Si6yHUk&#lQ@6dWrZ=_Wvli8T_3 z(7S>D{61g-i0wDjG=_@C0{Y_2npoB#p=nj=+zD&DllJo)X;if(G|)Rr(qd&bYv{Y$D^;Wxfk)4| zVTh`%j0$p>q}eTPjMyYmnJ0?_L-gU&8^2J#d~QPe;tDs7@0@~%#Cn|c&w6|0ko`WW zUe-hLlh93TFgw_|R<)3HScJT&gGiE|IV97N+Qh3!yrJZlMjQW`RBn$}VC;PKVBNiJ zsH+=6;-_nE4*z@jhtg3Nb|?+r>Ox`SP*$$(j3uKIyG*Rpsr7nRM1wr1V-AvAmnDyr zsA#Ij{E^JDtUkxJhfvx@XtYJbEj&N*o9XmrYJQ&DUGln#Q%$K{yLTuCDI9bh*H3m~ z+ej)Td@ku?5|M;~P?G?EH07@|Qz2B(nC*}HC>N!r>Ia3N=lndOKgvAWky>r`ZF*as zWTUyCL?kUk&91|VEnDh z-$N`SUpL#bvn4r_r;)Aa+@CQmKdm4ic;N#t=4M0IhumYNp^be4Vw2|WvZF7)rnH)+ zr`F0JNlBX=p$KWR?B0U;jUka{OX}K5&)@7Q@y5t>zeu&d^MePaow7ni2HSSmTxfe> zA)TR}B;|AUsF)2SSMoWJqVoNv8%qY?noO3ysn~8hs{3+^gZ#k7hB6oV9IsMe{S#Uk zpP#w?L)u!rT<@6vy2fma>gzWRQpBvgR%UQs7~@uWu10uE?Wuqh{r#BVP84}m?QVbK zi&%1li{-+u$z1!*+bwzHaJJIauOFNfTdr?jAD>BgFqlJ7!q;K{_*?eyU(YQ|Wrt}! zNoA>jZHTuikQa|LRsS?LbN%nDon#owjKcd{_dg!7|9&z}btbyAJ0+{P{T|!?g1wPs z5<{ir-YsIf24UUAwl7AKat_HI$vofaMmxyY`>rDPcZS4xhUIdS6v~%%`Z+k}jy_I^0>6 z;|pJ1gF0#{^u=#nL3P%-j;axe=@GvE?|A+@WU0$ z{ygNRmz~4(1~xt!Q~5eR4Mkz~fX3%U@vKMFGXtLVg@0cEF{P=w*ia}dP21l7;ekIq zxAS~P;vx97FrAkXB)4 zR6IDIKu&JGzp?G{p5Ny#6&)UAG~oOken9k;PX6bfGv+G6&MdqbB`3CS8&0{rzh-Bs zhGd2#teTZ*$~MRL(w1D-){(m}zQxTc??Iwmk45G!^8+J9Qh^>UalyulcOqy->ReK> zjAA|7I$uMvCpyZ_bzZR7SMhc=Y=~31$uo0-b-Q`g+jP@L3%c;J?N$Q7A@b3*!BSZY`tLH+n_?SQuwZ@3fD z(aNC4Pc!YFVG3@k1F>30FH0-#S_dnJ{dt%}7}f1tm?~>bqPNj`!@<0B9q!5kW+iP2 zN!!%ct2Na!vOCd_B4a%mrn&8F{k7PLzk?M{~#MOhWix!>1OC+V(&4`IL(|J@Ed0)# zFEcZ8GdvjhHFrKa$oyxo7@Jwpv74Q?5?kbsJogZ-=f5EK*R`)r(uGIx`dc-MGtKpP zvTyg_c^s$~>cBNn5qx0?2%j6uuE|P;Ixqb89lte``f0n<^Gkx`!T-9hL}jyqVhzdj z2iobG7rmIOoOWuoTIOgEc5CPgetzd}_4kjM=3wy<&36vp4Z^Cve^tCr-b`*6sIcwd z(jvW)tF|(elj==6b>f{HOs6i8D(7xVjBBXPJh-Wkmt#=rFf&KJ*|?*5|5sn#=^tWU zk+xq?ev^@nA`UT@8jWT@RGnbE>A;ia3WTQ(7$41xRURw&h7{5al$jv;*kVj zyH(;eQ%+6wdQbfN>EU?&;|9SiISd$OVgH2h(R+o|tuZR)l&X|b->qqha|R_FW>rPE zS$5{7D}?wYf2pETri;2mD|y#>BC)_Hj5mTj*vrnQCgYZ&j=V5y4Jo}lS?|5}a|(P@ zp&=B^Hl2ri<#@$R_@^qKitE;DHK$ZniDw%Pe8uYQy}K@9S_*4eIexj0Hb_tG8}@zo z-M*u-gOp?I-|uVK=OAI*>b{Ay%k^5ipPsEiKsV3Tiir`A@P;NffhXr@{rfC~zY}i7 z=t$IkIZ!0flsR1A&e(Q4D7Is0@?!Llp&^lHw)XNOz7x03j{&biCjDC?Uqa0(5GrK+ z<^y>91}zSEJhUFp7=)!HIt)l^H%*lW`w1{)xcOsp%VJZ*Qxp51#VP0Y*;;9iG@PWZ ztP?CI*d};Xg<6Kb*V{%uFV~RhwT1>Og$p}>R)ka=mWN|Fm`)>Ja?c*xaBI0^!at2v zt$4PE5ZNEleEQ^=3+7FI0>9J_rx3R;Qno)+M{GPR3VI?&H+2`XO2-<%4zw0A)FAgh zcFb?%13kL&DCQ{-xwc=aETn4gH+JYbYJ9*HBYgY%n`grko-wmW50KarryJ!FFeXkqQ_c4N%7y&C$-&7 z(#=KLF4X$SkE(o^Hk+nR)2y%a)YTnJhh)Y~&B%LDZAwEg;PI8?v5-bOkuowfrH8WS&ZbUu4Vtm`k0|`1Yfgv`s%<;<<-G=$f(^^_*Ybh*Y(P(aQ$C}{)!^u( zg_3O|0$J6+Zk27hly5g?uEwLOxqw`sYN}&`Fx2XjN)kY~&EZqd$Hz4O?4z>_j_f zLk|^4)UF>SfBvGjyrk#WXYS)|FU*b&J83BxOiCo04!pfLvNijDX&g~dXrLSY zyX2{q3)l~}82X>`;YAuTzxBRy1SOsSabL8gijf8?aS5{?YJxe(IE=1?_`d`UEz0be<$n?0jBu-Y;+xI{R+0ECX z8{edQSl?_c`pLBCrw?!AAdlp?%JqlevC3$@v@x|;^i7J=QGCoN+Jg--u^e}B)qc=Z zTcXasCnF*lnY1UB9--K2{YrPR*h4+o=ch!akoQ&h z%cSW=vU1z+y_zJdqU>#REO(Jpq;bx+kbIw=J|tvYJK8WYpmHYT;71l&yXR?gfyqkK zZ6Q9HEV=?+ZFELy^+jAyMOE%JOX$=UwK)lYa@;X8ttXIlFbCBMItMnnIMG;*Fi}a%-b}ud@Suk;FRf1$_V(WtXkPi0K3XN= z%s5T7gh_HK6ARbL^12FjueTVc?^z>c$EO=Jtyzidlf=fABx&fFZnyIDKEKH8m_Gmo zL5i~*au2k(sGM_DW9AYM?4dJwA6ij-KG4*W$o09@W7>1_`!Ij1!jy;tnmr@2TPg3S zZ_h5<&z@xS!e1!QCnU~Ta+Jx|g7SbI#hY38gTm~k^5-zN)x*#{PDn(zjvN|Ba33r( z_a6k*1Yc$0f1!>US-1@MK_l~*5fG$$@uM$89XokFEtW1H=znK5Pl!#R*RttxZATV6Vk07v?RbY#fpy*P9SKtfYz<+Zr z{sQ|(4Xv4$mD0aET#!w~pQgDAZ9#4gO~Z9u$-H~8Z$Ycj<}^>xC|t*vAgJn9Q1g2? zXckyxORIAo)E!nTvV}ZmR4>MLyb0o%%qpVy`rdFIe}cG^ zy$WT?VJL`OxQ;_XfMfUptrpV)(7wX+)jVqcCzMb5?*lgvNoeh|tR7H1o@f%T<5K2P zFbT5;32Y&_k55_fE!8Uz7Y{s41#u7e*%}CLfE34#E|p@Rd%G|%Rx!6a1L5Ea3JBZ; z8mpI;A_!kRPXXkDhZZ1Qd1wy9i;E6B2JxWGKY~9?@!#-($P{P@RK7!4ULVt|uj zWdpdSgVAhUO1=oYcNO-+w54MH_(Y6_j^H3VpV)9p@V0xf1^8^cvFysK|#{G2mLm z3aHNq-TyP@)kYR_59|pu~bU0=G+0od7YSEsB?sxm#IQt1ueO$4AhG(7rMr{v-Km zXs>Z)wIk?8D4Gcm^qki#55u@J!Vw#jQ1}@hHmnvO1i|WFnjen7Ik?=w>}bTW#s2?j zc*R_4v`t)@#E8vID7)hSyjfIUG1@M!yjsLAz10707nNm;whNarm|}|9y#i&N{`dP` zZJ_{WW+Ju0p{0Lg$uWosJ~EflM%|3t{?0 z`y(qAJX{#)6fckpCO09}cE#1H^D`{;j&JeJ703oNjSzO45T4GZ z5U!5K!-WIJTqF3K+W6p6O=rG-aW+se7#XqhQ3oF@sQ0;ZR+bro8xR_1KzyMLi#w)yR=po^vp!;A1 z9)fN({EzN0t5~>=g0XN2Kh+2yJ}NQ}?K+GGqrDLHRw!0^?UDy#zd$?~+JxY*Ljf3T zooG#PH}U>FfX_Bf6Yd6frEFn|U@_n6>=hQ~{EI1So$T;V4OpTG~s8fd5u4O9Sw`FpJc#_?Brej)`bnL`1)z+nGgkAn&Pm9XGa zf2BG&=U*8I&i_X?&VoZg{8g4=)IR-H7~s0V{wf!U3E+Q~05sTtw_?#9K>v(1V6prg zV8_OTK>QdGJK-@8YX$`YQGfu}u@ff3LILq65gQW-dO;EX+`jq^wJ!_?0>TW`Cl&@= zsLTtY^RL%_Q?ZNE5xfQiPfCds`lPI@oS)~0jZ*}+&q!&f39YIsr-DH==y9DZcz_i& z^8_N0w7*FvMs*=Kz~o-ix!V1hg9H&OlS5q70vNb#mV`{&N$6U)!cKX_?ZRj1&pb(`=IW zDsGsrq)>*m#t0=*G=rZTAt4@2W3&&wzj3{|#4o90{f2TY;>B*raC8j)WdzA7AaH`5 zmZ77>-a2x1A>z&^|Nh#HLt}jkV|{Acizb%#mzp>00!x`?C%jBXzZ)yyHim^9a+MNR zG_?Y!q(HqoE`NFr_a>>NN_82a4fridgV*Hzv-n$$#>Lr>dVg)hMH^-D7^yQHth%xD zje`r=w#&k=h_H5UB?S)7^OBbrO6T;G3YU`vE{1Q0?G7Jv$0Tj5=N2k`r7=3?o`?K- z8JdQj2w~Q0Umcc%fTS(NyUO@3p58psS$%17rk`X>!O~DcX0e^$OmP5-)r-byCwe(8 zlCZ^IeWLuQMhoMH11@Xqkr*hQ4TDTqR?P5(kWGU9&N<|~c&W$)Z)KGfsY1D5nzUAt z!AQzZ)Z@|SjA?%|jQ>IpDN+_J&oiA*{iY;1G%WR7#Pu*=T+uF3g5{?xoCsGZQi~+g zr=qeLEghb9=MAr5+KVJQLVJ%B_xoDA#SQe*zM{cR(lw1 z660U!eNbDOh0?l5yCC&zNtVwMy;fx|b!0*b$U9>b(Wy^SWeQsK6Jz)_Wv0CA{hep= z6M)W#Md4JYD8=!1e{|?tlx3TRWLAlHr*r8NvLIXIj`c`GEdEu$zEh(4i$`g)NYbBC z2`7gChjO4n{utPNPg*(ZhyAsJ1BJB-few?nz^h4UpdlGF;JnQ#s|^`8_@z0YOIkOz zVy{@;FoTo^g7nM6V{~cVjP0s)16$fh+?WxwJ$A&%{IF#FD>g;Cm{Y z`-1fRec8PlcCsO5R{s_170>TX^}^$W%*UZgqK5af{AN~P)|VS+4{G1vJRx@Ia-f`$ zSua+?w7EC7f_T$Z9XX)|Edn>%v4)P@7*h?wuZy#Y#)JXtOhjT(&ajw)CqvPo^x@*; zJ>lfkZCy}2gfyP$Vo2~1aTo^>zoR-V=%Dqa4pa6gA?Ry|qcVQUF>2qa^QM(|s4j`Y#^@zMs86wA(PhO8%BHIK+%B=z2&*;uVpO<8SP~x&X6C8(D za8qaGn>0+IGU*Ng;A%ob=R)d!k{UTB{7umX2_XTcvenTTW+E(p0TfGY9L};x?s1ZFf)r znEX<9pe2cKkSc0bE;+_P>yyIH(?kBmmlX8poaF|A@1T;csaVhsJ+z=(;lItWZJ+rQ zB%a^M9dJ$s z-VAPcn3lU7i!d(ho!dQJ|b56d&c>?xRu!tOg1jd<99r!XEmlx0VCHEkLyn)G4b*%PXw$o*Fr-CwMl3 zBu#>3z0}Is*d0l|{!xsJcO@UZ<2g6i?{nSdCqv&VQLe-dTd%HXv9Zq{vI!nWm+BoZ z;{h1@&MUp4V2pDY{TD>Od#THS+Cs}%ibolsU&}Z@I7A_i5#P(niPy}aNEw30rN z%`cjo1X`(438(B4*E-h`CIzU+1`a_I@^b(>rzed|a-aN0g_%ldfB)0M5?Q;7dJT-T zyz?U5tWDrAj3Nv)?_x_N3otu7{VH>Hbvn1V*B`78tSvW`>p%rLhz}!#jE=&X8fH>jOFB@5_-3a3 zxkb__UyWNMR=?AN)@>c|a=_+0T%qN&gZ`Zr0K$X!IK(&JjDUF_;v0sZ8@A8Wuv|j!ZnHwo7E2Ddp zkH3z8o~NvUT-TXa!)^8!zr!BK^sRoLm}wd9m+1V%OcDVNicK4UbyT}M`?y*vu%NxM z630Q!<-OhFOGP=JBD*L%LUorei@J-;GSzt-2WPY;ZcXPI-2pgKocnHlo{I;s)en)Y z6_-(Q{$(+~LgE&28x(VuZj)}!gIu15*XpJ0iR0UW*0Y2%2hXV&WR>G(tG7Tp0xWCw zG3H?L9`w~b0qSgk77=~1^&{Tk6HVp@G%wyEG;i)jID)_r6g=PO&m3KIzjfq_%%kAUGCn}ulxlQe5-)1%K_Q7Qs|wBX>$_(f3`?{;O%<*3 zHi+0v_YrT53Bi8HISD%lw*WUF1`XQuBdv2ym)Pxs8UQL?(o6P1K;y41m^RCgP0)B%;!2ZI^FvAu}7xxf)#Fpg? zF1O!Sl$N+3()QlZm3qN(xI755LwMYwm6|H;As2HA~yGSL4F#$UbZz5QcD zfb!Fyl=h#&AOYjQ!vgFSCSeDJ;IqD5i1LRMkwoqUN@6IILW>B$fSu#6MK*QVLA_6fPG{b+=VG>|A;1CBjcaKp&jy%XnOP+{ylnSK>P1?Nsv;q z(0n|){J}B*_~qLI9Du>p*4V|RSVdlTPzc#?K5l41!{+q~%)2g+!IO;y3PB`K$r?6? z^YnX3Qj?h~1Rw(n@KsPID|spCBEO&iN7v{~j~8oauHh9Ch`p0Vq3Qn02uwfB-Z3A& z8bJ6Tn&QT;_aEN5Xl7gtI{t;c{{yf242sfPk-;MtnKpGv!rAnJkL*0XLdRMwl3 z0^MIjQ;E`+DbYbf@|-)I+%^iin(e?*c;*#EU(w$pvu?2xel*Fa9CsRxXIDMBnI<>z z3vmYeqPHRVTth3Pv$YsEiw^fe>oYAf0Pw9faVuFw$lMhK=kRB4e)H!uFmeJM##( z|5w3@ryK;{F7m{t*~5b_hujDL*N4|hhOeZU4O~HuI0sA_ByI|8cQhkK%w&4;044?! zMq?2X;en#aD4G)NNQu{UwAE_ZZH^x)bGIRs(RL_Zt^;E`E%XE5Jb$z$Ku6=!-;E(* zC;em*_1O{`%4mhzp7<*P8QPYyJuK4B=S8Q`0bur;3U zK@y3rY=kNle$NKGDDh2HM5+G$xE$KU~=q?CE1rb}e0v8XJt23(l zs&Knz;y2&x8TFASKPfaCw#n|HXcP)=vC7_HldRKd(6a`h@tjagVHoGLi?g^- z@9&ZR%P6VFbpL2!#Kim`V=$N>g8rqJ?|k56){r0|&1nC>NM`Wb;_swq> znXYhl)X8B&A;jc%(&ZxkBQy&wnBR-+L}beY*Ui@HiljR_sUfx*)sQhzkcY4$J)cO2 zz{0Z%{T~3=h3~;(g)^J-K!JkI5lNrR4auXKDF=(ojZVS$w^t;P41nWsKr^;u0ptrl z_K-g%4b#Dps^^;U0SF}&w^t}y1n>hCSz=rX5Yb6S3lYQNuu4yFqFMMyWJg2Td&N@3 z+L2CWSzkc!RjPz0B4F^H5}&0NVx67k`WiuVOzX~-#a-B0_!r?h+(wIk`s8!+b1#DFmw64XewrX4Ss@1{3uuKeN5Ulc)%N>_Tq`9z1d{RFLvw! z92rUH4(u~56C4s24pv+GF)7GW)Z9D>Zd56jDI1rsDdhb97-5)3rJM`%SSy=bm}jt0 zx*~oT{oOrEQCIP7Bwi*ez6)sB0%T!7Q#4T5b)gZjwkPS}&QzWpTa(znOZMHt$L6u% zrrsyXtlm$GBm(+bk^lr@!@;*4a;@=$NIHF^oq1J^#5SwYgA$V)9K*v(<^wXPGE?)# zmaOBkq2^w!Vc*DdOFG#_tj@NaiHd{p^{kL=XqzU9`(wPC!}J#62Kb-s*R9Q&~!H7~G91+O88s9F;eh z3=*;?*BJ|08w;vlNesihgysxuOFn})PV9uYeR+*L$rUR}z6AOpyBXhjL-XVJZ?omo zSbIg;Qj{?=zXQGr8!i)OV5MhQ1IHTHtStG;DqZiRYXebPDh7RBIgT60zBdBlPE$>& z{dWL1cN(Ni0053hj*y%~VT$H%c9rC3c~?GX%d2xIZR@h^3Qy=1CKLXMu|DDPC47 zbm+fzHpsOiQ_@Ak@*}X%Q--p=N8;LaJB`H;Q}4mt}i?-CvPXV;fOeD2RQ2 z#-T;f6JT^Bi!f{Oqmn?W&XzM(-lRw06uCLFVM|32$O~Q@TzKliwC*f(Q$Ek<5V{b; zb$?fHDj`u?&MI+n!icfrDqBwq1$MYuC8@O1AS85DuuYWFc18^cCCl0u{vPct!zKeP zCL@TYY)LG-q3W7_y)~ttQ(aL=jln9t!Jf&Bx%`TlHE5qD$;pt1g@rOe{-f|#P;Bv? z7~`k0-Uu{?8-ylPXl?w^GFPZgsLKY$MzqUQ8Hz4^8RcAX*ciP5IP|TCGo6P%!cPi- zXbM0#r8oVlb-oRB=Hg*$o1Y8(N8e{alkMkRCkG#Shkc5ldfl0M44pyNp_k9RZE+~E zhiqCi*Jzs=2$#HCR)c+ug8t^*mTI`Xz5Ui3#M)LYC+l>1i|D12b2247^`RU0Z3&c@ zbW)t|DhFDa@#EVTLN1p1PBoO_QD8J77lc`$YkJ4O#&MLXU|o9 zzh~;I*38Cql%pxBJ>+Ped)dtZ>+-$n6%R>QWa>R~TS)P?_T@V@mAxS^mb9$Et!QAp zI)##ZniB?9oTr`(lrYmGt_&y+dC$~t!`({NOzj}sTF#;|C4uT!x$y_9M4ww}15^Fm z8s9|fm69m$Im>(D3ICoBtXFhup&SYhn$Jhu#MK2|2a5mkWMWQ^?$3*GARyPYARt`8 zd@wvygI z7buXClWdM|-)KesstWzqK;V>`+@PwN~Gc@lRI=)Qq zTL`i})Jo=?>D9a6@8MJ%eC74w24tTCf{A3F5};-qmMm{fkgu%1_if^D%3I_tp+r*Ye|~YNt`~CDO!JQ9DFExgZZV=80`&e=@GzkgGuFC>^UlL1z}ssA%TNOiU(<*T__s4dh1 zM)B96(^Y(8`R+pWL#qbRNjqz-wmw2j(HQP<{3>2s?|6n^hHy7WQ;;Kt z^})5gE$ddkE`UP1&q@}OjeRtDw)0>II{|r&_++CU9v9{j6Q}y1 zAur7xxI{3NZD+c52a4^I+q5NHw57hKFs{VtND0^G902F?V2^X92DI!8Q5m`XMNhJt zx^kbyJ#<6LpadqX3yKjVQkek(UMB_Ecwb=9u1W&ditss_u;_pxguMfFRVLv+0j3{b zme{0_rqoLm0Cxg3z22G zk&N&iEg(YsU=)J}jcTcnB@sHruNnp{AHt^ueHMM)N4rX0S%$Yc#J%8*IIi_YbZYq02Xw&BfOEmY( z+gLhPIePU*db}L|(0e(k`uhNIj+Mh^hFs9r96;oU&C(q!pEfrZHtCwHsAIvGIargA z`<_Syf z-mup$D{GA-fjhNLQ{1G}qSCr5vep{I($sQ``iU?Ot}Ca0QPZ~<)RN!)lxOEvZQ&>J z0$|@L^T0%$K|?&R5j`l$)ri&wHYE@4Yc?Z0ej&sv-RxX&MmB5OzhdFoRq=m;0s>fm zr3N3HfjgB7h3J=>^Th!sxdPsy7r1T>N2I%m_r<%!_CQ;PqzOFj;`yaz`xOfS7SUio1050FC0i#BW~^!jk)q+Ne3W8WbbQ zbPy4!2Jv|UcqF&VcT$H>3$!rd94SLI>C76WjFLYKHd|3eu$t9t(IpI}H*m>j$-gjY zCxyG1DNmfzw5msuIn~h3pvgjL@Z6faFr~zcr&Fa4u>>s6IJ`_~G@MUnchrn90qiGr zfatoilL@9cZfw$O$YkQ=>*wYw#he(Q7w(sVxlb&voLtI~5MqQ+b-E zZOGR&5NJl)^S+8&NSciA7N3VbiDC@|;G)I-&094_CAPI=x zE*?!Ss=)0d!x@iOU9rX#J zfj10?N+Q#nh!aX;ugaO5fb5vLvhv6yHaC5`x&aC7DQ907*7CwhSU2TCYZ}jo01-Te(nojKZ$6Yi ze-tcG>7oU^g=M z$!(+hxecn^{32wl!s)=Xk{*&lk|8A_@$js#7`Kzzk)*|#xBP&UqrW&K{@@l*uNzVm z&&g`!zI^0I9m|NF6+jLHM^%1g!HlVdsJ6jaPLQFI>BxC8ExUu6Gd?L(XH{37KUU8n zCWM_fAxyo)4TcNTePOVM7 zG$o$5PiLy12fZ+dr8gjOGyEs`9@z=58`NT z|E^$0kJ-In^8vWxc{TZZTc2plEAsQ>of`9Jo~|m)9u`tv@&$$})8!rgR;DW|aYv6T z(-w$iEu$tFHnGNxGl5|jFXRGd3`l1!a>h0iWe1l!ppyHsJ#pVBp=QkxjCzf?c_=f3 ztahaQw$F3I8y~f}{ehZMVh0|n5IBtaaWoBU!1$>=HxJMOe7hoL`ayzQK=+-W6z%UJBRllb-14@tRPTpfHQJSVdnE+;43qrpZF#di23s-(UbQ8ddqJusIOP=NpTo%1tYFav&3<182&fKz%ZUO|OGu)5USVBxDsK`-Z6E z10$UDHrUz{zOIz$b`3W(b_7G2pYf$FnM%DmJ-re!Zk@Y&yf=oj7B0qK1O^T?q8Vnj zJU8nIVd?J(-V0d$ub^fy4oTM~KrM>h4m2tr;{`w&XXRX*LEMP06bh2Q%*=vZK}(zl zQtqXpxn=XN9}6WR`_i)UCklBcYIZqB@@$7Va}q0k!6i{jq6ZoGFw?=Z!G*>R6@bqr) z032}jwm2bDbrp^LQ5mjsm&N+q+lk6|VO4CLYsZHC?&wni!}Z9~Nq`LlZE9 z{WnYKbxQ<$`PlT1`Y3|n{GTjA!phv%Ox3~JRnghZ-1%RUkgcX4^`{^Xct5z%wrRKd zT-|vo(4-7cL%O08-~5xjEh++HTW-F78WosW6!=C1fz|(aE4&NnT50#WiJZyhYP|h; z)Q=l-)H=k_)$9u?hTYd1C$r>4fC;Hk9JNYPZO@segJgG+;dYxfA>PIxIpO> zNB)Bxg3bU3A8$=ZMNjNGht8`TiXf8?(d}4D63Y|Yg1H6*k15X3#ipuO%4`eWFA~Do zL}6frEDNdZcB8w>MR1AsIjrSX-<6xy(jTHsh(K&U6_aG zn^DAg=sVRc{$lkZexgysFQdvUD+rE)M_Lx}3B3@vgaov2ofzj52J>~JqS6d}auty- zQBtr#pA0T<6I;PFN6RqJm|XKTLJC{DOhvDd+gv}VK1o}(6MfOqd~L#ILd?(L1@d&VDnJDElB~p9CM`qb7}+>} z!hrk-ZVmB#8x<|%#AOW`t$c{Xjs?s1^M7H}i1}sz-!|!QD+jQ@r?bdDY@wDP`}_>h zARu!82S`9BYgpj+3M#P24htY+MGKMaU0toouqe+)K@&X0hMF0_1VS$1hm%4r2i9rk zVO7v8lZ)$j4fRwQZHc+z*hsQIF*udZYT0w;YdJ&L>;L`)vqMcdS|9vk?O7KX=7}y& z5lI)MkyPR;3tudEn3n6^<(Ek#yyQ<1#z@18Ix6A!OPO~XQpI8j|$k&2{13yQ2^*C-e#!wYO!k^AX z&Lq?0{c-4VzR1};CyiBs>dQIS5uy9J=karomcS#yE^^OvbVjMEX*B&&3>2B-sZbWj{_qfp{*0z<5VQfW8B&Fgib&YkpI5pv-GUi~p_i zrkH7gh?LwsE}BU*G4oF=trDi`23hx1is#Dv^0_}WHsNXM(U|`gAwM}Ro!8?s%Vjp3 zck)V55b((}a@2}$rw5miZkL3RTv@7MEKj|dyc<`vT1jwkRFAWLaS<=)bG3c3{r!Co zJzYKkDfmvkBWDIdw5`UTE6}H<&;iP&c*R7@cAcOdbOPwxBT(HlTv-?Ur19A$N;DngwSB6g3C!)$qP>svk_ z(u`BF<@d64f914d*!{KF!pbmHgV1A_fN4*R{o{fGMQb&3+nM4Ya!SQIsv(4)@II`& zaX%GhJH7*~K41G>d^Yy1=#2}~52b$OWn~*&|D_20E#uXM!n^pY32a}Q$@hyckdg&J zHsW%XIK75#NpboH>z8M^zZx>WMDTRNBS^C!0IBE;qv^d5v2J&bJUPNxLQ`E*bBy~P zm_ujp^mdvUACe?SC{XXAiv69K)CGp(3zGBPvX0EkyWBt@Hj%W7nB_lxrMZP&?UO(b zCBN-&)%c6Vej0Jh@tKzoBr-$;CU#hU)x;AFs^{_$sStguDri>u1zzuTL|2@7mkuUJ zZ?aSuY7?Bq-<%rtP&04P=Mhwu*@kiJ2m4Fq@H^6w=@TZibx&+FN{iZ1$^egju8FL; zt@V|{Pz%cG#*jXs=Mn3_F1BX_i_84~0uhMoq5#nSgTXh*lYg98*<#SH#yOW(hK#DJ zJ0Gk?FD2)P`@xBgKN2^KBi?BItnd4YcH&rav^ntXIf69^EoQQ~@BEH=T`YdR9v?G; zDBf^IKx}9Z29fg(6>>Q{9pE%IG!+e-st+N*2jn>R z$Slvd8$&NIB1k&Uy5C>)>rHTCo2ZAP%?X#2d#<2ce4 z>x#3bpwi~P%^Z9Q4fOfm(pF9+ZQRnu$e({jbKdQ!2dlV=%W2q*=_Mah)|?$%O$_ z0dT)3zsceSZaaK1qUx(3%ZhoLb1&-$BTfS{4pJirV^(O0x-zDkoe?hprs!TeENO=U zrnt+1lNhsU$(7^^tL68f4Y_5Fli!dvMLA*zSRz*nH2q145JN3ps7yV%Jx*~je`A_H z@y$XgyqG9jnc0#`0F=(KAXE=U!C`b@bR?}}u_AR#jkaIEisJ&&LCQ#L;}LA(2kOKG zo|a%4P?8!{w2DvIR<+*&Ns$xa%G7!k+ZYX>+s;%i!Olc8)SEP@a!6TbvPxW81@1sp z;nLZwc5z9HB_CLJx7^n7t~ZI#DeNJ9b3uE=>aW4(pnF21Gipuk!s$^O$m?R)Kifvc ze=s7DUVm&3W#zQybfBswALlXS&>1KeG7p4D4@52-{ zFvo`ppsuU>5$wISq=K7(9F|Z~VJtMM1wG2r22$zByP=2T5Q*xO;I3s9#XjxzUNb(G z%}`C9MDJ&^zEO7S)dyKqNPY2XkRLtId7R)ma+F$bl1-ffAh@dJ}3Do&|A2W z4K;h?%bP*c3wW6=YTkbI!Oy0WOmUs=J8BaxHViAW471I`P4Nb1Qd1f^sMCa#)OS$L zfJO4lao_px+n4gB2Qp_-GFZ!v=8N8`kDlTEXk#&z}AI&O_mX1wYl zp1R+Y-z!Zz4U>{sd#1|e8zj6nn^M^?tJCi`4$0>jBN?kVU9FSVZ`%ms8TKW{CYvWG zj|Pj6_nf@()FT!7?r19a3^D^@CinfP0pyS`nRiLoU*W;%<7U6H6Ri|uiFeYt71f(y zGY=G9uyLp=T*|d4X#My}CfYl9yBg-ZtJ7$>V7HrN?am%$mnyUIIIZ5P<3?43efjIb z!8}fS>BxL5>+_m+9M41a*qjrxha0|7ZLGk3CDjS`AlG1dw~Z|RCr8C$KLX519)Q9w zzNp7%ywD!{(dgqkWywJ4xg&b3fYU?p$mbJy~{K4Y@ zjGo#?-r3(A)6S>EVv$?V{CPlQB8~dd;Ma_^Bj_EI8)_hp- zjM5Vr!_6BEk>AB?xDe;pXo--%@c_aVWPX$^d_EWtw!$8PCax~zlK3`&3Ss&k6@3qz z+=uBF{xin#qqL#aIhVOg*f$y}dbE~s!U5oAg7&=5G@+CNNxTA;pJnqu%UIFPWn$~MxvET@ zGyD^TEFWjXnZv;w#y+3X;*eH2l;@AlyS)|$s#q57beT032cq5*A292M$6J2EnoUf1 zb8Uu11Oid6zXVZ|kB25P?j@pZFup_l$Bi^P`VaprNZ<r+>MiSV-x=j>- zs*|mfv9s&Hv@a%3K5{?_Ik=L5{VmWlLK(8uxFu3na{!vVKl9sAaOxKW191KfIHaBY zp$AKLdp$Nac0={~-V5ei2^GUX~d%a$_!BM%6}Ey*~A*0ozIgTsn8&pWClBHiTu{ zx(4+yQ=()xa&kWn>;QO;Z#8^(<+7wNGr>jVk3|hjc|JNII!ZclLDj1}tqni@_btk0 zS%3Pw?28W2#6PVlpMc7&|CTN0?BMvn*Q~0qi1ra9&ev`-&@QNmE9I;Aw?OZYn!><@ z3$P2(kuVF$uS<8Db$(RsQan|%%_U0hAze%2T**}?YM2taA8mCW=lC3LrC$m5_=8>J zGvc>VX?yMv2PDRXc>@lN2=Latvxe~}Fli7Qa5b9itaf2UodJ%QtOw_od)+%d&^%oz z)Ql$!*etvTJK~-2x`*DClb!kSWLL63`|-qlkw+@X+Y@`jyO@v#1X1J-muO1i%TtYY zS?CtJg$PHwOVo~X8PHmS0W?XauTD%DZrz^-du`%H{0U{<`jOODD2-3QBxz^srzpVU zJ(q5@(ol72Hv;d=?xqSZpObtw=RXesZ;Q1{KS&lDb|+ln{q%Q)jo z%-SeUPFw$4$2}$uqYo{XCU~hoZY?%RLe)3Ng6BM$JlFUJCY6{yD3A7OD5z46zM(sG9X zl?Me{J~oMeIM8KC;G78|kT@6|xHAd~%-n_tB&*4~ph+UXN$6PFdByZ=k+uxd^3hFV z+Q>2OKp}BE(Z%l)PoT$5>fj!P{FK?!Z;#A!8CM)*$Eq10Cd-c`>Pv#Dyg7LL2f$smF#xh*XyAYDLj;1IvYNF#z9 zKz`&#chW`^pWUj@o0rHCTl>-Da#4bgUA9`&wYjMU+|sw1&bO>vve%laI9#2G&DN>2 ze*rDlG2PU2kk!l}IDNH#2{>)-G!V^rD>1cqFMgcTOF?`*0!M5yQ%WV6Yy@4cV%FG^ zsec$+Ymggt*0tcjwryp9bgZ@Ut(7GPG@5g7A{!2rSa@w&1q{NBx1CC*W){%IHLHLDb)^henVK7&?9jP)ACJeM>cXjdbgLXJ0i6OOKf z9tqsR$X#H8jsrSomzgQz?+zqpscpvYXe<~cIU?it@%9SJz$)#|?F1;Y>s;ymF*$=Mje^kQpCEPfQYqf+^w z^Eu;tICM5Xh;anY>Y;$d1}vURwNfi7lnomkF`F!o=DkvnDlylK9r`s#g3U%}BC?{z z0cH`GAa14e2$9(-yNW@d>@*hvUpA-D00Vb047ygvmfm> zhNOP)5KZHDW}%JfOr4C4YOU6IscgMx3Jwj<#rSCuzr$~Anu_Fj)4XEyZROv2xqc~WvJbB{+SV@2YM2%DyOoLKVn z@`l8=%a>yPr#UlxxLwQw)3j*g=mI(U;M8*|1jFT30s+@uEqOoi|FF5(0gti$pVW#J z;{UZdfV91f`Ty}>$*NW#T#oHuLci&*ji`w@TuHjqkW_BPgt6qdN=lm+9B=m6pVu zq&{%vYAdAkn8y}2D5sU_DBbM|g~A08vJ9=iFa&9@?L%!iwQG9N1Tc1c2av4p2{<(2 zjC5`>#n-4NUVQaEjjZzFgZArZT0S=5*RXZ*QCtWd$e?MZ;m4_B?rN23*0*e>=G$!w zeos)za%a7_8Mq0V1Y5mtJGZ^D(?nN@DXPzYReB=I(#*#jqwx?`)~aG5GhhRFd?~9> zycgrPwS^O`C~~)5YSTUJQS+WngLWsk`;wclIA;TAcp-r9>Y}KKs}vDzep$MST!6qu^#5Yy)Ns~6QK z!7eNIu(SF8v_^^6*4h-dXEY@M7Zy^3c`|-NEjM|~UX2Ae2e&Ok8_Xs$dOt8gH;vV3 zk2J_l1LTDJL2;Jp{r$&DsFN&z0+~Z|aO+^5ErNmT^;kDM+&gvykt1Y`5%nFU^y=M? z{3B^wVT)@e%Jb%Z(kWEtnZf;`yc>Okd_4Xj*&dmqamERGgD)w+g6}Xu0JO39^TQ>y z6YE_6Hx(#plM)HCb>T=Ys8i7s4y(a1rXDc}MoD^9G0BM7{*o3iYd+BwxmLEC9U5fm zWyfq>+EYj`Q!=!!Ze{$v2~IOW$lEW68#A-4Xjt6MuLi;;gka)7De+#%St-dpW|}ijT}rKJMqeSb!%{kzwZVv&VYcfx%3Er+W1-aFpg6S{tpAM$2r&GKUpzv{ z@Bd(U&B-TulP*nl5F+}kj@9F8!|T!|x1AO6{`is$!XQM!9QzA=Um@mY3v0JU`p ztGfb=0S3R-=Y~Z*VC7IJ-Kfy3mS#Bvz^lvBc546YzUZzw@f>TjPxYO^l5XQ+%$C7$ z&Ar8@fhM~H{t{)*B%Z4f34E8eIK9nlGKgO%1nCwVr$B-wfIKMx zZwb_mi>_ydyYr_2&8&vp6~UNxy?_Sv=68=udwp60I05jo2Iv<&-xzUVSYIL~T zz0i=> z25t~6k|zC2raz<}%NwMhc?0fk7wbwqPO#6drzv$tR^0JyZeNtH@}ui3-cB#429J2H z9(~kH%5)h7&6CrdS`AXwA*a?}FSY<+JW!*q^`Rb$))us8xJ$0v&?^r|fUja;zVLo6 zO`64qnsy%@a13KSjGk1Jc6L!Yo^o1;?RY^gRRwac)zQp^~9oveY{yB1>NT+Ga_XBuk5wQc3jDJ}OL~_pNYJR3h<6ln~XM zn255?Sd+nI5Y?O1Tj{NQ`p%p?Mt7R$ndjX5KfnKS{%5)O+;jfNDb3KuT4BwFHG4Q_ zzC$G~iHyW$VUJjse$4Wm-NG9&aeQ=MTha)9m|Vr4sy?+gt8A zk$f+Fc>A99Gd4|?mx`gNu~uqqSJg^LVOkytj@&+aIko@m=kMR$B+fP$X7rUxt42}p z=yq2>)ay2V&thpfyi8)Ia@LNde{g;mXQ}*vQNRoy*FIXe`Ou@^`*zZ=+ghovbsU-I zo-jIhH0__0qtSMU=U3#s39&gfw!ZUglTyx+xr3Asr1}oqwBX1>mN`!$%Ncwc(3LYQ3XXW2v-e)_ zP@5B@XD4TReT(}3?=kkt)3bZAYe_Xc^~U7qyZ@d1pQb^Z zj1XxrJzK?OY;;=a;OH~8$;ShXWh}NWxKB*S#|nw*_=}=aqIsp1WDw2E;{F2SVoRC! zlqv8~7w~6=4odG=SfKPv#VT2!6RRED11saHu-Qoi7nT)+<5s1v5Ir(Rll@|EYLyaK zbYSVl-Jz>Xz{6mR7Fd8s^bELKUg?5r}# z;L{I%%uM0mZD$n8#ah*8hhJH=#6B5h{}GmJ_Hkb>gSoBa&t??)FL|?L6sVPKa=mIUkBf+T?$>n3Upsy zg@c$HZFF5wvqq36J@G-eeot1SH2aAwNPwfLecaUsfB8QhJ>? zN*Q&2DDA295j$kZzJ7zcAh37xR1gUXbCH)MB(je8EC7jg6Y#!%4gyY|10fDvNrym7 zu&IHHbcHtHSerKDWi=4ItWJ05LMU7kb`)chl1+;tP#NrPlmhjO6+lQQ6)B7Goxe&7 zf^FdZLXX4{s4Ha9K)~$4Ppc~-U>5`%k$@$7U^ZJ5v^1)z3ChX3z*K$(rTqhgh{z^9 z1+&-=NLX%KQELShVg!YewPJ=)*dlP5Esu&=$i^|M5i%sqNCAwo39Cg1TFesX4>1vf zr-GFn6{PI!UOZbF8uSBh{xBn1E@vSE*I7})EshFO+Q`8%hSg75@&IolT&~lEV;$C_ ztnE$8NX0eJr7b0}EM642HGrf-(?JBTXi`PuUqBfPmW#-t%Vh-RLcZf}UQ~7$^3Q>? z^ht8efP1qw(nSgoCt<8sBB4aQxDwL!x*5lgISI*Hh@TWMOXB~pvk)izgD8E!XQb}3z95BZ7WetUGp5ZyrAdDpy%QK ze945)Vqu)%QL6&7sjwZ# zRDy&s8u(v3(LkuraLjqz1UFdoObMwf&peWs2t6?k&XdS(usB!*zVS>GfhR-o#O=Bi zG68lFvumL+C{N6r^p8U_#n8MdCembb@y(+C&A0**NkF2NwT1 zVjOF1o;H5CMO5)Y_@Fnju0m^~jvM$tg6 zZ~&cLQH1f-B;(xy0<#Xw0(CCo1AQ*+BNq@k?U)RZ>LVO5>>Z_c0JaV#IAoG#@KPa| zI3%tM@}^xzyoz1(k>jGRe8LN$&X8ZmE{yNK4FC?CPgg9?V>m`NU^ z$}Ulba-%+TL!>^ldoJ?s z!)_dl%@-}>`2}cn z5j{D*^tbo%usZj{>inI=5?_O43mmPNEdykGiGrx~;#f#6$_nVEBOl6zIOtu6zUM$W zsKT1*9d`-oB>>%*}F zohYlKPx!EgB)kWa)cc9o1Dk#vv+G5qXh;&wS<)eCcRwiWS4FoOk8v!uAGotL0X{$# zkdmIj_XYt)U-#z*Mw-_^OUYeLa{w|d1J4Jj>ZBKYSau6iB}Tu5KqFxKQeG}ZB18hC LOGvm53K0JXK%VLv delta 12028 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 diff --git a/src/com/turtleplayer/Player.java b/src/com/turtleplayer/Player.java index efcd50a..5482c67 100644 --- a/src/com/turtleplayer/Player.java +++ b/src/com/turtleplayer/Player.java @@ -54,6 +54,7 @@ import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.db.ObservableDatabase; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; +import com.turtleplayer.persistance.turtle.db.TurtleDatabaseImpl; import com.turtleplayer.persistance.turtle.db.structure.Tables; import com.turtleplayer.player.ObservableOutput; import com.turtleplayer.player.Output; @@ -250,7 +251,14 @@ else if(!Slides.NOW_PLAYING.equals(currSlide)) private void SetupApplication() { tp = (TurtlePlayer) getApplication(); - tp.db = new TurtleDatabase(tp.getApplicationContext()); + tp.db = new TurtleDatabase( new TurtleDatabaseImpl(tp.getApplicationContext()) + { + @Override + public void dbResetted() + { + tp.db.notifyCleared(); + } + }); tp.playlist = new Playlist(tp.getApplicationContext(), tp.db); fileChooser = new FileChooser(FileChooser.Mode.Genre, tp, this) { diff --git a/src/com/turtleplayer/persistance/turtle/FsReader.java b/src/com/turtleplayer/persistance/turtle/FsReader.java index 2b31bd3..934634a 100644 --- a/src/com/turtleplayer/persistance/turtle/FsReader.java +++ b/src/com/turtleplayer/persistance/turtle/FsReader.java @@ -25,6 +25,7 @@ import ch.hoene.perzist.access.filter.Operator; import ch.hoene.perzist.android.FirstSqlLite; import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.android.ReadOperationSqlLite; import ch.hoene.perzist.util.Shorty; import com.mpatric.mp3agic.ID3v1; import com.mpatric.mp3agic.InvalidDataException; @@ -208,11 +209,15 @@ public static String getAlbumArt(String mediaFileDir, TurtleDatabase db) final String result; AlbumArtLocation albumArtLocation = OperationExecutor.execute( - db, - new QuerySqlite( - new FieldFilter(Tables.AlbumArtLocations.PATH, Operator.EQ, mediaFileDir), - new FirstSqlLite(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()) - ) + db, + new ReadOperationSqlLite( + new QuerySqlite( + new FieldFilter( + Tables.AlbumArtLocations.PATH, + Operator.EQ, + mediaFileDir), + new FirstSqlLite(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()) + )) ); if(albumArtLocation != null) diff --git a/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java b/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java index 7f2b116..358e9de 100644 --- a/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java +++ b/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java @@ -1,6 +1,7 @@ package com.turtleplayer.persistance.turtle.db; -import ch.hoene.perzist.access.db.Database; +import android.database.sqlite.SQLiteOpenHelper; +import ch.hoene.perzist.android.DatabaseSqlLite; import com.turtleplayer.controller.Observer; import com.turtleplayer.model.Instance; @@ -24,10 +25,15 @@ * @author Simon Honegger (Hoene84) */ -public abstract class ObservableDatabase implements Database +public abstract class ObservableDatabase extends DatabaseSqlLite { - //--------------------------------------------- Observable + + protected ObservableDatabase(SQLiteOpenHelper sqLiteOpenHelper) { + super(sqLiteOpenHelper); + } + + //--------------------------------------------- Observable private final Map observers = new HashMap(); diff --git a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java index 0cf25c4..90a5bb8 100644 --- a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java +++ b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java @@ -36,6 +36,7 @@ import ch.hoene.perzist.android.MappingDistinctSqlLite; import ch.hoene.perzist.android.QuerySqlite; import ch.hoene.perzist.source.relational.FieldPersistable; +import ch.hoene.perzist.source.relational.FieldSortOrder; import ch.hoene.perzist.source.relational.View; import ch.hoene.perzist.source.sql.query.Select; import com.turtleplayer.model.Album; @@ -61,26 +62,14 @@ import java.util.Arrays; import java.util.List; -// Import - Android Content -// Import - Android Database -public class TurtleDatabase extends ObservableDatabase implements FileBase +public class TurtleDatabase extends ObservableDatabase implements FileBase { - final SQLiteDatabase db; - - public TurtleDatabase(Context context) + public TurtleDatabase(TurtleDatabaseImpl turtleDatabaseImpl) { - SQLiteOpenHelper turtleDatabaseImpl = new TurtleDatabaseImpl(context) - { - @Override - public void dbResetted() - { - notifyCleared(); - } - }; - db = turtleDatabaseImpl.getWritableDatabase(); + super(turtleDatabaseImpl); } //Write------------------------------------ @@ -90,7 +79,7 @@ public void dbResetted() */ public boolean push(final Track track) { - int insertedCount = OperationExecutor.execute(this, new InsertOperationSqlLite(new TrackToDbMapper()), track); + int insertedCount = push(track, new TrackToDbMapper()); if(insertedCount > 0) { notifyUpdate(track); @@ -101,18 +90,18 @@ public boolean push(final Track track) public void push(final AlbumArtLocation albumArtLocation) { - OperationExecutor.execute(this, new InsertOperationSqlLite(new AlbumArtLoactionToDbMapper()), albumArtLocation); + push(albumArtLocation, new AlbumArtLoactionToDbMapper()); } public void push(final FSobject dir) { - OperationExecutor.execute(this, new InsertOperationSqlLite(new FsObjectToDbMapper()), dir); + push(dir, new FsObjectToDbMapper()); } public void clear() { - OperationExecutor.execute(this, new DeleteTableContentSqlLite(), Tables.TRACKS); - OperationExecutor.execute(this, new DeleteTableContentSqlLite(), Tables.DIRS); + drop(Tables.TRACKS); + drop(Tables.DIRS); notifyCleared(); } @@ -120,101 +109,42 @@ public void clear() public boolean isEmpty(Filter filter) { - return OperationExecutor.execute( - this, - new QuerySqlite(filter, new CounterSqlite(Tables.TRACKS))).equals(0); + return isEmpty(filter, Tables.TRACKS); } public int countAvailableTracks(Filter filter) { - return OperationExecutor.execute( - this, - new QuerySqlite(filter, new CounterSqlite(Tables.TRACKS))); + return count(filter, Tables.TRACKS); } public List getTracks(Filter filter) { - return getList(filter, new TrackCreator(), Tables.TRACKS, Tables.TRACKS ,Tables.Tracks.TITLE); + return getList(filter, new TrackCreator(), Tables.TRACKS, Tables.TRACKS, new FieldSortOrder(Tables.Tracks.TITLE, SortOrder.ASC)); } public List getSongs(Filter filter) { - return getList(filter, new SongCreator(), Tables.TRACKS, Views.SONGS ,Tables.SongsReadable.TITLE); + return getList(filter, new SongCreator(), Tables.TRACKS, Views.SONGS, new FieldSortOrder(Tables.SongsReadable.TITLE, SortOrder.ASC)); } public List getArtists(Filter filter) { - return getList(filter, new ArtistCreator(), Tables.TRACKS, Views.ARTISTS, Tables.ArtistsReadable.ARTIST); + return getList(filter, new ArtistCreator(), Tables.TRACKS, Views.ARTISTS, new FieldSortOrder(Tables.ArtistsReadable.ARTIST, SortOrder.ASC)); } public List getGenres(Filter filter) { - return getList(filter, new GenreCreator(), Tables.TRACKS, Views.GENRES, Tables.GenresReadable.GENRE); + return getList(filter, new GenreCreator(), Tables.TRACKS, Views.GENRES, new FieldSortOrder(Tables.GenresReadable.GENRE, SortOrder.ASC)); } public List getAlbums(Filter filter) { - return getList(filter, new AlbumCreator(), Tables.TRACKS, Views.ALBUMS, Tables.AlbumsReadable.ALBUM); + return getList(filter, new AlbumCreator(), Tables.TRACKS, Views.ALBUMS, new FieldSortOrder(Tables.AlbumsReadable.ALBUM, SortOrder.ASC)); } public List getDirList(Filter filter) { - return getList(filter, new DirCreator(), Tables.DIRS, Tables.DIRS, Tables.Dirs.NAME); - } - - private List getList( - Filter filter, - ResultCreator creator, - PROJECTION view, - TARGET target, - FieldPersistable... sortFields) - { - return OperationExecutor.execute( - this, - new QuerySqlite>( - filter, - FieldOrder.getMultiFieldOrder(SortOrder.ASC, sortFields), - new MappingDistinctSqlLite(view, new CreatorForListSqlite(creator), target) - ) - ); - } - - - public I read(Select query, - Database.DbReadOp readOp) - { - Cursor cursor = null; - try - { - String[] params = new String[query.getParams().size()]; - int i = 0; - - for (Object param : query.getParams()) - { - params[i++] = param.toString(); - } - Log.v(TurtleDatabase.class.getName(), - "Running Query: " + query.toSql() + " with params " + Arrays.deepToString(params)); - - cursor = db.rawQuery(query.toSql(), params); - - Log.v(TurtleDatabase.class.getName(), - "Resulting in " + cursor.getCount() + " Resulting Rows"); - - return readOp.read(cursor); - } finally - { - if (cursor != null) - { - cursor.close(); - } - } - } - - public int write(DbWriteOp writeOp, - I instance) - { - return writeOp.write(db, instance); + return getList(filter, new DirCreator(), Tables.DIRS, Tables.DIRS, new FieldSortOrder(Tables.Dirs.NAME, SortOrder.ASC)); } } \ No newline at end of file diff --git a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java index 2bf2c44..f8973b2 100644 --- a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java +++ b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java @@ -4,9 +4,13 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import ch.hoene.perzist.source.relational.FieldPersistable; +import com.turtleplayer.controller.Observer; +import com.turtleplayer.model.Instance; import com.turtleplayer.persistance.turtle.db.structure.Tables; import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; /** * TURTLE PLAYER diff --git a/src/com/turtleplayer/playlist/Playlist.java b/src/com/turtleplayer/playlist/Playlist.java index 2d260f1..aff7ce4 100644 --- a/src/com/turtleplayer/playlist/Playlist.java +++ b/src/com/turtleplayer/playlist/Playlist.java @@ -29,6 +29,7 @@ import ch.hoene.perzist.access.sort.RandomOrder; import ch.hoene.perzist.android.FirstSqlLite; import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.android.ReadOperationSqlLite; import ch.hoene.perzist.util.Shorty; import com.turtleplayer.Stats; import com.turtleplayer.common.filefilter.FileFilters; @@ -139,9 +140,9 @@ public Set> getFilter() */ public TrackBundle enrich(PlayOrderStrategy strategy, Track track){ return new TrackBundle( - track, - strategy.getNext(track), - strategy.getPrevious(track) + track, + strategy.getNext(track), + strategy.getPrevious(track) ); } @@ -149,14 +150,21 @@ public Track getTrack(String src) { FSobject fsObject = new FSobject(src); return OperationExecutor.execute( - db, - new QuerySqlite( - new FilterSet( - getCompressedFilter(), - new FieldFilter(Tables.FsObjects.NAME, Operator.EQ, fsObject.getPath()), - new FieldFilter(Tables.FsObjects.PATH, Operator.EQ, fsObject.getName())), - new FirstSqlLite(Tables.TRACKS, new TrackCreator()) - ) + db, + new ReadOperationSqlLite( + new QuerySqlite( + new FilterSet( + getCompressedFilter(), + new FieldFilter( + Tables.FsObjects.NAME, + Operator.EQ, + fsObject.getPath()), + new FieldFilter( + Tables.FsObjects.PATH, + Operator.EQ, + fsObject.getName())), + new FirstSqlLite(Tables.TRACKS, new TrackCreator()) + )) ); } @@ -174,10 +182,11 @@ public Track getPrevious(PlayOrderStrategy strategy, Track ofTrack) public Track getRandom() { return OperationExecutor.execute(db, - new QuerySqlite( - getCompressedFilter(), - new RandomOrder(), - new FirstSqlLite(Tables.TRACKS, new TrackCreator()))); + new ReadOperationSqlLite( + new QuerySqlite( + getCompressedFilter(), + new RandomOrder(), + new FirstSqlLite(Tables.TRACKS, new TrackCreator())))); } /** diff --git a/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java b/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java index c4d0b0e..df79b95 100644 --- a/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java +++ b/src/com/turtleplayer/playlist/playorder/PlayOrderRandom.java @@ -4,6 +4,7 @@ import ch.hoene.perzist.access.sort.RandomOrder; import ch.hoene.perzist.android.FirstSqlLite; import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.android.ReadOperationSqlLite; import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; @@ -35,10 +36,15 @@ public Track getPrevious(Track currTrack) private Track get() { - return OperationExecutor.execute(db, - new QuerySqlite( - playlist.getCompressedFilter(), - new RandomOrder(), - new FirstSqlLite(Tables.TRACKS, new TrackCreator()))); + return OperationExecutor.execute( + db, + new ReadOperationSqlLite( + new QuerySqlite( + playlist.getCompressedFilter(), + new RandomOrder(), + new FirstSqlLite(Tables.TRACKS, new TrackCreator()) + ) + ) + ); } } diff --git a/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java b/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java index 55766a5..9b9963e 100644 --- a/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java +++ b/src/com/turtleplayer/playlist/playorder/PlayOrderSorted.java @@ -25,6 +25,7 @@ import ch.hoene.perzist.access.sort.SortOrder; import ch.hoene.perzist.android.FirstSqlLite; import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.android.ReadOperationSqlLite; import com.turtleplayer.model.Track; import com.turtleplayer.persistance.turtle.db.TurtleDatabase; import com.turtleplayer.persistance.turtle.db.structure.Tables; @@ -60,16 +61,17 @@ private Track get(Track ofTrack, OrderSet order) while(!currOrder.isEmpty()) { Log.v(PlayOrderSorted.class.getName(), - "Generate Paging Filters from: " + order); + "Generate Paging Filters from: " + order); Log.v(PlayOrderSorted.class.getName(), - "resulting in Paging Filters : " + Paging.getFilter(playlist.getCompressedFilter(), ofTrack, currOrder)); + "resulting in Paging Filters : " + Paging.getFilter(playlist.getCompressedFilter(), ofTrack, currOrder)); Track nextTrack = OperationExecutor.execute( - db, - new QuerySqlite( - Paging.getFilter(playlist.getCompressedFilter(), ofTrack, currOrder), - order, - new FirstSqlLite(Tables.TRACKS, new TrackCreator()) - ) + db, + new ReadOperationSqlLite( + new QuerySqlite( + Paging.getFilter(playlist.getCompressedFilter(), ofTrack, currOrder), + order, + new FirstSqlLite(Tables.TRACKS, new TrackCreator()) + )) ); if(nextTrack != null){ return nextTrack; diff --git a/src/com/turtleplayer/presentation/AlbumArtResolver.java b/src/com/turtleplayer/presentation/AlbumArtResolver.java index 0121ee7..ba815db 100644 --- a/src/com/turtleplayer/presentation/AlbumArtResolver.java +++ b/src/com/turtleplayer/presentation/AlbumArtResolver.java @@ -9,6 +9,7 @@ import ch.hoene.perzist.access.filter.Operator; import ch.hoene.perzist.android.FirstSqlLite; import ch.hoene.perzist.android.QuerySqlite; +import ch.hoene.perzist.android.ReadOperationSqlLite; import ch.hoene.perzist.util.Shorty; import com.mpatric.mp3agic.InvalidDataException; import com.mpatric.mp3agic.Mp3File; @@ -80,20 +81,27 @@ private interface LookupStrategy private class CachedFsLookupStrategy implements LookupStrategy { - public Bitmap lookup(Track track) - { - AlbumArtLocation albumArtLocation = OperationExecutor.execute( - db, - new QuerySqlite(new FieldFilter(Tables.AlbumArtLocations.PATH, Operator.EQ, track.getPath()), - new FirstSqlLite(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()))); + public Bitmap lookup(Track track) + { + AlbumArtLocation albumArtLocation = OperationExecutor.execute( + db, + new ReadOperationSqlLite( + new QuerySqlite( + new FieldFilter( + Tables.AlbumArtLocations.PATH, + Operator.EQ, + track.getPath()), + new FirstSqlLite( + Tables.ALBUM_ART_LOCATIONS, + new AlbumArtLocationCreator())))); - if(albumArtLocation != null) - { - return BitmapFactory.decodeFile(albumArtLocation.getAlbumArtpath()); - } - return null; - } - } + if(albumArtLocation != null) + { + return BitmapFactory.decodeFile(albumArtLocation.getAlbumArtpath()); + } + return null; + } + } private class FsLookupStrategy implements LookupStrategy From 0d5b88cb08dcdc6b703661e895381c80decbaa5c Mon Sep 17 00:00:00 2001 From: Simon Honegger Date: Sat, 19 Apr 2014 14:10:03 +0200 Subject: [PATCH 3/3] formatting and optimize imports --- src/com/turtleplayer/Player.java | 46 ++++----- .../persistance/turtle/FsReader.java | 50 +++++----- .../turtle/db/ObservableDatabase.java | 8 +- .../persistance/turtle/db/TurtleDatabase.java | 31 ++---- .../turtle/db/TurtleDatabaseImpl.java | 4 - .../mapping/AlbumArtLoactionToDbMapper.java | 8 +- .../turtle/mapping/AlbumCreator.java | 8 +- .../turtle/mapping/ArtistCreator.java | 8 +- .../turtle/mapping/FsObjectToDbMapper.java | 8 +- .../turtle/mapping/GenreCreator.java | 8 +- .../turtle/mapping/SongCreator.java | 8 +- .../turtle/mapping/TrackToDbMapper.java | 8 +- .../playlist/playorder/LimitedStack.java | 96 +++++++++---------- .../playlist/playorder/PlayOrderStrategy.java | 2 +- .../presentation/AlbumArtResolver.java | 38 ++++---- .../presentation/InstanceFormatter.java | 8 +- .../presentation/ShortInstanceFormatter.java | 14 +-- .../ShortWithNumberInstanceFormatter.java | 22 ++--- .../persistance/turtle/FsReaderTest.java | 32 +++---- 19 files changed, 195 insertions(+), 212 deletions(-) diff --git a/src/com/turtleplayer/Player.java b/src/com/turtleplayer/Player.java index 5482c67..7197d72 100644 --- a/src/com/turtleplayer/Player.java +++ b/src/com/turtleplayer/Player.java @@ -252,13 +252,13 @@ private void SetupApplication() { tp = (TurtlePlayer) getApplication(); tp.db = new TurtleDatabase( new TurtleDatabaseImpl(tp.getApplicationContext()) - { - @Override - public void dbResetted() - { - tp.db.notifyCleared(); - } - }); + { + @Override + public void dbResetted() + { + tp.db.notifyCleared(); + } + }); tp.playlist = new Playlist(tp.getApplicationContext(), tp.db); fileChooser = new FileChooser(FileChooser.Mode.Genre, tp, this) { @@ -274,7 +274,7 @@ protected void filterChoosen(Filter filter) standartPlayOrderStrategy = new PlayOrderSorted(tp.db, tp.playlist); shufflePlayOrderStrategy = new PlayOrderRandom(tp.db, tp.playlist); playOrderStrategy = tp.playlist.preferences.get(Keys.SHUFFLE) ? - shufflePlayOrderStrategy : standartPlayOrderStrategy; + shufflePlayOrderStrategy : standartPlayOrderStrategy; } // ========================================= // @@ -284,9 +284,9 @@ protected void filterChoosen(Filter filter) private void SetupButtons() { shuffleButton.setImageDrawable( - tp.playlist.preferences.get(Keys.SHUFFLE) ? - getResources().getDrawable(R.drawable.dice48_active) : - getResources().getDrawable(R.drawable.dice48) + tp.playlist.preferences.get(Keys.SHUFFLE) ? + getResources().getDrawable(R.drawable.dice48_active) : + getResources().getDrawable(R.drawable.dice48) ); shuffleCheckBox.setChecked(tp.playlist.preferences.get(Keys.SHUFFLE)); @@ -383,7 +383,7 @@ public boolean onLongClick(View v) shuffleCheckBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { public void onCheckedChanged(CompoundButton buttonView, - boolean isChecked) + boolean isChecked) { tp.playlist.preferences.set(Keys.SHUFFLE, isChecked); } @@ -418,7 +418,7 @@ public void onClick(View v) { Intent dirChooserIntent = new Intent(DIR_CHOOSER_ACTION); dirChooserIntent.putExtra(DirChooserConstants.ACTIVITY_PARAM_KEY_DIR_CHOOSER_INITIAL_DIR, - tp.playlist.preferences.getExitstingMediaPath().toString()); + tp.playlist.preferences.getExitstingMediaPath().toString()); Player.this.startActivityForResult(dirChooserIntent, DIR_CHOOSER_REQUEST); } }); @@ -479,7 +479,7 @@ public void run() } public void unpauseRescan(final int alreadyProcessed, - final int toProcess) + final int toProcess) { runOnUiThread(new Runnable() { @@ -603,7 +603,7 @@ public void changed(AbstractKey key) public void run() { shuffleButton.setImageDrawable(getResources().getDrawable( - shuffle ? R.drawable.dice48_active : R.drawable.dice48)); + shuffle ? R.drawable.dice48_active : R.drawable.dice48)); shuffleCheckBox.setChecked(shuffle); } }); @@ -678,8 +678,8 @@ public void onStartTrackingTouch(SeekBar seekBar) } public void onProgressChanged(SeekBar seekBar, - int progress, - boolean fromUser) + int progress, + boolean fromUser) { // Needed, Although Blank } @@ -842,9 +842,9 @@ private void SetupPhoneHandlers() @Override protected void onListItemClick(ListView l, - View v, - int position, - long id) + View v, + int position, + long id) { final Track trackSelected = fileChooser.choose((Instance) l.getItemAtPosition(position)); if (trackSelected != null) @@ -909,15 +909,15 @@ protected void rescan() @Override protected void onActivityResult(int requestCode, - int resultCode, - Intent data) + int resultCode, + Intent data) { if (requestCode == DIR_CHOOSER_REQUEST) { if (resultCode == RESULT_OK) { tp.playlist.preferences.set(Keys.MEDIA_DIR, - data.getStringExtra(DirChooserConstants.ACTIVITY_RETURN_KEY_DIR_CHOOSER_CHOOSED_DIR)); + data.getStringExtra(DirChooserConstants.ACTIVITY_RETURN_KEY_DIR_CHOOSER_CHOOSED_DIR)); mediaDir.setText(tp.playlist.preferences.getExitstingMediaPath().toString()); rescan(); } diff --git a/src/com/turtleplayer/persistance/turtle/FsReader.java b/src/com/turtleplayer/persistance/turtle/FsReader.java index 934634a..cb66133 100644 --- a/src/com/turtleplayer/persistance/turtle/FsReader.java +++ b/src/com/turtleplayer/persistance/turtle/FsReader.java @@ -57,9 +57,10 @@ public class FsReader { - public static boolean scanFile(String filePath, - TurtleDatabase db, - Set encounteredRootSrcs) throws IOException + public static boolean scanFile( + String filePath, + TurtleDatabase db, + Set encounteredRootSrcs) throws IOException { // http://www.exampledepot.com/egs/java.io/GetFiles.html @@ -121,12 +122,12 @@ else if(mp3file.hasId3v2Tag()) } Track t = new Track( - new SongDigest(title), - new ArtistDigest(artist), - new AlbumDigest(album), - new GenreDigest(genre < 0 ? "" : String.valueOf(genre)), - number, - filePath + new SongDigest(title), + new ArtistDigest(artist), + new AlbumDigest(album), + new GenreDigest(genre < 0 ? "" : String.valueOf(genre)), + number, + filePath ); Log.v(Preferences.TAG, "created " + (System.currentTimeMillis() - start) + "ms"); boolean added = db.push(t); @@ -146,7 +147,12 @@ else if(mp3file.hasId3v2Tag()) return added; } - static public List getMediaFilesPaths(String mediaPath, List filters, boolean recursive, boolean getFirstMatch){ + static public List getMediaFilesPaths( + String mediaPath, + List filters, + boolean recursive, + boolean getFirstMatch) + { List candidates = new ArrayList(); @@ -211,13 +217,13 @@ public static String getAlbumArt(String mediaFileDir, TurtleDatabase db) AlbumArtLocation albumArtLocation = OperationExecutor.execute( db, new ReadOperationSqlLite( - new QuerySqlite( - new FieldFilter( - Tables.AlbumArtLocations.PATH, - Operator.EQ, - mediaFileDir), - new FirstSqlLite(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()) - )) + new QuerySqlite( + new FieldFilter( + Tables.AlbumArtLocations.PATH, + Operator.EQ, + mediaFileDir), + new FirstSqlLite(Tables.ALBUM_ART_LOCATIONS, new AlbumArtLocationCreator()) + )) ); if(albumArtLocation != null) @@ -278,11 +284,11 @@ static double parseDuration(String duration) final static FileFilter isDIR = new FileFilter() { final String[] IGNORED_DIRS = new String[]{ - "/proc/", - "/sys/", - "/system/", - "/proc/", - "/root/", + "/proc/", + "/sys/", + "/system/", + "/proc/", + "/root/", }; public boolean accept(File file) diff --git a/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java b/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java index 358e9de..4e11425 100644 --- a/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java +++ b/src/com/turtleplayer/persistance/turtle/db/ObservableDatabase.java @@ -29,11 +29,11 @@ public abstract class ObservableDatabase extends DatabaseSqlLite { - protected ObservableDatabase(SQLiteOpenHelper sqLiteOpenHelper) { - super(sqLiteOpenHelper); - } + protected ObservableDatabase(SQLiteOpenHelper sqLiteOpenHelper) { + super(sqLiteOpenHelper); + } - //--------------------------------------------- Observable + //--------------------------------------------- Observable private final Map observers = new HashMap(); diff --git a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java index 90a5bb8..5cd95e9 100644 --- a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java +++ b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabase.java @@ -18,27 +18,9 @@ package com.turtleplayer.persistance.turtle.db; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; -import ch.hoene.perzist.access.creator.ResultCreator; -import ch.hoene.perzist.access.db.Database; -import ch.hoene.perzist.access.executor.OperationExecutor; import ch.hoene.perzist.access.filter.Filter; -import ch.hoene.perzist.access.sort.FieldOrder; import ch.hoene.perzist.access.sort.SortOrder; -import ch.hoene.perzist.android.CounterSqlite; -import ch.hoene.perzist.android.CreatorForListSqlite; -import ch.hoene.perzist.android.DeleteTableContentSqlLite; -import ch.hoene.perzist.android.InsertOperationSqlLite; -import ch.hoene.perzist.android.MappingDistinctSqlLite; -import ch.hoene.perzist.android.QuerySqlite; -import ch.hoene.perzist.source.relational.FieldPersistable; import ch.hoene.perzist.source.relational.FieldSortOrder; -import ch.hoene.perzist.source.relational.View; -import ch.hoene.perzist.source.sql.query.Select; import com.turtleplayer.model.Album; import com.turtleplayer.model.AlbumArtLocation; import com.turtleplayer.model.Artist; @@ -59,7 +41,6 @@ import com.turtleplayer.persistance.turtle.mapping.TrackCreator; import com.turtleplayer.persistance.turtle.mapping.TrackToDbMapper; -import java.util.Arrays; import java.util.List; @@ -69,7 +50,7 @@ public class TurtleDatabase extends ObservableDatabase implements FileBase public TurtleDatabase(TurtleDatabaseImpl turtleDatabaseImpl) { - super(turtleDatabaseImpl); + super(turtleDatabaseImpl); } //Write------------------------------------ @@ -79,7 +60,7 @@ public TurtleDatabase(TurtleDatabaseImpl turtleDatabaseImpl) */ public boolean push(final Track track) { - int insertedCount = push(track, new TrackToDbMapper()); + int insertedCount = push(track, new TrackToDbMapper()); if(insertedCount > 0) { notifyUpdate(track); @@ -90,18 +71,18 @@ public boolean push(final Track track) public void push(final AlbumArtLocation albumArtLocation) { - push(albumArtLocation, new AlbumArtLoactionToDbMapper()); + push(albumArtLocation, new AlbumArtLoactionToDbMapper()); } public void push(final FSobject dir) { - push(dir, new FsObjectToDbMapper()); + push(dir, new FsObjectToDbMapper()); } public void clear() { drop(Tables.TRACKS); - drop(Tables.DIRS); + drop(Tables.DIRS); notifyCleared(); } @@ -114,7 +95,7 @@ public boolean isEmpty(Filter filter) public int countAvailableTracks(Filter filter) { - return count(filter, Tables.TRACKS); + return count(filter, Tables.TRACKS); } public List getTracks(Filter filter) diff --git a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java index f8973b2..2bf2c44 100644 --- a/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java +++ b/src/com/turtleplayer/persistance/turtle/db/TurtleDatabaseImpl.java @@ -4,13 +4,9 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import ch.hoene.perzist.source.relational.FieldPersistable; -import com.turtleplayer.controller.Observer; -import com.turtleplayer.model.Instance; import com.turtleplayer.persistance.turtle.db.structure.Tables; import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; /** * TURTLE PLAYER diff --git a/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java b/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java index f81e3cc..378b354 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/AlbumArtLoactionToDbMapper.java @@ -25,11 +25,11 @@ public class AlbumArtLoactionToDbMapper implements Mapping { - public Table get() { - return Tables.ALBUM_ART_LOCATIONS; - } + public Table get() { + return Tables.ALBUM_ART_LOCATIONS; + } - public ContentValues create(AlbumArtLocation albumArtLocation) + public ContentValues create(AlbumArtLocation albumArtLocation) { final ContentValues values = new ContentValues(); diff --git a/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java index 4e9c0c2..32f665b 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/AlbumCreator.java @@ -25,8 +25,8 @@ public class AlbumCreator implements ResultCreator { - public Album create(Cursor source) - { - return new AlbumDigest(source.getString(source.getColumnIndex(Tables.AlbumsReadable.ALBUM.getName()))); - } + public Album create(Cursor source) + { + return new AlbumDigest(source.getString(source.getColumnIndex(Tables.AlbumsReadable.ALBUM.getName()))); + } } diff --git a/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java index ea34d59..2b2bfc2 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/ArtistCreator.java @@ -25,8 +25,8 @@ public class ArtistCreator implements ResultCreator { - public ArtistDigest create(Cursor source) - { - return new ArtistDigest(source.getString(source.getColumnIndex(Tables.ArtistsReadable.ARTIST.getName()))); - } + public ArtistDigest create(Cursor source) + { + return new ArtistDigest(source.getString(source.getColumnIndex(Tables.ArtistsReadable.ARTIST.getName()))); + } } diff --git a/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java b/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java index 73d1f8b..65f3539 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/FsObjectToDbMapper.java @@ -25,11 +25,11 @@ public class FsObjectToDbMapper implements Mapping { - public Table get() { - return Tables.DIRS; - } + public Table get() { + return Tables.DIRS; + } - public ContentValues create(FSobject fsObject) + public ContentValues create(FSobject fsObject) { final ContentValues values = new ContentValues(); diff --git a/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java index 30cab69..4ea3feb 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/GenreCreator.java @@ -24,8 +24,8 @@ public class GenreCreator implements ResultCreator { - public GenreDigest create(Cursor source) - { - return new GenreDigest(source.getString(source.getColumnIndex(Tables.GenresReadable.GENRE.getName()))); - } + public GenreDigest create(Cursor source) + { + return new GenreDigest(source.getString(source.getColumnIndex(Tables.GenresReadable.GENRE.getName()))); + } } diff --git a/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java b/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java index 7917ac5..7916453 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/SongCreator.java @@ -25,8 +25,8 @@ public class SongCreator implements ResultCreator { - public SongDigest create(Cursor source) - { - return new SongDigest(source.getString(source.getColumnIndex(Tables.SongsReadable.TITLE.getName()))); - } + public SongDigest create(Cursor source) + { + return new SongDigest(source.getString(source.getColumnIndex(Tables.SongsReadable.TITLE.getName()))); + } } diff --git a/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java b/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java index 0e46a81..71e344c 100644 --- a/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java +++ b/src/com/turtleplayer/persistance/turtle/mapping/TrackToDbMapper.java @@ -25,11 +25,11 @@ public class TrackToDbMapper implements Mapping { - public Table get() { - return Tables.TRACKS; - } + public Table get() { + return Tables.TRACKS; + } - public ContentValues create(Track track) + public ContentValues create(Track track) { final ContentValues values = new ContentValues(); diff --git a/src/com/turtleplayer/playlist/playorder/LimitedStack.java b/src/com/turtleplayer/playlist/playorder/LimitedStack.java index 3994bf4..ea2cec3 100644 --- a/src/com/turtleplayer/playlist/playorder/LimitedStack.java +++ b/src/com/turtleplayer/playlist/playorder/LimitedStack.java @@ -11,59 +11,59 @@ */ public class LimitedStack extends ArrayList { - private final int maxSize; - private final static double CLEAR_PERCENT = 0.1; + private final int maxSize; + private final static double CLEAR_PERCENT = 0.1; - public LimitedStack(int maxSize) { - super(maxSize); - this.maxSize = maxSize; - } + public LimitedStack(int maxSize) { + super(maxSize); + this.maxSize = maxSize; + } - @Override - public boolean add(T object) - { - boolean returnValue = super.add(object); - keepMaxSize(); - return returnValue; - } + @Override + public boolean add(T object) + { + boolean returnValue = super.add(object); + keepMaxSize(); + return returnValue; + } - @Override - public void add(int index, T object) - { - super.add(index, object); - keepMaxSize(); - } + @Override + public void add(int index, T object) + { + super.add(index, object); + keepMaxSize(); + } - @Override - public boolean addAll(Collection collection) - { - boolean returnValue = super.addAll(collection); //To change body of overridden methods use File | Settings | File Templates. - keepMaxSize(); - return returnValue; - } + @Override + public boolean addAll(Collection collection) + { + boolean returnValue = super.addAll(collection); //To change body of overridden methods use File | Settings | File Templates. + keepMaxSize(); + return returnValue; + } - @Override - public boolean addAll(int index, Collection collection) - { - boolean returnValue = super.addAll(index, collection); //To change body of overridden methods use File | Settings | File Templates. - keepMaxSize(); - return returnValue; - } + @Override + public boolean addAll(int index, Collection collection) + { + boolean returnValue = super.addAll(index, collection); //To change body of overridden methods use File | Settings | File Templates. + keepMaxSize(); + return returnValue; + } - /** - * @return last addded item. Dont call when empty - */ - public T pop(){ - T poppedipop = get(size() - 1); - remove(size() - 1); - return poppedipop; - } + /** + * @return last addded item. Dont call when empty + */ + public T pop(){ + T poppedipop = get(size() - 1); + remove(size() - 1); + return poppedipop; + } - private void keepMaxSize() - { - if(size() > maxSize) - { - subList((int)(maxSize * CLEAR_PERCENT), size()); - } - } + private void keepMaxSize() + { + if(size() > maxSize) + { + subList((int)(maxSize * CLEAR_PERCENT), size()); + } + } } diff --git a/src/com/turtleplayer/playlist/playorder/PlayOrderStrategy.java b/src/com/turtleplayer/playlist/playorder/PlayOrderStrategy.java index 319060a..5151d9a 100644 --- a/src/com/turtleplayer/playlist/playorder/PlayOrderStrategy.java +++ b/src/com/turtleplayer/playlist/playorder/PlayOrderStrategy.java @@ -6,7 +6,7 @@ public interface PlayOrderStrategy { /* * @return null if strategy has no next song for this config and tracklist - */ + */ Track getNext(Track currTrack); /** diff --git a/src/com/turtleplayer/presentation/AlbumArtResolver.java b/src/com/turtleplayer/presentation/AlbumArtResolver.java index ba815db..5ddab6e 100644 --- a/src/com/turtleplayer/presentation/AlbumArtResolver.java +++ b/src/com/turtleplayer/presentation/AlbumArtResolver.java @@ -81,26 +81,26 @@ private interface LookupStrategy private class CachedFsLookupStrategy implements LookupStrategy { - public Bitmap lookup(Track track) - { - AlbumArtLocation albumArtLocation = OperationExecutor.execute( - db, - new ReadOperationSqlLite( - new QuerySqlite( - new FieldFilter( - Tables.AlbumArtLocations.PATH, - Operator.EQ, - track.getPath()), - new FirstSqlLite( - Tables.ALBUM_ART_LOCATIONS, - new AlbumArtLocationCreator())))); + public Bitmap lookup(Track track) + { + AlbumArtLocation albumArtLocation = OperationExecutor.execute( + db, + new ReadOperationSqlLite( + new QuerySqlite( + new FieldFilter( + Tables.AlbumArtLocations.PATH, + Operator.EQ, + track.getPath()), + new FirstSqlLite( + Tables.ALBUM_ART_LOCATIONS, + new AlbumArtLocationCreator())))); - if(albumArtLocation != null) - { - return BitmapFactory.decodeFile(albumArtLocation.getAlbumArtpath()); - } - return null; - } + if(albumArtLocation != null) + { + return BitmapFactory.decodeFile(albumArtLocation.getAlbumArtpath()); + } + return null; + } } diff --git a/src/com/turtleplayer/presentation/InstanceFormatter.java b/src/com/turtleplayer/presentation/InstanceFormatter.java index 237e48d..1f11942 100644 --- a/src/com/turtleplayer/presentation/InstanceFormatter.java +++ b/src/com/turtleplayer/presentation/InstanceFormatter.java @@ -4,9 +4,9 @@ public abstract class InstanceFormatter implements InstanceVisitor { - final static String DELIMITER = " - "; + final static String DELIMITER = " - "; - public final static InstanceFormatter SHORT = new ShortInstanceFormatter(); - public final static InstanceFormatter SHORT_WITH_NUMBER = new ShortWithNumberInstanceFormatter(); - public final static InstanceFormatter LIST = new OverAllFormatter(); + public final static InstanceFormatter SHORT = new ShortInstanceFormatter(); + public final static InstanceFormatter SHORT_WITH_NUMBER = new ShortWithNumberInstanceFormatter(); + public final static InstanceFormatter LIST = new OverAllFormatter(); } diff --git a/src/com/turtleplayer/presentation/ShortInstanceFormatter.java b/src/com/turtleplayer/presentation/ShortInstanceFormatter.java index d1ae244..8110425 100644 --- a/src/com/turtleplayer/presentation/ShortInstanceFormatter.java +++ b/src/com/turtleplayer/presentation/ShortInstanceFormatter.java @@ -27,10 +27,10 @@ class ShortInstanceFormatter extends InstanceFormatter { - public String visit(Track track) - { - return track.getSongName(); - } + public String visit(Track track) + { + return track.getSongName(); + } public String visit(SongDigest track) { @@ -38,9 +38,9 @@ public String visit(SongDigest track) } public String visit(Album album) - { - return album.getAlbumName(); - } + { + return album.getAlbumName(); + } public String visit(GenreDigest genre) { diff --git a/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java b/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java index 66ddcf4..00a860b 100644 --- a/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java +++ b/src/com/turtleplayer/presentation/ShortWithNumberInstanceFormatter.java @@ -23,17 +23,17 @@ class ShortWithNumberInstanceFormatter extends ShortInstanceFormatter { - @Override - public String visit(Track track) - { - String trackName = track.getSongName(); + @Override + public String visit(Track track) + { + String trackName = track.getSongName(); - int number = track.GetNumber(); + int number = track.GetNumber(); - if(!Shorty.isVoid(number)) - { - return number + DELIMITER + trackName; - } - return trackName; - } + if(!Shorty.isVoid(number)) + { + return number + DELIMITER + trackName; + } + return trackName; + } } diff --git a/test/com/turtleplayer/persistance/turtle/FsReaderTest.java b/test/com/turtleplayer/persistance/turtle/FsReaderTest.java index 8c05ba1..5cc1b6d 100644 --- a/test/com/turtleplayer/persistance/turtle/FsReaderTest.java +++ b/test/com/turtleplayer/persistance/turtle/FsReaderTest.java @@ -25,20 +25,20 @@ public class FsReaderTest { - @Test - public void testParseTrackNumber() throws Exception - { - assertEquals(1, FsReader.parseTrackNumber("1")); - assertEquals(1, FsReader.parseTrackNumber("01")); - assertEquals(1, FsReader.parseTrackNumber("1/2")); - assertEquals(1, FsReader.parseTrackNumber("1,2")); - assertEquals(1, FsReader.parseTrackNumber("1;2")); - assertEquals(0, FsReader.parseTrackNumber("00")); - assertEquals(0, FsReader.parseTrackNumber("0")); - assertEquals(0, FsReader.parseTrackNumber("0/0")); - assertEquals(0, FsReader.parseTrackNumber("")); - assertEquals(0, FsReader.parseTrackNumber("asdad")); - assertEquals(10, FsReader.parseTrackNumber("10")); - assertEquals(10, FsReader.parseTrackNumber("010")); - } + @Test + public void testParseTrackNumber() throws Exception + { + assertEquals(1, FsReader.parseTrackNumber("1")); + assertEquals(1, FsReader.parseTrackNumber("01")); + assertEquals(1, FsReader.parseTrackNumber("1/2")); + assertEquals(1, FsReader.parseTrackNumber("1,2")); + assertEquals(1, FsReader.parseTrackNumber("1;2")); + assertEquals(0, FsReader.parseTrackNumber("00")); + assertEquals(0, FsReader.parseTrackNumber("0")); + assertEquals(0, FsReader.parseTrackNumber("0/0")); + assertEquals(0, FsReader.parseTrackNumber("")); + assertEquals(0, FsReader.parseTrackNumber("asdad")); + assertEquals(10, FsReader.parseTrackNumber("10")); + assertEquals(10, FsReader.parseTrackNumber("010")); + } }