This is an automated email from the git hooks/post-receive script. New commit to branch feature/7457 in repository observe. See http://git.codelutin.com/observe.git commit b542c7696773c9bc8da396f10e9c5234fdd4e0af Author: Tony CHEMIT <chemit@codelutin.com> Date: Sun Aug 16 13:21:01 2015 +0200 Ajout du module d'implantation topia des services On a conserver dans le répertoire src/main/fromRefactor l'état d'avancement de ce qui a déjà été effectué See #7457 --- observe-services-topia/LICENSE.txt | 674 +++++++++++++++++ observe-services-topia/README.txt | 2 + observe-services-topia/pom.xml | 122 +++ .../observe/services/AbstractObserveService.java | 492 ++++++++++++ .../ObserveServiceFactoryProviderTopia.java | 190 +++++ .../observe/services/ReplicationServiceImpl.java | 423 +++++++++++ .../observe/services/data/OpenableServiceImpl.java | 157 ++++ .../ird/observe/services/data/TripServiceImpl.java | 211 ++++++ .../data/longline/ActivityLonglineServiceImpl.java | 145 ++++ .../data/longline/BaitsCompositionServiceImpl.java | 76 ++ .../BranchlinesCompositionServiceImpl.java | 72 ++ .../data/longline/CatchLonglineServiceImpl.java | 245 ++++++ .../data/longline/EncounterServiceImpl.java | 72 ++ .../longline/FloatlinesCompositionServiceImpl.java | 72 ++ .../GearUseFeaturesLonglineServiceImpl.java | 214 ++++++ .../data/longline/HooksCompositionServiceImpl.java | 72 ++ .../LonglineDetailCompositionServiceImpl.java | 191 +++++ .../LonglineGlobalCompositionServiceImpl.java | 65 ++ .../data/longline/SensorUsedServiceImpl.java | 107 +++ .../data/longline/SetLonglineServiceImpl.java | 179 +++++ .../services/data/longline/TdrServiceImpl.java | 105 +++ .../data/longline/TripLonglineServiceImpl.java | 136 ++++ .../data/seine/ActivitySeineServiceImpl.java | 202 +++++ .../data/seine/FloatingObjectServiceImpl.java | 194 +++++ .../seine/GearUseFeaturesSeineServiceImpl.java | 211 ++++++ .../data/seine/NonTargetCatchServiceImpl.java | 114 +++ .../data/seine/NonTargetSampleServiceImpl.java | 245 ++++++ .../seine/ObjectObservedSpeciesServiceImpl.java | 66 ++ .../seine/ObjectSchoolEstimateServiceImpl.java | 67 ++ .../services/data/seine/RouteServiceImpl.java | 162 ++++ .../data/seine/SchoolEstimateServiceImpl.java | 72 ++ .../services/data/seine/SetSeineServiceImpl.java | 151 ++++ .../data/seine/TargetCatchServiceImpl.java | 164 ++++ .../data/seine/TargetSampleServiceImpl.java | 276 +++++++ .../services/data/seine/TripSeineServiceImpl.java | 136 ++++ .../services/operation/ComputeDataServiceImpl.java | 832 +++++++++++++++++++++ .../services/operation/GpsImportServiceImpl.java | 133 ++++ .../services/operation/SynchronizeServiceImpl.java | 218 ++++++ .../services/operation/ValidationServiceImpl.java | 94 +++ .../referential/ReferentialServiceImpl.java | 518 +++++++++++++ .../services/ObserveServiceContextTopia.java | 10 + .../ObserveServiceFactoryProviderTopia.java | 27 + .../ird/observe/services/ObserveServiceTopia.java | 17 + .../services/service/ReferentialServiceTopia.java | 58 ++ ....observe.services.ObserveServiceFactoryProvider | 1 + .../referential/ReferentialServiceTopiaTest.java | 39 + .../src/test/resources/log4j.properties | 32 + pom.xml | 2 +- 48 files changed, 8062 insertions(+), 1 deletion(-) diff --git a/observe-services-topia/LICENSE.txt b/observe-services-topia/LICENSE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/observe-services-topia/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/observe-services-topia/README.txt b/observe-services-topia/README.txt new file mode 100644 index 0000000..d2e50d3 --- /dev/null +++ b/observe-services-topia/README.txt @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install diff --git a/observe-services-topia/pom.xml b/observe-services-topia/pom.xml new file mode 100644 index 0000000..67df2d2 --- /dev/null +++ b/observe-services-topia/pom.xml @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>fr.ird.observe</groupId> + <artifactId>observe</artifactId> + <version>4.0.2-SNAPSHOT</version> + </parent> + + <artifactId>observe-services-topia</artifactId> + + <name>ObServe :: Services (impl Topia)</name> + <description>ObServe services (Implementation Topia)</description> + + <dependencies> + + <!-- sibling dependencies --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>observe-services-model</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>observe-services-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>observe-entities</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>observe-business</artifactId> + <version>${project.version}</version> + </dependency> + + + <!-- commons dependencies --> + + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>commons-primitives</groupId> + <artifactId>commons-primitives</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-collections4</artifactId> + </dependency> + <dependency> + <groupId>commons-jxpath</groupId> + <artifactId>commons-jxpath</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + + <!-- Nuiton --> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-decorator</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton.i18n</groupId> + <artifactId>nuiton-i18n</artifactId> + </dependency> + + <!-- persistence --> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton.topia</groupId> + <artifactId>topia-persistence</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton.topia</groupId> + <artifactId>topia-service-replication</artifactId> + </dependency> + + <!-- Logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-jcl</artifactId> + <scope>runtime</scope> + </dependency> + + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>runtime</scope> + </dependency> + + <!-- test dependencies --> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + + </dependencies> + + +</project> \ No newline at end of file diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/AbstractObserveService.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/AbstractObserveService.java new file mode 100644 index 0000000..8fe48d5 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/AbstractObserveService.java @@ -0,0 +1,492 @@ +package fr.ird.observe.services; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import fr.ird.observe.BinderService; +import fr.ird.observe.IObserveConfig; +import fr.ird.observe.ObserveEntityEnum; +import fr.ird.observe.db.DataSource; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.EntityMap; +import fr.ird.observe.entities.constants.ReferenceLocale; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.decorator.Decorator; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; +import org.nuiton.topia.persistence.util.TopiaEntityHelper; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + * @since 4.0 + */ +public abstract class AbstractObserveService implements ObserveService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(AbstractObserveService.class); + + String PARENT_BEAN = "parentBean"; + + String BEAN = "bean"; + + protected ObserveServiceContext serviceContext; + + @Override + public void setServiceContext(ObserveServiceContext serviceContext) { + this.serviceContext = serviceContext; + } + + @Override + public <E extends TopiaEntity> EntityMap findAllUsages(E entity) { + + Class<E> entityType = getEntityContractClass(entity); + + TopiaDAO<E> dao = getDao(entityType); + + // always get a fresh version of object + entity = dao.findByTopiaId(entity.getTopiaId()); + EntityMap result; + result = new EntityMap(dao.findAllUsages(entity)); + // on charge les entites + for (Class<? extends TopiaEntity> aClass : result.keySet()) { + + List topiaEntities = result.get(aClass); + decorate(aClass, topiaEntities); + + } + return result; + + } + + @Override + public <E extends TopiaEntity> List<E> getList(Class<E> klass) { + + List<E> list = getList(klass, null); + return list; + } + + @Override + public <E extends TopiaEntity> List<E> getList(Class<E> klass, Predicate<E> predicate) { + + if (Entities.isDataClass(klass)) { + // on verifie que l'on a le droit de lire la donnee + if (!getDataSource().canReadData()) { + if (log.isDebugEnabled()) { + log.debug("Can not read data, no read credential"); + } + return new ArrayList<E>(); + } + } + + if (Entities.isReferentielClass(klass)) { + // on verifie que l'on a le droit de lire la donnee + if (!getDataSource().canReadReferentiel()) { + if (log.isDebugEnabled()) { + log.debug("Can not read referentiel, no read credential"); + } + return new ArrayList<E>(); + } + } + + List<E> result = getList0(klass, predicate); + + //TC-20100208 : on peut modifier la liste (pour supprimer par + // exemple les entites non active), on doit donc toujours travailler + // sur une copie de la liste + return new ArrayList<E>(result); + + } + + public TopiaContext getTransaction() { + return serviceContext.getTransaction(); + } + + public IObserveConfig getConfig() { + return serviceContext.getConfig(); + } + + public ReferenceLocale getReferentielLocale() { + return serviceContext.getReferentielLocale(); + } + + public Date now() { + return serviceContext.now(); + } + + public BinderService getBinderService() { + return serviceContext.getBinderService(); + } + + public <E extends TopiaEntity> void copy(Class<E> type, String context, E source, E target) { + getBinderService().copy(type, context, source, target); + } + + public <E extends TopiaEntity> void copyExcluding(Class<E> type, String context, E source, E target, String... propertyNames) { + getBinderService().copyExcluding(type, context, source, target, propertyNames); + } + + public <E extends TopiaEntity> void copyExcluding(Class<E> type, String context, E source, E target, boolean bindTechnical, String... propertyNames) { + getBinderService().copyExcluding(type, context, source, target, bindTechnical, propertyNames); + } + + public <E extends TopiaEntity> void copy(Class<E> type, String context, E source, E target, boolean bindTechnical) { + getBinderService().copy(type, context, source, target, bindTechnical); + } + + public <E extends TopiaEntity> Map<String, Object> obtainProperties(Class<E> type, String context, E source) { + return getBinder(type, context).obtainProperties(source); + } + + public <E extends TopiaEntity> TopiaEntityBinder<E> getBinder(Class<E> entityClass, String contextName) { + return getBinderService().getBinder(entityClass, contextName); + } + + protected <E extends TopiaEntity> TopiaDAO<E> getDao(E entity) { + Class<E> entityType = getEntityContractClass(entity); + return getDataSource().getDAO(getTransaction(), entityType); + } + + protected DataSource getDataSource() { + return serviceContext.getDataSource(); + } + + protected <E extends TopiaEntity> TopiaDAO<E> getDao(Class<E> entityType) { + return getDataSource().getDAO(getTransaction(), entityType); + } + + protected <E extends TopiaEntity> E findByTopiaId(Class<E> entityType, String topiaId) { + + TopiaDAO<E> dao = getDataSource().getDAO(getTransaction(), entityType); + return dao.findByTopiaId(topiaId); + + } + + protected <O> Decorator<O> getDecoratorByType(Class<O> entityType, String context) { + return serviceContext.getDecoratorService().getDecoratorByType(entityType, context); + } + + + protected <O> void decorate(Class<O> objectType, Collection<O> objects) { + + Decorator<O> decorator = getDecoratorByType(objectType, null); + for (Object object : objects) { + decorator.toString(object); + } + + } + + protected <O> void decorate(Class<O> objectType, O object) { + + Decorator<O> decorator = getDecoratorByType(objectType, null); + decorator.toString(object); + + } + + protected <E extends TopiaEntity> String decorateEntity(E entity) { + + Class<E> entityType = getEntityContractClass(entity); + Decorator<E> decorator = getDecoratorByType(entityType, null); + return decorator.toString(entity); + + } + + protected <E extends TopiaEntity> Class<E> getEntityContractClass(E entity) { + return (Class<E>) ObserveEntityEnum.valueOf(entity).getContract(); + } + + protected <E extends TopiaEntity> List<E> getList0(Class<E> klass, Predicate<E> predicate) { + + TopiaDAO<E> dao = getDao(klass); + List<E> result = dao.findAll(); + + if (predicate != null) { + + // use a filter + result = Lists.newArrayList(Iterables.filter(result, predicate)); + + } + + return result; + + } + + protected <P extends TopiaEntity, E extends TopiaEntity> String doSave(String parentId, E toSave, SaveAction<P, E> saveAction) { + E saved; + + saveAction.beforeSave(parentId, toSave); + + P parent = null; + + if (parentId != null) { + + parent = findByTopiaId(saveAction.parentClass, parentId); + + checkNotNullAndExistingEntity(PARENT_BEAN, parent); + } + + if (Entities.isNew(toSave)) { + + checkNotNullAndNoneExistingEntity(BEAN, toSave); + + saved = saveAction.onCreate(parent, toSave); + + } else { + + checkNotNullAndExistingEntity(BEAN, toSave); + + saved = saveAction.onUpdate(parent, toSave); + + checkNotNullAndExistingEntity(BEAN, saved); + + } + + if (parent == null) { + + // sauvegarde de l'entité + getDao(saveAction.entityClass).update(saved); + + } else { + + // sauvegarde du père de l'entité + getDao(saveAction.parentClass).update(parent); + + } + + return saved.getTopiaId(); + + + } + + protected abstract class SaveAction<P extends TopiaEntity, E extends TopiaEntity> { + + protected final Class<P> parentClass; + + protected final Class<E> entityClass; + + public SaveAction(Class<P> parentClass, Class<E> entityClass) { + this.parentClass = parentClass; + this.entityClass = entityClass; + } + + public void beforeSave(String parentId, E toSave) { + + } + + public abstract E onCreate(P parent, E toCreate); + + public E onUpdate(P parent, E toSave) { + + E saved = findByTopiaId(entityClass, toSave.getTopiaId()); + checkNotNullAndExistingEntity(BEAN, saved); + return saved; + + } + + } + + protected <P extends TopiaEntity, E extends TopiaEntity> void doDelete(String parentId, String idToDelete, DeleteAction<P, E> deleteAction) { + + P parent = null; + + if (parentId != null) { + + parent = findByTopiaId(deleteAction.parentClass, parentId); + + checkNotNullAndExistingEntity(PARENT_BEAN, parent); + + } + + E toDelete = findByTopiaId(deleteAction.entityClass, idToDelete); + + checkNotNullAndExistingEntity(BEAN, toDelete); + + deleteAction.onDelete(parent, toDelete); + + if (parentId != null) { + + getDao(deleteAction.parentClass).update(parent); + + } + + } + + protected class DeleteAction<P extends TopiaEntity, E extends TopiaEntity> { + + protected final Class<P> parentClass; + + protected final Class<E> entityClass; + + public DeleteAction(Class<P> parentClass, Class<E> entityClass) { + this.parentClass = parentClass; + this.entityClass = entityClass; + } + + public void onDelete(P parent, E toDelete) { + getDao(entityClass).delete(toDelete); + } + + } + + protected <P extends TopiaEntity, E extends TopiaEntity> void doSaveList(P parentToSave, SaveCollectionAction<P, E> saveCollectionAction) { + + Collection<E> childrenToSave = saveCollectionAction.listUpdator.getChilds(parentToSave); + + saveCollectionAction.prepareSave(parentToSave, childrenToSave); + + P parentSaved = saveCollectionAction.onUpdateParent(parentToSave); + + List<E> oldChilds = new ArrayList<E>(saveCollectionAction.listUpdator.getChilds(parentSaved)); + + saveCollectionAction.listUpdator.removeAll(parentSaved); + + for (E childToSave : childrenToSave) { + + E childSaved; + + if (Entities.isNew(childToSave)) { + + // creation du fils + childSaved = saveCollectionAction.onCreateChild(childToSave); + + } else { + + // mise a jour du fils + childSaved = saveCollectionAction.onUpdateChild(childToSave); + + } + + saveCollectionAction.listUpdator.addToList(parentSaved, childSaved); + + } + + for (E childNotSaved : Iterables.filter(oldChilds, Predicates.not(saveCollectionAction.childPredicate))) { + saveCollectionAction.listUpdator.addToList(parentSaved, childNotSaved); + } + + // on donne la main aux implantations pour faire des traitements supplémentaires + saveCollectionAction.onUpdateFinalize(parentSaved, oldChilds); + + } + + + protected class SaveCollectionAction<P extends TopiaEntity, E extends TopiaEntity> { + + protected final Class<P> parentClass; + + protected final Class<E> entityClass; + + protected final EntityListUpdator<P, E> listUpdator; + + protected final TopiaEntityBinder<P> parentBinder; + + protected final TopiaEntityBinder<E> childBinder; + + protected final Predicate<E> childPredicate; + + public SaveCollectionAction(Class<P> parentClass, + Class<E> entityClass, + EntityListUpdator<P, E> listUpdator, + TopiaEntityBinder<P> parentBinder, + TopiaEntityBinder<E> childBinder, + Predicate<E> childPredicate) { + this.parentClass = parentClass; + this.entityClass = entityClass; + this.listUpdator = listUpdator; + this.parentBinder = parentBinder; + this.childBinder = childBinder; + this.childPredicate = childPredicate; + } + + public SaveCollectionAction(Class<P> parentClass, + Class<E> entityClass, + EntityListUpdator<P, E> listUpdator, + TopiaEntityBinder<P> parentBinder, + TopiaEntityBinder<E> childBinder) { + this.parentClass = parentClass; + this.entityClass = entityClass; + this.listUpdator = listUpdator; + this.parentBinder = parentBinder; + this.childBinder = childBinder; + this.childPredicate = Predicates.alwaysTrue(); + } + + public void prepareSave(P parentToSave, Collection<E> toSaves) { + // par defaut, rien de specifique a faire avant de faire la sauvegarde + } + + public void onUpdateFinalize(P parentSaved, Collection<E> oldChilds) throws TopiaException { + // par défaut, rien à faire après la sauvegarde de la liste + } + + public P onUpdateParent(P parentToSave) { + + TopiaDAO<P> dao = getDao(parentClass); + + P parentSaved = dao.findByTopiaId(parentToSave.getTopiaId()); + parentBinder.copyExcluding(parentToSave, parentSaved, listUpdator.getPropertyName()); + parentSaved = dao.update(parentSaved); + + return parentSaved; + + } + + public E onCreateChild(E childToCreate) { + + Map<String, Object> properties = childBinder.obtainProperties(childToCreate); + E childCreated = getDao(entityClass).create(properties); + + return childCreated; + + } + + public E onUpdateChild(E childToUpdate) { + + TopiaDAO<E> dao = getDao(entityClass); + + E childUpdated = dao.findByTopiaId(childToUpdate.getTopiaId()); + childBinder.load(childToUpdate, childUpdated, true); + childUpdated = dao.update(childUpdated); + + return childUpdated; + + } + + } + + protected <E extends TopiaEntity> void checkNotNullAndNoneExistingEntity(String variableName, E entity) { + TopiaEntityHelper.checkNotNullAndNoneExistingEntity(variableName, entity); + } + + + protected <E extends TopiaEntity> void checkNotNullAndExistingEntity(String variableName, E entity) { + TopiaEntityHelper.checkNotNullAndExistingEntity(variableName, entity); + } + + protected <S extends ObserveService> S newService(Class<S> serviceType) { + + S service = ObserveServiceFactoryProviderTopia.newSimpleService(serviceType, serviceContext); + return service; + + } + + protected <S extends ObserveService> S newService(DataSource dataSource, Class<S> serviceType) { + + ObserveServiceContext serviceContext1 = new ObserveServiceContext(serviceContext.applicationContext, dataSource); + S service = new ObserveServiceFactoryProviderTopia().newService(serviceType, serviceContext1); + return service; + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/ObserveServiceFactoryProviderTopia.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/ObserveServiceFactoryProviderTopia.java new file mode 100644 index 0000000..3ee2edc --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/ObserveServiceFactoryProviderTopia.java @@ -0,0 +1,190 @@ +package fr.ird.observe.services; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Sets; +import fr.ird.observe.ObserveTechnicalException; +import fr.ird.observe.db.DataSource; +import fr.ird.observe.db.impl.H2DataSource; +import fr.ird.observe.db.impl.PGDataSource; +import org.apache.commons.lang3.reflect.ConstructorUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.TopiaContext; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Set; + +/** + * Created on 5/4/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ObserveServiceFactoryProviderTopia implements ObserveServiceFactoryProvider { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ObserveServiceFactoryProviderTopia.class); + + @Override + public boolean acceptDataSource(DataSource dataSource) { + + boolean result = false; + if (dataSource instanceof H2DataSource) { + result = true; + } else if (dataSource instanceof PGDataSource) { + result = true; + } + return result; + + } + + @Override + public <S extends ObserveService> S newService(Class<S> serviceType, ObserveServiceContext serviceContext) { + + Preconditions.checkNotNull(serviceType, "serviceType can't be null"); + Preconditions.checkArgument(serviceType.isInterface(), "serviceType must be an interface"); + Preconditions.checkNotNull(serviceContext, "serviceContext can't be null"); + + S service = newSimpleService(serviceType, serviceContext); + S proxyService = addProxyService(serviceType, service, serviceContext); + return proxyService; + + } + + public static <S extends ObserveService> S newSimpleService(Class<S> serviceType, ObserveServiceContext serviceContext) { + + //FIXME Rename implementation to TopiaImpl + Class<S> serviceImpl; + try { + serviceImpl = (Class<S>) Class.forName(serviceType.getName() + "Impl"); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Could not find implementation class for " + serviceType); + } + + try { + + // Instanciate concrete service + S service = ConstructorUtils.invokeConstructor(serviceImpl); + service.setServiceContext(serviceContext); + + return service; + + } catch (Exception e) { + throw new ObserveTechnicalException("Could not create service: " + serviceType, e); + } + + } + + protected <S extends ObserveService> S addProxyService(Class<S> serviceType, S service, ObserveServiceContext serviceContext) { + + // Instanciate transactional proxied service + ServiceInvocationHandler invocationHandler = new ServiceInvocationHandler(serviceContext, service); + S proxyService = (S) Proxy.newProxyInstance(ObserveServiceFactoryProviderTopia.class.getClassLoader(), new Class[]{serviceType}, invocationHandler); + + return proxyService; + + } + + protected static class ServiceInvocationHandler implements InvocationHandler { + + private final ObserveServiceContext serviceContext; + + private final ObserveService target; + + private final Set<String> methodNamesToByPass; + + protected ServiceInvocationHandler(ObserveServiceContext serviceContext, ObserveService target) { + + this.serviceContext = serviceContext; + this.target = target; + this.methodNamesToByPass = Sets.newHashSet( + "equals", + "hashCode", + "finalize", + "toString", + "clone", + "getClass", + "close"); + + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + + Object result; + + if (methodNamesToByPass.contains(method.getName()) || method.isAnnotationPresent(NoTransaction.class)) { + + result = invokeMethod(method, args); + + } else { + + result = invokeMethodWithTransaction(method, args); + + } + + return result; + + } + + protected Object invokeMethod(Method method, Object... args) throws Throwable { + try { + Object result = method.invoke(target, args); + return result; + } catch (InvocationTargetException e) { + if (log.isErrorEnabled()) { + log.error("Error in method " + method.getName(), e); + } + throw e.getCause(); + } + } + + + protected Object invokeMethodWithTransaction(Method method, Object... args) throws Throwable { + + String methodName = method.getName(); + + DataSource source = serviceContext.getDataSource(); + + TopiaContext tx = source.beginTransaction(methodName); + + try { + + serviceContext.setTransaction(tx); + + Object invoke = invokeMethod(method, args); + + if (method.isAnnotationPresent(Commit.class)) { + + // do commit + source.commitTransaction(tx, methodName); + + } + + return invoke; + + } finally { + + try { + + // always rollback transaction to avoid dirty transactions + source.rollbackTransaction(tx, methodName); + + + } finally { + + serviceContext.setTransaction(null); + source.closeTransaction(tx, methodName); + + } + + } + + } + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/ReplicationServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/ReplicationServiceImpl.java new file mode 100644 index 0000000..d64ddc3 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/ReplicationServiceImpl.java @@ -0,0 +1,423 @@ +package fr.ird.observe.services; + +import fr.ird.observe.DecoratorService; +import fr.ird.observe.ObserveDAOHelper; +import fr.ird.observe.ObserveEntityEnum; +import fr.ird.observe.SendMessageAble; +import fr.ird.observe.db.DataSource; +import fr.ird.observe.db.DataSourceException; +import fr.ird.observe.db.constants.DataSourceState; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.Trip; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.entities.longline.TripLonglines; +import fr.ird.observe.entities.seine.TripSeineDAO; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.TopiaContext; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.framework.TopiaContextImplementor; +import org.nuiton.topia.framework.TopiaSQLQuery; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.replication.TopiaReplicationService; +import org.nuiton.topia.replication.model.ReplicationModel; +import org.nuiton.util.StringUtil; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 5/3/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ReplicationServiceImpl extends AbstractObserveService implements ReplicationService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ReplicationServiceImpl.class); + + @Override + public void replicateObsoletesEntities(List<TopiaEntity> obsoleteEntities, DataSource source, SendMessageAble messanger) throws DataSourceException { + + String txName = "replicateObsoletesEntities"; + TopiaContext sourceCtxt = source.beginTransaction(txName); + try { + + for (ObserveEntityEnum constant : Entities.REFERENCE_ENTITIES) { + + Class<? extends TopiaEntity> contractClass = constant.getContract(); + List<TopiaEntity> toReplicate = new ArrayList<TopiaEntity>(); + for (Iterator<TopiaEntity> itr = obsoleteEntities.iterator(); itr.hasNext(); ) { + + TopiaEntity e = itr.next(); + if (contractClass.isAssignableFrom(e.getClass())) { + if (log.isDebugEnabled()) { + log.debug("obsolete to inject : " + e.getTopiaId()); + } + itr.remove(); + + // cet objet doit etre replique + toReplicate.add(e); + + messanger.sendMessage(t("observe.message.synchro.obsolete.data.to.duplicate", e)); + } + } + + if (toReplicate.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("no obsolete entity " + constant); + } + continue; + } + + if (log.isDebugEnabled()) { + log.debug("inject obsolete entity " + constant + " (" + toReplicate.size() + ")"); + } + + sourceCtxt.replicateEntities(getTransaction(), toReplicate); + + getTransaction().commitTransaction(); + + } + + } finally { + + source.closeTransaction(sourceCtxt, txName); + + } + + if (!obsoleteEntities.isEmpty()) { + throw new IllegalStateException("there is still obsolete entities to inject in synchro db : " + obsoleteEntities); + } + + } + + /** + * Duplication du référentiel depuis la source donnée en paramètre vers la source de ce service. + * + * @param srcService le service source qui contient les référentiels à repliquer + * @throws DataSourceException if pb + */ + public void replicateReferentiel(DataSource srcService) throws DataSourceException { + + if (srcService == null) { + throw new NullPointerException("srcService can not be null"); + } + + srcService.checkState(DataSourceState.OPEN); + + if (srcService.equals(getDataSource())) { + throw new IllegalArgumentException("can not duplicate to the same service..."); + } + long t0 = System.nanoTime(); + + Date date = new Date(); + srcService.fireNewMessage(t("observe.storage.message.replicate.referentiel.starting", date)); + + try { + + TopiaReplicationService service = srcService.getTopiaService(TopiaReplicationService.class); + + ReplicationModel model = service.prepareForAll(Entities.REFERENCE_ENTITIES); + + service.doReplicate(model, getTransaction()); + + String delay = StringUtil.convertTime(t0, System.nanoTime()); + srcService.fireNewMessage( + t("observe.storage.message.replicate.referentiel.done", delay)); + } catch (Exception e) { + throw new DataSourceException(e, "replicateReferentiel"); + } + } + + @Override + public void replicateReferentiel(DataSource srcService, List<String> ids, SendMessageAble messanger) throws DataSourceException { + + for (String id : ids) { + + String txName = "replicateReferentiel::" + id; + TopiaContext tx = srcService.beginTransaction(txName); + + try { + + TopiaEntity entity = tx.findByTopiaId(id); + String message = t("observe.synchro.add.object", id); + messanger.sendMessage(message); + tx.replicateEntity(getTransaction(), entity); + + // On est obligé de commiter à chaque ajout sinon si + // une autre entité à ajouter depend de celle là, on + // ne la retrouve pas + getTransaction().commitTransaction(); + if (log.isDebugEnabled()) { + log.debug("add [" + id + "] : "); + } + + } finally { + + // rollback context since we do not want to keep any modification + try { + srcService.rollbackTransaction(tx, txName); + } finally { + srcService.closeTransaction(tx, txName); + } + + } + + } + + } + + /** + * Duplication de toutes les données depuis le service passé en paramètre. + * + * @param srcService le service source + * @throws DataSourceException if pb + */ + public void replicateAllData(DataSource srcService) throws DataSourceException { + + srcService.checkState(DataSourceState.OPEN); + + // le service peut-être en cours d'ouverture + getDataSource().checkState(DataSourceState.INIT, DataSourceState.OPEN); + + if (srcService.equals(getDataSource())) { + throw new IllegalArgumentException("can not replcate to the same service..."); + } + + // recuperation des marees a repliquer + + String[] topiaIds = null; + + TopiaContext srcCtxt = srcService.beginTransaction("replicateData"); + try { + + TripSeineDAO srcTripDAO = ObserveDAOHelper.getTripSeineDAO(srcCtxt); + List<String> allIds = srcTripDAO.findAllIds(); + + if (CollectionUtils.isEmpty(allIds)) { + + // aucune donnee a repliquer + srcService.fireNewMessage(t("observe.storage.message.replicate.data.no.data")); + return; + + } + + topiaIds = allIds.toArray(new String[allIds.size()]); + + } catch (TopiaException e) { + + throw new DataSourceException(e, "replicateData"); + + } finally { + + // rollback context since we do not want to keep any modification + try { + srcService.rollbackTransaction(srcCtxt, "replicateData"); + } finally { + srcService.closeTransaction(srcCtxt, "replicateData"); + } + + } + + // replication des marees + replicateData(srcService, topiaIds); + + } + + /** + * Duplication de données observateur depuis la source passée en paramètre. + * + * @param srcService le service source + * @param ids les ids des entités à répliquer + * @throws DataSourceException if pb + */ + public void replicateData(DataSource srcService, String... ids) throws DataSourceException { + + if (srcService == null) { + throw new NullPointerException("srcService can not be null"); + } + + srcService.checkState(DataSourceState.OPEN); + // le service peut-être en cours d'ouverture + getDataSource().checkState(DataSourceState.INIT, DataSourceState.OPEN); + + if (srcService.equals(getDataSource())) { + throw new IllegalArgumentException("can not replcate to the same service..."); + } + + long t0 = System.nanoTime(); + + srcService.fireNewMessage(t("observe.storage.message.replicate.entities.starting", now())); + + for (String id : ids) { + replicateOneData(srcService, id); + } + + String time = StringUtil.convertTime(t0, System.nanoTime()); + srcService.fireNewMessage(t("observe.storage.message.replicate.entities.done", time)); + + } + + /** + * Duplication de l'unique donnée observateur depuis ce service vers le service donné. + * <p/> + * La duplication utilise une transaction dédiée afin de ne pas saturer le serveur + * et aussi une meilleure maitrise du rollback en cas d'une erreur. + * <p/> + * Voir http://forge.codelutin.com/issues/4837 + * + * @param srcService le service source + * @param id les ids des entités à répliquer + * @throws DataSourceException if pb + */ + protected void replicateOneData(DataSource srcService, String id) throws DataSourceException { + + String dstLabel = getDataSource().getShortLabel(); + + TopiaReplicationService service = srcService.getTopiaService(TopiaReplicationService.class); + + ReplicationModel model; + try { + model = service.prepare(Entities.DATA_ENTITIES, false, id); + } catch (TopiaException e) { + throw new DataSourceException(e, "replicateData"); + } + + // To fix missing tdr associations (see https://forge.codelutin.com/issues/6611) + List<Pair<String, String>> tdrAssociation = null; + + TopiaContext srcCtxt = srcService.beginTransaction("replicateData"); + try { + + TopiaEntity e = srcCtxt.findByTopiaId(id); + String label = t(DecoratorService.getEntityLabel(e.getClass())) + " :: " + id; + srcService.fireNewMessage(t("observe.storage.message.replicate.data.entity", label, dstLabel)); + + if (e instanceof Trip && Entities.isLonglineId(id)) { + + // Grab tdr missing associations (see https://forge.codelutin.com/issues/6611) + if (log.isInfoEnabled()) { + log.info("Should keep SetLongline - Tdr association ids for: " + id); + } + + tdrAssociation = getTdrAssociationIds(srcCtxt, (TripLongline) e); + + } + } catch (TopiaException e) { + throw new DataSourceException(e, "replicateData"); + } finally { + srcService.closeTransaction(srcCtxt, "replicateData"); + } + + TopiaContext dstCtxt = getTransaction(); + try { + + // do the replicate + service.doReplicate(model, dstCtxt); + + // Apply back tdr missing associations (see https://forge.codelutin.com/issues/6611) + applyTdrAssociationFix(dstCtxt, tdrAssociation); + + // commit the result + getTransaction().commitTransaction(); + + } catch (Exception e) { + getTransaction().rollbackTransaction(); + throw new DataSourceException(e, "replicateData"); + } finally { + + getTransaction().rollbackTransaction(); + + } + + } + + private void applyTdrAssociationFix(TopiaContext dstCtxt, List<Pair<String, String>> tdrAssociation) throws TopiaException { + + String request = "\nUPDATE OBSERVE_LONGLINE.TDR SET SET = '%s' WHERE topiaid = '%s';"; + + StringBuilder builder = new StringBuilder(); + + if (CollectionUtils.isNotEmpty(tdrAssociation)) { + for (Pair<String, String> entry : tdrAssociation) { + builder.append(String.format(request, entry.getKey(), entry.getValue())); + } + } + + dstCtxt.executeSQL(builder.toString()); + + } + + private List<Pair<String, String>> getTdrAssociationIds(TopiaContext srcCtxt, TripLongline e) throws TopiaException { + + List<Pair<String, String>> result = new ArrayList<Pair<String, String>>(); + + Set<String> setIds = TripLonglines.getSetIdsWithTdr(e); + + GetTdrIdsQuery query = new GetTdrIdsQuery(); + + for (String setId : setIds) { + + List<Pair<String, String>> multipleResult = query.execute((TopiaContextImplementor) srcCtxt, setId); + + if (log.isDebugEnabled()) { + log.debug("Found TDR associations: " + multipleResult); + } + result.addAll(multipleResult); + + } + + return result; + } + + + private static class GetTdrIdsQuery extends TopiaSQLQuery<Pair<String, String>> { + + private String setId; + + public List<Pair<String, String>> execute(TopiaContextImplementor tx, String setId) throws TopiaException { + try { + + this.setId = setId; + return findMultipleResult(tx); + + } finally { + + this.setId = null; + + } + } + + @Override + protected PreparedStatement prepareQuery(Connection connection) throws SQLException { + String sql = "SELECT t.SET, t.topiaId " + + "FROM OBSERVE_LONGLINE.TDR t " + + "WHERE t.SET = ?"; + PreparedStatement ps = connection.prepareStatement(sql); + ps.setString(1, setId); + return ps; + } + + @Override + protected Pair<String, String> prepareResult(ResultSet set) throws SQLException { + Pair<String, String> result = + Pair.of(set.getString(1), set.getString(2)); + return result; + } + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/OpenableServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/OpenableServiceImpl.java new file mode 100644 index 0000000..ec1f06f --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/OpenableServiceImpl.java @@ -0,0 +1,157 @@ +package fr.ird.observe.services.data; + +import fr.ird.observe.entities.OpenableEntity; +import fr.ird.observe.entities.OpenableEntityDAOImpl; +import fr.ird.observe.entities.longline.ActivityLongline; +import fr.ird.observe.entities.longline.ActivityLonglineDAO; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.entities.longline.TripLonglineDAO; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeineDAO; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.RouteDAO; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.entities.seine.TripSeineDAO; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class OpenableServiceImpl extends AbstractObserveService implements OpenableService { + + @Override + public String[] getOpenIds() { + + List<String> result = new ArrayList<String>(); + + { + TripSeine trip = getOpen(TripSeine.class); + if (trip != null) { + if (trip.getProgram() != null) { + result.add(trip.getProgram().getTopiaId()); + } + result.add(trip.getTopiaId()); + Route route = getOpen(Route.class); + if (route != null) { + result.add(route.getTopiaId()); + ActivitySeine activity = getOpen(ActivitySeine.class); + if (activity != null) { + result.add(activity.getTopiaId()); + SetSeine set = activity.getSetSeine(); + if (set != null) { + result.add(set.getTopiaId()); + } + } + } + } + } + + { + TripLongline trip = getOpen(TripLongline.class); + if (trip != null) { + if (trip.getProgram() != null) { + result.add(trip.getProgram().getTopiaId()); + } + result.add(trip.getTopiaId()); + ActivityLongline activity = getOpen(ActivityLongline.class); + if (activity != null) { + result.add(activity.getTopiaId()); + SetLongline set = activity.getSetLongline(); + if (set != null) { + result.add(set.getTopiaId()); + } + } + } + } + + return result.toArray(new String[result.size()]); + + } + + @Override + public <E extends OpenableEntity & TopiaEntity> E getOpen(Class<E> klass) { + + OpenableEntityDAOImpl dao = (OpenableEntityDAOImpl) getDao(klass); + E result = (E) dao.findByOpen(true); + return result; + + } + + @Override + public void updateOpenState(String topiaId, boolean openState) { + + OpenableEntity entity = findByTopiaId(OpenableEntity.class, topiaId); + entity.setOpen(openState); + + } + + public int getOpenablePosition(String containerId, String childId) { + if (childId.startsWith(TripSeine.class.getName())) { + return getTripSeinePosition(containerId, childId); + } + if (childId.startsWith(TripLongline.class.getName())) { + return getTripLonglinePosition(containerId, childId); + } + if (childId.startsWith(Route.class.getName())) { + return getRoutePosition(containerId, childId); + } + if (childId.startsWith(ActivitySeine.class.getName())) { + return getActivitySeinePosition(containerId, childId); + } + if (childId.startsWith(ActivityLongline.class.getName())) { + return getActivityLonglinePosition(containerId, childId); + } + throw new IllegalStateException("Can not come here!"); + } + + protected int getTripLonglinePosition(String programId, String tripLonglineId) { + + TripLonglineDAO dao = (TripLonglineDAO) getDao(TripLongline.class); + int pos = dao.findPositionByProgramId(programId, tripLonglineId); + return pos; + + } + + protected int getActivityLonglinePosition(String tripLonglineId, String activityLonglineId) { + + ActivityLonglineDAO dao = (ActivityLonglineDAO) getDao(ActivityLongline.class); + int pos = dao.getActivityLonglinePosition(tripLonglineId, activityLonglineId); + return pos; + + } + + protected int getTripSeinePosition(String programId, String tripSeineId) { + + TripSeineDAO dao = (TripSeineDAO) getDao(TripSeine.class); + int pos = dao.findPositionByProgramId(programId, tripSeineId); + return pos; + + } + + protected int getRoutePosition(String tripSeineId, String routeId) { + + RouteDAO dao = (RouteDAO) getDao(Route.class); + int position = dao.getRoutePosition(tripSeineId, routeId); + return position; + + } + + + protected int getActivitySeinePosition(String routeId, String activitySeineId) { + + ActivitySeineDAO dao = (ActivitySeineDAO) getDao(ActivitySeine.class); + int pos = dao.getActivitySeinePosition(routeId, activitySeineId); + return pos; + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/TripServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/TripServiceImpl.java new file mode 100644 index 0000000..d820490 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/TripServiceImpl.java @@ -0,0 +1,211 @@ +package fr.ird.observe.services.data; + +import fr.ird.observe.ObserveTechnicalException; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.Trip; +import fr.ird.observe.entities.constants.GearType; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.entities.longline.TripLonglineDAO; +import fr.ird.observe.entities.referentiel.Ocean; +import fr.ird.observe.entities.referentiel.Program; +import fr.ird.observe.entities.referentiel.ProgramDAO; +import fr.ird.observe.entities.referentiel.Programs; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.entities.seine.TripSeineDAO; +import fr.ird.observe.services.AbstractObserveService; +import fr.ird.observe.services.data.longline.TripLonglineService; +import fr.ird.observe.services.data.seine.TripSeineService; +import fr.ird.observe.services.referential.ReferentialService; +import fr.ird.observe.tripMap.TripMapPoint; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class TripServiceImpl extends AbstractObserveService implements TripService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(TripServiceImpl.class); + + @Override + public DataSelectionModel loadDataSelectionModel() { + + DataSelectionModel result = new DataSelectionModel(); + + Map<String, List<String>> datas = new HashMap<String, List<String>>(); + + TripSeineService tripSeineService = newService(TripSeineService.class); + TripLonglineService tripLonglineService = newService(TripLonglineService.class); + + List<Program> programs = newService(ReferentialService.class).getAllProgramStub(); + for (Program program : programs) { + + if (Programs.isProgramSeine(program)) { + List<TripSeine> trips = tripSeineService.getTripSeineStubByProgram(program.getTopiaId()); + populate(result, program, trips, datas); + } + + if (Programs.isProgramLongline(program)) { + List<TripLongline> trips = tripLonglineService.getTripLonglineStubByProgram(program.getTopiaId()); + populate(result, program, trips, datas); + } + + } + result.setDatas(datas); + + return result; + + } + + @Override + public List<Program> getPossibleProgramsForTrip(String tripId) { + + Trip trip = getTrip(tripId); + + GearType gearType = trip.getProgram().getGearType(); + + ProgramDAO dao = (ProgramDAO) getDao(Program.class); + + List<Program> programs = dao.findAllByGearType(gearType); + + decorate(Program.class, programs); + + Programs.sort(programs); + + return programs; + + } + + @Override + public Trip getTrip(String tripId) { + + Trip trip; + + if (tripId.startsWith(TripSeine.class.getName())) { + trip = findByTopiaId(TripSeine.class, tripId); + } else { + trip = findByTopiaId(TripLongline.class, tripId); + } + + return trip; + + } + + @Override + public Ocean getTripOcean(String tripId) { + + Trip trip = getTrip(tripId); + + return trip.getOcean(); + + } + + @Override + public void moveTripToProgram(String tripId, String programId) { + + Trip trip = getTrip(tripId); + + Program program = findByTopiaId(Program.class, programId); + + trip.setProgram(program); + + } + + @Override + public List<TripMapPoint> loadTripMapActivityPoints(String tripId) { + + List<TripMapPoint> tripMapPoints; + + if (Entities.isSeineId(tripId)) { + TripSeineDAO dao = (TripSeineDAO) getDao(TripSeine.class); + + tripMapPoints = dao.extractTripMapActivityPoints(tripId); + + } else if (Entities.isLonglineId(tripId)) { + + TripLonglineDAO dao = (TripLonglineDAO) getDao(TripLongline.class); + + tripMapPoints = dao.extractTripMapActivityPoints(tripId); + + } else { + throw new ObserveTechnicalException(String.format("id '%s' is not seine id or longe line id", tripId)); + } + + return tripMapPoints; + + } + + @Override + public void deleteTrip(String tripId) { + + if (Entities.isSeineId(tripId)) { + + TripSeineDAO dao = (TripSeineDAO) getDao(TripSeine.class); + TripSeine result = dao.findByTopiaId(tripId); + dao.delete(result); + + } else { + + TripLonglineDAO dao = (TripLonglineDAO) getDao(TripLongline.class); + TripLongline result = dao.findByTopiaId(tripId); + dao.delete(result); + + } + + } + + protected static <T extends Trip> void populate(DataSelectionModel model, + Program program, + List<T> trips, + Map<String, List<String>> datas) { + + model.cacheEntity(program); + + if (!trips.isEmpty()) { + List<String> tripIds = new ArrayList<String>(); + + if (model.isUseOpenData()) { + + // ajout de toutes les marées ouvertes ou non + for (T trip : trips) { + trip.setProgram(program); + model.cacheEntity(trip); + tripIds.add(trip.getTopiaId()); + } + + } else { + + // ajout de toutes les marées non ouvertes + for (T trip : trips) { + trip.setProgram(program); + if (!trip.isOpen()) { + model.cacheEntity(trip); + tripIds.add(trip.getTopiaId()); + } + } + + } + + if (!tripIds.isEmpty()) { + + datas.put(program.getTopiaId(), tripIds); + if (log.isDebugEnabled()) { + log.debug("Add program " + program.getLabel1() + " with " + tripIds.size() + " trip(s)."); + } + + } + + } + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/ActivityLonglineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/ActivityLonglineServiceImpl.java new file mode 100644 index 0000000..6540b46 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/ActivityLonglineServiceImpl.java @@ -0,0 +1,145 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.constants.ReferenceLocale; +import fr.ird.observe.entities.longline.ActivityLongline; +import fr.ird.observe.entities.longline.ActivityLonglineDAO; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.services.AbstractObserveService; + +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/25/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ActivityLonglineServiceImpl extends AbstractObserveService implements ActivityLonglineService { + + @Override + public List<ActivityLongline> getActivityLonglineStubByTrip(String tripId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + List<ActivityLongline> result = getDao().findAllStubByTripId(tripId, referentielLocale); + return result; + + } + + @Override + public ActivityLongline getActivityLonglineStub(String activityId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + ActivityLongline result = getDao().findStubByTopiaId(activityId, referentielLocale); + return result; + + } + + @Override + public ActivityLongline loadForEdit(String activityLonglineId) { + + ActivityLongline loaded = getDao().newInstance(); + ActivityLongline toLoad = getDao().findByTopiaId(activityLonglineId); + copy(ActivityLongline.class, BinderService.EDIT, toLoad, loaded); + + return loaded; + + } + + + @Override + public ActivityLongline preCreate(String tripLonglineId) { + + TripLongline tripLongline = findByTopiaId(TripLongline.class, tripLonglineId); + + ActivityLongline preCreated = getDao().newInstance(); + + preCreated.setOpen(true); + + ActivityLongline lastActivityLongline = tripLongline.getLastActivity(); + + Date timestamp; + + if (lastActivityLongline == null) { + + // première activité, on utilise la date de début de marée (voir http://forge.codelutin.com/issues/6777) + Calendar calendar = Calendar.getInstance(); + calendar.setTime(tripLongline.getStartDate()); + timestamp = calendar.getTime(); + + } else { + + // passage en coordonnées absolue + quadrant + lastActivityLongline.initCoordinates(); + + // on recupère le quadrant de cette activity + // et on l'affecte à la nouvelle activity + Integer quadrant = lastActivityLongline.getQuadrant(); + + preCreated.setQuadrant(quadrant); + + // on reprend la date et l'heure de la dernière activité + timestamp = lastActivityLongline.getTimeStamp(); + } + + preCreated.setTimeStamp(timestamp); + + + return preCreated; + + } + + @Override + public String save(String tripLonglineId, ActivityLongline toSave) { + + String activityLonglineId = doSave(tripLonglineId, toSave, new SaveAction<TripLongline, ActivityLongline>(TripLongline.class, ActivityLongline.class) { + + @Override + public ActivityLongline onCreate(TripLongline parent, ActivityLongline toCreate) { + + Map<String, Object> properties = obtainProperties(ActivityLongline.class, BinderService.EDIT, toCreate); + ActivityLongline created = getDao().create(properties); + + parent.addActivityLongline(created); + return created; + } + + @Override + public ActivityLongline onUpdate(TripLongline parent, ActivityLongline toUpdate) { + + ActivityLongline updated = super.onUpdate(parent, toUpdate); + + copyExcluding(ActivityLongline.class, BinderService.EDIT, + toUpdate, updated, + ActivityLongline.PROPERTY_ENCOUNTER, + ActivityLongline.PROPERTY_SENSOR_USED); + return updated; + + } + }); + + return activityLonglineId; + + } + + @Override + public void delete(String tripLonglineId, String activityLonglineId) { + doDelete(tripLonglineId, activityLonglineId, new DeleteAction<TripLongline, ActivityLongline>(TripLongline.class, ActivityLongline.class) { + + @Override + public void onDelete(TripLongline parent, ActivityLongline toDelete) { + super.onDelete(parent, toDelete); + parent.removeActivityLongline(toDelete); + } + }); + + } + + protected ActivityLonglineDAO getDao() { + return (ActivityLonglineDAO) getDao(ActivityLongline.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/BaitsCompositionServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/BaitsCompositionServiceImpl.java new file mode 100644 index 0000000..4fc502e --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/BaitsCompositionServiceImpl.java @@ -0,0 +1,76 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.BaitsComposition; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/29/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class BaitsCompositionServiceImpl extends AbstractObserveService implements BaitsCompositionService { + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + SetLongline parentToLoad = findByTopiaId(SetLongline.class, setLonglineId); + + SetLongline parentLoaded = getDao(SetLongline.class).newInstance(); + + copy(SetLongline.class, BinderService.EDIT_BAITS_COMPOSITION, parentToLoad, parentLoaded); + + if (!parentToLoad.isBaitsCompositionEmpty()) { + + TopiaEntityBinder<BaitsComposition> binder = getBinder(BaitsComposition.class, BinderService.EDIT); + + TopiaDAO<BaitsComposition> childDao = getDao(BaitsComposition.class); + + List<BaitsComposition> childs = new ArrayList<BaitsComposition>(); + + for (BaitsComposition sourceChild : parentToLoad.getBaitsComposition()) { + + BaitsComposition targetChild = childDao.newInstance(); + + binder.load(sourceChild, targetChild, true); + + childs.add(targetChild); + + } + + parentLoaded.setBaitsComposition(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(SetLongline setLongline) { + + TopiaEntityBinder<SetLongline> parentBinder = getBinder(SetLongline.class, BinderService.EDIT_BAITS_COMPOSITION); + TopiaEntityBinder<BaitsComposition> childBinder = getBinder(BaitsComposition.class, BinderService.EDIT); + + doSaveList(setLongline, new SaveCollectionAction<SetLongline, BaitsComposition>( + SetLongline.class, BaitsComposition.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<SetLongline, BaitsComposition> getListUpdator() { + EntityListUpdator<SetLongline, BaitsComposition> listUpdator = EntityListUpdator.newEntityListUpdator( + SetLongline.class, + BaitsComposition.class, + SetLongline.PROPERTY_BAITS_COMPOSITION); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/BranchlinesCompositionServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/BranchlinesCompositionServiceImpl.java new file mode 100644 index 0000000..d8c933e --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/BranchlinesCompositionServiceImpl.java @@ -0,0 +1,72 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.BranchlinesComposition; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/29/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class BranchlinesCompositionServiceImpl extends AbstractObserveService implements BranchlinesCompositionService { + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + SetLongline parentToLoad = findByTopiaId(SetLongline.class, setLonglineId); + + SetLongline parentLoaded = getDao(SetLongline.class).newInstance(); + copy(SetLongline.class, BinderService.EDIT_BRANCHLINES_COMPOSITION, parentToLoad, parentLoaded); + + if (!parentToLoad.isBranchlinesCompositionEmpty()) { + + TopiaEntityBinder<BranchlinesComposition> binder = getBinder(BranchlinesComposition.class, BinderService.EDIT); + TopiaDAO<BranchlinesComposition> childDao = getDao(BranchlinesComposition.class); + + List<BranchlinesComposition> childs = new ArrayList<BranchlinesComposition>(); + + for (BranchlinesComposition sourceChild : parentToLoad.getBranchlinesComposition()) { + + BranchlinesComposition targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setBranchlinesComposition(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(SetLongline setLongline) { + + TopiaEntityBinder<SetLongline> parentBinder = getBinder(SetLongline.class, BinderService.EDIT_BRANCHLINES_COMPOSITION); + TopiaEntityBinder<BranchlinesComposition> childBinder = getBinder(BranchlinesComposition.class, BinderService.EDIT); + + doSaveList(setLongline, new SaveCollectionAction<SetLongline, BranchlinesComposition>( + SetLongline.class, BranchlinesComposition.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<SetLongline, BranchlinesComposition> getListUpdator() { + EntityListUpdator<SetLongline, BranchlinesComposition> listUpdator = EntityListUpdator.newEntityListUpdator( + SetLongline.class, + BranchlinesComposition.class, + SetLongline.PROPERTY_BRANCHLINES_COMPOSITION); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/CatchLonglineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/CatchLonglineServiceImpl.java new file mode 100644 index 0000000..511768d --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/CatchLonglineServiceImpl.java @@ -0,0 +1,245 @@ +package fr.ird.observe.services.data.longline; + +import com.google.common.collect.Lists; +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.longline.Branchline; +import fr.ird.observe.entities.longline.BranchlineDAO; +import fr.ird.observe.entities.longline.CatchLongline; +import fr.ird.observe.entities.longline.CatchLonglineDAO; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.entities.longline.SizeMeasure; +import fr.ird.observe.entities.longline.WeightMeasure; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.collections4.CollectionUtils; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class CatchLonglineServiceImpl extends AbstractObserveService implements CatchLonglineService { + + @Override + public Branchline loadBranchlineForEdit(String branchelineId) { + + BranchlineDAO dao = (BranchlineDAO) getDao(Branchline.class); + Branchline toLoad = dao.findByTopiaId(branchelineId); + Branchline loaded = dao.newInstance(); + copy(Branchline.class, BinderService.EDIT_CATCH_LONGLINE, toLoad, loaded); + return loaded; + + } + + @Override + public Branchline saveBranchline(Branchline toSave) { + + BranchlineDAO dao = (BranchlineDAO) getDao(Branchline.class); + Branchline saved = dao.findByTopiaId(toSave.getTopiaId()); + copy(Branchline.class, BinderService.EDIT_CATCH_LONGLINE, toSave, saved); + return saved; + + } + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + SetLongline parentToLoad = findByTopiaId(SetLongline.class, setLonglineId); + + SetLongline parentLoaded = getDao(SetLongline.class).newInstance(); + copy(SetLongline.class, BinderService.EDIT_CATCH_LONGLINE, parentToLoad, parentLoaded); + + if (!parentToLoad.isCatchLonglineEmpty()) { + + TopiaEntityBinder<CatchLongline> binder = getBinder(CatchLongline.class, BinderService.EDIT); + TopiaDAO<CatchLongline> childDao = getDao(CatchLongline.class); + + List<CatchLongline> childs = new ArrayList<CatchLongline>(); + + for (CatchLongline sourceChild : parentToLoad.getCatchLongline()) { + + CatchLongline targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setCatchLongline(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(SetLongline setLongline) { + + TopiaEntityBinder<SetLongline> parentBinder = getBinder(SetLongline.class, BinderService.EDIT_CATCH_LONGLINE); + TopiaEntityBinder<CatchLongline> childBinder = getBinder(CatchLongline.class, BinderService.EDIT); + + doSaveList(setLongline, + new SaveCollectionAction<SetLongline, CatchLongline>(SetLongline.class, + CatchLongline.class, + getListUpdator(), parentBinder, childBinder) { + + @Override + public CatchLongline onCreateChild(CatchLongline childToCreate) { + + CatchLongline childCreated = super.onCreateChild(childToCreate); + saveSizeMeasures(childCreated, childToCreate.getSizeMeasure()); + saveWeightMeasures(childCreated, childToCreate.getWeightMeasure()); + return childCreated; + + } + + @Override + public CatchLongline onUpdateChild(CatchLongline childToUpdate) { + + CatchLongline childUpdated = super.onUpdateChild(childToUpdate); + saveSizeMeasures(childUpdated, childToUpdate.getSizeMeasure()); + saveWeightMeasures(childUpdated, childToUpdate.getWeightMeasure()); + return childUpdated; + + } + + protected void saveSizeMeasures(CatchLongline childSaved, Collection<SizeMeasure> sizeMeasuresToSave) { + + List<SizeMeasure> sizeMeasuresSaveds = Lists.newArrayList(); + + if (CollectionUtils.isNotEmpty(sizeMeasuresToSave)) { + + TopiaDAO<SizeMeasure> dao = getDao(SizeMeasure.class); + TopiaEntityBinder<SizeMeasure> binder = getBinder(SizeMeasure.class, BinderService.EDIT); + + for (SizeMeasure sizeMeasureToSave : sizeMeasuresToSave) { + + SizeMeasure sizeMeasureSaved; + + if (Entities.isNew(sizeMeasureToSave)) { + + Map<String, Object> properties = binder.obtainProperties(sizeMeasureToSave); + sizeMeasureSaved = dao.create(properties); + + } else { + + sizeMeasureSaved = dao.findByTopiaId(sizeMeasureToSave.getTopiaId()); + binder.load(sizeMeasureToSave, sizeMeasureSaved, true); + + } + + sizeMeasuresSaveds.add(sizeMeasureSaved); + + } + + } + + childSaved.clearSizeMeasure(); + childSaved.addAllSizeMeasure(sizeMeasuresSaveds); + + } + + protected void saveWeightMeasures(CatchLongline childSaved, Collection<WeightMeasure> weightMeasuresToSave) { + + List<WeightMeasure> weightMeasuresSaved = Lists.newArrayList(); + + if (CollectionUtils.isNotEmpty(weightMeasuresToSave)) { + + TopiaDAO<WeightMeasure> dao = getDao(WeightMeasure.class); + TopiaEntityBinder<WeightMeasure> binder = getBinder(WeightMeasure.class, BinderService.EDIT); + + for (WeightMeasure weightMeasureToSave : weightMeasuresToSave) { + + WeightMeasure weightMeasureSaved; + + if (Entities.isNew(weightMeasureToSave)) { + + Map<String, Object> properties = binder.obtainProperties(weightMeasureToSave); + weightMeasureSaved = dao.create(properties); + + } else { + + weightMeasureSaved = dao.findByTopiaId(weightMeasureToSave.getTopiaId()); + binder.load(weightMeasureToSave, weightMeasureSaved, true); + + } + + weightMeasuresSaved.add(weightMeasureSaved); + + } + + } + + childSaved.clearWeightMeasure(); + childSaved.addAllWeightMeasure(weightMeasuresSaved); + + } + } + + ); + + } + + @Override + public List<SizeMeasure> getCatchLonglineSizeMeasures(String catchLonglineId) { + + CatchLongline catchLongline = getDao().findByTopiaId(catchLonglineId); + List<SizeMeasure> result = new ArrayList<SizeMeasure>(); + if (!catchLongline.isSizeMeasureEmpty()) { + + TopiaEntityBinder<SizeMeasure> binder = getBinder(SizeMeasure.class, BinderService.EDIT); + TopiaDAO<SizeMeasure> sizeMeasureDao = getDao(SizeMeasure.class); + + for (SizeMeasure sizeSource : catchLongline.getSizeMeasure()) { + SizeMeasure target = sizeMeasureDao.newInstance(); + binder.load(sizeSource, target, true); + result.add(target); + } + } + return result; + + } + + @Override + public List<WeightMeasure> getCatchLonglineWeightMeasures(String catchLonglineId) { + + CatchLongline catchLongline = getDao().findByTopiaId(catchLonglineId); + List<WeightMeasure> result = new ArrayList<WeightMeasure>(); + if (!catchLongline.isWeightMeasureEmpty()) { + + TopiaEntityBinder<WeightMeasure> binder = getBinder(WeightMeasure.class, BinderService.EDIT); + TopiaDAO<WeightMeasure> weightMeasureDao = getDao(WeightMeasure.class); + + for (WeightMeasure weightSource : catchLongline.getWeightMeasure()) { + WeightMeasure target = weightMeasureDao.newInstance(); + binder.load(weightSource, target, true); + result.add(target); + } + + } + + return result; + + } + + protected CatchLonglineDAO getDao() { + return (CatchLonglineDAO) getDao(CatchLongline.class); + } + + protected EntityListUpdator<SetLongline, CatchLongline> getListUpdator() { + EntityListUpdator<SetLongline, CatchLongline> listUpdator = EntityListUpdator.newEntityListUpdator( + SetLongline.class, + CatchLongline.class, + SetLongline.PROPERTY_CATCH_LONGLINE); + return listUpdator; + } +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/EncounterServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/EncounterServiceImpl.java new file mode 100644 index 0000000..eaaa8ee --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/EncounterServiceImpl.java @@ -0,0 +1,72 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.ActivityLongline; +import fr.ird.observe.entities.longline.Encounter; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/29/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class EncounterServiceImpl extends AbstractObserveService implements EncounterService { + + @Override + public ActivityLongline loadForEdit(String activityLonglineId) { + + ActivityLongline parentToLoad = findByTopiaId(ActivityLongline.class, activityLonglineId); + + ActivityLongline parentLoaded = getDao(ActivityLongline.class).newInstance(); + copy(ActivityLongline.class, BinderService.EDIT_ENCOUNTER, parentToLoad, parentLoaded); + + if (!parentToLoad.isEncounterEmpty()) { + + TopiaEntityBinder<Encounter> binder = getBinder(Encounter.class, BinderService.EDIT); + TopiaDAO<Encounter> childDao = getDao(Encounter.class); + + List<Encounter> childs = new ArrayList<Encounter>(); + + for (Encounter sourceChild : parentToLoad.getEncounter()) { + + Encounter targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setEncounter(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(ActivityLongline activityLongline) { + + TopiaEntityBinder<ActivityLongline> parentBinder = getBinder(ActivityLongline.class, BinderService.EDIT_ENCOUNTER); + TopiaEntityBinder<Encounter> childBinder = getBinder(Encounter.class, BinderService.EDIT); + + doSaveList(activityLongline, new SaveCollectionAction<ActivityLongline, Encounter>( + ActivityLongline.class, Encounter.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<ActivityLongline, Encounter> getListUpdator() { + EntityListUpdator<ActivityLongline, Encounter> listUpdator = EntityListUpdator.newEntityListUpdator( + ActivityLongline.class, + Encounter.class, + ActivityLongline.PROPERTY_ENCOUNTER); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/FloatlinesCompositionServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/FloatlinesCompositionServiceImpl.java new file mode 100644 index 0000000..07f8d26 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/FloatlinesCompositionServiceImpl.java @@ -0,0 +1,72 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.FloatlinesComposition; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/29/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class FloatlinesCompositionServiceImpl extends AbstractObserveService implements FloatlinesCompositionService { + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + SetLongline parentToLoad = findByTopiaId(SetLongline.class, setLonglineId); + + SetLongline parentLoaded = getDao(SetLongline.class).newInstance(); + copy(SetLongline.class, BinderService.EDIT_FLOATLINES_COMPOSITION, parentToLoad, parentLoaded); + + if (!parentToLoad.isFloatlinesCompositionEmpty()) { + + TopiaEntityBinder<FloatlinesComposition> binder = getBinder(FloatlinesComposition.class, BinderService.EDIT); + TopiaDAO<FloatlinesComposition> childDao = getDao(FloatlinesComposition.class); + + List<FloatlinesComposition> childs = new ArrayList<FloatlinesComposition>(); + + for (FloatlinesComposition sourceChild : parentToLoad.getFloatlinesComposition()) { + + FloatlinesComposition targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setFloatlinesComposition(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(SetLongline setLongline) { + + TopiaEntityBinder<SetLongline> parentBinder = getBinder(SetLongline.class, BinderService.EDIT_FLOATLINES_COMPOSITION); + TopiaEntityBinder<FloatlinesComposition> childBinder = getBinder(FloatlinesComposition.class, BinderService.EDIT); + + doSaveList(setLongline, new SaveCollectionAction<SetLongline, FloatlinesComposition>( + SetLongline.class, FloatlinesComposition.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<SetLongline, FloatlinesComposition> getListUpdator() { + EntityListUpdator<SetLongline, FloatlinesComposition> listUpdator = EntityListUpdator.newEntityListUpdator( + SetLongline.class, + FloatlinesComposition.class, + SetLongline.PROPERTY_FLOATLINES_COMPOSITION); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/GearUseFeaturesLonglineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/GearUseFeaturesLonglineServiceImpl.java new file mode 100644 index 0000000..ec780c6 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/GearUseFeaturesLonglineServiceImpl.java @@ -0,0 +1,214 @@ +package fr.ird.observe.services.data.longline; + +import com.google.common.collect.Lists; +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.longline.GearUseFeaturesLongline; +import fr.ird.observe.entities.longline.GearUseFeaturesMeasurementLongline; +import fr.ird.observe.entities.longline.GearUseFeaturesMeasurementLonglineDAO; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.entities.referentiel.Gear; +import fr.ird.observe.entities.referentiel.GearCaracteristic; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.collections4.CollectionUtils; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class GearUseFeaturesLonglineServiceImpl extends AbstractObserveService implements GearUseFeaturesLonglineService { + + @Override + public List<GearUseFeaturesMeasurementLongline> getDefaultGearUseFeaturesMeasurementLongline(String gearId) { + + Gear gear = findByTopiaId(Gear.class, gearId); + + List<GearUseFeaturesMeasurementLongline> result = new ArrayList<GearUseFeaturesMeasurementLongline>(); + + if (gear.isGearCaracteristicEmpty()) { + + GearUseFeaturesMeasurementLonglineDAO dao = getDao(); + + for (GearCaracteristic caracteristic : gear.getGearCaracteristic()) { + + GearUseFeaturesMeasurementLongline target = dao.newInstance(); + target.setGearCaracteristic(caracteristic); + result.add(target); + + } + + } + + return result; + + } + + @Override + public List<GearUseFeaturesMeasurementLongline> loadGearUseFeaturesMeasurementLonglineForEdit(String gearUseFeaturesLonglineId) { + + GearUseFeaturesLongline gearUseFeaturesLongline = findByTopiaId(GearUseFeaturesLongline.class, gearUseFeaturesLonglineId); + List<GearUseFeaturesMeasurementLongline> result = new ArrayList<GearUseFeaturesMeasurementLongline>(); + + if (!gearUseFeaturesLongline.isGearUseFeaturesMeasurementEmpty()) { + + GearUseFeaturesMeasurementLonglineDAO dao = getDao(); + TopiaEntityBinder<GearUseFeaturesMeasurementLongline> binder = getBinder(GearUseFeaturesMeasurementLongline.class, BinderService.EDIT); + + for (GearUseFeaturesMeasurementLongline measurementSource : gearUseFeaturesLongline.getGearUseFeaturesMeasurement()) { + + GearUseFeaturesMeasurementLongline target = dao.newInstance(); + measurementSource.getGearCaracteristic().getGearCaracteristicType(); + binder.load(measurementSource, target, true); + result.add(target); + + } + + } + + return result; + + } + + @Override + public TripLongline loadForEdit(String tripLonglineId) { + + TripLongline toLoad = findByTopiaId(TripLongline.class, tripLonglineId); + + TripLongline loaded = getDao(TripLongline.class).newInstance(); + copy(TripLongline.class, BinderService.EDIT_GEAR_USE_FEATURES_LONGLINE, toLoad, loaded); + + if (!toLoad.isGearUseFeaturesLonglineEmpty()) { + + TopiaDAO<GearUseFeaturesLongline> childDao = getDao(GearUseFeaturesLongline.class); + TopiaDAO<GearUseFeaturesMeasurementLongline> measurementDao = getDao(GearUseFeaturesMeasurementLongline.class); + TopiaEntityBinder<GearUseFeaturesLongline> childBinder = getBinder(GearUseFeaturesLongline.class, BinderService.EDIT); + TopiaEntityBinder<GearUseFeaturesMeasurementLongline> measurementBinder = getBinder(GearUseFeaturesMeasurementLongline.class, BinderService.EDIT); + + List<GearUseFeaturesLongline> childsLoaded = new ArrayList<GearUseFeaturesLongline>(); + + if (!toLoad.isGearUseFeaturesLonglineEmpty()) { + + for (GearUseFeaturesLongline childToLoad : toLoad.getGearUseFeaturesLongline()) { + + GearUseFeaturesLongline childLoaded = childDao.newInstance(); + childBinder.load(childToLoad, childLoaded, true); + childsLoaded.add(childLoaded); + + if (!childToLoad.isGearUseFeaturesMeasurementEmpty()) { + + List<GearUseFeaturesMeasurementLongline> measurementsLoaded = new ArrayList<GearUseFeaturesMeasurementLongline>(); + + for (GearUseFeaturesMeasurementLongline measurementToLoad : childToLoad.getGearUseFeaturesMeasurement()) { + + GearUseFeaturesMeasurementLongline measurementLoaded = measurementDao.newInstance(); + measurementBinder.load(measurementToLoad, measurementLoaded, true); + measurementsLoaded.add(measurementLoaded); + + } + + childLoaded.setGearUseFeaturesMeasurement(measurementsLoaded); + + } + + } + + } + + loaded.setGearUseFeaturesLongline(childsLoaded); + + } + + return loaded; + + } + + @Override + public void save(TripLongline tripLongline) { + + TopiaEntityBinder<TripLongline> parentBinder = getBinder(TripLongline.class, BinderService.EDIT_GEAR_USE_FEATURES_LONGLINE); + TopiaEntityBinder<GearUseFeaturesLongline> childBinder = getBinder(GearUseFeaturesLongline.class, BinderService.EDIT); + + doSaveList(tripLongline, new SaveCollectionAction<TripLongline, GearUseFeaturesLongline>( + TripLongline.class, GearUseFeaturesLongline.class, getListUpdator(), parentBinder, childBinder) { + + @Override + public GearUseFeaturesLongline onCreateChild(GearUseFeaturesLongline childToCreate) { + + GearUseFeaturesLongline childCreated = super.onCreateChild(childToCreate); + saveMeasurement(childCreated, childToCreate.getGearUseFeaturesMeasurement()); + return childCreated; + + } + + @Override + public GearUseFeaturesLongline onUpdateChild(GearUseFeaturesLongline childToUpdate) { + + GearUseFeaturesLongline childUpdated = super.onUpdateChild(childToUpdate); + saveMeasurement(childUpdated, childToUpdate.getGearUseFeaturesMeasurement()); + return childUpdated; + + } + + protected void saveMeasurement(GearUseFeaturesLongline childSaved, List<GearUseFeaturesMeasurementLongline> measurementsToSave) { + + List<GearUseFeaturesMeasurementLongline> measurementsSaved = Lists.newArrayList(); + + if (CollectionUtils.isNotEmpty(measurementsToSave)) { + + TopiaDAO<GearUseFeaturesMeasurementLongline> dao = getDao(GearUseFeaturesMeasurementLongline.class); + TopiaEntityBinder<GearUseFeaturesMeasurementLongline> binder = getBinder(GearUseFeaturesMeasurementLongline.class, BinderService.EDIT); + + for (GearUseFeaturesMeasurementLongline measurementToSave : measurementsToSave) { + + GearUseFeaturesMeasurementLongline measurementSaved; + + if (Entities.isNew(measurementToSave)) { + + Map<String, Object> properties = binder.obtainProperties(measurementToSave); + measurementSaved = dao.create(properties); + + } else { + + measurementSaved = dao.findByTopiaId(measurementToSave.getTopiaId()); + binder.load(measurementToSave, measurementSaved, true); + + } + + measurementsSaved.add(measurementSaved); + + } + + } + + childSaved.clearGearUseFeaturesMeasurement(); + childSaved.addAllGearUseFeaturesMeasurement(measurementsSaved); + + } + + + }); + + } + + protected GearUseFeaturesMeasurementLonglineDAO getDao() { + return (GearUseFeaturesMeasurementLonglineDAO) getDao(GearUseFeaturesMeasurementLongline.class); + } + + protected EntityListUpdator<TripLongline, GearUseFeaturesLongline> getListUpdator() { + EntityListUpdator<TripLongline, GearUseFeaturesLongline> listUpdator = EntityListUpdator.newEntityListUpdator( + TripLongline.class, + GearUseFeaturesLongline.class, + TripLongline.PROPERTY_GEAR_USE_FEATURES_LONGLINE); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/HooksCompositionServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/HooksCompositionServiceImpl.java new file mode 100644 index 0000000..043b3dc --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/HooksCompositionServiceImpl.java @@ -0,0 +1,72 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.HooksComposition; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/29/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class HooksCompositionServiceImpl extends AbstractObserveService implements HooksCompositionService { + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + SetLongline parentToLoad = findByTopiaId(SetLongline.class, setLonglineId); + + SetLongline parentLoaded = getDao(SetLongline.class).newInstance(); + copy(SetLongline.class, BinderService.EDIT_HOOKS_COMPOSITION, parentToLoad, parentLoaded); + + if (!parentToLoad.isHooksCompositionEmpty()) { + + TopiaEntityBinder<HooksComposition> binder = getBinder(HooksComposition.class, BinderService.EDIT); + TopiaDAO<HooksComposition> childDao = getDao(HooksComposition.class); + + List<HooksComposition> childs = new ArrayList<HooksComposition>(); + + for (HooksComposition sourceChild : parentToLoad.getHooksComposition()) { + + HooksComposition targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setHooksComposition(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(SetLongline setLongline) { + + TopiaEntityBinder<SetLongline> parentBinder = getBinder(SetLongline.class, BinderService.EDIT_HOOKS_COMPOSITION); + TopiaEntityBinder<HooksComposition> childBinder = getBinder(HooksComposition.class, BinderService.EDIT); + + doSaveList(setLongline, new SaveCollectionAction<SetLongline, HooksComposition>( + SetLongline.class, HooksComposition.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<SetLongline, HooksComposition> getListUpdator() { + EntityListUpdator<SetLongline, HooksComposition> listUpdator = EntityListUpdator.newEntityListUpdator( + SetLongline.class, + HooksComposition.class, + SetLongline.PROPERTY_HOOKS_COMPOSITION); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/LonglineDetailCompositionServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/LonglineDetailCompositionServiceImpl.java new file mode 100644 index 0000000..b256d17 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/LonglineDetailCompositionServiceImpl.java @@ -0,0 +1,191 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.longline.Basket; +import fr.ird.observe.entities.longline.Branchline; +import fr.ird.observe.entities.longline.Section; +import fr.ird.observe.entities.longline.SectionWithTemplate; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class LonglineDetailCompositionServiceImpl extends AbstractObserveService implements LonglineDetailCompositionService { + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + TopiaDAO<SetLongline> dao = getDao(SetLongline.class); + SetLongline toLoad = dao.findByTopiaId(setLonglineId); + SetLongline loaded = dao.newInstance(); + copy(SetLongline.class, BinderService.EDIT_DETAIL_COMPOSITION, toLoad, loaded); + + return loaded; + + } + + @Override + public void save(SetLongline toSave, List<SectionWithTemplate> sections) { + + SetLongline saved = findByTopiaId(SetLongline.class, toSave.getTopiaId()); + + copyExcluding(SetLongline.class, BinderService.EDIT_DETAIL_COMPOSITION, toSave, saved, SetLongline.PROPERTY_SECTION); + + TopiaDAO<Section> sectionsDao = getDao(Section.class); + TopiaDAO<Basket> basketDao = getDao(Basket.class); + TopiaDAO<Branchline> branchlineDao = getDao(Branchline.class); + + TopiaEntityBinder<Section> sectionBinder = getBinder(Section.class, BinderService.EDIT_DETAIL_COMPOSITION); + TopiaEntityBinder<Basket> basketBinder = getBinder(Basket.class, BinderService.EDIT_DETAIL_COMPOSITION); + TopiaEntityBinder<Branchline> branchlineBinder = getBinder(Branchline.class, BinderService.EDIT_DETAIL_COMPOSITION); + + List<Section> sectionsToSave = new ArrayList<Section>(); + + for (SectionWithTemplate section : sections) { + + Section sectionToSave = persistSection(sectionBinder, + basketBinder, + branchlineBinder, + sectionsDao, + basketDao, + branchlineDao, + section); + sectionsToSave.add(sectionToSave); + sectionToSave.setSetLongline(saved); + + } + + saved.clearSection(); + saved.addAllSection(sectionsToSave); + + } + + protected Section persistSection(TopiaEntityBinder<Section> sectionBinder, + TopiaEntityBinder<Basket> basketBinder, + TopiaEntityBinder<Branchline> branchlineBinder, + TopiaDAO<Section> sectionsDao, + TopiaDAO<Basket> basketDao, + TopiaDAO<Branchline> branchlineDao, + Section section) throws TopiaException { + + Section sectionToSave; + + if (Entities.isNew(section)) { + + // create + sectionToSave = sectionsDao.create( + Section.PROPERTY_SETTING_IDENTIFIER, section.getSettingIdentifier(), + Section.PROPERTY_HAULING_IDENTIFIER, section.getHaulingIdentifier()); + + } else { + + sectionToSave = sectionsDao.findByTopiaId(section.getTopiaId()); + + } + + sectionBinder.copyExcluding(section, sectionToSave, Section.PROPERTY_BASKET); + + Map<String, Basket> existingBasketsByTopiaId = Entities.toIdMap(sectionToSave.getBasket()); + + List<Basket> baskets = section.getBasket(); + sectionToSave.clearBasket(); + + for (Basket basket : baskets) { + + Basket basketToSave = persistBasket(basketBinder, + branchlineBinder, + basketDao, + branchlineDao, + existingBasketsByTopiaId, + basket); + sectionToSave.addBasket(basketToSave); + + } + + return sectionToSave; + + } + + protected Basket persistBasket(TopiaEntityBinder<Basket> basketBinder, + TopiaEntityBinder<Branchline> branchlineBinder, + TopiaDAO<Basket> basketDao, + TopiaDAO<Branchline> branchlineDao, + Map<String, Basket> existingBasketsByTopiaId, + Basket basket) throws TopiaException { + + Basket basketToSave; + + if (Entities.isNew(basket)) { + + // create + basketToSave = basketDao.create( + Basket.PROPERTY_SETTING_IDENTIFIER, basket.getSettingIdentifier(), + Basket.PROPERTY_HAULING_IDENTIFIER, basket.getHaulingIdentifier()); + + } else { + + basketToSave = existingBasketsByTopiaId.get(basket.getTopiaId()); + + } + + basketBinder.copyExcluding(basket, basketToSave, Basket.PROPERTY_BRANCHLINE); + + Map<String, Branchline> existingBranchlinesByTopiaId = Entities.toIdMap(basketToSave.getBranchline()); + + basketToSave.clearBranchline(); + + List<Branchline> branchlines = basket.getBranchline(); + + for (Branchline branchline : branchlines) { + + Branchline branchlineToSave = persistBranchline(branchlineBinder, + branchlineDao, + existingBranchlinesByTopiaId, + branchline); + basketToSave.addBranchline(branchlineToSave); + + } + + return basketToSave; + + } + + protected Branchline persistBranchline(TopiaEntityBinder<Branchline> branchlineBinder, + TopiaDAO<Branchline> branchlineDao, + Map<String, Branchline> existingBranchlinesByTopiaId, + Branchline branchline) throws TopiaException { + + Branchline branchlineToSave; + + if (Entities.isNew(branchline)) { + + // create + branchlineToSave = branchlineDao.create( + Branchline.PROPERTY_SETTING_IDENTIFIER, branchline.getSettingIdentifier(), + Branchline.PROPERTY_HAULING_IDENTIFIER, branchline.getHaulingIdentifier()); + + } else { + + branchlineToSave = existingBranchlinesByTopiaId.get(branchline.getTopiaId()); + + } + + branchlineBinder.copy(branchline, branchlineToSave); + + return branchlineToSave; + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/LonglineGlobalCompositionServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/LonglineGlobalCompositionServiceImpl.java new file mode 100644 index 0000000..3785293 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/LonglineGlobalCompositionServiceImpl.java @@ -0,0 +1,65 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.entities.referentiel.longline.MitigationType; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + * @since 4.0 + */ +public class LonglineGlobalCompositionServiceImpl extends AbstractObserveService implements LonglineGlobalCompositionService { + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + TopiaDAO<SetLongline> dao = getDao(SetLongline.class); + SetLongline toLoad = dao.findByTopiaId(setLonglineId); + SetLongline loaded = dao.newInstance(); + copy(SetLongline.class, BinderService.EDIT_GLOBAL_COMPOSITION, toLoad, loaded); + + return loaded; + + } + + @Override + public String save(SetLongline toSave) { + + SetLongline saved = findByTopiaId(SetLongline.class, toSave.getTopiaId()); + + copyExcluding(SetLongline.class, BinderService.EDIT_GLOBAL_COMPOSITION, toSave, saved, SetLongline.PROPERTY_MITIGATION_TYPE); + + Collection<MitigationType> mitigationTypesSaved = new ArrayList<MitigationType>(); + + if (!toSave.isMitigationTypeEmpty()) { + + TopiaDAO<MitigationType> dao = getDao(MitigationType.class); + + for (MitigationType mitigationTypeToSave : toSave.getMitigationType()) { + + MitigationType mitigationTypeSaved = dao.findByTopiaId(mitigationTypeToSave.getTopiaId()); + mitigationTypesSaved.add(mitigationTypeSaved); + + } + } + + saved.clearMitigationType(); + saved.addAllMitigationType(mitigationTypesSaved); + + getDao(SetLongline.class).update(saved); + + newService(FloatlinesCompositionService.class).save(toSave); + newService(BranchlinesCompositionService.class).save(toSave); + newService(HooksCompositionService.class).save(toSave); + newService(BaitsCompositionService.class).save(toSave); + + return saved.getTopiaId(); + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/SensorUsedServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/SensorUsedServiceImpl.java new file mode 100644 index 0000000..d10093c --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/SensorUsedServiceImpl.java @@ -0,0 +1,107 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.ActivityLongline; +import fr.ird.observe.entities.longline.SensorUsed; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.entities.longline.TripLonglineDAO; +import fr.ird.observe.entities.referentiel.longline.SensorType; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class SensorUsedServiceImpl extends AbstractObserveService implements SensorUsedService { + + @Override + public String getSensorUsedDataFilename(SensorUsed sensorUsed) { + + TripLonglineDAO tripDao = (TripLonglineDAO) getDao(TripLongline.class); + TripLongline tripLongline = tripDao.findByOpen(true); + + StringBuilder filenameBuilder = new StringBuilder("sensorData"); + String code = tripLongline.getVessel().getCode(); + filenameBuilder.append("-").append(code); + + Date startDate = tripLongline.getStartDate(); + filenameBuilder.append("-").append(new SimpleDateFormat("yyyy.MM.dd").format(startDate)); + + SensorType sensorType = sensorUsed.getSensorType(); + if (sensorType != null && sensorType.getCode() != null) { + filenameBuilder.append("-").append(sensorType.getCode()); + } + + String sensorSerialNo = sensorUsed.getSensorSerialNo(); + if (sensorSerialNo != null) { + filenameBuilder.append("-").append(sensorSerialNo); + } + filenameBuilder.append("-").append(sensorUsed.getDataFilename()); + + String filename = filenameBuilder.toString(); + return filename; + + } + + + @Override + public ActivityLongline loadForEdit(String activityLonglineId) { + + ActivityLongline parentToLoad = findByTopiaId(ActivityLongline.class, activityLonglineId); + + ActivityLongline parentLoaded = getDao(ActivityLongline.class).newInstance(); + copy(ActivityLongline.class, BinderService.EDIT_SENSOR_USED, parentToLoad, parentLoaded); + + if (!parentToLoad.isSensorUsedEmpty()) { + + TopiaEntityBinder<SensorUsed> binder = getBinder(SensorUsed.class, BinderService.EDIT); + TopiaDAO<SensorUsed> childDao = getDao(SensorUsed.class); + + List<SensorUsed> childs = new ArrayList<SensorUsed>(); + + for (SensorUsed sourceChild : parentToLoad.getSensorUsed()) { + + SensorUsed targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setSensorUsed(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(ActivityLongline activityLongline) { + + TopiaEntityBinder<ActivityLongline> parentBinder = getBinder(ActivityLongline.class, BinderService.EDIT_SENSOR_USED); + TopiaEntityBinder<SensorUsed> childBinder = getBinder(SensorUsed.class, BinderService.EDIT); + + doSaveList(activityLongline, new SaveCollectionAction<ActivityLongline, SensorUsed>( + ActivityLongline.class, SensorUsed.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<ActivityLongline, SensorUsed> getListUpdator() { + EntityListUpdator<ActivityLongline, SensorUsed> listUpdator = EntityListUpdator.newEntityListUpdator( + ActivityLongline.class, + SensorUsed.class, + ActivityLongline.PROPERTY_SENSOR_USED); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/SetLonglineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/SetLonglineServiceImpl.java new file mode 100644 index 0000000..7f7c1aa --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/SetLonglineServiceImpl.java @@ -0,0 +1,179 @@ +package fr.ird.observe.services.data.longline; + +import com.google.common.collect.Lists; +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.ActivityLongline; +import fr.ird.observe.entities.longline.Basket; +import fr.ird.observe.entities.longline.Branchline; +import fr.ird.observe.entities.longline.Section; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.entities.longline.SetLonglineDAO; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.lang3.time.DateUtils; +import org.nuiton.topia.persistence.TopiaDAO; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class SetLonglineServiceImpl extends AbstractObserveService implements SetLonglineService { + + public List<Section> getSections(String setLonglineId) { + + TopiaDAO<Section> dao = getDao(Section.class); + + List<Section> sectionsSaved = dao.findAllByProperties(Section.PROPERTY_SET_LONGLINE + "." + Section.TOPIA_ID, setLonglineId); + + List<Section> sections = Lists.newLinkedList(); + + for (Section sectionSaved : sectionsSaved) { + + Section section = dao.newInstance(); + + copyExcluding(Section.class, BinderService.EDIT_DETAIL_COMPOSITION, sectionSaved, section, Section.PROPERTY_BASKET); + + for (Basket basketSaved : sectionSaved.getBasket()) { + + Basket basket = getDao(Basket.class).newInstance(); + + copyExcluding(Basket.class, BinderService.EDIT_DETAIL_COMPOSITION, basketSaved, basket, Basket.PROPERTY_BRANCHLINE); + + for (Branchline branchlineSaved : basketSaved.getBranchline()) { + + Branchline branchline = getDao(Branchline.class).newInstance(); + + copy(Branchline.class, BinderService.EDIT_DETAIL_COMPOSITION, branchlineSaved, branchline); + + basket.addBranchline(branchline); + + } + + section.addBasket(basket); + + } + + sections.add(section); + } + + return sections; + + } + + @Override + public SetLongline loadForDisplay(String setLonglineId) { + + SetLonglineDAO dao = getDao(); + + SetLongline loaded = dao.newInstance(); + SetLongline toLoad = dao.findByTopiaId(setLonglineId); + copy(SetLongline.class, BinderService.EDIT, toLoad, loaded); + return loaded; + + } + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + SetLonglineDAO dao = getDao(); + + SetLongline loaded = dao.newInstance(); + SetLongline toLoad = dao.findByTopiaId(setLonglineId); + copy(SetLongline.class, BinderService.EDIT, toLoad, loaded); + return loaded; + + } + + @Override + public SetLongline preCreate(String activityLonglineId) { + + ActivityLongline activityLongline = findByTopiaId(ActivityLongline.class, activityLonglineId); + + SetLongline preCreated = getDao().newInstance(); + + // on utilise la date - heure de l'activité pour initialiser les horodatages + // de l'opération de peche + Date timeStamp = activityLongline.getTimeStamp(); + preCreated.setSettingStartTimeStamp(timeStamp); + preCreated.setSettingEndTimeStamp(DateUtils.addHours(timeStamp, 1)); + preCreated.setHaulingStartTimeStamp(DateUtils.addHours(timeStamp, 2)); + preCreated.setHaulingEndTimeStamp(DateUtils.addHours(timeStamp, 3)); + + // on reporte la position de l'activité pour la position de début de filage + Float latitude = activityLongline.getLatitude(); + Float longitude = activityLongline.getLongitude(); + + // On enregistre deux fois les coordonnées car la première fois on perd le signe à cause de l'éditeur + preCreated.setSettingStartLatitude(latitude); + preCreated.setSettingStartLongitude(longitude); + preCreated.setSettingStartLatitude(latitude); + preCreated.setSettingStartLongitude(longitude); + + return preCreated; + + } + + @Override + public String save(String activityLonglineId, SetLongline setLongline) { + + String setLonglineId = doSave(activityLonglineId, setLongline, new SaveAction<ActivityLongline, SetLongline>(ActivityLongline.class, SetLongline.class) { + + @Override + public SetLongline onCreate(ActivityLongline parent, SetLongline toCreate) { + + Map<String, Object> properties = obtainProperties(SetLongline.class, BinderService.EDIT, toCreate); + SetLongline created = getDao().create(properties); + parent.setSetLongline(created); + + return created; + } + + @Override + public SetLongline onUpdate(ActivityLongline parent, SetLongline toUpdate) { + + SetLongline updated = super.onUpdate(parent, toUpdate); + + copyExcluding(SetLongline.class, BinderService.EDIT, + toUpdate, updated, + SetLongline.PROPERTY_BAITS_COMPOSITION, + SetLongline.PROPERTY_FLOATLINES_COMPOSITION, + SetLongline.PROPERTY_HOOKS_COMPOSITION, + SetLongline.PROPERTY_BRANCHLINES_COMPOSITION, + SetLongline.PROPERTY_SECTION, + SetLongline.PROPERTY_CATCH_LONGLINE, + SetLongline.PROPERTY_MITIGATION_TYPE, + SetLongline.PROPERTY_TDR); + return updated; + + } + }); + + return setLonglineId; + + } + + @Override + public void delete(String activityLonglineId, String setLonglineId) { + + // on doit supprimer physiquement la set + // car il n'y a pas de delete-orphan sur une telle relation + SetLonglineDAO dao = getDao(); + SetLongline setsetLongline = dao.findByTopiaId(setLonglineId); + dao.delete(setsetLongline); + + // supprime la reference sur l'activite + ActivityLongline activitySeine = findByTopiaId(ActivityLongline.class, activityLonglineId); + activitySeine.setSetLongline(null); + + } + + protected SetLonglineDAO getDao() { + return (SetLonglineDAO) getDao(SetLongline.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/TdrServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/TdrServiceImpl.java new file mode 100644 index 0000000..e59f6d6 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/TdrServiceImpl.java @@ -0,0 +1,105 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.longline.SetLongline; +import fr.ird.observe.entities.longline.Tdr; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.entities.longline.TripLonglineDAO; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class TdrServiceImpl extends AbstractObserveService implements TdrService { + + public String getTdrDataFilename(Tdr tdr) { + + TripLonglineDAO tripDao = (TripLonglineDAO) getDao(TripLongline.class); + TripLongline tripLongline = tripDao.findByOpen(true); + + StringBuilder filenameBuilder = new StringBuilder("tdr"); + String code = tripLongline.getVessel().getCode(); + filenameBuilder.append("-").append(code); + + Date startDate = tripLongline.getStartDate(); + filenameBuilder.append("-").append(new SimpleDateFormat("yyyy.MM.dd").format(startDate)); + + String homeId = tdr.getHomeId(); + if (homeId != null) { + filenameBuilder.append("-").append(homeId); + } + + String serialNo = tdr.getSerialNo(); + if (serialNo != null) { + filenameBuilder.append("-").append(serialNo); + } + filenameBuilder.append("-").append(tdr.getDataFilename()); + + String filename = filenameBuilder.toString(); + return filename; + + + } + + @Override + public SetLongline loadForEdit(String setLonglineId) { + + SetLongline parentToLoad = findByTopiaId(SetLongline.class, setLonglineId); + + SetLongline parentLoaded = getDao(SetLongline.class).newInstance(); + copy(SetLongline.class, BinderService.EDIT_TDR, parentToLoad, parentLoaded); + + if (!parentToLoad.isTdrEmpty()) { + + TopiaEntityBinder<Tdr> binder = getBinder(Tdr.class, BinderService.EDIT); + TopiaDAO<Tdr> childDao = getDao(Tdr.class); + + List<Tdr> childs = new ArrayList<Tdr>(); + + for (Tdr sourceChild : parentToLoad.getTdr()) { + + Tdr targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setTdr(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(SetLongline setLongline) { + + TopiaEntityBinder<SetLongline> parentBinder = getBinder(SetLongline.class, BinderService.EDIT_TDR); + TopiaEntityBinder<Tdr> childBinder = getBinder(Tdr.class, BinderService.EDIT); + + doSaveList(setLongline, new SaveCollectionAction<SetLongline, Tdr>( + SetLongline.class, Tdr.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<SetLongline, Tdr> getListUpdator() { + EntityListUpdator<SetLongline, Tdr> listUpdator = EntityListUpdator.newEntityListUpdator( + SetLongline.class, + Tdr.class, + SetLongline.PROPERTY_TDR); + return listUpdator; + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/TripLonglineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/TripLonglineServiceImpl.java new file mode 100644 index 0000000..6c505ca --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/longline/TripLonglineServiceImpl.java @@ -0,0 +1,136 @@ +package fr.ird.observe.services.data.longline; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.constants.ReferenceLocale; +import fr.ird.observe.entities.longline.ActivityLonglines; +import fr.ird.observe.entities.longline.TripLongline; +import fr.ird.observe.entities.longline.TripLonglineDAO; +import fr.ird.observe.entities.referentiel.Program; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.util.DateUtil; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class TripLonglineServiceImpl extends AbstractObserveService implements TripLonglineService { + + @Override + public List<TripLongline> getTripLonglineStubByProgram(String programId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + List<TripLongline> result = getDao().findAllStubByProgramId(programId, referentielLocale); + return result; + + } + + @Override + public TripLongline getTripLonglineStub(String tripId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + TripLongline result = getDao().findStubByTopiaId(tripId, referentielLocale); + return result; + + } + + @Override + public TripLongline loadForDisplay(String tripLonglineId) { + + TripLongline loaded = getDao().newInstance(); + TripLongline toLoad = getDao().findByTopiaId(tripLonglineId); + copy(TripLongline.class, BinderService.EDIT, toLoad, loaded); + + if (!loaded.isActivityLonglineEmpty()) { + + // on force le trie des routes + ActivityLonglines.sort(loaded.getActivityLongline()); + + } + + return loaded; + + } + + @Override + public TripLongline loadForEdit(String tripLonglineId) { + + TripLongline loaded = loadForDisplay(tripLonglineId); + + if (loaded.getEndDate() == null) { + Date date = DateUtil.getEndOfDay(now()); + loaded.setEndDate(date); + } + + return loaded; + + } + + @Override + public TripLongline preCreate(String programId) { + + Program program = findByTopiaId(Program.class, programId); + + TripLongline preCreated = getDao().newInstance(); + + Date date = DateUtil.getDay(now()); + preCreated.setStartDate(date); + preCreated.setEndDate(date); + preCreated.setProgram(program); + + return preCreated; + + } + + @Override + public String save(TripLongline toSave) { + + String tripLonglineId = doSave(null, toSave, new SaveAction<Program, TripLongline>(Program.class, TripLongline.class) { + + @Override + public void beforeSave(String parentId, TripLongline toSave) { + + super.beforeSave(parentId, toSave); + Date startDate = DateUtil.getDay(toSave.getStartDate()); + toSave.setStartDate(startDate); + + // mise a jour de la date de fin + toSave.updateDateFin(); + + } + + @Override + public TripLongline onCreate(Program parent, TripLongline toCreate) { + + Map<String, Object> properties = obtainProperties(TripLongline.class, BinderService.EDIT, toCreate); + TripLongline created = getDao().create(properties); + return created; + + } + + @Override + public TripLongline onUpdate(Program parent, TripLongline toUpdate) { + + TripLongline updated = super.onUpdate(parent, toUpdate); + copyExcluding(TripLongline.class, BinderService.EDIT, toUpdate, updated, TripLongline.PROPERTY_ACTIVITY_LONGLINE); + return updated; + + } + }); + + return tripLonglineId; + + } + + @Override + public void delete(String tripLonglineId) { + doDelete(null, tripLonglineId, new DeleteAction<Program, TripLongline>(Program.class, TripLongline.class)); + } + + protected TripLonglineDAO getDao() { + return (TripLonglineDAO) getDao(TripLongline.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ActivitySeineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ActivitySeineServiceImpl.java new file mode 100644 index 0000000..c5328ba --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ActivitySeineServiceImpl.java @@ -0,0 +1,202 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.constants.ReferenceLocale; +import fr.ird.observe.entities.constants.seine.SchoolType; +import fr.ird.observe.entities.referentiel.FpaZone; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.ActivitySeineDAO; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.util.DateUtil; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/24/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ActivitySeineServiceImpl extends AbstractObserveService implements ActivitySeineService { + + @Override + public List<ActivitySeine> getActivitySeineStubByRoute(String routeId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + List<ActivitySeine> result = getDao().findAllStubByRouteId(routeId, referentielLocale); + return result; + + } + + @Override + public ActivitySeine getActivitySeineStub(String activityId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + ActivitySeine result = getDao().findStubByTopiaId(activityId, referentielLocale); + return result; + + } + + @Override + public ActivitySeine loadForEdit(String activitySeineId) { + + ActivitySeine loaded = getDao().newInstance(); + ActivitySeine toLoad = getDao().findByTopiaId(activitySeineId); + copy(ActivitySeine.class, BinderService.EDIT, toLoad, loaded); + return loaded; + + } + + @Override + public ActivitySeine loadForEditObservedSystem(String activitySeineId) { + + ActivitySeine toLoad = getDao().findByTopiaId(activitySeineId); + ActivitySeine loaded = getDao().newInstance(); + copy(ActivitySeine.class, BinderService.EDIT_OBSERVED_SYSTEM, toLoad, loaded); + return loaded; + + } + + @Override + public ActivitySeine preCreate(String routeId) { + + Route tripLongline = findByTopiaId(Route.class, routeId); + + ActivitySeine preCreated = getDao().newInstance(); + + preCreated.setOpen(true); + + ActivitySeine lastActivitySeine = tripLongline.getLastActivity(); + + Date time; + + FpaZone currentFpaZone = null; + + if (lastActivitySeine == null) { + + // première activité, on utilise l'heure courante + time = serviceContext.now(); + + } else { + + // passage en coordonnées absolue + quadrant + lastActivitySeine.initCoordinates(); + + // on recupère le quadrant de cette activity + // et on l'affecte à la nouvelle activity + Integer quadrant = lastActivitySeine.getQuadrant(); + if (quadrant != null) { + + preCreated.setQuadrant(quadrant); + + } + + // on reprend l'heure de la dernière activité + time = lastActivitySeine.getTime(); + + // utilisation des zones fpa de la dernière activité + currentFpaZone = lastActivitySeine.getNextFpaZone(); + if (currentFpaZone == null) { + currentFpaZone = lastActivitySeine.getCurrentFpaZone(); + } + + } + + preCreated.setTime(DateUtil.getTime(time, false, false)); + preCreated.setCurrentFpaZone(currentFpaZone); + + return preCreated; + + } + + @Override + public ActivitySeine updateObservedSystem(ActivitySeine toUpdate) { + + ActivitySeineDAO dao = getDao(); + + boolean needUpdateSet = false; + SchoolType newTypeBanc = toUpdate.getSchoolType(); + SetSeine set = toUpdate.getSetSeine(); + if (set != null) { + + // on regarde si le type de banc de la calée a changé + SchoolType oldTypeBanc = set.getSchoolType(); + needUpdateSet = oldTypeBanc == null || newTypeBanc != oldTypeBanc; + + } + + ActivitySeine updated = dao.findByTopiaId(toUpdate.getTopiaId()); + + copy(ActivitySeine.class, BinderService.EDIT_OBSERVED_SYSTEM, toUpdate, updated); + + if (needUpdateSet) { + + // mise à jour de la propriété schoolType dans la set + updated.getSetSeine().setSchoolType(newTypeBanc); + + } + + return updated; + + } + + + @Override + public String save(String routeId, ActivitySeine toSave) { + + String activitySeineId = doSave(routeId, toSave, new SaveAction<Route, ActivitySeine>(Route.class, ActivitySeine.class) { + + @Override + public ActivitySeine onCreate(Route parent, ActivitySeine toCreate) { + + Map<String, Object> properties = obtainProperties(ActivitySeine.class, BinderService.EDIT, toCreate); + ActivitySeine created = getDao().create(properties); + + parent.addActivitySeine(created); + return created; + + } + + @Override + public ActivitySeine onUpdate(Route parent, ActivitySeine toUpdate) { + + ActivitySeine updated = super.onUpdate(parent, toUpdate); + + Date d = DateUtil.getDateAndTime(parent.getDate(), toUpdate.getTime(), false, false); + + toUpdate.setTime(d); + + copyExcluding(ActivitySeine.class, BinderService.EDIT, toUpdate, updated, true, + ActivitySeine.PROPERTY_OBSERVED_SYSTEM, ActivitySeine.PROPERTY_FLOATING_OBJECT); + return updated; + + } + }); + + return activitySeineId; + + } + + @Override + public void delete(String routeId, String activitySeineId) { + doDelete(routeId, activitySeineId, new DeleteAction<Route, ActivitySeine>(Route.class, ActivitySeine.class) { + + @Override + public void onDelete(Route parent, ActivitySeine toDelete) { + super.onDelete(parent, toDelete); + parent.removeActivitySeine(toDelete); + + } + }); + + } + + protected ActivitySeineDAO getDao() { + return (ActivitySeineDAO) getDao(ActivitySeine.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/FloatingObjectServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/FloatingObjectServiceImpl.java new file mode 100644 index 0000000..d9174e3 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/FloatingObjectServiceImpl.java @@ -0,0 +1,194 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.constants.ReferenceLocale; +import fr.ird.observe.entities.referentiel.Country; +import fr.ird.observe.entities.referentiel.seine.TransmittingBuoyOperation; +import fr.ird.observe.entities.referentiel.seine.TransmittingBuoyType; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.FloatingObject; +import fr.ird.observe.entities.seine.FloatingObjectDAO; +import fr.ird.observe.entities.seine.TransmittingBuoy; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.decorator.Decorator; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/24/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class FloatingObjectServiceImpl extends AbstractObserveService implements FloatingObjectService { + + @Override + public List<FloatingObject> getFloatinObjectStubByActivitySeine(String activitySeineId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + List<FloatingObject> result = getDao().findAllStubByActivityId(activitySeineId, referentielLocale); + return result; + + } + + @Override + public FloatingObject getFloatinObjectStub(String floatingObjectId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + FloatingObject result = getDao().findStubByTopiaId(floatingObjectId, referentielLocale); + return result; + + } + + @Override + public FloatingObject loadForEdit(String floatingObjectId) { + + FloatingObjectDAO dao = getDao(); + + FloatingObject loaded = dao.newInstance(); + FloatingObject toLoad = dao.findByTopiaId(floatingObjectId); + copy(FloatingObject.class, BinderService.EDIT, toLoad, loaded, true); + + return loaded; + + } + + @Override + public FloatingObject loadForTransmittingBuoyOperation(String floatingObjectId) { + + FloatingObjectDAO dao = getDao(); + + FloatingObject loaded = dao.newInstance(); + FloatingObject toLoad = dao.findByTopiaId(floatingObjectId); + + copy(FloatingObject.class, BinderService.EDIT_OBJECT_OPERATION_TRANSMITTING_BUOY, toLoad, loaded); + + if (!toLoad.isTransmittingBuoyEmpty()) { + + Decorator<Country> countryDecorator = getDecoratorByType(Country.class, null); + Decorator<TransmittingBuoyOperation> transmittingBuoyOperationDecorator = getDecoratorByType(TransmittingBuoyOperation.class, null); + Decorator<TransmittingBuoyType> transmittingBuoyTypeDecorator = getDecoratorByType(TransmittingBuoyType.class, null); + + TopiaEntityBinder<TransmittingBuoy> binder = getBinder(TransmittingBuoy.class, BinderService.EDIT); + TopiaDAO<TransmittingBuoy> transmittingBuoyDao = getDao(TransmittingBuoy.class); + List<TransmittingBuoy> transmittingBuoys = new ArrayList<TransmittingBuoy>(); + for (TransmittingBuoy transmittingBuoyToLoad : toLoad.getTransmittingBuoy()) { + + transmittingBuoyOperationDecorator.toString(transmittingBuoyToLoad.getTransmittingBuoyOperation()); + transmittingBuoyTypeDecorator.toString(transmittingBuoyToLoad.getTransmittingBuoyType()); + countryDecorator.toString(transmittingBuoyToLoad.getCountry()); + + TransmittingBuoy transmittingBuoyLoaded = transmittingBuoyDao.newInstance(); + binder.load(transmittingBuoyToLoad, transmittingBuoyLoaded, true); + transmittingBuoys.add(transmittingBuoyLoaded); + + } + + loaded.setTransmittingBuoy(transmittingBuoys); + + } + return loaded; + + } + + @Override + public FloatingObject preCreate(String activitySeineId) { + + FloatingObject preCreated = getDao().newInstance(); + return preCreated; + + } + + @Override + public String save(String activitySeineId, FloatingObject toSave) { + + String floatingObjectId = doSave(activitySeineId, toSave, new SaveAction<ActivitySeine, FloatingObject>(ActivitySeine.class, FloatingObject.class) { + + @Override + public FloatingObject onCreate(ActivitySeine parent, FloatingObject toCreate) { + + Map<String, Object> properties = obtainProperties(FloatingObject.class, BinderService.EDIT, toCreate); + FloatingObject created = getDao().create(properties); + parent.addFloatingObject(created); + return created; + + } + + @Override + public FloatingObject onUpdate(ActivitySeine parent, FloatingObject toUpdate) { + + FloatingObject updated = super.onUpdate(parent, toUpdate); + copy(FloatingObject.class, BinderService.EDIT, toUpdate, updated, true); + return updated; + + } + }); + + return floatingObjectId; + + } + + @Override + public void saveForTransmittingBuoyOperation(FloatingObject toSave) { + + FloatingObject saved = getDao().findByTopiaId(toSave.getTopiaId()); + saved.setComment(toSave.getComment()); + saved.clearTransmittingBuoy(); + + if (!toSave.isTransmittingBuoyEmpty()) { + + TopiaEntityBinder<TransmittingBuoy> binder = getBinder(TransmittingBuoy.class, BinderService.EDIT); + TopiaDAO<TransmittingBuoy> transmittingBuoyDAO = getDao(TransmittingBuoy.class); + + List<TransmittingBuoy> transmittingBuoys = new ArrayList<TransmittingBuoy>(); + + for (TransmittingBuoy transmittingBuoyToSave : toSave.getTransmittingBuoy()) { + + TransmittingBuoy transmittingBuoySaved; + + if (Entities.isNew(transmittingBuoyToSave)) { + + // creation de la balise + Map<String, Object> properties = binder.obtainProperties(transmittingBuoyToSave); + transmittingBuoySaved = transmittingBuoyDAO.create(properties); + + } else { + + // mise a jour de la balise + + transmittingBuoySaved = transmittingBuoyDAO.findByTopiaId(transmittingBuoyToSave.getTopiaId()); + binder.load(transmittingBuoyToSave, transmittingBuoySaved, true); + + } + + transmittingBuoys.add(transmittingBuoySaved); + + } + + saved.addAllTransmittingBuoy(transmittingBuoys); + + } + + } + + @Override + public void delete(String activitySeineId, String floatingObjectId) { + + FloatingObjectDAO dao = getDao(); + FloatingObject toDelete = dao.findByTopiaId(floatingObjectId); + + ActivitySeine activitySeine = findByTopiaId(ActivitySeine.class, activitySeineId); + activitySeine.removeFloatingObject(toDelete); + + } + + protected FloatingObjectDAO getDao() { + return (FloatingObjectDAO) getDao(FloatingObject.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/GearUseFeaturesSeineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/GearUseFeaturesSeineServiceImpl.java new file mode 100644 index 0000000..2d01767 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/GearUseFeaturesSeineServiceImpl.java @@ -0,0 +1,211 @@ +package fr.ird.observe.services.data.seine; + +import com.google.common.collect.Lists; +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.referentiel.Gear; +import fr.ird.observe.entities.referentiel.GearCaracteristic; +import fr.ird.observe.entities.seine.GearUseFeaturesMeasurementSeine; +import fr.ird.observe.entities.seine.GearUseFeaturesMeasurementSeineDAO; +import fr.ird.observe.entities.seine.GearUseFeaturesSeine; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.collections4.CollectionUtils; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class GearUseFeaturesSeineServiceImpl extends AbstractObserveService implements GearUseFeaturesSeineService { + + @Override + public List<GearUseFeaturesMeasurementSeine> getDefaultGearUseFeaturesMeasurementSeine(String gearId) { + + Gear gear = findByTopiaId(Gear.class, gearId); + + List<GearUseFeaturesMeasurementSeine> result = new ArrayList<GearUseFeaturesMeasurementSeine>(); + + if (!gear.isGearCaracteristicEmpty()) { + + GearUseFeaturesMeasurementSeineDAO dao = getDao(); + + for (GearCaracteristic caracteristic : gear.getGearCaracteristic()) { + + GearUseFeaturesMeasurementSeine target = dao.newInstance(); + target.setGearCaracteristic(caracteristic); + result.add(target); + + } + + } + + return result; + + } + + @Override + public List<GearUseFeaturesMeasurementSeine> loadGearUseFeaturesMeasurementSeineForEdit(String gearUseFeaturesSeineId) { + + GearUseFeaturesSeine gearUseFeaturesSeine = findByTopiaId(GearUseFeaturesSeine.class, gearUseFeaturesSeineId); + List<GearUseFeaturesMeasurementSeine> result = new ArrayList<GearUseFeaturesMeasurementSeine>(); + + if (!gearUseFeaturesSeine.isGearUseFeaturesMeasurementEmpty()) { + + GearUseFeaturesMeasurementSeineDAO dao = getDao(); + TopiaEntityBinder<GearUseFeaturesMeasurementSeine> binder = getBinder(GearUseFeaturesMeasurementSeine.class, BinderService.EDIT); + + for (GearUseFeaturesMeasurementSeine measurementSource : gearUseFeaturesSeine.getGearUseFeaturesMeasurement()) { + + GearUseFeaturesMeasurementSeine target = dao.newInstance(); + measurementSource.getGearCaracteristic().getGearCaracteristicType(); + binder.load(measurementSource, target, true); + result.add(target); + + } + + } + + return result; + + } + + @Override + public TripSeine loadForEdit(String tripId) { + + TopiaDAO<TripSeine> dao = getDao(TripSeine.class); + TripSeine toLoad = dao.findByTopiaId(tripId); + + TripSeine loaded = dao.newInstance(); + + if (toLoad != null) { + + copyExcluding(TripSeine.class, BinderService.EDIT_GEAR_USE_FEATURES_SEINE, toLoad, loaded, TripSeine.PROPERTY_GEAR_USE_FEATURES_SEINE); + + if (!toLoad.isGearUseFeaturesSeineEmpty()) { + + TopiaDAO<GearUseFeaturesSeine> childDao = getDao(GearUseFeaturesSeine.class); + TopiaDAO<GearUseFeaturesMeasurementSeine> measurementDao = getDao(GearUseFeaturesMeasurementSeine.class); + TopiaEntityBinder<GearUseFeaturesSeine> childBinder = getBinder(GearUseFeaturesSeine.class, BinderService.EDIT); + TopiaEntityBinder<GearUseFeaturesMeasurementSeine> measurementBinder = getBinder(GearUseFeaturesMeasurementSeine.class, BinderService.EDIT); + + List<GearUseFeaturesSeine> childsLoaded = new ArrayList<GearUseFeaturesSeine>(); + + for (GearUseFeaturesSeine childToLoad : toLoad.getGearUseFeaturesSeine()) { + + GearUseFeaturesSeine childLoaded = childDao.newInstance(); + childBinder.load(childToLoad, childLoaded, true); + childsLoaded.add(childLoaded); + + if (!childToLoad.isGearUseFeaturesMeasurementEmpty()) { + + List<GearUseFeaturesMeasurementSeine> measurementsLoaded = new ArrayList<GearUseFeaturesMeasurementSeine>(); + + for (GearUseFeaturesMeasurementSeine measurementToLoad : childToLoad.getGearUseFeaturesMeasurement()) { + + GearUseFeaturesMeasurementSeine measurementLoaded = measurementDao.newInstance(); + measurementBinder.load(measurementToLoad, measurementLoaded, true); + measurementsLoaded.add(measurementLoaded); + + } + + childLoaded.setGearUseFeaturesMeasurement(measurementsLoaded); + + } + + } + + loaded.setGearUseFeaturesSeine(childsLoaded); + + } + + } + + return loaded; + } + + @Override + public void save(TripSeine parent) { + + TopiaEntityBinder<TripSeine> parentBinder = getBinder(TripSeine.class, BinderService.EDIT_GEAR_USE_FEATURES_SEINE); + TopiaEntityBinder<GearUseFeaturesSeine> childBinder = getBinder(GearUseFeaturesSeine.class, BinderService.EDIT); + + doSaveList(parent, new SaveCollectionAction<TripSeine, GearUseFeaturesSeine>( + TripSeine.class, GearUseFeaturesSeine.class, getListUpdator(), parentBinder, childBinder) { + + @Override + public GearUseFeaturesSeine onCreateChild(GearUseFeaturesSeine childToCreate) { + + GearUseFeaturesSeine childCreated = super.onCreateChild(childToCreate); + saveMeasurement(childCreated, childToCreate.getGearUseFeaturesMeasurement()); + return childCreated; + + } + + @Override + public GearUseFeaturesSeine onUpdateChild(GearUseFeaturesSeine childToUpdate) { + + GearUseFeaturesSeine childUpdated = super.onUpdateChild(childToUpdate); + saveMeasurement(childUpdated, childToUpdate.getGearUseFeaturesMeasurement()); + return childUpdated; + + } + + protected void saveMeasurement(GearUseFeaturesSeine childSaved, List<GearUseFeaturesMeasurementSeine> measurementsToSave) { + + List<GearUseFeaturesMeasurementSeine> measurementsSaved = Lists.newArrayList(); + + if (CollectionUtils.isNotEmpty(measurementsToSave)) { + + TopiaDAO<GearUseFeaturesMeasurementSeine> dao = getDao(GearUseFeaturesMeasurementSeine.class); + TopiaEntityBinder<GearUseFeaturesMeasurementSeine> binder = getBinder(GearUseFeaturesMeasurementSeine.class, BinderService.EDIT); + + for (GearUseFeaturesMeasurementSeine measurementToSave : measurementsToSave) { + + GearUseFeaturesMeasurementSeine measurementSaved; + + if (Entities.isNew(measurementToSave)) { + + Map<String, Object> properties = binder.obtainProperties(measurementToSave); + measurementSaved = dao.create(properties); + + } else { + + measurementSaved = dao.findByTopiaId(measurementToSave.getTopiaId()); + binder.load(measurementToSave, measurementSaved, true); + + } + + measurementsSaved.add(measurementSaved); + + } + + } + + childSaved.clearGearUseFeaturesMeasurement(); + childSaved.addAllGearUseFeaturesMeasurement(measurementsSaved); + + } + }); + } + + protected EntityListUpdator<TripSeine, GearUseFeaturesSeine> getListUpdator() { + return EntityListUpdator.newEntityListUpdator( + TripSeine.class, + GearUseFeaturesSeine.class, + TripSeine.PROPERTY_GEAR_USE_FEATURES_SEINE); + } + + protected GearUseFeaturesMeasurementSeineDAO getDao() { + return (GearUseFeaturesMeasurementSeineDAO) getDao(GearUseFeaturesMeasurementSeine.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/NonTargetCatchServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/NonTargetCatchServiceImpl.java new file mode 100644 index 0000000..af19eee --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/NonTargetCatchServiceImpl.java @@ -0,0 +1,114 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.seine.NonTargetCatch; +import fr.ird.observe.entities.seine.NonTargetLength; +import fr.ird.observe.entities.seine.NonTargetSample; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.Collection; +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class NonTargetCatchServiceImpl extends AbstractObserveService implements NonTargetCatchService { + + private static final Log log = LogFactory.getLog(NonTargetCatchServiceImpl.class); + + @Override + public SetSeine loadForEdit(String setId) { + + SetSeine toLoad = findByTopiaId(SetSeine.class, setId); + + SetSeine loaded = getDao(SetSeine.class).newInstance(); + + if (toLoad != null) { + + copyExcluding(SetSeine.class, BinderService.EDIT_NON_TARGET_CATCH, toLoad, loaded, SetSeine.PROPERTY_NON_TARGET_CATCH); + + if (!toLoad.isNonTargetCatchEmpty()) { + + TopiaDAO<NonTargetCatch> dao = getDao(NonTargetCatch.class); + TopiaEntityBinder<NonTargetCatch> binder = getBinder(NonTargetCatch.class, BinderService.EDIT); + + for (NonTargetCatch childToLoad : toLoad.getNonTargetCatch()) { + + NonTargetCatch childLoaded = dao.newInstance(); + binder.load(childToLoad, childLoaded, true); + loaded.addNonTargetCatch(childLoaded); + + } + } + + } + + return loaded; + + } + + @Override + public void save(SetSeine toSave, final List<NonTargetLength> nonTargetLengthsToDelete) { + + TopiaEntityBinder<SetSeine> parentBinder = getBinder(SetSeine.class, BinderService.EDIT_NON_TARGET_CATCH); + TopiaEntityBinder<NonTargetCatch> childbinder = getBinder(NonTargetCatch.class, BinderService.EDIT); + + doSaveList(toSave, new SaveCollectionAction<SetSeine, NonTargetCatch>( + SetSeine.class, NonTargetCatch.class, getListUpdator(), parentBinder, childbinder) { + + @Override + public void prepareSave(SetSeine parentToSave, Collection<NonTargetCatch> nonTargetCatchesToSave) { + + // mise a jour de la propriete nonTargetDiscarded + + boolean hasRejet = false; + for (NonTargetCatch c : nonTargetCatchesToSave) { + if (c.getReasonForDiscard() != null) { + // on a trouve un rejet de faune + hasRejet = true; + break; + } + } + + parentToSave.setNonTargetDiscarded(hasRejet); + + } + + @Override + public void onUpdateFinalize(SetSeine parentSaved, Collection<NonTargetCatch> oldChilds) throws TopiaException { + + if (CollectionUtils.isNotEmpty(nonTargetLengthsToDelete)) { + + // on a demande la suppression de taille obsoletes + + if (log.isInfoEnabled()) { + log.info("Will remove " + nonTargetLengthsToDelete.size() + " obsolete nonTargetSample(s)."); + } + + NonTargetSample echantillon = parentSaved.getNonTargetSample().get(0); + + // on supprime les echantillons obsoletes + echantillon.getNonTargetLength().removeAll(nonTargetLengthsToDelete); + + } + } + }); + + } + + protected EntityListUpdator<SetSeine, NonTargetCatch> getListUpdator() { + return EntityListUpdator.newEntityListUpdator( + SetSeine.class, + NonTargetCatch.class, + SetSeine.PROPERTY_NON_TARGET_CATCH); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/NonTargetSampleServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/NonTargetSampleServiceImpl.java new file mode 100644 index 0000000..dacc978 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/NonTargetSampleServiceImpl.java @@ -0,0 +1,245 @@ +package fr.ird.observe.services.data.seine; + +import com.google.common.collect.Lists; +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.referentiel.Species; +import fr.ird.observe.entities.seine.NonTargetCatch; +import fr.ird.observe.entities.seine.NonTargetLength; +import fr.ird.observe.entities.seine.NonTargetSample; +import fr.ird.observe.entities.seine.NonTargetSampleDAO; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class NonTargetSampleServiceImpl extends AbstractObserveService implements NonTargetSampleService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(NonTargetSampleServiceImpl.class); + + protected NonTargetSampleDAO getDao() { + return (NonTargetSampleDAO) getDao(NonTargetSample.class); + } + + @Override + public List<Species> getAvailableSpeciesForNonTargetSample(String setSeineId) { + + List<Species> speciesList = new ArrayList<Species>(); + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + + // on recupere la liste des espèces faune utilisees dans le rejet + Collection<NonTargetCatch> nonTargetCatches = setSeine.getNonTargetCatch(); + + if (nonTargetCatches != null) { + + for (NonTargetCatch nonTargetCatch : nonTargetCatches) { + // on retient toute les espèces (capturées ou rejetées) + if (!speciesList.contains(nonTargetCatch.getSpecies())) { + speciesList.add(nonTargetCatch.getSpecies()); + } + } + + } + + return speciesList; + + } + + @Override + public NonTargetSample loadForEdit(String setSeineId) { + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + + NonTargetSample toLoad; + + if (setSeine.isNonTargetSampleEmpty()) { + + toLoad = null; + + } else { + + List<NonTargetSample> nonTargetSamples = setSeine.getNonTargetSample(); + toLoad = nonTargetSamples.get(0); + + } + + NonTargetSample loaded = getDao(NonTargetSample.class).newInstance(); + + if (toLoad != null) { + + copyExcluding(NonTargetSample.class, BinderService.EDIT_NON_TARGET_LENGTH, toLoad, loaded, NonTargetSample.PROPERTY_NON_TARGET_LENGTH); + + if (!toLoad.isNonTargetLengthEmpty()) { + + TopiaDAO<NonTargetLength> dao = getDao(NonTargetLength.class); + TopiaEntityBinder<NonTargetLength> binder = getBinder(NonTargetLength.class, BinderService.EDIT); + + for (NonTargetLength childToLoad : toLoad.getNonTargetLength()) { + + NonTargetLength childLoaded = dao.newInstance(); + binder.load(childToLoad, childLoaded, true); + loaded.addNonTargetLength(childLoaded); + + } + } + } + + return loaded; + } + + @Override + public boolean canUseNonTargetSample(String setSeineId) { + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + return setSeine.canUseNonTargetSample(); + + } + + @Override + public List<NonTargetLength> getObsoleteNonTargetLengths(String setSeineId, Set<String> speciesIdsUsed) { + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + + List<NonTargetLength> nonTargetLengthsToDelete = new ArrayList<NonTargetLength>(); + + if (!setSeine.isNonTargetSampleEmpty()) { + + NonTargetSample nonTargetSample = setSeine.getNonTargetSample().get(0); + + if (!nonTargetSample.isNonTargetLengthEmpty()) { + + for (NonTargetLength taille : nonTargetSample.getNonTargetLength()) { + + Species species = taille.getSpecies(); + if (!speciesIdsUsed.contains(species.getTopiaId())) { + + // l'espèce n'existe plus dans les rejet faune, on doit le supprimer + nonTargetLengthsToDelete.add(taille); + if (log.isDebugEnabled()) { + log.debug("remove obsolote echantillon " + taille + " for species " + species); + } + + } + + } + + } + + } + + return nonTargetLengthsToDelete; + + } + + @Override + public String save(String setSeineId, NonTargetSample nonTargetSampleToSave) { + + String savedId = doSave(setSeineId, nonTargetSampleToSave, new SaveAction<SetSeine, NonTargetSample>(SetSeine.class, NonTargetSample.class) { + + @Override + public NonTargetSample onCreate(SetSeine parent, NonTargetSample toCreate) { + + NonTargetSampleDAO dao = getDao(); + + Map<String, Object> properties = obtainProperties(NonTargetSample.class, BinderService.EDIT, toCreate); + NonTargetSample created = dao.create(properties); + parent.addNonTargetSample(created); + + saveTargetLengths(toCreate.getNonTargetLength(), created); + + dao.update(created); + return created; + + } + + @Override + public NonTargetSample onUpdate(SetSeine parent, NonTargetSample toUpdate) { + + NonTargetSample updated = super.onUpdate(parent, toUpdate); + + copyExcluding(NonTargetSample.class, BinderService.EDIT, toUpdate, updated, false, NonTargetSample.PROPERTY_NON_TARGET_LENGTH); + + saveTargetLengths(toUpdate.getNonTargetLength(), updated); + + getDao().update(updated); + return updated; + + } + + protected void saveTargetLengths(Collection<NonTargetLength> nonTargetLengthsToSave, NonTargetSample childSaved) { + + List<NonTargetLength> nonTargetLengthsSaved = Lists.newArrayList(); + + if (CollectionUtils.isNotEmpty(nonTargetLengthsToSave)) { + + TopiaDAO<NonTargetLength> dao = getDao(NonTargetLength.class); + TopiaEntityBinder<NonTargetLength> binder = getBinder(NonTargetLength.class, BinderService.EDIT); + + for (NonTargetLength nonTargetLengthToSave : nonTargetLengthsToSave) { + + NonTargetLength nonTargetLengthSaved; + + if (Entities.isNew(nonTargetLengthToSave)) { + + Map<String, Object> properties = binder.obtainProperties(nonTargetLengthToSave); + nonTargetLengthSaved = dao.create(properties); + + } else { + + nonTargetLengthSaved = dao.findByTopiaId(nonTargetLengthToSave.getTopiaId()); + binder.load(nonTargetLengthToSave, nonTargetLengthSaved, true); + + } + + nonTargetLengthsSaved.add(nonTargetLengthSaved); + + } + + } + + childSaved.clearNonTargetLength(); + childSaved.addAllNonTargetLength(nonTargetLengthsSaved); + + } + + }); + + return savedId; + + } + + @Override + public void delete(String setSeineId, NonTargetSample nonTargetSampleToDelete) { + + doDelete(setSeineId, nonTargetSampleToDelete.getTopiaId(), new DeleteAction<SetSeine, NonTargetSample>(SetSeine.class, NonTargetSample.class) { + + @Override + public void onDelete(SetSeine parent, NonTargetSample toDelete) { + + super.onDelete(parent, toDelete); + parent.removeNonTargetSample(toDelete); + + } + + }); + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ObjectObservedSpeciesServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ObjectObservedSpeciesServiceImpl.java new file mode 100644 index 0000000..bd4b6f2 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ObjectObservedSpeciesServiceImpl.java @@ -0,0 +1,66 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.seine.FloatingObject; +import fr.ird.observe.entities.seine.ObjectObservedSpecies; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ObjectObservedSpeciesServiceImpl extends AbstractObserveService implements ObjectObservedSpeciesService { + + @Override + public FloatingObject loadForEdit(String floatingObjectId) { + + FloatingObject parentToLoad = findByTopiaId(FloatingObject.class, floatingObjectId); + + FloatingObject parentLoaded = getDao(FloatingObject.class).newInstance(); + + copy(FloatingObject.class, BinderService.EDIT_OBJECT_OBSERVED_SPECIES, parentToLoad, parentLoaded); + + if (!parentToLoad.isObjectObservedSpeciesEmpty()) { + + TopiaDAO<ObjectObservedSpecies> childDao = getDao(ObjectObservedSpecies.class); + TopiaEntityBinder<ObjectObservedSpecies> binder = getBinder(ObjectObservedSpecies.class, BinderService.EDIT); + List<ObjectObservedSpecies> childs = new ArrayList<ObjectObservedSpecies>(); + + for (ObjectObservedSpecies sourceChild : parentToLoad.getObjectObservedSpecies()) { + + ObjectObservedSpecies targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setObjectObservedSpecies(childs); + + } + + return parentLoaded; + } + + @Override + public void save(FloatingObject floatingObject) { + + TopiaEntityBinder<FloatingObject> parentBinder = getBinder(FloatingObject.class, BinderService.EDIT_OBJECT_OBSERVED_SPECIES); + TopiaEntityBinder<ObjectObservedSpecies> childbinder = getBinder(ObjectObservedSpecies.class, BinderService.EDIT); + + doSaveList(floatingObject, new SaveCollectionAction<FloatingObject, ObjectObservedSpecies>( + FloatingObject.class, ObjectObservedSpecies.class, getListUpdator(), parentBinder, childbinder)); + + } + + protected EntityListUpdator<FloatingObject, ObjectObservedSpecies> getListUpdator() { + return EntityListUpdator.newEntityListUpdator( + FloatingObject.class, + ObjectObservedSpecies.class, + FloatingObject.PROPERTY_OBJECT_OBSERVED_SPECIES); + } +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ObjectSchoolEstimateServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ObjectSchoolEstimateServiceImpl.java new file mode 100644 index 0000000..a5c55b6 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/ObjectSchoolEstimateServiceImpl.java @@ -0,0 +1,67 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.seine.FloatingObject; +import fr.ird.observe.entities.seine.ObjectSchoolEstimate; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sylvain Bavencoff - bavencoff@codelutin.com + */ +public class ObjectSchoolEstimateServiceImpl extends AbstractObserveService implements ObjectSchoolEstimateService { + + @Override + public FloatingObject loadForEdit(String floatingObjectId) { + + FloatingObject parentToLoad = findByTopiaId(FloatingObject.class, floatingObjectId); + + FloatingObject parentLoaded = getDao(FloatingObject.class).newInstance(); + + copy(FloatingObject.class, BinderService.EDIT_OBJECT_SCHOOL_ESTIMATE, parentToLoad, parentLoaded); + + if (!parentToLoad.isObjectSchoolEstimateEmpty()) { + + TopiaDAO<ObjectSchoolEstimate> childDao = getDao(ObjectSchoolEstimate.class); + TopiaEntityBinder<ObjectSchoolEstimate> binder = getBinder(ObjectSchoolEstimate.class, BinderService.EDIT); + + List<ObjectSchoolEstimate> childs = new ArrayList<ObjectSchoolEstimate>(); + + for (ObjectSchoolEstimate sourceChild : parentToLoad.getObjectSchoolEstimate()) { + + ObjectSchoolEstimate targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setObjectSchoolEstimate(childs); + + } + + return parentLoaded; + } + + @Override + public void save(FloatingObject floatingObject) { + + TopiaEntityBinder<FloatingObject> parentBinder = getBinder(FloatingObject.class, BinderService.EDIT_OBJECT_SCHOOL_ESTIMATE); + TopiaEntityBinder<ObjectSchoolEstimate> childBinder = getBinder(ObjectSchoolEstimate.class, BinderService.EDIT); + + doSaveList(floatingObject, new SaveCollectionAction<FloatingObject, ObjectSchoolEstimate>( + FloatingObject.class, ObjectSchoolEstimate.class, getListUpdator(), parentBinder, childBinder)); + + } + + protected EntityListUpdator<FloatingObject, ObjectSchoolEstimate> getListUpdator() { + return EntityListUpdator.newEntityListUpdator( + FloatingObject.class, + ObjectSchoolEstimate.class, + FloatingObject.PROPERTY_OBJECT_SCHOOL_ESTIMATE); + } +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/RouteServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/RouteServiceImpl.java new file mode 100644 index 0000000..7d86f73 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/RouteServiceImpl.java @@ -0,0 +1,162 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.seine.ActivitySeines; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.RouteDAO; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.lang3.time.DateUtils; +import org.nuiton.util.DateUtil; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/24/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class RouteServiceImpl extends AbstractObserveService implements RouteService { + + @Override + public List<Route> getRouteStubByTrip(String tripSeineId) { + + List<Route> result = getDao().findAllStubByTripId(tripSeineId); + return result; + + } + + @Override + public Route getRouteStub(String routeId) { + + Route result = getDao().findStubByTopiaId(routeId); + return result; + + } + + @Override + public Route loadForEdit(String routeId) { + + Route loaded = getDao().newInstance(); + Route toLoad = getDao().findByTopiaId(routeId); + copy(Route.class, BinderService.EDIT, toLoad, loaded); + + if (!loaded.isActivitySeineEmpty()) { + + // on force le trie des activites + ActivitySeines.sort(loaded.getActivitySeine()); + } + + return loaded; + + } + + @Override + public Route preCreate(String tripSeineId) { + + TripSeine tripLongline = findByTopiaId(TripSeine.class, tripSeineId); + + Route preCreated = getDao().newInstance(); + + preCreated.setOpen(true); + + Route lastRoute = tripLongline.getLastRoute(); + + Date date; + if (lastRoute == null) { + + // aucune route defini, on utilise la date courante + date = now(); + + } else { + + // une route precedente est definie sur la maree + // le jour d'observation est le jour suivant celui de la + // derniere route + date = DateUtils.addDays(lastRoute.getDate(), 1); + + // le loch du matin est le loch du soir de la derniere route + preCreated.setStartLogValue(lastRoute.getEndLogValue()); + } + + preCreated.setDate(DateUtil.getDay(date)); + + return preCreated; + + } + + @Override + public String save(String tripSeineId, Route toSave) { + + String routeId = doSave(tripSeineId, toSave, new SaveAction<TripSeine, Route>(TripSeine.class, Route.class) { + + @Override + public Route onCreate(TripSeine parent, Route toCreate) { + + Map<String, Object> properties = obtainProperties(Route.class, BinderService.EDIT, toCreate); + Route created = getDao().create(properties); + + parent.addRoute(created); + + // on met a jour si necessaire la date de fin de la maree + parent.updateDateFin(); + + return created; + } + + @Override + public Route onUpdate(TripSeine parent, Route toUpdate) { + + Route updated = super.onUpdate(parent, toUpdate); + + // on conserve l'ancienne date d'observation + Date oldDate = DateUtil.getDay(toUpdate.getDate()); + + // recopie des propriétés vers le bean a sauver + copyExcluding(Route.class, BinderService.EDIT, toUpdate, updated, Route.PROPERTY_ACTIVITY_SEINE); + + if (!oldDate.equals(toUpdate.getDate())) { + + //FIXME Faire cela avec une requete sql, sinon ca charge trop de données + // le jour a change, il faut mettre à jour les dates des activites et des calees + updated.updateDates(); + + } + + // on met a jour si necessaire la date de fin de la maree + parent.updateDateFin(); + + return updated; + + } + }); + + return routeId; + + } + + @Override + public void delete(String tripSeineId, String routeId) { + doDelete(tripSeineId, routeId, new DeleteAction<TripSeine, Route>(TripSeine.class, Route.class) { + + @Override + public void onDelete(TripSeine parent, Route toDelete) { + super.onDelete(parent, toDelete); + + // suppression de la route + parent.removeRoute(toDelete); + + // mise à jour de la date de fin de marée + parent.updateDateFin(); + } + }); + } + + protected RouteDAO getDao() { + return (RouteDAO) getDao(Route.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/SchoolEstimateServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/SchoolEstimateServiceImpl.java new file mode 100644 index 0000000..8661272 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/SchoolEstimateServiceImpl.java @@ -0,0 +1,72 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.seine.SchoolEstimate; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created on 4/28/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class SchoolEstimateServiceImpl extends AbstractObserveService implements SchoolEstimateService { + + @Override + public SetSeine loadForEdit(String setSeineId) { + + SetSeine parentToLoad = findByTopiaId(SetSeine.class, setSeineId); + + SetSeine parentLoaded = getDao(SetSeine.class).newInstance(); + + copy(SetSeine.class, BinderService.EDIT_SCHOOL_ESTIMATE, parentToLoad, parentLoaded); + + if (!parentToLoad.isSchoolEstimateEmpty()) { + + TopiaDAO<SchoolEstimate> childDao = getDao(SchoolEstimate.class); + TopiaEntityBinder<SchoolEstimate> binder = getBinder(SchoolEstimate.class, BinderService.EDIT); + + List<SchoolEstimate> childs = new ArrayList<SchoolEstimate>(); + + for (SchoolEstimate sourceChild : parentToLoad.getSchoolEstimate()) { + + SchoolEstimate targetChild = childDao.newInstance(); + binder.load(sourceChild, targetChild, true); + childs.add(targetChild); + + } + + parentLoaded.setSchoolEstimate(childs); + + } + + return parentLoaded; + + } + + @Override + public void save(SetSeine parent) { + + TopiaEntityBinder<SetSeine> parentBinder = getBinder(SetSeine.class, BinderService.EDIT_SCHOOL_ESTIMATE); + TopiaEntityBinder<SchoolEstimate> childBinder = getBinder(SchoolEstimate.class, BinderService.EDIT); + + doSaveList(parent, new SaveCollectionAction<SetSeine, SchoolEstimate>( + SetSeine.class, SchoolEstimate.class, getListUpdator(), parentBinder, childBinder)); + } + + protected EntityListUpdator<SetSeine, SchoolEstimate> getListUpdator() { + return EntityListUpdator.newEntityListUpdator( + SetSeine.class, + SchoolEstimate.class, + SetSeine.PROPERTY_SCHOOL_ESTIMATE); + } + + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/SetSeineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/SetSeineServiceImpl.java new file mode 100644 index 0000000..54d1384 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/SetSeineServiceImpl.java @@ -0,0 +1,151 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.constants.seine.SchoolType; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.NonTargetSample; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.entities.seine.SetSeineDAO; +import fr.ird.observe.entities.seine.TargetSample; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.util.DateUtil; + +import java.util.Date; +import java.util.Map; + +/** + * Created on 4/24/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class SetSeineServiceImpl extends AbstractObserveService implements SetSeineService { + + @Override + public SetSeine loadSet(String setSeineId) { + return null; + } + + @Override + public Date getRouteDate(String routeId) { + + Route route = findByTopiaId(Route.class, routeId); + Date date = route.getDate(); + return date; + + } + + @Override + public SetSeine loadForEdit(String setSeineId) { + + SetSeineDAO dao = getDao(); + SetSeine loaded = dao.newInstance(); + SetSeine toLoad = dao.findByTopiaId(setSeineId); + copy(SetSeine.class, BinderService.EDIT, toLoad, loaded); + + //FIXME See why need this ? + if (!loaded.isTargetSampleEmpty()) { + for (TargetSample e : loaded.getTargetSample()) { + e.isTargetLengthEmpty(); + } + } + + //FIXME See why need this ? + if (!loaded.isNonTargetSampleEmpty()) { + for (NonTargetSample e : loaded.getNonTargetSample()) { + e.isNonTargetLengthEmpty(); + } + } + + return loaded; + + } + + + @Override + public SetSeine preCreate(String routeId, String activitySeineId) { + + ActivitySeine activitySeine = findByTopiaId(ActivitySeine.class, activitySeineId); + + // on utilise l'heure de l'activité comme début de calée + Date date = DateUtil.getTime(activitySeine.getTime(), false, false); + + SetSeine preCreated = getDao().newInstance(); + + preCreated.setStartTime(date); + + // pour les dates de fin on utilise la date de la route + Date routeDate = getRouteDate(routeId); + + preCreated.setEndSetTimeStamp(date); + preCreated.setEndPursingTimeStamp(date); + + preCreated.setEndSetDate(routeDate); + preCreated.setEndPursingDate(routeDate); + + // recuperation du type de set a partir de l'activity + SchoolType schoolType = activitySeine.getSchoolType(); + preCreated.setSchoolType(schoolType); + + return preCreated; + + } + + @Override + public String save(String activitySeineId, SetSeine toSave) { + + String setSeineId = doSave(activitySeineId, toSave, new SaveAction<ActivitySeine, SetSeine>(ActivitySeine.class, SetSeine.class) { + + @Override + public SetSeine onCreate(ActivitySeine parent, SetSeine toCreate) { + + Map<String, Object> properties = obtainProperties(SetSeine.class, BinderService.EDIT, toCreate); + SetSeine created = getDao().create(properties); + + parent.setSetSeine(created); + + return created; + } + + @Override + public SetSeine onUpdate(ActivitySeine parent, SetSeine toUpdate) { + + SetSeine updated = super.onUpdate(parent, toUpdate); + + copyExcluding(SetSeine.class, + BinderService.EDIT, + toUpdate, + updated, + SetSeine.PROPERTY_TARGET_SAMPLE, + SetSeine.PROPERTY_NON_TARGET_SAMPLE); + return updated; + + } + }); + + return setSeineId; + + } + + + @Override + public void delete(String activitySeineId, String setSeineId) { + + // on doit supprimer physiquement la set + // car il n'y a pas de delete-orphan sur une telle relation + SetSeineDAO dao = getDao(); + SetSeine setSeine = dao.findByTopiaId(setSeineId); + dao.delete(setSeine); + + // supprime la reference sur l'activité + ActivitySeine activitySeine = findByTopiaId(ActivitySeine.class, activitySeineId); + activitySeine.setSetSeine(null); + + } + + protected SetSeineDAO getDao() { + return (SetSeineDAO) getDao(SetSeine.class); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TargetCatchServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TargetCatchServiceImpl.java new file mode 100644 index 0000000..39d45bf --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TargetCatchServiceImpl.java @@ -0,0 +1,164 @@ +package fr.ird.observe.services.data.seine; + +import com.google.common.base.Predicate; +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.referentiel.seine.WeightCategory; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.entities.seine.TargetCatch; +import fr.ird.observe.entities.seine.TargetCatches; +import fr.ird.observe.entities.seine.TargetLength; +import fr.ird.observe.entities.seine.TargetSample; +import fr.ird.observe.services.AbstractObserveService; +import fr.ird.observe.services.referential.ReferentialService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Created on 5/2/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class TargetCatchServiceImpl extends AbstractObserveService implements TargetCatchService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(TargetCatchServiceImpl.class); + + @Override + public SetSeine loadForEdit(String setSeineId) { + + SetSeine loaded = load(setSeineId, BinderService.EDIT_TARGET_CATCH, TargetCatches.TARGET_CATCH_IS_NOT_DISCARDED); + return loaded; + + } + + @Override + public SetSeine loadForEditDiscarded(String setSeineId) { + + SetSeine loaded = load(setSeineId, BinderService.EDIT_DISCARD_TARGET_CATCH, TargetCatches.TARGET_CATCH_IS_DISCARDED); + return loaded; + + } + + @Override + public void save(SetSeine setSeinetoSave, final List<TargetLength> targetLengthsToDelete) { + + save(setSeinetoSave, BinderService.EDIT_TARGET_CATCH, TargetCatches.TARGET_CATCH_IS_NOT_DISCARDED, targetLengthsToDelete); + + } + + @Override + public void saveForDiscarded(SetSeine setSeinetoSave, final List<TargetLength> targetLengthsToDelete) { + + save(setSeinetoSave, BinderService.EDIT_DISCARD_TARGET_CATCH, TargetCatches.TARGET_CATCH_IS_DISCARDED, targetLengthsToDelete); + + } + + protected SetSeine load(String setId, String binderContext, Predicate<TargetCatch> predicate) { + + TopiaDAO<SetSeine> setSeineDao = getDao(SetSeine.class); + SetSeine toLoad = setSeineDao.findByTopiaId(setId); + SetSeine loaded = setSeineDao.newInstance(); + + copyExcluding(SetSeine.class, binderContext, toLoad, loaded, SetSeine.PROPERTY_TARGET_CATCH); + + if (!toLoad.isTargetCatchEmpty()) { + + ReferentialService referentialService = newService(ReferentialService.class); + + TopiaDAO<TargetCatch> dao = getDao(TargetCatch.class); + TopiaEntityBinder<TargetCatch> binder = getBinder(TargetCatch.class, binderContext); + + List<TargetCatch> childsLoaded = new ArrayList<TargetCatch>(); + + for (TargetCatch childToLoad : toLoad.getTargetCatch()) { + + if (predicate.apply(childToLoad)) { + + WeightCategory weightCategory = childToLoad.getWeightCategory(); + if (weightCategory != null) { + referentialService.loadDecoratedWeightCategory(weightCategory); + } + + TargetCatch childLoaded = dao.newInstance(); + binder.load(childToLoad, childLoaded, true); + childsLoaded.add(childLoaded); + + } + + } + + loaded.setTargetCatch(childsLoaded); + + } + + return loaded; + + } + + void save(SetSeine setSeinetoSave, String binderContext, final Predicate<TargetCatch> predicate, final List<TargetLength> targetLengthsToDelete) { + + TopiaEntityBinder<SetSeine> parentBinder = getBinder(SetSeine.class, binderContext); + TopiaEntityBinder<TargetCatch> childBinder = getBinder(TargetCatch.class, binderContext); + + doSaveList(setSeinetoSave, new SaveCollectionAction<SetSeine, TargetCatch>( + SetSeine.class, TargetCatch.class, getListUpdator(), parentBinder, childBinder, predicate) { + + @Override + public void onUpdateFinalize(SetSeine parentSaved, Collection<TargetCatch> oldChilds) throws TopiaException { + + if (CollectionUtils.isNotEmpty(oldChilds)) { + + Collection<TargetCatch> targetCatchesToReinject = new ArrayList<TargetCatch>(); + + for (TargetCatch oldChild : oldChilds) { + + if (predicate.apply(oldChild)) { + + // on réinjecte cette capture + targetCatchesToReinject.add(oldChild); + + } + + } + + parentSaved.addAllTargetCatch(targetCatchesToReinject); + + } + + if (CollectionUtils.isNotEmpty(targetLengthsToDelete)) { + + // suppression des échantillons obsoletes + + if (log.isInfoEnabled()) { + log.info("Will remove " + targetLengthsToDelete.size() + " obsolete targetLength(s)."); + } + + TargetSample targetSample = parentSaved.getTargetSample().get(0); + + // on supprime les echantillons obsoletes + targetSample.getTargetLength().removeAll(targetLengthsToDelete); + + } + } + }); + + } + + protected EntityListUpdator<SetSeine, TargetCatch> getListUpdator() { + return EntityListUpdator.newEntityListUpdator( + SetSeine.class, + TargetCatch.class, + SetSeine.PROPERTY_TARGET_CATCH); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TargetSampleServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TargetSampleServiceImpl.java new file mode 100644 index 0000000..5777067 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TargetSampleServiceImpl.java @@ -0,0 +1,276 @@ +package fr.ird.observe.services.data.seine; + +import com.google.common.collect.Lists; +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.referentiel.Species; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.entities.seine.TargetCatch; +import fr.ird.observe.entities.seine.TargetLength; +import fr.ird.observe.entities.seine.TargetLengthDAO; +import fr.ird.observe.entities.seine.TargetSample; +import fr.ird.observe.entities.seine.TargetSampleDAO; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * Created on 4/26/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class TargetSampleServiceImpl extends AbstractObserveService implements TargetSampleService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(TargetSampleServiceImpl.class); + + @Override + public List<Species> getAvailableSpeciesForTargetSample(String setSeineId, boolean discarded) { + + List<Species> speciesList = new ArrayList<Species>(); + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + + // on recupere la liste des espèces thon utilisees dans le rejet + Collection<TargetCatch> targetCatches = setSeine.getTargetCatch(); + + // on filtre sur les espèces montées sur le pont et rejetées + + if (targetCatches != null) { + + for (TargetCatch targetCatch : targetCatches) { + + boolean keep; + + if (discarded) { + + // on ne conserve que les espèces rejectées montées sur le pont + keep = targetCatch.isDiscarded() && targetCatch.getBroughtOnDeck(); + + } else { + + // on ne conserve que les espèces rejectées + keep = !targetCatch.isDiscarded(); + } + + if (keep && + !speciesList.contains(targetCatch.getWeightCategory().getSpecies())) { + speciesList.add(targetCatch.getWeightCategory().getSpecies()); + } + + } + + } + + return speciesList; + + } + + @Override + public TargetSample loadForEdit(String setSeineId, boolean discarded) { + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + + TargetSample toLoad = null; + + if (!setSeine.isTargetSampleEmpty()) { + + List<TargetSample> targetSamples = setSeine.getTargetSample(); + for (TargetSample targetSample : targetSamples) { + + Boolean isDiscarded = targetSample.getDiscarded(); + + if (discarded == (isDiscarded != null && isDiscarded)) { + toLoad = targetSample; + } + + } + + } + + TargetSample loaded = getDao().newInstance(); + + if (toLoad != null) { + + copyExcluding(TargetSample.class, BinderService.EDIT_TARGET_LENGTH, toLoad, loaded, TargetSample.PROPERTY_TARGET_LENGTH); + + + if (!toLoad.isTargetLengthEmpty()) { + + TopiaEntityBinder<TargetLength> binder = getBinder(TargetLength.class, BinderService.EDIT); + TopiaDAO<TargetLength> dao = getDao(TargetLength.class); + + for (TargetLength childToLoad : toLoad.getTargetLength()) { + + TargetLength childLoaded = dao.newInstance(); + binder.load(childToLoad, childLoaded, true); + loaded.addTargetLength(childLoaded); + + } + } + } + + + return loaded; + } + + @Override + public boolean canUseTargetSample(String setSeineId, boolean discarded) { + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + return setSeine.canUseTargetSample(discarded); + + } + + @Override + public List<TargetLength> getObsoleteTargetLengths(String setSeineId, Set<String> speciesIdsUsed, boolean discarded) { + + SetSeine setSeine = findByTopiaId(SetSeine.class, setSeineId); + + List<TargetLength> targetLengthsToDelete = new ArrayList<TargetLength>(); + + if (!setSeine.isTargetSampleEmpty()) { + + TargetSample targetSample = setSeine.getTargetSample(discarded); + if (targetSample != null && !targetSample.isTargetLengthEmpty()) { + + for (TargetLength targetLength : targetSample.getTargetLength()) { + + Species species = targetLength.getSpecies(); + + if (!speciesIdsUsed.contains(species.getTopiaId())) { + // l'espèce n'existe plus dans les rejet faune, on doit le supprimer + targetLengthsToDelete.add(targetLength); + if (log.isDebugEnabled()) { + log.debug("remove obsolote echantillon " + targetLength + " for species " + species); + } + } + + } + + } + + } + + return targetLengthsToDelete; + + } + + @Override + public String save(String setSeineId, TargetSample toSave) { + + String savedId = doSave(setSeineId, toSave, new SaveAction<SetSeine, TargetSample>(SetSeine.class, TargetSample.class) { + + @Override + public TargetSample onCreate(SetSeine parent, TargetSample toCreate) { + + TargetSample created = getDao().create(); + copyExcluding(TargetSample.class, BinderService.EDIT, toCreate, created, false, TargetSample.PROPERTY_TARGET_LENGTH); + parent.addTargetSample(created); + + saveTargetLengths(toCreate.getTargetLength(), created); + + getDao().update(created); + return created; + + } + + @Override + public TargetSample onUpdate(SetSeine parent, TargetSample toUpdate) { + + TargetSample updated = super.onUpdate(parent, toUpdate); + + copyExcluding(TargetSample.class, BinderService.EDIT, toUpdate, updated, false, TargetSample.PROPERTY_TARGET_LENGTH); + + saveTargetLengths(toUpdate.getTargetLength(), updated); + + getDao().update(updated); + return updated; + + } + + protected void saveTargetLengths(Collection<TargetLength> targetLengthsToSave, TargetSample childSaved) { + + List<TargetLength> targetLengthsSaved = Lists.newArrayList(); + + if (CollectionUtils.isNotEmpty(targetLengthsToSave)) { + + TopiaDAO<TargetLength> dao = getDao(TargetLength.class); + TopiaEntityBinder<TargetLength> binder = getBinder(TargetLength.class, BinderService.EDIT); + + for (TargetLength targetLengthToSave : targetLengthsToSave) { + + TargetLength targetLengthSaved; + + if (Entities.isNew(targetLengthToSave)) { + + targetLengthSaved = dao.create(); + binder.load(targetLengthToSave, targetLengthSaved, false); + + } else { + + targetLengthSaved = dao.findByTopiaId(targetLengthToSave.getTopiaId()); + binder.load(targetLengthToSave, targetLengthSaved, true); + + } + + targetLengthsSaved.add(targetLengthSaved); + + } + + } + + childSaved.clearTargetLength(); + childSaved.addAllTargetLength(targetLengthsSaved); + + } + + + }); + + return savedId; + + } + + @Override + public void delete(String setSeineId, TargetSample bean) { + + doDelete(setSeineId, bean.getTopiaId(), new DeleteAction<SetSeine, TargetSample>(SetSeine.class, TargetSample.class) { + + @Override + public void onDelete(SetSeine parent, TargetSample toDelete) { + + super.onDelete(parent, toDelete); + parent.removeTargetSample(toDelete); + + } + }); + + } + + protected TargetSampleDAO getDao() { + return (TargetSampleDAO) getDao(TargetSample.class); + } + + protected TargetLengthDAO getChildDao() { + return (TargetLengthDAO) getDao(TargetLength.class); + } + + protected EntityListUpdator<TargetSample, TargetLength> getListUpdator() { + return EntityListUpdator.newEntityListUpdator( + TargetSample.class, + TargetLength.class, + TargetSample.PROPERTY_TARGET_LENGTH); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TripSeineServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TripSeineServiceImpl.java new file mode 100644 index 0000000..7c63b1b --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/data/seine/TripSeineServiceImpl.java @@ -0,0 +1,136 @@ +package fr.ird.observe.services.data.seine; + +import fr.ird.observe.BinderService; +import fr.ird.observe.entities.constants.ReferenceLocale; +import fr.ird.observe.entities.referentiel.Program; +import fr.ird.observe.entities.seine.Routes; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.entities.seine.TripSeineDAO; +import fr.ird.observe.services.AbstractObserveService; +import org.nuiton.util.DateUtil; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Created on 4/24/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class TripSeineServiceImpl extends AbstractObserveService implements TripSeineService { + + protected TripSeineDAO getDao() { + return (TripSeineDAO) getDao(TripSeine.class); + } + + @Override + public List<TripSeine> getTripSeineStubByProgram(String programId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + List<TripSeine> result = getDao().findAllStubByProgramId(programId, referentielLocale); + return result; + + } + + @Override + public TripSeine getTripSeineStub(String tripId) { + + ReferenceLocale referentielLocale = getReferentielLocale(); + TripSeine result = getDao().findStubByTopiaId(tripId, referentielLocale); + return result; + + } + + @Override + public TripSeine loadForDisplay(String tripSeineId) { + + TripSeine loaded = getDao().newInstance(); + TripSeine toLoad = getDao().findByTopiaId(tripSeineId); + copy(TripSeine.class, BinderService.EDIT, toLoad, loaded); + + if (!loaded.isRouteEmpty()) { + + // on force le trie des routes + Routes.sort(loaded.getRoute()); + } + + return loaded; + + } + + @Override + public TripSeine loadForEdit(String tripSeineId) { + + TripSeine loaded = loadForDisplay(tripSeineId); + if (loaded.getEndDate() == null) { + Date date = DateUtil.getEndOfDay(now()); + loaded.setEndDate(date); + } + + return loaded; + + } + + @Override + public TripSeine preCreate(String programId) { + + Program program = findByTopiaId(Program.class, programId); + + TripSeine preCreated = getDao().newInstance(); + + Date date = DateUtil.getDay(now()); + preCreated.setStartDate(date); + preCreated.setEndDate(date); + preCreated.setProgram(program); + + return preCreated; + + } + + @Override + public String save(TripSeine toSave) { + String tripSeineId = doSave(null, toSave, new SaveAction<Program, TripSeine>(Program.class, TripSeine.class) { + + @Override + public void beforeSave(String parentId, TripSeine toSave) { + + super.beforeSave(parentId, toSave); + Date startDate = DateUtil.getDay(toSave.getStartDate()); + toSave.setStartDate(startDate); + + // mise a jour de la date de fin + toSave.updateDateFin(); + + } + + @Override + public TripSeine onCreate(Program parent, TripSeine toCreate) { + + Map<String, Object> properties = obtainProperties(TripSeine.class, BinderService.EDIT, toCreate); + TripSeine created = getDao().create(properties); + return created; + + } + + @Override + public TripSeine onUpdate(Program parent, TripSeine toUpdate) { + + TripSeine updated = super.onUpdate(parent, toUpdate); + copyExcluding(TripSeine.class, BinderService.EDIT, toUpdate, updated, TripSeine.PROPERTY_ROUTE); + return updated; + + } + }); + + return tripSeineId; + + } + + @Override + public void delete(String idtoDelete) { + doDelete(null, idtoDelete, new DeleteAction<Program, TripSeine>(Program.class, TripSeine.class)); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/ComputeDataServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/ComputeDataServiceImpl.java new file mode 100644 index 0000000..511b351 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/ComputeDataServiceImpl.java @@ -0,0 +1,832 @@ +package fr.ird.observe.services.operation; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.Collections2; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import fr.ird.observe.DecoratorService; +import fr.ird.observe.ObserveDAOHelper; +import fr.ird.observe.SendMessageAble; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.LengthWeightComputable; +import fr.ird.observe.entities.constants.seine.NonTargetCatchComputedValueSource; +import fr.ird.observe.entities.constants.seine.SchoolType; +import fr.ird.observe.entities.referentiel.LengthWeightParameter; +import fr.ird.observe.entities.referentiel.Ocean; +import fr.ird.observe.entities.referentiel.Sex; +import fr.ird.observe.entities.referentiel.Species; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.NonTargetCatch; +import fr.ird.observe.entities.seine.NonTargetLength; +import fr.ird.observe.entities.seine.NonTargetSample; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.SetSeine; +import fr.ird.observe.entities.seine.TargetLength; +import fr.ird.observe.entities.seine.TargetSample; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.services.AbstractObserveService; +import fr.ird.observe.services.referential.ReferentialService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.util.TopiaEntityHelper; +import org.nuiton.topia.persistence.util.TopiaEntityRef; +import org.nuiton.util.beans.BeanMonitor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; + +import static org.nuiton.i18n.I18n.t; + +/** + * FIXME A revoir, utiliser un context pour ne pas avoir d'état dans le service + on ne peut plus utiliser de messager + * On retounera un objet de type result. + * + * Created on 5/3/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ComputeDataServiceImpl extends AbstractObserveService implements ComputeDataService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ComputeDataServiceImpl.class); + + private static final String MESSAGE_FORMAT_3 = + "[%1$s] %2$s calculé : %3$s (%4$s:%5$s, %6$s:%7$s)"; + + protected final BeanMonitor targetLengthMonitor = new BeanMonitor( + TargetLength.PROPERTY_LENGTH, + TargetLength.PROPERTY_LENGTH_SOURCE, + TargetLength.PROPERTY_WEIGHT, + TargetLength.PROPERTY_WEIGHT_SOURCE); + + protected final BeanMonitor nonTargetLengthMonitor = new BeanMonitor( + NonTargetLength.PROPERTY_LENGTH, + NonTargetLength.PROPERTY_LENGTH_SOURCE, + NonTargetLength.PROPERTY_WEIGHT, + NonTargetLength.PROPERTY_WEIGHT_SOURCE); + + protected final BeanMonitor nonTargetCatchMonitor = new BeanMonitor( + NonTargetCatch.PROPERTY_MEAN_LENGTH, + NonTargetCatch.PROPERTY_MEAN_LENGTH_COMPUTED_SOURCE, + NonTargetCatch.PROPERTY_MEAN_WEIGHT, + NonTargetCatch.PROPERTY_MEAN_WEIGHT_COMPUTED_SOURCE, + NonTargetCatch.PROPERTY_CATCH_WEIGHT, + NonTargetCatch.PROPERTY_CATCH_WEIGHT_COMPUTED_SOURCE, + NonTargetCatch.PROPERTY_TOTAL_COUNT, + NonTargetCatch.PROPERTY_TOTAL_COUNT_COMPUTED_SOURCE + ); + + protected String nonTargetCatcheLabel; + + protected String speciesLabel; + + protected ReferentialService referentialService; + + protected ReferentialService getReferentialService() { + if (referentialService == null) { + referentialService = newService(ReferentialService.class); + } + return referentialService; + } + + protected String getNonTargetCatcheLabel() { + if (nonTargetCatcheLabel == null) { + nonTargetCatcheLabel = t(DecoratorService.getEntityLabel(NonTargetCatch.class)); + } + return nonTargetCatcheLabel; + } + + protected String getSpeciesLabel() { + if (speciesLabel == null) { + speciesLabel = t(DecoratorService.getEntityLabel(Species.class)); + } + return speciesLabel; + + } + + protected void clear() { + + nonTargetLengthMonitor.setBean(null); + targetLengthMonitor.setBean(null); + nonTargetCatchMonitor.setBean(null); + nonTargetCatcheLabel = null; + speciesLabel = null; + + } + + @Override + public void consolidateTrips(SendMessageAble messager, Set<String> tripIds) { + + if (messager == null) { + + messager = new SendMessageAble() { + + @Override + public void sendMessage(String message) { + if (log.isInfoEnabled()) { + log.info(message); + } + } + }; + + } + + TopiaDAO<TripSeine> dao = getDao(TripSeine.class); + + List<TripSeine> toUpdate = new ArrayList<TripSeine>(tripIds.size()); + + for (String tripId : tripIds) { + + if (Entities.isSeineId(tripId)) { + + TripSeine trip = dao.findByTopiaId(tripId); + + boolean needUpdate = consolidateTripSeine(messager, trip); + if (needUpdate) { + + // on met a jour la maree en base + dao.update(trip); + + // on conserve une reference sur la maree mise à jour + toUpdate.add(trip); + + } + + } + + } + + // on commite si quelque chose a ete mise a jour + boolean needCommit = !toUpdate.isEmpty(); + + if (needCommit) { + + messager.sendMessage(t("observe.message.consolidate.save.changes", toUpdate.size())); + getTransaction().commitTransaction(); + + } + + } + + protected boolean consolidateTripSeine(SendMessageAble messager, TripSeine maree) { + + clear(); + + String mareeStr = decorateEntity(maree); + + messager.sendMessage(t("observe.message.consolidate.start.maree", mareeStr)); + + // recuperation des ids des sets de la maree + String[] activityIds = getActivityIds(maree); + + if (activityIds.length == 0) { + + // pas de set dans cette maree, donc rien a sauvegarder + messager.sendMessage(t("observe.message.consolidate.no.activity.from.maree", mareeStr)); + return false; + } + + // recuperation des references vers les activitys avec set + SortedMap<TopiaEntity, List<TopiaEntityRef>> result; + + result = TopiaEntityHelper.detectReferences( + ObserveDAOHelper.getContracts(), activityIds, maree); + + List<ActivitySeine> toUpdate = new ArrayList<ActivitySeine>(result.size()); + for (Map.Entry<TopiaEntity, List<TopiaEntityRef>> e : + result.entrySet()) { + ActivitySeine activitySeine = (ActivitySeine) e.getKey(); + List<TopiaEntityRef> refs = e.getValue(); + TopiaEntityRef ref = refs.get(0); + TopiaEntity[] path = ref.getPath(); + Route route = (Route) path[path.length - 2]; + boolean needUpdate = consolidateActivity(messager, + maree, + route, + activitySeine + ); + if (needUpdate) { + toUpdate.add(activitySeine); + } + } + if (toUpdate.isEmpty()) { + + // rien n'a ete modifie + messager.sendMessage(t("observe.message.consolidate.nothing.to.save.for.maree", mareeStr)); + return false; + + } + + // on devra mettre a jour en base la maree + messager.sendMessage(t("observe.message.consolidate.maree.need.update", mareeStr)); + + return true; + + } + + protected boolean consolidateActivity(SendMessageAble messager, + TripSeine maree, + Route route, + ActivitySeine activity) { + + messager.sendMessage(t("observe.message.consolidate.start.activity", decorateEntity(activity))); + + boolean needUpdate = false; + SetSeine set = activity.getSetSeine(); + SchoolType oldTypeBanc = set.getSchoolType(); + SchoolType newTypeBanc = activity.getSchoolType(); + if (oldTypeBanc == null || oldTypeBanc != newTypeBanc) { + + // le type de banc a change, on doit sauver l'activity + needUpdate = true; + set.setSchoolType(newTypeBanc); + } + + if (!set.isTargetSampleEmpty()) { + + // des echantillons thons trouves + for (TargetSample targetSample : set.getTargetSample()) { + if (!targetSample.isTargetLengthEmpty()) { + for (TargetLength targetLength : + targetSample.getTargetLength()) { + + targetLengthMonitor.setBean(targetLength); + + updateLengthWeightAble( + maree, + route.getDate(), + targetLength.getSpecies(), + null, // pas de gender precise + targetLength + ); + + if (targetLengthMonitor.wasModified()) { + needUpdate = true; + } + } + } + } + } + + if (!set.isNonTargetSampleEmpty()) { + + // des echantillons faunes trouves + for (NonTargetSample nonTargetSample : + set.getNonTargetSample()) { + + if (!nonTargetSample.isNonTargetLengthEmpty()) { + for (NonTargetLength nonTargetLength : + nonTargetSample.getNonTargetLength()) { + + nonTargetLengthMonitor.setBean(nonTargetLength); + + updateLengthWeightAble( + maree, + route.getDate(), + nonTargetLength.getSpecies(), + nonTargetLength.getSex(), + nonTargetLength + ); + if (nonTargetLengthMonitor.wasModified()) { + needUpdate = true; + } + } + } + } + } + + if (!set.isNonTargetCatchEmpty()) { + + // des captures (ou rejets) faunes trouves + for (NonTargetCatch nonTargetCatch : set.getNonTargetCatch()) { + + nonTargetCatchMonitor.setBean(nonTargetCatch); + + // suppression de tous les champs précédemment calculés + + if (nonTargetCatch.isCatchWeightComputed()) { + nonTargetCatch.setCatchWeight(null); + nonTargetCatch.setCatchWeightComputedSource(null); + } + + if (nonTargetCatch.isTotalCountComputed()) { + nonTargetCatch.setTotalCount(null); + nonTargetCatch.setTotalCountComputedSource(null); + } + + if (nonTargetCatch.isMeanWeightComputed()) { + nonTargetCatch.setMeanWeight(null); + nonTargetCatch.setMeanWeightComputedSource(null); + } + + if (nonTargetCatch.isMeanLengthComputed()) { + nonTargetCatch.setMeanLength(null); + nonTargetCatch.setMeanLengthComputedSource(null); + } + + updateNonTargetCatch( + maree, + set, + route.getDate(), + nonTargetCatch + ); + + if (nonTargetCatchMonitor.wasModified()) { + needUpdate = true; + } + } + } + return needUpdate; + } + + protected void updateNonTargetCatch(TripSeine maree, + SetSeine set, + Date jour, + NonTargetCatch nonTargetCatch) { + + final Species species = nonTargetCatch.getSpecies(); + + // récupération du référentiel + LengthWeightParameter parametrage = getReferentialService().findLengthWeightParameter(species, + maree.getOcean(), + null, // pas de sexe spécifié + jour); + + // -- Cas n°1 (calcul uniquement à partir des relations taille - poids) + updateNonTargetCatchByLengthWeightRelation(nonTargetCatch, parametrage); + + if (allNonTargetCatchDataFilled(nonTargetCatch)) { + + // tout est rempli, plus rien à faire + return; + } + + // répération des échantillon de cette espèce sur les calée + + Collection<NonTargetLength> samples = null; + + if (!set.isNonTargetSampleEmpty()) { + samples = Collections2.filter(set.getNonTargetSample().iterator().next().getNonTargetLength(), new Predicate<NonTargetLength>() { + + @Override + public boolean apply(NonTargetLength input) { + return species.equals(input.getSpecies()); + } + }); + } + + + if (nonTargetCatch.getCatchWeight() != null || nonTargetCatch.getTotalCount() != null) { + + // -- Cas n°2 (pas de taille / poids moyen mais au moins un des deux taille / poids) + computeNonTargetCatchTailleMoyenne(nonTargetCatch, samples, parametrage); + } + + if (allNonTargetCatchDataFilled(nonTargetCatch)) { + + // tout est rempli, plus rien à faire + return; + } + + // -- Cas n°3 (pas de nombre estimé) + + if (nonTargetCatch.getTotalCount() == null) { + + computeNonTargetCatchNombreEstime(nonTargetCatch, samples, parametrage); + + } + + if (allNonTargetCatchDataFilled(nonTargetCatch)) { + + // tout est rempli, plus rien à faire + return; + } + + // -- Cas n°4 (pas de poids moyen, taille moyenne) + + computeNonTargetCatchMeanValues(nonTargetCatch, parametrage); + } + + protected void updateNonTargetCatchByLengthWeightRelation(NonTargetCatch nonTargetCatch, + LengthWeightParameter parametrage) { + + // calcul via le paramétrage taille - poids + updateLengthWeightAble( + nonTargetCatch.getSpecies(), + nonTargetCatch, + parametrage + ); + + // calcule l'un des trois champs poids estimé - nbEstime - poids moyen + updateNonTargetCatchPoidsEstimeNbEstimePoidsMoyen(nonTargetCatch); + + // on ressaye d'appliquer la relation taille - poids au cas où une des + // trois valeurs précédentes a été calculée, on pourrait peut-être + // ainsi en déduire via le paramétrage la taille moyenne + updateLengthWeightAble( + nonTargetCatch.getSpecies(), + nonTargetCatch, + parametrage + ); + } + + protected void updateNonTargetCatchPoidsEstimeNbEstimePoidsMoyen(NonTargetCatch nonTargetCatch) { + + Float meanWeight = nonTargetCatch.getMeanWeight(); + Float catchWeight = nonTargetCatch.getCatchWeight(); + Integer nbEstime = nonTargetCatch.getTotalCount(); + + String entityLabel = getNonTargetCatcheLabel(); + + if (catchWeight == null && nbEstime != null && meanWeight != null) { + + // calcul le weight poids à partir de nb estime et du poids moyen + catchWeight = meanWeight * (float) nbEstime / 1000; + nonTargetCatch.setCatchWeight(catchWeight); + nonTargetCatch.setCatchWeightComputedSource(NonTargetCatchComputedValueSource.FROM_DATA); + String message = String.format(MESSAGE_FORMAT_3, + entityLabel, + t("observe.common.catchWeight"), + catchWeight, + t("observe.common.meanWeight"), + meanWeight, + t("observe.common.totalCount"), + nbEstime); + if (log.isInfoEnabled()) { + log.info(message); + } + } + + if (nbEstime == null && catchWeight != null && meanWeight != null) { + + // calcul le nb estime à partir du poids estime et du poids moyen + nbEstime = (int) ((float) 1000 * catchWeight / meanWeight); + nonTargetCatch.setTotalCount(nbEstime); + nonTargetCatch.setTotalCountComputedSource(NonTargetCatchComputedValueSource.FROM_DATA); + String message = String.format(MESSAGE_FORMAT_3, + entityLabel, + t("observe.common.totalCount"), + nbEstime, + t("observe.common.meanWeight"), + meanWeight, + t("observe.common.catchWeight"), + catchWeight); + if (log.isInfoEnabled()) { + log.info(message); + } + } + + if (meanWeight == null && nbEstime != null && nbEstime != 0 && catchWeight != null && + !NonTargetCatchComputedValueSource.FROM_SAMPLE.equals(nonTargetCatch.getTotalCountComputedSource())) { + + // calcul le poids moyen à partir de nb estime et du poids estime + // uniquement si le nombre estimé ne vient pas des échantillons (voir http://forge.codelutin.com/issues/4670) + + meanWeight = catchWeight * (float) 1000 / (float) nbEstime; + nonTargetCatch.setMeanWeight(meanWeight); + nonTargetCatch.setMeanWeightComputedSource(NonTargetCatchComputedValueSource.FROM_DATA); + String message = String.format(MESSAGE_FORMAT_3, + entityLabel, + t("observe.common.meanWeight"), + meanWeight, + t("observe.common.totalCount"), + nbEstime, + t("observe.common.catchWeight"), + catchWeight); + if (log.isInfoEnabled()) { + log.info(message); + } + } + } + + protected void updateLengthWeightAble(TripSeine maree, + Date jour, + Species species, + Sex sex, + LengthWeightComputable e) { + + Ocean ocean = maree.getOcean(); + + String entityLabel = getSpeciesLabel(); + + Float weight = e.getWeight(); + boolean computePoids = false; + boolean computeTaille = false; + Float taille = e.getLength(); + + if (weight == null && taille != null) { + + // on essaye de calculer le weight + computePoids = true; + } + + if (taille == null && weight != null) { + + // on essaye de calcule la length + computeTaille = true; + } + + if (!computeTaille && !computePoids) { + + // rien a calculer + return; + } + + // recherche du parametrage adequate + LengthWeightParameter parametrage = + getReferentialService().findLengthWeightParameter( + species, + ocean, + sex, + jour + ); + + if (parametrage == null) { + + // aucun parametrage connu + + String message = t("observe.message.consolidate.no.parametrage.found", + t(entityLabel), + decorateEntity(species) + ); + if (log.isWarnEnabled()) { + log.warn(message); + } + return; + } + + if (computeTaille) { + Float newTaille = parametrage.computeLength(weight); + if (newTaille != null) { + + // la taille a ete calculee + String message = + "[" + t(entityLabel) + "] " + + t("observe.message.consolidate.computed.taille", + newTaille, + weight, + parametrage.getWeightLengthFormula(), + parametrage.getCoefficients() + ); + if (log.isInfoEnabled()) { + log.info(message); + } + e.setLength(newTaille); + e.setLengthSource(true); + return; + } + + // la taille n'a pas changee, on peut quitter car il est impossible + // de calculer et la taille et le poids... + return; + } + + // on cherche obligatoirement a calculer le poids + Float newPoids = parametrage.computeWeight(taille); + if (newPoids != null) { + + // le poids a ete calcule + String message = "[" + t(entityLabel) + "] " + + t("observe.message.consolidate.computed.weight", + newPoids, + taille, + parametrage.getLengthWeightFormula(), + parametrage.getCoefficients()); + if (log.isInfoEnabled()) { + log.info(message); + } + e.setWeight(newPoids); + e.setWeightSource(true); + } + } + + protected void updateLengthWeightAble(Species species, + LengthWeightComputable e, + LengthWeightParameter parametrage) { + + String entityLabel = getSpeciesLabel(); + + Float weight = e.getWeight(); + boolean computePoids = false; + boolean computeTaille = false; + Float taille = e.getLength(); + + if (weight == null && taille != null) { + + // on essaye de calculer le weight + computePoids = true; + } + + if (taille == null && weight != null) { + + // on essaye de calcule la length + computeTaille = true; + } + + if (!computeTaille && !computePoids) { + + // rien a calculer + return; + } + + if (parametrage == null) { + + // aucun parametrage connu + + String message = t("observe.message.consolidate.no.parametrage.found", + t(entityLabel), + decorateEntity(species) + ); + if (log.isWarnEnabled()) { + log.warn(message); + } + return; + } + + if (computeTaille) { + Float newTaille = parametrage.computeLength(weight); + if (newTaille != null) { + + // la taille a ete calculee + String message = + "[" + t(entityLabel) + "] " + + t("observe.message.consolidate.computed.taille", + newTaille, + weight, + parametrage.getWeightLengthFormula(), + parametrage.getCoefficients() + ); + if (log.isInfoEnabled()) { + log.info(message); + } + e.setLength(newTaille); + e.setLengthSource(true); + return; + } + + // la taille n'a pas changee, on peut quitter car il est impossible + // de calculer et la taille et le poids... + return; + } + + // on cherche obligatoirement a calculer le weight + Float newPoids = parametrage.computeWeight(taille); + if (newPoids != null) { + + // le weight a ete calcule + String message = "[" + t(entityLabel) + "] " + + t("observe.message.consolidate.computed.weight", + newPoids, + taille, + parametrage.getLengthWeightFormula(), + parametrage.getCoefficients()); + if (log.isInfoEnabled()) { + log.info(message); + } + e.setWeight(newPoids); + e.setWeightSource(true); + } + } + + protected void computeNonTargetCatchTailleMoyenne(NonTargetCatch nonTargetCatch, + Collection<NonTargetLength> samples, + LengthWeightParameter parametrage) { + + Float meanLength = null; + NonTargetCatchComputedValueSource computedSource = null; + + if (CollectionUtils.isNotEmpty(samples)) { + + // on calcul la taille moyenne à partir des échantillons + float totalTaille = 0f; + int nbIndividus = 0; + for (NonTargetLength sample : samples) { + + Integer count = sample.getCount(); + Float length = sample.getLength(); + + if (count != null && length != null) { + nbIndividus += count; + totalTaille += length * count; + } + } + + if (nbIndividus != 0) { + + meanLength = totalTaille / nbIndividus; + + computedSource = NonTargetCatchComputedValueSource.FROM_SAMPLE; + } + } + + if (meanLength == null && parametrage != null) { + + // on prend directement la valeur fournie par le référentiel + + meanLength = parametrage.getMeanLength(); + computedSource = NonTargetCatchComputedValueSource.FROM_REFERENTIEL; + } + + if (meanLength != null) { + + // la taille moyenne a pu etre calculee, on la pousse alors + nonTargetCatch.setMeanLength(meanLength); + nonTargetCatch.setMeanLengthComputedSource(computedSource); + + // on peut aussi relancer la calcul du cas n°1 + updateNonTargetCatchByLengthWeightRelation(nonTargetCatch, parametrage); + } + + } + + private void computeNonTargetCatchNombreEstime(NonTargetCatch nonTargetCatch, + Collection<NonTargetLength> samples, + LengthWeightParameter parametrage) { + + + if (CollectionUtils.isNotEmpty(samples)) { + + // on calcul la taille moyenne à partir des échantillons + int nbIndividus = 0; + for (NonTargetLength sample : samples) { + + Integer count = sample.getCount(); + + if (count != null) { + nbIndividus += count; + } + } + + if (nbIndividus != 0) { + + nonTargetCatch.setTotalCount(nbIndividus); + nonTargetCatch.setTotalCountComputedSource(NonTargetCatchComputedValueSource.FROM_SAMPLE); + + if (nonTargetCatch.getMeanWeight() != null || nonTargetCatch.getMeanLength() != null) { + + // on peut aussi relancer la calcul du cas n°1 + updateNonTargetCatchByLengthWeightRelation(nonTargetCatch, parametrage); + } + } + } + } + + private void computeNonTargetCatchMeanValues(NonTargetCatch nonTargetCatch, + LengthWeightParameter parametrage) { + + if (parametrage != null) { + + nonTargetCatch.setMeanLength(parametrage.getMeanLength()); + nonTargetCatch.setMeanLengthComputedSource(NonTargetCatchComputedValueSource.FROM_REFERENTIEL); + + nonTargetCatch.setMeanWeight(parametrage.getMeanWeight()); + nonTargetCatch.setMeanWeightComputedSource(NonTargetCatchComputedValueSource.FROM_REFERENTIEL); + + if (nonTargetCatch.getMeanWeight() != null || nonTargetCatch.getMeanLength() != null) { + + // on peut aussi relancer la calcul du cas n°1 + updateNonTargetCatchByLengthWeightRelation(nonTargetCatch, parametrage); + } + } + } + + //FIXME Use a simple sql query + protected String[] getActivityIds(TripSeine maree) { + List<String> tmpIds = new ArrayList<String>(); + if (!maree.isRouteEmpty()) { + for (Route route : maree.getRoute()) { + if (!route.isActivitySeineEmpty()) { + for (ActivitySeine activitySeine : route.getActivitySeine()) { + if (activitySeine.getSetSeine() != null) { + + // on ne retient que les activitys avec set + tmpIds.add(activitySeine.getTopiaId()); + } + } + } + } + } + String[] result = tmpIds.toArray(new String[tmpIds.size()]); + return result; + } + + protected boolean allNonTargetCatchDataFilled(NonTargetCatch nonTargetCatch) { + return Iterables.all( + Sets.newHashSet(nonTargetCatch.getCatchWeight(), + nonTargetCatch.getTotalCount(), + nonTargetCatch.getMeanWeight(), + nonTargetCatch.getMeanLength()), + Predicates.notNull()); + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/GpsImportServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/GpsImportServiceImpl.java new file mode 100644 index 0000000..4c59cdd --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/GpsImportServiceImpl.java @@ -0,0 +1,133 @@ +package fr.ird.observe.services.operation; + +import fr.ird.observe.SendMessageAble; +import fr.ird.observe.entities.seine.ActivitySeine; +import fr.ird.observe.entities.seine.Route; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.entities.seine.TripSeineDAO; +import fr.ird.observe.gps.GPSPoint; +import fr.ird.observe.services.AbstractObserveService; +import org.apache.commons.collections.primitives.ArrayIntList; +import org.apache.commons.collections.primitives.IntIterator; +import org.apache.commons.collections.primitives.IntList; +import org.nuiton.decorator.Decorator; +import org.nuiton.topia.persistence.TopiaDAO; + +import java.util.HashMap; +import java.util.Map; + +import static org.nuiton.i18n.I18n.t; + +/** + * Created on 5/3/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class GpsImportServiceImpl extends AbstractObserveService implements GpsImportService { + + @Override + public Map<ActivitySeine, GPSPoint> getActivitiesForOpenRoute(String openTripSeineId) { + + Map<ActivitySeine, GPSPoint> data; + + + TripSeine openTripSeine = findByTopiaId(TripSeine.class, openTripSeineId); + + if (openTripSeine.isRouteEmpty()) { + + // pas de route sur la maree ouverte + data = null; + + } else { + + data = new HashMap<ActivitySeine, GPSPoint>(); + + for (Route r : openTripSeine.getRoute()) { + if (!r.isActivitySeineEmpty()) { + // on enregistre les actitives + for (ActivitySeine a : r.getActivitySeine()) { + data.put(a, null); + } + } + } + } + + return data; + + } + + @Override + public void applyPoints(Map<ActivitySeine, GPSPoint> data, int[] selectedIndex, SendMessageAble messanger) { + + Decorator<ActivitySeine> dActivity = getDecoratorByType(ActivitySeine.class, "activity-gps"); + Decorator<GPSPoint> dGPSPoint = getDecoratorByType(GPSPoint.class, "gpsPoint-gps"); + + IntList lIndex = new ArrayIntList(selectedIndex.length); + + for (int i : selectedIndex) { + lIndex.add(i); + } + IntIterator indexItr = lIndex.iterator(); + + int currentActivityIndex = 0; + int nextActivityIndex = indexItr.next(); + + TopiaDAO<ActivitySeine> activityDAO = getDao(ActivitySeine.class); + + for (ActivitySeine a : data.keySet()) { + + if (currentActivityIndex == nextActivityIndex) { + + // l'activité courante a ete selectionne + GPSPoint p = data.get(a); + + messanger.sendMessage(t("observe.message.importGPS.apply.point", dGPSPoint.toString(p), dActivity.toString(a))); +// sendMessage(t("observe.message.importGPS.apply.point", p, a.getVesselActivity().getLabel2())); + float latitude = Math.abs(p.getLatitude()); + float longitude = Math.abs(p.getLongitude()); + int quadrant = p.getQuadrant(); + // application de la position + + ActivitySeine aa = activityDAO.findByTopiaId(a.getTopiaId()); + aa.setLatitude(latitude); + aa.setLongitude(longitude); + aa.setQuadrant(quadrant); + //TODO appliquer la vitesse ? + //a.setVesselSpeed(p.getVitesse()); + + // mise a jour de l'activité + + activityDAO.update(aa); + + if (indexItr.hasNext()) { + + // il reste au moins une activité a traiter + // recuperation du prochain index d'activité a traiter + nextActivityIndex = indexItr.next(); + + } else { + + // plus d'activité a traiter + break; + + } + + } + + currentActivityIndex++; + + } + + } + + @Override + public TripSeine getOpenTrip() { + + TripSeineDAO dao = (TripSeineDAO) getDao(TripSeine.class); + TripSeine openTrip = dao.findByOpen(true); + return openTrip; + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/SynchronizeServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/SynchronizeServiceImpl.java new file mode 100644 index 0000000..ad59453 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/SynchronizeServiceImpl.java @@ -0,0 +1,218 @@ +package fr.ird.observe.services.operation; + +import fr.ird.observe.DecoratorService; +import fr.ird.observe.ObserveDAOHelper; +import fr.ird.observe.ObserveEntityEnum; +import fr.ird.observe.SendMessageAble; +import fr.ird.observe.db.DataSource; +import fr.ird.observe.db.DataSourceException; +import fr.ird.observe.entities.Entities; +import fr.ird.observe.entities.referentiel.ReferenceEntities; +import fr.ird.observe.entities.seine.TripSeine; +import fr.ird.observe.services.AbstractObserveService; +import fr.ird.observe.services.ReplicationService; +import fr.ird.observe.services.referential.ReferentialService; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.hibernate.jdbc.Work; +import org.nuiton.topia.TopiaException; +import org.nuiton.topia.framework.TopiaContextImplementor; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.util.DiffState; +import org.nuiton.topia.persistence.util.TopiaEntityHelper; +import org.nuiton.topia.persistence.util.TopiaEntityRef; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; + +import static org.nuiton.i18n.I18n.t; + +/** + * FIXME Utiliser des pattern Request, Result, Context + * FIXME Ne plus utilisers des messanger + * + * Created on 5/3/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class SynchronizeServiceImpl extends AbstractObserveService implements SynchronizeService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(SynchronizeServiceImpl.class); + + @Override + public DiffState.DiffStateMap buildReferentielDifferentiel(final DataSource centralDataSource, final SendMessageAble messanger) { + + final DiffState.DiffStateMap result = DiffState.newMap(); + + final ReferentialService centralReferentialService = newService(centralDataSource, ReferentialService.class); + + ReferenceEntities.walk(new ReferenceEntities.ReferentielWalker() { + + + public <E extends TopiaEntity> void walk(Class<E> contractClass) { + + String s = t(DecoratorService.getEntityLabel(contractClass)); + String message = + t("observe.service.build.synchro.referentiel", s); + if (messanger != null) { + messanger.sendMessage(message); + } + if (log.isInfoEnabled()) { + log.info(message); + } + List<E> list = centralReferentialService.getList(contractClass); + List<E> list2 = getList(contractClass); + DiffState.DiffStateMap tmp; + // recuperation du differentiel pour le type d'entitétmp = + tmp = TopiaEntityHelper.buildDifferentiel(list, list2); + // ajout au resultat + DiffState.addAll(result, tmp); + // on nettoie + DiffState.clear(tmp); + } + }); + DiffState.removeEmptyStates(result); + return result; + + } + + @Override + public SortedMap<TopiaEntity, List<TopiaEntityRef>> detectObsoleteEntities(DiffState.DiffStateMap diff) { + + // detection des entites obsoletes + + List<String> removedList = diff.get(DiffState.REMOVED); + + String[] ids = removedList.toArray(new String[removedList.size()]); + + // detection des entites obsoletes + + // des suppressions ont ete detectees, on doit retrouver + // dans la base locale les entites utilisant ces entites obsoletes + List<TripSeine> marees = getDao(TripSeine.class).findAll(); + + ObserveEntityEnum[] contracts = ObserveDAOHelper.getContracts(); + + SortedMap<TopiaEntity, List<TopiaEntityRef>> result; + + result = TopiaEntityHelper.detectReferences(contracts, ids, marees); + return result; + + } + + @Override + public void saveReferentiel(DataSource centralDataSource, + DiffState.DiffStateMap diff, + List<ObsoleteReferenceToReplace> obsoleteReferencesToReplace, + SendMessageAble messanger) throws DataSourceException { + + Map<TopiaEntity, Long> versionsToUpdate = new HashMap<TopiaEntity, Long>(); + + List<String> ids; + + // ajout des nouvelles entites du referentiel + + ids = diff.get(DiffState.NEW); + if (CollectionUtils.isNotEmpty(ids)) { + + ReplicationService replicationService = newService(ReplicationService.class); + + replicationService.replicateReferentiel(centralDataSource, ids, messanger); + + } + + ReferentialService localReferentialService = newService(ReferentialService.class); + + // mis a jour des entites modifiees + + ids = diff.get(DiffState.MODIFIED); + if (CollectionUtils.isNotEmpty(ids)) { + + ReferentialService service = newService(centralDataSource, ReferentialService.class); + Collection<? extends TopiaEntity> entitiesToCopy = service.loadSimpleEntities(ids); + + localReferentialService.copySimpleEntities(entitiesToCopy); + + } + + // mise à jour des données utilisateurs (remplacements d'objets obsolètes) + + for (ObsoleteReferenceToReplace referenceToReplace : obsoleteReferencesToReplace) { + + String message = t("observe.synchro.replaceObsolete.object", referenceToReplace.getObsoleteId()); + messanger.sendMessage(message); + + localReferentialService.replaceObsoleteReference(referenceToReplace); + + } + + // si on ne commite pas ici, les modifications utilisateurs sont perdues + getTransaction().commitTransaction(); + + // suppression des entités obsoletes de la base source + + ids = diff.get(DiffState.REMOVED); + if (CollectionUtils.isNotEmpty(ids)) { + + localReferentialService.deleteEntities(ids); + + } + + if (MapUtils.isNotEmpty(versionsToUpdate)) { + + // on applique le patch sur les versions pour bien avoir + // la bonne version de topiaversion et pas seulement un incrément + // de 1 puisque ce champs est géré par hibernate et qu'il ne nous laisse + // pas la possibilité de choisir la valeur qu'on veut attribuer au champs... + patchTopiaVersions(versionsToUpdate); + } + + getTransaction().commitTransaction(); + + } + + private static final String UPDATE_VERSION_PATTERN = "UPDATE %1$s SET topiaversion = %2$d WHERE topiaid='%3$s';\n"; + + protected void patchTopiaVersions(Map<TopiaEntity, Long> versionsToUpdate) throws TopiaException { + + final StringBuilder buffer = new StringBuilder(); + + for (Map.Entry<TopiaEntity, Long> entry : + versionsToUpdate.entrySet()) { + TopiaEntity entity = entry.getKey(); + String id = entity.getTopiaId(); + Long version = entry.getValue(); + String tableName = Entities.getTableName(entity); + buffer.append(String.format(UPDATE_VERSION_PATTERN, tableName, version, id)); + + } + ((TopiaContextImplementor) getTransaction()).getHibernate().doWork(new Work() { + + @Override + public void execute(Connection connection) throws SQLException { + String sql = buffer.toString(); + PreparedStatement sta = connection.prepareStatement(sql); + try { + if (log.isDebugEnabled()) { + log.debug("Will execute sql code :\n" + sql); + } + sta.executeUpdate(); + } finally { + sta.close(); + } + } + }); + } + + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/ValidationServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/ValidationServiceImpl.java new file mode 100644 index 0000000..381336d --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/operation/ValidationServiceImpl.java @@ -0,0 +1,94 @@ +package fr.ird.observe.services.operation; + +import fr.ird.observe.DecoratorService; +import fr.ird.observe.SendMessageAble; +import fr.ird.observe.entities.Trip; +import fr.ird.observe.entities.referentiel.Program; +import fr.ird.observe.services.AbstractObserveService; +import fr.ird.observe.services.data.TripService; +import fr.ird.observe.services.data.DataSelectionModel; +import fr.ird.observe.validation.ValidationMessageDetector; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.TopiaEntity; + +import java.util.List; +import java.util.Set; + +import static org.nuiton.i18n.I18n.t; + +/** + * //FIXME A revoir, on doit utiliser un pattern de Request, Context et Result + * //FIXME Le detector doit être interne + * Created on 5/3/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ValidationServiceImpl extends AbstractObserveService implements ValidationService { + + @Override + public void validate(SendMessageAble messager, ValidationMessageDetector detector, DataSelectionModel dataModel) { + + if (dataModel.isUseReferentiel()) { + + // validation des referentiels selectionnes + + validateReferentiel(messager, detector, dataModel); + } + + if (dataModel.isUseData()) { + + // validation des donnees observateur selectionnee + + validateData(messager, detector, dataModel); + } + + } + + protected void validateData(SendMessageAble messager, + ValidationMessageDetector detector, + DataSelectionModel dataModel) { + + Set<String> tripIds = dataModel.getSelectedData(); + + TripService tripService = newService(TripService.class); + + for (String tripId : tripIds) { + + Trip trip = tripService.getTrip(tripId); + Program program = trip.getProgram(); + + messager.sendMessage(t("observe.message.validation.start.maree", decorateEntity(trip), decorateEntity(program))); + detector.detectMessages(trip); + + } + + } + + protected void validateReferentiel(SendMessageAble messager, + ValidationMessageDetector detector, + DataSelectionModel dataModel) { + + Set<Class<?>> classes = dataModel.getSelectedReferentiel(); + + for (Class<?> klass : classes) { + + Class<? extends TopiaEntity> refClass = (Class<? extends TopiaEntity>) klass; + TopiaDAO<? extends TopiaEntity> dao = getDao(refClass); + + List<String> ids = dao.findAllIds(); + String entityLabel = t(DecoratorService.getEntityLabel(klass)); + messager.sendMessage(t("observe.message.validation.start.referentiel", entityLabel, ids.size())); + + for (String id : ids) { + TopiaEntity entity = dao.findByTopiaId(id); + detector.detectMessages(entity); + } + + ids.clear(); + + } + + } + +} diff --git a/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/referential/ReferentialServiceImpl.java b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/referential/ReferentialServiceImpl.java new file mode 100644 index 0000000..57cf028 --- /dev/null +++ b/observe-services-topia/src/main/fromRefactor/fr/ird/observe/services/referential/ReferentialServiceImpl.java @@ -0,0 +1,518 @@ +package fr.ird.observe.services.referential; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import fr.ird.observe.BinderService; +import fr.ird.observe.ObserveTechnicalException; +import fr.ird.observe.entities.constants.ReferenceLocale; +import fr.ird.observe.entities.constants.ReferenceStatus; +import fr.ird.observe.entities.referentiel.LengthWeightParameter; +import fr.ird.observe.entities.referentiel.LengthWeightParameterDAO; +import fr.ird.observe.entities.referentiel.LengthWeightParemeterHelper; +import fr.ird.observe.entities.referentiel.Ocean; +import fr.ird.observe.entities.referentiel.Program; +import fr.ird.observe.entities.referentiel.ProgramDAO; +import fr.ird.observe.entities.referentiel.Programs; +import fr.ird.observe.entities.referentiel.ReferenceEntity; +import fr.ird.observe.entities.referentiel.Sex; +import fr.ird.observe.entities.referentiel.SexDAO; +import fr.ird.observe.entities.referentiel.Species; +import fr.ird.observe.entities.referentiel.SpeciesList; +import fr.ird.observe.entities.referentiel.seine.WeightCategory; +import fr.ird.observe.services.AbstractObserveService; +import fr.ird.observe.services.operation.ObsoleteReferenceToReplace; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.decorator.Decorator; +import org.nuiton.topia.persistence.TopiaDAO; +import org.nuiton.topia.persistence.TopiaEntity; +import org.nuiton.topia.persistence.util.EntityListUpdator; +import org.nuiton.topia.persistence.util.TopiaEntityBinder; +import org.nuiton.topia.persistence.util.TopiaEntityHelper; +import org.nuiton.topia.persistence.util.TopiaEntityRef; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Created on 4/25/15. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 4.0 + */ +public class ReferentialServiceImpl extends AbstractObserveService implements ReferentialService { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ReferentialServiceImpl.class); + + @Override + public List<Program> getAllProgramStub() { + + ProgramDAO dao = (ProgramDAO) getDao(Program.class); + ReferenceLocale referentielLocale = getReferentielLocale(); + List<Program> result = dao.findAllStub(referentielLocale); + return result; + + } + + @Override + public int getProgramPosition(String programId) { + + List<Program> allProgramStub = getAllProgramStub(); + Program programStub = getProgramStub(programId); + int result = 0; + if (CollectionUtils.isNotEmpty(allProgramStub)) { + Programs.sort(allProgramStub); + result = allProgramStub.indexOf(programStub); + } + return result; + + } + + @Override + public Program getProgramStub(String programId) { + + ProgramDAO dao = (ProgramDAO) getDao(Program.class); + ReferenceLocale referentielLocale = getReferentielLocale(); + Program result = dao.findStubByTopiaId(programId, referentielLocale); + return result; + + } + + @Override + public <E extends ReferenceEntity> List<E> loadListForEdit(Class<E> entityType) { + + List<E> entities = getDao(entityType).findAll(); + TopiaEntityBinder<E> binder = getBinder(entityType, BinderService.EDIT); + for (E entity : entities) { + binder.obtainProperties(entity); + } + return Lists.newArrayList(entities); + + } + + @Override + public <E extends ReferenceEntity> List<E> loadAndDecorateList(Class<E> entityType) { + + List<E> entities = getDao(entityType).findAll(); + decorate(entityType, entities); + return Lists.newArrayList(entities); + + } + + @Override + public <E extends ReferenceEntity> E loadAndDecorate(Class<E> entityType, String topiaId) { + + E entity = findByTopiaId(entityType, topiaId); + decorate(entityType, entity); + return entity; + + } + + @Override + public List<Species> loadDecoratedSpecies(String speciesListCode) { + + List<Species> speciess = new ArrayList<Species>(); + + SpeciesList speciesList = findByTopiaId(SpeciesList.class, speciesListCode); + + speciess.addAll(speciesList.getSpecies()); + + decorate(Species.class, speciess); + + return speciess; + + } + + @Override + public List<WeightCategory> loadDecoratedWeightCategory() { + + List<WeightCategory> weightCategories = loadAndDecorateList(WeightCategory.class); + Decorator<Species> speciesDecorator = getDecoratorByType(Species.class, null); + for (WeightCategory weightCategory : weightCategories) { + speciesDecorator.toString(weightCategory.getSpecies()); + } + return weightCategories; + } + + @Override + public void loadDecoratedWeightCategory(WeightCategory weightCategory) { + + decorate(WeightCategory.class, weightCategory); + decorate(Species.class, weightCategory.getSpecies()); + + } + + @Override + public Collection<? extends TopiaEntity> loadSimpleEntities(Collection<String> entityIds) { + + Collection<TopiaEntity> result = new ArrayList<TopiaEntity>(); + + for (String entityId : entityIds) { + + TopiaEntity entityToLoad = getTransaction().findByTopiaId(entityId); + TopiaDAO<TopiaEntity> dao = getDao(entityToLoad); + TopiaEntity entityLoaded = dao.newInstance(); + loadEntity(entityToLoad, entityLoaded, true); + + result.add(entityLoaded); + + } + + return result; + + } + + @Override + public Set<String> getSpeciesListSpeciesIds(String speciesListId) { + + SpeciesList speciesList = findByTopiaId(SpeciesList.class, speciesListId); + + Set<String> ids = Sets.newHashSet(TopiaEntityHelper.getTopiaIdList(speciesList.getSpecies())); + + return ids; + + } + + /** + * Recherche d'un {@link LengthWeightParameter} à partir des paramètres donnés. + * <p/> + * La recherche peut ne peut être aussi exacte que les paramètres donnés : + * <p/> + * Dans le cas d'une espèce faune, si non trouvé alors on recherche sur son + * speciesGroup d'espèce. + * <p/> + * Si non trouvé pour l'océan donné (et que celui-ci est non null), alors on + * recherche avec un ocean vide. + * <p/> + * Si non trouvé sur le gender (et que le gender n'est pas indéterminé) , alors + * on recherche avec le gender indéterminé (gender=0). + * + * @param species l'espèce sur lequel on recherche le paramétrage + * @param ocean l'ocean recherché (peut être null) + * @param sex le sexe recherché (on essayera sans sexe (sexe.code=0) si non trouvé) + * @param date le jour recherché + * @return le paramétrage adéquate + * @since 1.5 + */ + public LengthWeightParameter findLengthWeightParameter(Species species, Ocean ocean, Sex sex, Date date) throws ObserveTechnicalException { + + LengthWeightParameterDAO dao = (LengthWeightParameterDAO) getDao(LengthWeightParameter.class); + List<LengthWeightParameter> list = dao.findAllBySpecies(species); + + if (CollectionUtils.isEmpty(list)) { + + // aucun parametrage pour le type donne + return null; + + } + + // filtrage par ocean + list = LengthWeightParemeterHelper.filterByOcean(list, ocean); + + if (CollectionUtils.isEmpty(list) && ocean != null) { + + // filtre par ocean null + list = LengthWeightParemeterHelper.filterByOcean(list, null); + + } + + if (CollectionUtils.isEmpty(list)) { + + // pas d'ocean adequate + return null; + + } + + // filtrage par sexe + list = LengthWeightParemeterHelper.filterBySexe(list, sex); + + if (CollectionUtils.isEmpty(list)) { + + // Sex with code 0 + Sex unkwonSex = ((SexDAO) getDao(Sex.class)).getUnknownSex(); + + if (unkwonSex.equals(sex)) { + + // filtrage par sexe indetermine + list = LengthWeightParemeterHelper.filterBySexe(list, unkwonSex); + + } + + } + + if (CollectionUtils.isEmpty(list)) { + + // pas de sexe adequate + return null; + + } + + // filtrage par startDate de validite + list = LengthWeightParemeterHelper.filterByDateDebutValidite(list, date); + + if (CollectionUtils.isEmpty(list)) { + + // pas de date de debut adequate + return null; + + } + + // filtrage par endDate de validite + list = LengthWeightParemeterHelper.filterByDateFinValidite(list, date); + + if (CollectionUtils.isEmpty(list)) { + + // pas de date de fin adequate + return null; + + } + + // au final il ne devrait en rester qu'un + + if (list.size() > 1) { + + StringBuilder sb = new StringBuilder("Il existe plusieurs paramétrages possibles pour les données suivantes :"); + sb.append("\nEspece : "); + sb.append(decorateEntity(species)); + sb.append("\nOcean : "); + sb.append(decorateEntity(ocean)); + sb.append("\nSex : "); + sb.append(decorateEntity(sex)); + sb.append("\nDate : ").append(date); + sb.append("\nParamétrages trouvés : "); + for (LengthWeightParameter p : list) { + sb.append("\n - ").append(decorateEntity(p)); + } + + //FIXME Use a specific exception for this + throw new ObserveTechnicalException(sb.toString()); + + } + + LengthWeightParameter result = list.get(0); + if (log.isDebugEnabled()) { + + StringBuilder sb = new StringBuilder("Paramétrage trouvé pour les données suivantes :"); + sb.append("\nEspece : "); + sb.append(decorateEntity(species)); + sb.append("\nOcean : "); + sb.append(decorateEntity(ocean)); + sb.append("\nSex : "); + sb.append(decorateEntity(sex)); + sb.append("\nDate : ").append(date); + sb.append("\nParamétrage: ").append(decorateEntity(result)); + log.debug(sb.toString()); + + } + + return result; + + } + + @Override + public <R extends ReferenceEntity> R preCreate(Class<R> entityType) { + + R preCreated = getDao(entityType).newInstance(); + preCreated.setStatus(ReferenceStatus.enabled); + return preCreated; + + } + + @Override + public <R extends ReferenceEntity> String save(R toSave) { + + Class<R> entityType = getEntityContractClass(toSave); + + String referentialId = doSave(null, toSave, new SaveAction<R, R>(entityType, entityType) { + + @Override + public R onCreate(R parent, R toCreate) { + + Map<String, Object> properties = obtainProperties(entityClass, BinderService.EDIT, toCreate); + R created = getDao(entityClass).create(properties); + + return created; + + } + + @Override + public R onUpdate(R parent, R toUpdate) { + + R updated = super.onUpdate(parent, toUpdate); + copy(entityClass, BinderService.EDIT, toUpdate, updated); + return updated; + + } + }); + + return referentialId; + + } + + @Override + public <R extends ReferenceEntity> void delete(Class<R> entityType, String referentialId) { + + doDelete(null, referentialId, new DeleteAction<R, R>(entityType, entityType)); + + } + + @Override + public void deleteEntities(Collection<String> entityIds) { + + for (String entityId : entityIds) { + + TopiaEntity entityToDelete = getTransaction().findByTopiaId(entityId); + Class<TopiaEntity> entityType = getEntityContractClass(entityToDelete); + TopiaDAO<TopiaEntity> dao = getDao(entityType); + dao.delete(entityToDelete); + + } + } + + @Override + public void copySimpleEntities(Collection<? extends TopiaEntity> entities) { + + for (TopiaEntity entity : entities) { + + TopiaDAO<TopiaEntity> dao = getDao(entity); + + TopiaEntity entityLoaded = dao.findByTopiaId(entity.getTopiaId()); + loadEntity(entity, entityLoaded, false); + + } + + } + + @Override + public void replaceObsoleteReference(ObsoleteReferenceToReplace action) { + + String obsoleteId = action.getObsoleteId(); + String safeId = action.getSafeId(); + TopiaEntityRef[] refs = action.getRefs(); + + if (log.isInfoEnabled()) { + log.info("load obsolete object " + obsoleteId); + } + + if (log.isInfoEnabled()) { + log.info("load safe object " + safeId); + } + + TopiaEntity safeRef = getTransaction().findByTopiaId(safeId); + + // on remplace les references + for (TopiaEntityRef ref : refs) { + + TopiaEntity invoker = ref.getInvoker(); + + if (invoker == null) { + throw new NullPointerException("can not have a null invoker in " + ref); + } + + TopiaDAO<TopiaEntity> dao = getDao(invoker); + + + if (log.isInfoEnabled()) { + log.info("load invoker object " + invoker.getTopiaId()); + } + + invoker = dao.findByTopiaId(invoker.getTopiaId()); + + // switch entity + + String path = ref.getInvokerProperty(); + + JXPathContext jxcontext = JXPathContext.newContext(invoker); + + TopiaEntity oldValue = (TopiaEntity) jxcontext.getValue(path); + + if (log.isDebugEnabled()) { + log.debug("property to switch " + path + " old : " + + oldValue); + } + + if (log.isInfoEnabled()) { + log.info("change path : " + path); + log.info("old value : " + oldValue.getTopiaId()); + } + + jxcontext.setValue(path, safeRef); + + TopiaEntity newValue = (TopiaEntity) jxcontext.getValue(path); + + if (log.isInfoEnabled()) { + log.info("new value : " + newValue.getTopiaId()); + } + if (log.isDebugEnabled()) { + log.debug("property to switch " + path + " new : " + + safeRef); + log.debug("property to switch " + path + " new Check : " + + newValue); + } + + dao.update(invoker); + + } + + } + + protected <E extends TopiaEntity> void loadEntity(E source, E target, boolean tech) { + + getBinderService().simpleCopy(source, target, tech); + + if (source instanceof Species) { + + // Need also to bind ocean + loadAssociation(Species.class, Ocean.class, Species.PROPERTY_OCEAN, (Species) source, (Species) target); + + } else if (source instanceof SpeciesList) { + + // Need also to bind species + loadAssociation(SpeciesList.class, Species.class, SpeciesList.PROPERTY_SPECIES, (SpeciesList) source, (SpeciesList) target); + + } + + } + + public <E extends TopiaEntity, C extends TopiaEntity> void loadAssociation(Class<E> entityType, + Class<C> childEntityType, + String propertyName, + E source, + E target) { + + EntityListUpdator<E, C> listUpdator = EntityListUpdator.newEntityListUpdator(entityType, childEntityType, propertyName); + + int size = listUpdator.size(source); + + List<C> targetList = Lists.newArrayListWithCapacity(size); + + if (size > 0) { + + TopiaDAO<C> dao = getDao(childEntityType); + + Collection<C> sourceList = listUpdator.getChilds(source); + + for (C childToLoad : sourceList) { + + C childLoaded = dao.newInstance(); + childLoaded.setTopiaId(childToLoad.getTopiaId()); + childLoaded.setTopiaVersion(childToLoad.getTopiaVersion()); + childLoaded.setTopiaCreateDate(childToLoad.getTopiaCreateDate()); + targetList.add(childLoaded); + + } + + } + + listUpdator.setChilds(target, targetList); + + } + +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceContextTopia.java b/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceContextTopia.java new file mode 100644 index 0000000..af08ad3 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceContextTopia.java @@ -0,0 +1,10 @@ +package fr.ird.observe.services; + +/** + * Created on 16/08/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ObserveServiceContextTopia implements ObserveServiceContext { + +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceFactoryProviderTopia.java b/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceFactoryProviderTopia.java new file mode 100644 index 0000000..463f97e --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceFactoryProviderTopia.java @@ -0,0 +1,27 @@ +package fr.ird.observe.services; + +/** + * Created on 16/08/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ObserveServiceFactoryProviderTopia implements ObserveServiceFactoryProvider { + + @Override + public <S extends ObserveService> boolean accept(ObserveServiceContext serviceContext, Class<S> serviceType) { + return serviceContext != null && serviceType != null; + } + + @Override + public <S extends ObserveService> S newService(ObserveServiceContext serviceContext, Class<S> serviceType) { + + String fqn = serviceType.getName() + "Topia"; + try { + S service = (S) Class.forName(fqn).newInstance(); + service.setServiceContext(serviceContext); + return service; + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + throw new IllegalStateException("Could not create service", e); + } + } +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceTopia.java b/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceTopia.java new file mode 100644 index 0000000..3431515 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/ObserveServiceTopia.java @@ -0,0 +1,17 @@ +package fr.ird.observe.services; + +/** + * Created on 16/08/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ObserveServiceTopia implements ObserveService { + + protected ObserveServiceContext serviceContext; + + @Override + public void setServiceContext(ObserveServiceContext serviceContext) { + + this.serviceContext = serviceContext; + } +} diff --git a/observe-services-topia/src/main/java/fr/ird/observe/services/service/ReferentialServiceTopia.java b/observe-services-topia/src/main/java/fr/ird/observe/services/service/ReferentialServiceTopia.java new file mode 100644 index 0000000..28ba8f5 --- /dev/null +++ b/observe-services-topia/src/main/java/fr/ird/observe/services/service/ReferentialServiceTopia.java @@ -0,0 +1,58 @@ +package fr.ird.observe.services.service; + +import fr.ird.observe.services.ObserveServiceContext; +import fr.ird.observe.services.ObserveServiceTopia; +import fr.ird.observe.services.model.referential.ReferentialFormModel; +import fr.ird.observe.services.model.referential.ReferentialLabelSetModel; +import fr.ird.observe.services.model.referential.ReferentialModel; + +import java.util.Collection; + +/** + * Created on 16/08/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ReferentialServiceTopia extends ObserveServiceTopia implements ReferentialService { + + @Override + public <R extends ReferentialModel> ReferentialLabelSetModel getReferentialLabelSet(Class<R> type) { + + return new ReferentialLabelSetModel(); + } + + @Override + public <R extends ReferentialModel> ReferentialFormModel<R> loadToRead(Class<R> type, String id) { + return null; + } + + @Override + public <R extends ReferentialModel> ReferentialFormModel<R> loadToEdit(Class<R> type, String id) { + return null; + } + + @Override + public <R extends ReferentialModel> ReferentialFormModel<R> preCreate(Class<R> type) { + return null; + } + + @Override + public <R extends ReferentialModel> String save(ReferentialFormModel<R> form) { + return null; + } + + @Override + public <R extends ReferentialModel> void delete(Class<R> type, String id) { + + } + + @Override + public <R extends ReferentialModel> void delete(Class<R> type, Collection<String> ids) { + + } + + @Override + public void setServiceContext(ObserveServiceContext serviceContext) { + + } +} diff --git a/observe-services-topia/src/main/resources/META-INF/services/fr.ird.observe.services.ObserveServiceFactoryProvider b/observe-services-topia/src/main/resources/META-INF/services/fr.ird.observe.services.ObserveServiceFactoryProvider new file mode 100644 index 0000000..d88eed8 --- /dev/null +++ b/observe-services-topia/src/main/resources/META-INF/services/fr.ird.observe.services.ObserveServiceFactoryProvider @@ -0,0 +1 @@ +fr.ird.observe.services.ObserveServiceFactoryProviderTopia \ No newline at end of file diff --git a/observe-services-topia/src/test/java/fr/ird/observe/services/service/referential/ReferentialServiceTopiaTest.java b/observe-services-topia/src/test/java/fr/ird/observe/services/service/referential/ReferentialServiceTopiaTest.java new file mode 100644 index 0000000..26b9645 --- /dev/null +++ b/observe-services-topia/src/test/java/fr/ird/observe/services/service/referential/ReferentialServiceTopiaTest.java @@ -0,0 +1,39 @@ +package fr.ird.observe.services.service.referential; + +import fr.ird.observe.services.ObserveServiceContextTopia; +import fr.ird.observe.services.ObserveServiceFactory; +import fr.ird.observe.services.model.referential.ReferentialLabelSetModel; +import fr.ird.observe.services.model.referential.SexModel; +import fr.ird.observe.services.service.ReferentialService; +import org.junit.Before; +import org.junit.Test; + +/** + * Created on 16/08/15. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ReferentialServiceTopiaTest { + + + protected ReferentialService service; + + @Before + public void setUp() throws Exception { + + ObserveServiceFactory factory = new ObserveServiceFactory(); + + ObserveServiceContextTopia context = new ObserveServiceContextTopia(); + + service = factory.newService(context, ReferentialService.class); + + } + + @Test + public void testGetReferentialLabelSet() throws Exception { + + ReferentialLabelSetModel referentialLabelSet = service.getReferentialLabelSet(SexModel.class); + + } + +} \ No newline at end of file diff --git a/observe-services-topia/src/test/resources/log4j.properties b/observe-services-topia/src/test/resources/log4j.properties new file mode 100644 index 0000000..0f21768 --- /dev/null +++ b/observe-services-topia/src/test/resources/log4j.properties @@ -0,0 +1,32 @@ +### +# #%L +# ObServe :: Swing +# %% +# Copyright (C) 2008 - 2010 IRD, Codelutin, Tony Chemit +# %% +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/gpl-3.0.html>. +# #L% +### + +# Global logging configuration +log4j.rootLogger=ERROR, stdout +#log4j.rootLogger=ERROR, stdout +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%c:%L) %M - %m%n +#log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n + +log4j.logger.fr.ird.observe=INFO diff --git a/pom.xml b/pom.xml index f123ce3..f120318 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ <module>observe-entities</module> <module>observe-business</module> <module>observe-validation</module> - <!--module>observe-services-topia</module--> + <module>observe-services-topia</module> <!--module>observe-services-rest</module--> <module>observe-swing</module> </modules> -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@list.forge.codelutin.com>.