diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad8a572 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.classpath +.project +.settings +/distrib +/lib +/bin +**/.DS_Store diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..dba13ed --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are 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. + + 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. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + 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 Affero 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. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + 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 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 work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 Affero 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 Affero 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 Affero 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + 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 AGPL, see +. diff --git a/NOTICE.txt b/NOTICE.txt new file mode 100644 index 0000000..b348201 --- /dev/null +++ b/NOTICE.txt @@ -0,0 +1,24 @@ +This product includes software developed by: + + The Plealog Team (http://www.plealog.com) + Plealog license is here: http://www.apache.org/licenses/LICENSE-2.0 + It targets: jgaf + Plealog license is here: https://www.gnu.org/licenses/agpl-3.0.txt + It targets: pb-core, pb-ui + + The Apache Software Foundation (http://www.apache.org/) + Apache license is here: http://www.apache.org/licenses/LICENSE-2.0 + It targets: commons-xxx, xerces, xmlParser + + The Castor Framework Team (http://castor-data-binding.github.io/castor) + Castor license is here: http://castor-data-binding.github.io/castor/about/licenses.html + It targets: castor-xml + + The XStream Framework Team (http://x-stream.github.io/): + XStream License is here: http://x-stream.github.io/license.html + It targets: xstream + + The JGoodies Forms Framework Team (http://www.jgoodies.com/freeware/libraries/forms/). + JGoodies license is here: https://opensource.org/licenses/bsd-license.html + It targets: forms + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee7be0b --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +#BlastViewer + +[![License](https://img.shields.io/badge/license-Affero%20GPL%203.0-blue.svg)](https://www.gnu.org/licenses/agpl-3.0.txt) + +##Introduction + +This is the BlastViewer Tool. It aims at displaying in a graphical way results from the NCBI BLAST software. + +![BlastViewer](doc/BlastViewer.png) + +##Requirements + +Use a [Java Virtual Machine](http://www.oracle.com/technetwork/java/javase/downloads/index.html) 1.7 (or above) from Oracle. + +*Not tested with any other JVM providers but Oracle... so there is no guarantee that the software will work as expected if not using Oracle's JVM.* + +##Software use + + +See the Wiki page of this project. + + +##License and dependencies + +BlastViewer itself is released under the GNU Affero General Public License, Version 3.0. [AGPL](https://www.gnu.org/licenses/agpl-3.0.txt) + +It depends on several thrid-party libraries as stated in the NOTICE.txt file provided with this project. + +##Once upon a time was: VisualBlast / KoriBlast + +During Summer 2004 I was asking myself how easy it could be to rewrite in Java the original [VisualBlast software](http://www.ncbi.nlm.nih.gov/pubmed/9283755) written in C for the MS-Windows platform. + +Actually, the answer was quite immediate: it took me a few days to fully rewrite Visual Blast, thanks to the many libraries available, mostly from Sun MicroSystems and the Apache Software Foundation. + +So, during my holidays on Summer 2004, I started a wonderful story: the creation of what would eventually become the [KoriBlast/ngKLAST suite of softwares](http://plealog.com/korilog/product-sheets/ngKLAST.pdf), the founding software of my company, Korilog. + +Korilog ceased its activities on June 2015, therefore I decided to release these UI components to the open source community... just in time for Christmas 2016! ;-) + +-- +(c) 2003-2016 - Patrick G. Durand diff --git a/build.xml b/build.xml new file mode 100755 index 0000000..6e5217a --- /dev/null +++ b/build.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Ant task to handle BLAST Viewer Tool project. + + compile: compile the code. + makedistrib: compile and make release JAR of the BLAST system. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/blastp.xml b/data/blastp.xml new file mode 100755 index 0000000..02d56e9 --- /dev/null +++ b/data/blastp.xml @@ -0,0 +1,596 @@ + + + + blastp + BLASTN 2.4.0+ + Altschul, Stephen F., Thomas L. Madden, Alejandro A. Schaffer, Jinghui Zhang, Zheng Zhang, Webb Miller, and David J. Lipman (1997), "Gapped BLAST and PSI-BLAST: a new generation of protein database search programs", Nucleic Acids Res. 25:3389-3402. + pdb + 1_3291 + P29972 Aquaporin-CHIP + 269 + + + BLOSUM62 + 10 + 11 + 1 + L; + + + + + 1 + 1_3291 + P29972 Aquaporin-CHIP + 269 + + + 1 + gi|11514550|pdb|1FQY|A + Chain A, Structure Of Aquaporin-1 At 3.8 A Resolution By Electron Crystallography >gi|14278358|pdb|1IH5|A Chain A, Crystal Structure Of Aquaporin-1 >gi|18159033|pdb|1H6I|A Chain A, A Refined Structure Of Human Aquaporin 1 + 1FQY-A + 269 + + + 1 + 528.094 + 1359 + 7.60283e-151 + 1 + 269 + 1 + 269 + 0 + 0 + 269 + 269 + 0 + 269 + MASEFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMKPK + MASEFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMKPK + MASEFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMKPK + + + + + 2 + gi|20150315|pdb|1J4N|A + Chain A, Crystal Structure Of The Aqp1 Water Channel + 1J4N-A + 271 + + + 1 + 483.411 + 1243 + 2.14755e-137 + 1 + 269 + 1 + 271 + 0 + 0 + 248 + 255 + 2 + 271 + MASEFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQT--AVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMKPK + MASEFKKKLFWRAVVAEFLAMILFIFISIGSALGFHYPIKSNQTTGAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISVLRAIMYIIAQCVGAIVATAILSGITSSLPDNSLGLNALAPGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSGPLAIGFSVALGHLLAIDYTGCGINPARSFGSSVITHNFQDHWIFWVGPFIGAALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMKPK + MASEFKKKLFWRAVVAEFLA LF+FISIGSALGF YP+ +NQT AVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQIS+ RA+MYIIAQCVGAIVATAILSGITSSL NSLG N LA GVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGS PLAIG SVALGHLLAIDYTGCGINPARSFGS+VITHNF +HWIFWVGPFIG ALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMKPK + + + + + 3 + gi|83754265|pdb|2B6O|A + Chain A, Electron Crystallographic Structure Of Lens Aquaporin-0 (Aqp0) (Lens Mip) At 1.9a Resolution, In A Closed Pore State + 2B6O-A + 263 + + + 1 + 233.802 + 595 + 2.96373e-62 + 4 + 267 + 3 + 259 + 0 + 0 + 117 + 166 + 7 + 264 + EFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMK + ELRSASFWRAIFAEFFATLFYVFFGLGASL--RWAPGPLHV-----LQVALAFGLALATLVQAVGHISGAHVNPAVTFAFLVGSQMSLLRAICYVVAQLLGAVAGAAVLYSVTPPAVRGNLALNTLHPGVSVGQATIVEIFLTLQFVLCIFATYDERRNGRLGSVALAVGFSLTLGHLFGMYYTGAGMNPARSFAPAILTRNFTNHWVYWVGPVIGAGLGSLLYDFLLFPRLKSVSERLSILKGTRPSESNGQPEVTGEPVELK + E + FWRA+ AEF AT +VF +G++L ++ G ++V+LAFGL++ATL Q+VGHISGAH+NPAVT L+ Q+S+ RA+ Y++AQ +GA+ A+L +T +L N L GV+ GQ +EI TLQ VLC+ AT D RR GS LA+G S+ LGHL + YTG G+NPARSF A++T NF+NHW++WVGP IG L L+YDF+L PR +++R+ + + E + + VE+K + + + + + 4 + gi|61680729|pdb|1YMG|A + Chain A, The Channel Architecture Of Aquaporin O At 2.2 Angstrom Resolution >gi|83754266|pdb|2B6P|A Chain A, X-Ray Structure Of Lens Aquaporin-0 (Aqp0) (Lens Mip) In An Open Pore State >gi|85544350|pdb|2C32|A Chain A, Co-Axial Association Of Recombinant Eye Lens Aquaporin-0 Observed In Loosely Packed 3d-Crystals + 1YMG-A + 263 + + + 1 + 232.261 + 591 + 8.62313e-62 + 4 + 267 + 3 + 259 + 0 + 0 + 116 + 166 + 7 + 264 + EFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVEMK + ELRSASFWRAICAEFFASLFYVFFGLGASL--RWAPGPLHV-----LQVALAFGLALATLVQAVGHISGAHVNPAVTFAFLVGSQMSLLRAICYMVAQLLGAVAGAAVLYSVTPPAVRGNLALNTLHPGVSVGQATIVEIFLTLQFVLCIFATYDERRNGRLGSVALAVGFSLTLGHLFGMYYTGAGMNPARSFAPAILTRNFTNHWVYWVGPVIGAGLGSLLYDFLLFPRLKSVSERLSILKGSRPSESNGQPEVTGEPVELK + E + FWRA+ AEF A+ +VF +G++L ++ G ++V+LAFGL++ATL Q+VGHISGAH+NPAVT L+ Q+S+ RA+ Y++AQ +GA+ A+L +T +L N L GV+ GQ +EI TLQ VLC+ AT D RR GS LA+G S+ LGHL + YTG G+NPARSF A++T NF+NHW++WVGP IG L L+YDF+L PR +++R+ + + E + + VE+K + + + + + 5 + gi|49259096|pdb|1SOR|A + Chain A, Aquaporin-0 Membrane Junctions Reveal The Structure Of A Closed Water Pore + 1SOR-A + 235 + + + 1 + 230.335 + 586 + 3.27678e-61 + 10 + 244 + 5 + 232 + 0 + 0 + 112 + 156 + 7 + 235 + FWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKV + FWRAIFAEFFATLFYVFFGLGASL--RWAPGPLHV-----LQVALAFGLALATLVQAVGHISGAHVNPAVTFAFLVGSQMSLLRAICYVVAQLLGAVAGAAVLYSVTPPAVRGNLALNTLHPGVSVGQATIVEIFLTLQFVLCIFATYDERRNGRLGSVALAVGFSLTLGHLFGMYYTGAGMNPARSFAPAILTRNFTNHWVYWVGPVIGAGLGSLLYDFLLFPRLKSVSERLSI + FWRA+ AEF AT +VF +G++L ++ G ++V+LAFGL++ATL Q+VGHISGAH+NPAVT L+ Q+S+ RA+ Y++AQ +GA+ A+L +T +L N L GV+ GQ +EI TLQ VLC+ AT D RR GS LA+G S+ LGHL + YTG G+NPARSF A++T NF+NHW++WVGP IG L L+YDF+L PR +++R+ + + + + + + 6 + gi|88192744|pdb|2D57|A + Chain A, Double Layered 2d Crystal Structure Of Aquaporin-4 (Aqp4m23) At 3.2 A Resolution By Electron Crystallography + 2D57-A + 301 + + + 1 + 220.705 + 561 + 2.59635e-58 + 10 + 265 + 12 + 266 + 0 + 0 + 117 + 164 + 7 + 259 + FWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYD---LDADDINSRVE + FWKAVTAEFLAMLIFVLLSVGSTINWG---GSENPLPVDMVLISLCFGLSIATMVQCFGHISGGHINPAVTVAMVCTRKISIAKSVFYITAQCLGAIIGAGILYLVTPPSVVGGLGVTTVHGNLTAGHGLLVELIITFQLVFTIFASCDSKRTDVTGSVALAIGFSVAIGHLFAINYTGASMNPARSFGPAVIMGNWENHWIYWVGPIIGAVLAGALYEYVFCP-DVELKRRLKEAFSKAAQQTKGSYMEVEDNRSQVE + FW+AV AEFLA +FV +S+GS + + G+ D V +SL FGLSIAT+ Q GHISG H+NPAVT+ ++ + +ISI +++ YI AQC+GAI+ IL +T LG + + +G GL +E+I T QLV + A+ D +R D+ GS LAIG SVA+GHL AI+YTG +NPARSFG AVI N+ NHWI+WVGP IG LA +Y+++ P +L R+K S ++ ++ +D S+VE + + + + + 7 + gi|85544225|pdb|2B5F|A + Chain A, Crystal Structure Of The Spinach Aquaporin Sopip2;1 In An Open Conformation To 3.9 Resolution >gi|85544226|pdb|2B5F|B Chain B, Crystal Structure Of The Spinach Aquaporin Sopip2;1 In An Open Conformation To 3.9 Resolution >gi|85544227|pdb|2B5F|C Chain C, Crystal Structure Of The Spinach Aquaporin Sopip2;1 In An Open Conformation To 3.9 Resolution >gi|85544228|pdb|2B5F|D Chain D, Crystal Structure Of The Spinach Aquaporin Sopip2;1 In An Open Conformation To 3.9 Resolution + 2B5F-A + 303 + + + 1 + 176.407 + 446 + 5.61533e-45 + 4 + 265 + 31 + 297 + 0 + 0 + 112 + 159 + 23 + 276 + EFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVK---VSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAI----VATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRR--RD--LGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHN---FSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDLDADDINSRVE + ELKLWSFWRAAIAEFIATLLFLYITVATVIGH-----SKETVVCGSVGLLGIAWAFGGMIFVLVYCTAGISGGHINPAVTFGLFLARKVSLLRALVYMIAQCLGAICGVGLVKAFMKGPYNQFGG---GANSVALGYNKGTALGAEIIGTFVLVYTVFSATDPKRSARDSHVPILAPLPIGFAVFMVHLATIPITGTGINPARSFGAAVIFNSNKVWDDQWIFWVGPFIGAAVAAAYHQYVLRAAAIKALGSFRS-NPTNLEQKLISEEDLNSAVD + E K FWRA +AEF+AT LF++I++ + +G + +T V +V ++ AFG I L ISG H+NPAVT GL L+ ++S+ RAL+Y+IAQC+GAI + A + G + G G N +A G N G LG EIIGT LV V + TD +R RD + APL IG +V + HL I TG GINPARSFG+AVI ++ + + WIFWVGPFIG A+A + ++L + + +E+ + +D+NS V+ + + + + + 8 + gi|85544014|pdb|1Z98|A + Chain A, Crystal Structure Of The Spinach Aquaporin Sopip2;1 In A Closed Conformation >gi|85544015|pdb|1Z98|M Chain M, Crystal Structure Of The Spinach Aquaporin Sopip2;1 In A Closed Conformation + 1Z98-A + 281 + + + 1 + 175.252 + 443 + 1.25097e-44 + 4 + 231 + 31 + 264 + 0 + 0 + 107 + 146 + 22 + 242 + EFKKKLFWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVK---VSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAI----VATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRR--RD--LGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHN---FSNHWIFWVGPFIGGALAVLIYDFIL + ELKLWSFWRAAIAEFIATLLFLYITVATVIGH-----SKETVVCGSVGLLGIAWAFGGMIFVLVYCTAGISGGHINPAVTFGLFLARKVSLLRALVYMIAQCLGAICGVGLVKAFMKGPYNQFGG---GANSVALGYNKGTALGAEIIGTFVLVYTVFSATDPKRSARDSHVPILAPLPIGFAVFMVHLATIPITGTGINPARSFGAAVIFNSNKVWDDQWIFWVGPFIGAAVAAAYHQYVL + E K FWRA +AEF+AT LF++I++ + +G + +T V +V ++ AFG I L ISG H+NPAVT GL L+ ++S+ RAL+Y+IAQC+GAI + A + G + G G N +A G N G LG EIIGT LV V + TD +R RD + APL IG +V + HL I TG GINPARSFG+AVI ++ + + WIFWVGPFIG A+A + ++L + + + + + 9 + gi|134105082|pdb|2O9D|A + Chain A, Crystal Structure Of Aqpz Mutant T183c. >gi|134105083|pdb|2O9D|B Chain B, Crystal Structure Of Aqpz Mutant T183c. + 2O9D-A + 234 + + + 1 + 125.561 + 314 + 1.13671e-29 + 11 + 234 + 5 + 233 + 0 + 0 + 85 + 121 + 17 + 235 + WRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLAD---------GVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFS--NHWIFWVGPFIGGALAVLIYDFILAPR + FRKLAAESFGTFWLVFGGSGSAV---LAAGFPELGI-GFAGVALAFGLTVLTMAFAVGHISGGHFNPAVTIGLWAGGRFPAKEVVGYVIAQVVGGIVAAALLYLIASGKTGFDAAASGFASNGYGEHSPGGYSMLSALVVELVLSAGFLLVIHGATDKFAP--AGFAPIAIGLALTLIHLISIPVTNCSVNPARSTAVAIFQGGWALEQLWFFWVVPIVGGIIGGLIYRTLLEKR + +R + AE T VF GSA+ G + + V+LAFGL++ T+A +VGHISG H NPAVT+GL + + Y+IAQ VG IVA A+L I S TG + A G + L +E++ + +L + TD+ G AP+AIGL++ L HL++I T C +NPARS A+ ++ W FWV P +GG + LIY +L R + + + + + 10 + gi|134105084|pdb|2O9E|A + Chain A, Crystal Structure Of Aqpz Mutant T183c Complexed With Mercury + 2O9E-A + 234 + + + 1 + 125.561 + 314 + 1.13671e-29 + 11 + 234 + 5 + 233 + 0 + 0 + 85 + 121 + 17 + 235 + WRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLAD---------GVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFS--NHWIFWVGPFIGGALAVLIYDFILAPR + FRKLAAESFGTFWLVFGGSGSAV---LAAGFPELGI-GFAGVALAFGLTVLTMAFAVGHISGGHFNPAVTIGLWAGGRFPAKEVVGYVIAQVVGGIVAAALLYLIASGKTGFDAAASGFASNGYGEHSPGGYSMLSALVVELVLSAGFLLVIHGATDKFAP--AGFAPIAIGLALTLIHLISIPVTNCSVNPARSTAVAIFQGGWALEQLWFFWVVPIVGGIIGGLIYRTLLEKR + +R + AE T VF GSA+ G + + V+LAFGL++ T+A +VGHISG H NPAVT+GL + + Y+IAQ VG IVA A+L I S TG + A G + L +E++ + +L + TD+ G AP+AIGL++ L HL++I T C +NPARS A+ ++ W FWV P +GG + LIY +L R + + + + + 11 + gi|39654847|pdb|1RC2|B + Chain B, 2.5 Angstrom Resolution X-Ray Structure Of Aquaporin Z >gi|39654848|pdb|1RC2|A Chain A, 2.5 Angstrom Resolution X-Ray Structure Of Aquaporin Z >gi|78101284|pdb|2ABM|A Chain A, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels >gi|78101285|pdb|2ABM|B Chain B, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels >gi|78101286|pdb|2ABM|C Chain C, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels >gi|78101287|pdb|2ABM|D Chain D, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels >gi|78101288|pdb|2ABM|E Chain E, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels >gi|78101289|pdb|2ABM|F Chain F, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels >gi|78101290|pdb|2ABM|G Chain G, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels >gi|78101291|pdb|2ABM|H Chain H, Crystal Structure Of Aquaporin Z Tetramer Reveals Both Open And Closed Water-Conducting Channels + 1RC2-B + 231 + + + 1 + 122.094 + 305 + 1.25678e-28 + 11 + 234 + 2 + 230 + 0 + 0 + 84 + 120 + 17 + 235 + WRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLAD---------GVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFS--NHWIFWVGPFIGGALAVLIYDFILAPR + FRKLAAECFGTFWLVFGGCGSAV---LAAGFPELGI-GFAGVALAFGLTVLTMAFAVGHISGGHFNPAVTIGLWAGGRFPAKEVVGYVIAQVVGGIVAAALLYLIASGKTGFDAAASGFASNGYGEHSPGGYSMLSALVVELVLSAGFLLVIHGATDKFAP--AGFAPIAIGLALTLIHLISIPVTNTSVNPARSTAVAIFQGGWALEQLWFFWVVPIVGGIIGGLIYRTLLEKR + +R + AE T VF GSA+ G + + V+LAFGL++ T+A +VGHISG H NPAVT+GL + + Y+IAQ VG IVA A+L I S TG + A G + L +E++ + +L + TD+ G AP+AIGL++ L HL++I T +NPARS A+ ++ W FWV P +GG + LIY +L R + + + + + 12 + gi|134105085|pdb|2O9F|A + Chain A, Crystal Structure Of Aqpz Mutant L170c >gi|134105086|pdb|2O9F|B Chain B, Crystal Structure Of Aqpz Mutant L170c >gi|134105087|pdb|2O9G|A Chain A, Crystal Structure Of Aqpz Mutant L170c Complexed With Mercury. + 2O9F-A + 234 + + + 1 + 120.939 + 302 + 2.79982e-28 + 11 + 234 + 5 + 233 + 0 + 0 + 84 + 119 + 17 + 235 + WRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLAD---------GVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVITHNFS--NHWIFWVGPFIGGALAVLIYDFILAPR + FRKLAAESFGTFWLVFGGSGSAV---LAAGFPELGI-GFAGVALAFGLTVLTMAFAVGHISGGHFNPAVTIGLWAGGRFPAKEVVGYVIAQVVGGIVAAALLYLIASGKTGFDAAASGFASNGYGEHSPGGYSMLSALVVELVLSAGFLLVIHGATDKFAP--AGFAPIAIGLACTLIHLISIPVTNTSVNPARSTAVAIFQGGWALEQLWFFWVVPIVGGIIGGLIYRTLLEKR + +R + AE T VF GSA+ G + + V+LAFGL++ T+A +VGHISG H NPAVT+GL + + Y+IAQ VG IVA A+L I S TG + A G + L +E++ + +L + TD+ G AP+AIGL+ L HL++I T +NPARS A+ ++ W FWV P +GG + LIY +L R + + + + + 13 + gi|83754991|pdb|2EVU|A + Chain A, Crystal Structure Of Aquaporin Aqpm At 2.3a Resolution >gi|83755033|pdb|2F2B|A Chain A, Crystal Structure Of Integral Membrane Protein Aquaporin Aqpm At 1.68a Resolution + 2EVU-A + 246 + + + 1 + 94.7449 + 234 + 2.14872e-20 + 15 + 230 + 9 + 243 + 0 + 0 + 73 + 118 + 25 + 238 + VAEFLATTLFVFISIGSALGFKYPVGNNQTA-------------VQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAIL---SGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAVI------THNFSNHWIFWVGPFIGGALAVLIYDFI + IAEFIGTFILVFFGAGSA-AVTLMIASGGTSPNPFNIGIGLLGGLGDWVAIGLAFGFAIAASIYALGNISGCHINPAVTIGLWSVKKFPGREVVPYIIAQLLGAAFGSFIFLQCAGIGAATVG-GLGATAPFPGISYWQAMLAEVVGTFLLMITIMGIAVDERAP-KGFAGIIIGLTVAGIITTLGNISGSSLNPARTFGPYLNDMIFAGTDLWNYYSIYVIGPIVGAVLAALTYQYL + +AEF+ T + VF GSA + + T+ + D V + LAFG +IA ++G+ISG H+NPAVT+GL + + YIIAQ +GA + I +GI ++ G LG G++ Q + E++GT L++ ++ R G A + IGL+VA + +G +NPAR+FG + T ++ + I+ +GP +G LA L Y ++ + + + 2 + 50.0618 + 118 + 6.06945e-07 + 10 + 117 + 143 + 245 + 0 + 0 + 34 + 57 + 15 + 113 + FWRAVVAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRAL-----MYIIAQCVGAIVATAILSGITS + YWQAMLAEVVGTFLLMITIMGIAVDERAPKG----------FAGIIIGLTVAGIITTLGNISGSSLNPARTFGPYLNDMIFAGTDLWNYYSIYVIGPIVGAVLAALTYQYLTS + +W+A++AE + T L + +G A+ + P G + GL++A + ++G+ISG+ LNPA T G L+ I L +Y+I VGA++A +TS + + + + + 14 + gi|21466057|pdb|1LDF|A + Chain A, Crystal Structure Of The E. Coli Glycerol Facilitator (Glpf) Mutation W48f, F200t + 1LDF-A + 281 + + + 1 + 82.0333 + 201 + 1.44128e-16 + 15 + 201 + 12 + 212 + 0 + 0 + 65 + 93 + 24 + 206 + VAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGI----------TSSLTGNSLGRNDLA--------DGVNSGQGLGIEIIGTLQLVLCVLATTDRRRR-DLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAV + IAEFLGTGLLIFFGVGCVAALKVA-----GASFGQWEISVIFGLGVAMAIYLTAGVSGAHLNPAVTIALWLFACFDKRKVIPFIVSQVAGAFCAAALVYGLYYNLFFDFEQTHHIVRGSVESVDLAGTFSTYPNPHINFVQAFAVEMVITAILMGLILALTDDGNGVPRGPLAPLLIGLLIAVIGASMGPLTGTAMNPARDFGPKV + +AEFL T L +F +G K A ++S+ FGL +A +SGAHLNPAVT+ L L + + +I++Q GA A A++ G+ T + S+ DLA +N Q +E++ T L+ +LA TD G APL IGL +A+ TG +NPAR FG V + + + + + 15 + gi|11514194|pdb|1FX8|A + Chain A, Crystal Structure Of The E. Coli Glycerol Facilitator (Glpf) With Substrate Glycerol >gi|21466052|pdb|1LDA|A Chain A, Crystal Structure Of The E. Coli Glycerol Facilitator (Glpf) Without Substrate Glycerol >gi|21466058|pdb|1LDI|A Chain A, Crystal Structure Of The E. Coli Glycerol Facilitator (Glpf) Without Substrate Glycerol + 1FX8-A + 281 + + + 1 + 79.7221 + 195 + 7.15301e-16 + 15 + 201 + 12 + 212 + 0 + 0 + 64 + 93 + 24 + 206 + VAEFLATTLFVFISIGSALGFKYPVGNNQTAVQDNVKVSLAFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGI----------TSSLTGNSLGRNDLA--------DGVNSGQGLGIEIIGTLQLVLCVLATTDRRRR-DLGGSAPLAIGLSVALGHLLAIDYTGCGINPARSFGSAV + IAEFLGTGLLIFFGVGCVAALKVA-----GASFGQWEISVIWGLGVAMAIYLTAGVSGAHLNPAVTIALWLFACFDKRKVIPFIVSQVAGAFCAAALVYGLYYNLFFDFEQTHHIVRGSVESVDLAGTFSTYPNPHINFVQAFAVEMVITAILMGLILALTDDGNGVPRGPLAPLLIGLLIAVIGASMGPLTGFAMNPARDFGPKV + +AEFL T L +F +G K A ++S+ +GL +A +SGAHLNPAVT+ L L + + +I++Q GA A A++ G+ T + S+ DLA +N Q +E++ T L+ +LA TD G APL IGL +A+ TG +NPAR FG V + + + + + 16 + gi|82407721|pdb|2A9M|L + Chain L, Structural Analysis Of A Tight-Binding Fluorescein-Scfv; Apo Form >gi|82407723|pdb|2A9M|M Chain M, Structural Analysis Of A Tight-Binding Fluorescein-Scfv; Apo Form >gi|82407725|pdb|2A9N|L Chain L, A Mutation Designed To Alter Crystal Packing Permits Structural Analysis Of A Tight-Binding Fluorescein-Scfv Complex >gi|82407727|pdb|2A9N|M Chain M, A Mutation Designed To Alter Crystal Packing Permits Structural Analysis Of A Tight-Binding Fluorescein-Scfv Complex + 2A9M-L + 110 + + + 1 + 27.335 + 59 + 4.21299 + 203 + 255 + 25 + 75 + 0 + 0 + 16 + 25 + 2 + 53 + THNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDL + TSNIGNNYVSWYQQHPGKAPKLMIYD--VSKRPSGVPDRFSGSKSGNSASLDI + T N N+++ W G A ++IYD ++ R S + DR SG D+ + + + + + 17 + gi|56967161|pdb|1XMX|A + Chain A, Crystal Structure Of Protein Vc1899 From Vibrio Cholerae + 1XMX-A + 385 + + + 1 + 27.335 + 59 + 4.21299 + 23 + 53 + 115 + 145 + 0 + 0 + 12 + 17 + 0 + 31 + LFVFISIGSALGFKYPVGNNQTAVQDNVKVS + IFVVEPNSDCLCWLYPEGNNDTQVQDRITIA + +FV L + YP GNN T VQD + ++ + + + + + 18 + gi|42543068|pdb|1NL0|L + Chain L, Crystal Structure Of Human Factor Ix Gla Domain In Complex Of An Inhibitory Antibody, 10c12 + 1NL0-L + 213 + + + 1 + 27.335 + 59 + 4.21299 + 203 + 255 + 26 + 76 + 0 + 0 + 16 + 25 + 2 + 53 + THNFSNHWIFWVGPFIGGALAVLIYDFILAPRSSDLTDRVKVWTSGQVEEYDL + TSNIGNNYVSWYQQHPGKAPKLMIYD--VSKRPSGVPDRFSGSKSGNSASLDI + T N N+++ W G A ++IYD ++ R S + DR SG D+ + + + + + 19 + gi|13399662|pdb|1EVY|A + Chain A, Crystal Structure Of Leishmania Mexicana Glycerol-3- Phosphate Dehydrogenase >gi|13399663|pdb|1EVZ|A Chain A, Crystal Structure Of Leishmania Mexicana Glycerol-3- Phosphate Dehydrogenase In Complex With Nad >gi|21730363|pdb|1JDJ|A Chain A, Crystal Structure Of Leishmania Mexicana Glycerol-3- Phosphate Dehydrogenase In Complex With 2-Fluoro-6- Chloropurine >gi|27573848|pdb|1M66|A Chain A, Crystal Structure Of Leishmania Mexicana Gpdh Complexed With Inhibitor 2-Bromo-6-Chloro-Purine >gi|27573849|pdb|1M67|A Chain A, Crystal Structure Of Leishmania Mexicana Gpdh Complexed With Inhibitor 2-Bromo-6-Hydroxy-Purine >gi|31615595|pdb|1N1E|A Chain A, Crystal Structure Of Leishmania Mexicana Glycerol-3- Phosphate Dehydrogenase Complexed With Dhap And Nad >gi|31615596|pdb|1N1E|B Chain B, Crystal Structure Of Leishmania Mexicana Glycerol-3- Phosphate Dehydrogenase Complexed With Dhap And Nad >gi|38492474|pdb|1N1G|A Chain A, Crystal Structure Of Leishmania Mexicana Glycerol-3- Phosphate Dehydrogenase With Inhibitor Bcp + 1EVY-A + 366 + + + 1 + 26.1794 + 56 + 9.38556 + 55 + 181 + 155 + 264 + 0 + 0 + 32 + 50 + 17 + 127 + AFGLSIATLAQSVGHISGAHLNPAVTLGLLLSCQISIFRALMYIIAQCVGAIVATAILSGITSSLTGNSLGRNDLADGVNSGQGLGIEIIGTLQLVLCVLATTDRRRRDLGGSAPLAIGLSVALGHL + SFAIEVATGVFTCVSIASADINVARRLQRIMSTGDRSF--VCWATTDTVGCEVASAV--------------KNVLAIGSGVANGLGMGLNARAALIMRGLLEIRDLTAALGGDGSAVFGLA-GLGDL + +F + +AT + I+ A +N A L ++S F + + VG VA+A+ +N LA G GLG+ + L++ L LGG GL+ LG L + + + + + + + 30464 + 6832400 + 0 + 0 + 0.041 + 0.267 + 0.14 + + + + + + + + + diff --git a/doc/BlastViewer.png b/doc/BlastViewer.png new file mode 100644 index 0000000..624f9d5 Binary files /dev/null and b/doc/BlastViewer.png differ diff --git a/doc/Getting-NCBI-RID.png b/doc/Getting-NCBI-RID.png new file mode 100644 index 0000000..4a195e1 Binary files /dev/null and b/doc/Getting-NCBI-RID.png differ diff --git a/jar/BrowserLauncher.jar b/jar/BrowserLauncher.jar new file mode 100644 index 0000000..35b7615 Binary files /dev/null and b/jar/BrowserLauncher.jar differ diff --git a/jar/castor-xml-1.1.2.jar b/jar/castor-xml-1.1.2.jar new file mode 100755 index 0000000..202c8cd Binary files /dev/null and b/jar/castor-xml-1.1.2.jar differ diff --git a/jar/commons-configuration-1.10.jar b/jar/commons-configuration-1.10.jar new file mode 100755 index 0000000..7922436 Binary files /dev/null and b/jar/commons-configuration-1.10.jar differ diff --git a/jar/commons-io-2.4.jar b/jar/commons-io-2.4.jar new file mode 100755 index 0000000..90035a4 Binary files /dev/null and b/jar/commons-io-2.4.jar differ diff --git a/jar/commons-lang-2.6.jar b/jar/commons-lang-2.6.jar new file mode 100755 index 0000000..98467d3 Binary files /dev/null and b/jar/commons-lang-2.6.jar differ diff --git a/jar/commons-logging-1.1.jar b/jar/commons-logging-1.1.jar new file mode 100755 index 0000000..2ff9bbd Binary files /dev/null and b/jar/commons-logging-1.1.jar differ diff --git a/jar/forms-1.1.jar b/jar/forms-1.1.jar new file mode 100755 index 0000000..50c1eb8 Binary files /dev/null and b/jar/forms-1.1.jar differ diff --git a/jar/jgaf-2.1.1.jar b/jar/jgaf-2.1.1.jar new file mode 100644 index 0000000..0c30134 Binary files /dev/null and b/jar/jgaf-2.1.1.jar differ diff --git a/jar/log4j-1.2.14.jar b/jar/log4j-1.2.14.jar new file mode 100755 index 0000000..6251307 Binary files /dev/null and b/jar/log4j-1.2.14.jar differ diff --git a/jar/pb-core-5.0.3.jar b/jar/pb-core-5.0.3.jar new file mode 100644 index 0000000..3c54db0 Binary files /dev/null and b/jar/pb-core-5.0.3.jar differ diff --git a/jar/pb-ui-5.1.0.jar b/jar/pb-ui-5.1.0.jar new file mode 100644 index 0000000..1dce6d4 Binary files /dev/null and b/jar/pb-ui-5.1.0.jar differ diff --git a/jar/xercesImpl-2.7.1.jar b/jar/xercesImpl-2.7.1.jar new file mode 100755 index 0000000..eac75ae Binary files /dev/null and b/jar/xercesImpl-2.7.1.jar differ diff --git a/jar/xmlParserAPIs.jar b/jar/xmlParserAPIs.jar new file mode 100755 index 0000000..243eaea Binary files /dev/null and b/jar/xmlParserAPIs.jar differ diff --git a/jar/xstream.jar b/jar/xstream.jar new file mode 100755 index 0000000..392e1c9 Binary files /dev/null and b/jar/xstream.jar differ diff --git a/src/bzh/plealog/blastviewer/BlastViewer.java b/src/bzh/plealog/blastviewer/BlastViewer.java new file mode 100644 index 0000000..3276bec --- /dev/null +++ b/src/bzh/plealog/blastviewer/BlastViewer.java @@ -0,0 +1,412 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.GridBagLayout; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JMenuBar; +import javax.swing.JPanel; +import javax.swing.JToolBar; +import javax.swing.SwingConstants; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.BasicConfigurator; + +import bzh.plealog.bioinfo.api.core.config.CoreSystemConfigurator; +import bzh.plealog.bioinfo.ui.blast.config.ConfigManager; +import bzh.plealog.bioinfo.ui.blast.config.color.ColorPolicyConfig; +import bzh.plealog.bioinfo.ui.config.UISystemConfigurator; +import bzh.plealog.blastviewer.actions.FetchFromNcbiAction; +import bzh.plealog.blastviewer.actions.OpenFileAction; +import bzh.plealog.blastviewer.config.color.ColorPolicyConfigImplem; +import bzh.plealog.blastviewer.config.directory.DirManager; +import bzh.plealog.blastviewer.hittable.BVHitTableFactoryImplem; +import bzh.plealog.blastviewer.resources.BVMessages; +import bzh.plealog.blastviewer.util.BlastViewerOpener; + +import com.plealog.genericapp.api.EZApplicationBranding; +import com.plealog.genericapp.api.EZEnvironment; +import com.plealog.genericapp.api.EZGenericApplication; +import com.plealog.genericapp.api.EZUIStarterListener; +import com.plealog.genericapp.api.file.EZFileUtils; +import com.plealog.genericapp.api.log.EZLogger; +import com.plealog.genericapp.api.log.EZLoggerManager; +import com.plealog.genericapp.api.log.EZLoggerManager.LogLevel; +import com.plealog.genericapp.api.log.EZSingleLineFormatter; +import com.plealog.genericapp.ui.desktop.CascadingWindowPositioner; +import com.plealog.genericapp.ui.desktop.GDesktopPane; +import com.plealog.genericapp.ui.desktop.JWindowsMenu; + +/** + * Starter class for the Blast Viewer software. + * + * @author Patrick G. Durand + */ +public class BlastViewer { + + /** + * JVM optional argument. Provide a configuration directory. If not provided, + * software locates its resources and configuration files within compiled Java + * codes. Sample use: -DV_CONF=./config + */ + private static final String JVM_ARG_CONF = "V_CONF"; + /** + * JVM optional argument. Switch debug mode to true or false. If not provided, + * debug mode is disabled. Sample use: -DV_DEBUG=true + */ + public static final String JVM_ARG_DEBUG = "V_DEBUG"; + + private static final String LOAD_ERR = "Load Color configuration from: %s"; + private static final String CONF_ERR = "Unable to load color configuration: "; + + /** + * Start application. Relies on the Java Generic Application Framework. See + * https://github.com/pgdurand/jGAF + */ + public static void main(String[] args) { + // This has to be done at the very beginning, i.e. first method call within + // main(). + EZGenericApplication.initialize("BLASTViewer"); + // Add application branding + Properties props = getVersionProperties(); + EZApplicationBranding.setAppName(props.getProperty("prg.app.name")); + EZApplicationBranding.setAppVersion(props.getProperty("prg.version")); + EZApplicationBranding.setCopyRight(props.getProperty("prg.copyright")); + EZApplicationBranding.setProviderName(props.getProperty("prg.provider")); + + // setup the logger framework + // turn off Java Logging standard console log + EZLoggerManager.enableConsoleLogger(false); + // turn on UI logger; text size limit is set to 2 million characters (when + // content of UI logger reaches that limit, then UI text component simply + // reset its content). + EZLoggerManager.enableUILogger(true, 2); + // delegate LogLevel to software config since JVM argument can be used + // to modify standard behavior (see DocViewerConfig.JVM_ARG_DEBUG) + initLogLevel(); + // setup the logging system + EZLoggerManager.initialize(); + + // some third party libraries rely on log4j (e.g. Castor XML framework) + BasicConfigurator.configure(); + + // Required to use Plealog Bioinformatics Core objects such as Features, + // FeatureTables, Sequences + CoreSystemConfigurator.initializeSystem(); + + // Required to use the Plealog Bioinformatics UI library (CartoViewer + // default graphics) + UISystemConfigurator.initializeSystem(); + + // we need to know where are located this application resources (messages + // and icons) + EZEnvironment + .addResourceLocator(bzh.plealog.blastviewer.resources.BVMessages.class); + + // we enable the application to automatically serialize application + // properties (e.g. column model of the BlastHitTable) + ConfigManager.setEnableSerialApplicationProperty(true); + // we redirect the factory to use our implementation of a BlastHitTable + ConfigManager.setHitTableFactory(new BVHitTableFactoryImplem()); + // we setup the Directory Manager + ConfigManager.addConfig(new DirManager()); + // we setup the color policy + initColorPolicyConfig(); + + // Add a listener to application startup cycle (see below) + EZEnvironment.setUIStarterListener(new MyStarterListener()); + + // Start the application + EZGenericApplication.startApplication(args); + } + + /** + * Set the log level to info or debug. Rely on the JVM argument DV_DEBUG. Use: + * -DDV_DEBUG=true. + */ + public static void initLogLevel() { + String dbg = System.getProperty(JVM_ARG_DEBUG); + if (dbg != null) { + EZLoggerManager + .setLevel(dbg.toLowerCase().equals("true") ? LogLevel.debug + : LogLevel.info); + } + // set the Formatter of the UI logger: in debug mode, provide full + // class/method names + EZLoggerManager.setUILoggerFormatter(new EZSingleLineFormatter( + EZLoggerManager.getLevel() == LogLevel.debug)); + } + + /** + * Return the software configuration file. By default, there is no such + * directory available. Has to be setup using JRM argument: DV_CONF, with + * value targeting a directory. + */ + public static String getConfigurationPath() { + String confP = System.getProperty(JVM_ARG_CONF); + + if (confP == null) + return null; + + return EZFileUtils.terminatePath(confP); + } + + /** + * Return the content of the version resource. + */ + private static Properties getVersionProperties() { + Properties props = new Properties(); + try (InputStream in = BlastViewer.class + .getResourceAsStream("version.properties");) { + props.load(in); + in.close(); + } catch (Exception ex) {// should not happen + System.err.println("Unable to read props: " + ex.toString()); + } + return props; + } + + /** + * Initializes colors system. + */ + private static void initColorPolicyConfig() { + ColorPolicyConfig nc; + FileInputStream fis = null; + String confPath; + File f; + InputStream in = null; + + try { + // first, try to locate the file in the user conf dir + confPath = getConfigurationPath(); + if (confPath != null) { + confPath += ColorPolicyConfigImplem.CONFIG_FILE_NAME; + f = new File(confPath); + if (f.exists()) { + EZLogger.debug(String.format(LOAD_ERR, f.getAbsolutePath())); + in = new FileInputStream(f); + } + } + // try from software resource + if (in == null) { + EZLogger.debug(String.format( + LOAD_ERR, + BVMessages.class.getResource( + ColorPolicyConfigImplem.CONFIG_FILE_NAME).toString())); + in = BVMessages.class + .getResourceAsStream(ColorPolicyConfigImplem.CONFIG_FILE_NAME); + } + // will use default color config + if (in == null) + return; + + nc = new ColorPolicyConfigImplem(confPath); + nc.load(in); + // nc.dumpConfig(); + ConfigManager.addConfig(nc); + } catch (Exception ex) { + EZLogger.warn(CONF_ERR + ex.toString()); + } finally { + IOUtils.closeQuietly(fis); + } + } + + /** + * Implementation of the jGAF API. + */ + private static class MyStarterListener implements EZUIStarterListener { + + private GDesktopPane _desktop = new GDesktopPane(); + private Component _mainCompo = null; + private JPanel _btnPanel; + + private Component prepareDesktop() { + JPanel dpanel, mnuPnl, hlpPnl; + JButton logBtn; + JWindowsMenu windowsMenu; + + dpanel = new JPanel(new BorderLayout()); + mnuPnl = new JPanel(new BorderLayout()); + + _btnPanel = new JPanel(new BorderLayout()); + + JMenuBar menuBar = new JMenuBar(); + ImageIcon icon = EZEnvironment.getImageIcon("documents.png"); + if (icon != null) { + windowsMenu = new JWindowsMenu(_desktop.getDesktopPane()); + windowsMenu.setIcon(icon); + } else { + windowsMenu = new JWindowsMenu( + BVMessages.getString("DocumentViewer.docs.mnu"), + _desktop.getDesktopPane()); + } + windowsMenu.setWindowPositioner(new CascadingWindowPositioner(_desktop + .getDesktopPane())); + menuBar.add(windowsMenu); + + logBtn = new JButton(EZEnvironment.getImageIcon("logger.png")); + logBtn.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + logBtn.addActionListener(new ShowLoggerFrame()); + logBtn.setVerticalTextPosition(SwingConstants.BOTTOM); + logBtn.setHorizontalTextPosition(SwingConstants.CENTER); + logBtn.setText("Log"); + + windowsMenu.setFont(logBtn.getFont()); + + mnuPnl.add(menuBar, BorderLayout.WEST); + mnuPnl.add(logBtn, BorderLayout.EAST); + _btnPanel.add(mnuPnl, BorderLayout.EAST); + hlpPnl = new JPanel(new GridBagLayout()); + hlpPnl.add(BlastViewerOpener.getHelperField()); + _btnPanel.add(hlpPnl, BorderLayout.CENTER); + _btnPanel.add(getToolbar(), BorderLayout.WEST); + dpanel.add(_btnPanel, BorderLayout.NORTH); + dpanel.add(_desktop, BorderLayout.CENTER); + + BlastViewerOpener.setDesktop(_desktop); + + return dpanel; + } + + @Override + public Component getApplicationComponent() { + if (_mainCompo != null) + return _mainCompo; + + // prepare the desktop viewer system + _mainCompo = prepareDesktop(); + + return _mainCompo; + } + + @Override + public boolean isAboutToQuit() { + // You can add some code to figure out if application can exit. + + // Return false to prevent application from exiting (e.g. a background + // task is still running). + // Return true otherwise. + + // Do not add a Quit dialogue box to ask user confirmation: the framework + // already does that for you. + return true; + } + + @Override + public void postStart() { + // This method is called by the framework just before displaying UI + // (main frame). + EZLogger.info(String.format("%s - %s", + EZApplicationBranding.getAppName(), + EZApplicationBranding.getAppVersion())); + EZLogger.info(EZApplicationBranding.getCopyRight()); + try { + DirManager dmgr = (DirManager) ConfigManager.getConfig(DirManager.NAME); + //EZLogger.info(dmgr.getApplicationDataPath()); + EZLogger.info("Storage directory is: "+dmgr.getBlastDataPath()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Override + public void preStart() { + // This method is called by the framework at the very beginning of + // application startup. + } + + } + + private static JToolBar getToolbar() { + JToolBar tBar; + ImageIcon icon; + Action act; + JButton btn; + + tBar = new JToolBar(); + tBar.setFloatable(false); + + icon = EZEnvironment.getImageIcon("open.png"); + if (icon != null) { + act = new OpenFileAction("", icon); + } else { + act = new OpenFileAction(BVMessages.getString("OpenBlastList.open.name")); + } + act.setEnabled(true); + btn = tBar.add(act); + btn.setToolTipText(BVMessages.getString("OpenBlastList.open.tip")); + btn.setText(BVMessages.getString("OpenBlastList.open.name")); + + icon = EZEnvironment.getImageIcon("download.png"); + if (icon != null) { + act = new FetchFromNcbiAction("", icon); + } else { + act = new FetchFromNcbiAction( + BVMessages.getString("OpenBlastList.openrid.name")); + } + act.setEnabled(true); + btn = tBar.add(act); + btn.setToolTipText(BVMessages.getString("OpenBlastList.openrid.tip")); + btn.setText(BVMessages.getString("OpenBlastList.openrid.name")); + return tBar; + } + + /** + * Utility class to show the UI Logger component. + */ + private static class ShowLoggerFrame implements ActionListener { + private JFrame frame; + + @Override + public void actionPerformed(ActionEvent e) { + if (frame == null) { + makeFrame(); + } + frame.setVisible(!frame.isVisible()); + } + + private void makeFrame() { + int delta = 50; + frame = new JFrame(BVMessages.getString("DocumentViewer.docs.tab2")); + frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); + Rectangle rect = EZEnvironment.getParentFrame().getBounds(); + rect.x += delta; + rect.y += delta; + rect.width -= 2 * delta; + rect.height -= 2 * delta; + frame.getContentPane().add(EZLoggerManager.getUILogger()); + frame.setBounds(rect); + } + } + +} diff --git a/src/bzh/plealog/blastviewer/BlastViewerPanel.java b/src/bzh/plealog/blastviewer/BlastViewerPanel.java new file mode 100755 index 0000000..9e0404a --- /dev/null +++ b/src/bzh/plealog/blastviewer/BlastViewerPanel.java @@ -0,0 +1,254 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.util.Collections; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; + +import bzh.plealog.bioinfo.api.core.config.CoreSystemConfigurator; +import bzh.plealog.bioinfo.api.data.feature.Feature; +import bzh.plealog.bioinfo.api.data.feature.Qualifier; +import bzh.plealog.bioinfo.api.data.searchresult.SRHsp; +import bzh.plealog.bioinfo.api.data.searchresult.SROutput; +import bzh.plealog.bioinfo.api.data.searchresult.SRRequestInfo; +import bzh.plealog.bioinfo.ui.blast.config.ConfigManager; +import bzh.plealog.bioinfo.ui.blast.config.color.ColorPolicyConfig; +import bzh.plealog.bioinfo.ui.blast.config.color.DefaultHitColorPolicy; +import bzh.plealog.bioinfo.ui.blast.core.BlastEntry; +import bzh.plealog.bioinfo.ui.blast.core.BlastHitHSP; +import bzh.plealog.bioinfo.ui.blast.event.BlastHitListSupport; +import bzh.plealog.bioinfo.ui.blast.hittable.BlastHitTable; +import bzh.plealog.bioinfo.ui.blast.nav.BlastNavigator; +import bzh.plealog.bioinfo.ui.blast.saviewer.SeqAlignViewer; +import bzh.plealog.bioinfo.ui.blast.summary.GraphicViewer; +import bzh.plealog.bioinfo.ui.carto.data.BasicFeatureOrganizer; +import bzh.plealog.bioinfo.ui.carto.data.FGraphics; +import bzh.plealog.bioinfo.ui.carto.data.FeatureOrganizerManager; +import bzh.plealog.bioinfo.ui.carto.painter.FeaturePainter; +import bzh.plealog.bioinfo.ui.resources.SVMessages; +import bzh.plealog.bioinfo.ui.util.JHeadPanel; + +import com.plealog.genericapp.api.EZEnvironment; + +/** + * This is the BlastViewer Main Module. + * + * It wraps within a single component the various + * elements required to displayed Blast data: a BlastNavigator, a Blast Hit Table, + * the pairwise sequence alignment viewer, etc. + * + * @author Patrick G. Durand + */ +public class BlastViewerPanel extends JPanel { + + private static final long serialVersionUID = -2405089127382200483L; + + protected BlastHitTable _hitListPane; + protected SeqAlignViewer _seqAlignViewer; + protected BlastNavigator _summaryPane; + protected JPanel _rightPane; + protected BlastHitListSupport _updateSupport; + protected GraphicViewer _cartoViewer; + + protected static final String HITPANEL_HEADER = SVMessages.getString("BlastViewerPanel.0"); + protected static final String HITPANEL_LIST = SVMessages.getString("BlastViewerPanel.1"); + protected static final String HITPANEL_GRAPHIC = SVMessages.getString("BlastViewerPanel.2"); + + /** + * Default constructor. + */ + public BlastViewerPanel() { + super(); + createGUI(); + BasicFeatureOrganizer.setFeatureOrganizerManager(new LocalFeatureOrganizerManager()); + } + + /** + * Set the data to display in this viewer. + */ + public void setContent(BlastEntry entry) { + _summaryPane.setContent(entry); + } + + /** + * Set the data to display in this viewer. + */ + public void setContent(SROutput so, String soPath) { + _summaryPane.setContent(prepareEntry(so, soPath)); + } + + /** + * Set the data to display in this viewer. + */ + public void setContent(SROutput so) { + _summaryPane.setContent(prepareEntry(so, null)); + } + + /** + * Return the Hit currently selected in this BlastViewerPanel. Actually, the + * method returns the Hit that is currently displayed by the SeqAlignViewer + * panel. + */ + public BlastHitHSP getSelectedHit() { + return _seqAlignViewer.getCurrentHit(); + } + + /** + * Return the HSP currently selected in this BlastViewerPanel. Actually, the + * method returns the HSP that is currently displayed by the SeqAlignViewer + * panel. + */ + public SRHsp getSelectedHsp() { + return _seqAlignViewer.getCurrentHsp(); + } + + private BlastEntry prepareEntry(SROutput bo, String soPath) { + String val; + int pos; + + // analyze SROutput object (i.e. a Blast result) to get: + // program name, query name and databank name + SRRequestInfo bri = bo.getRequestInfo(); + Object obj = bri.getValue(SRRequestInfo.PRGM_VERSION_DESCRIPTOR_KEY); + if (obj != null) { + val = obj.toString(); + if ((pos = val.indexOf('[')) > 0) { + val = val.substring(0, pos - 1); + } else { + val = obj.toString(); + } + } else { + val = null; + } + String program = val != null ? val : "?"; + obj = bri.getValue(SRRequestInfo.DATABASE_DESCRIPTOR_KEY); + String dbname = obj != null ? obj.toString() : "?"; + obj = bri.getValue(SRRequestInfo.QUERY_DEF_DESCRIPTOR_KEY); + String queryName = obj != null ? obj.toString() : "?"; + + return new BlastEntry(program, queryName, soPath, bo, null, dbname, false); + } + + private void createGUI() { + JHeadPanel headPanel; + ImageIcon icon; + + _updateSupport = new BlastHitListSupport(); + _summaryPane = new BlastNavigator(); + _hitListPane = ConfigManager.getHitTableFactory().createViewer(); + _seqAlignViewer = ConfigManager.getSeqAlignViewerFactory().createViewer(); + icon = EZEnvironment.getImageIcon("hitTable.png"); + if (icon != null) { + headPanel = new JHeadPanel(icon, HITPANEL_HEADER, _hitListPane); + } else { + headPanel = new JHeadPanel(null, HITPANEL_HEADER, _hitListPane); + } + headPanel.setToolPanel(_summaryPane); + _rightPane = new JPanel(new BorderLayout()); + // _rightPane.add(_summaryPane, BorderLayout.NORTH); + _rightPane.add(headPanel, BorderLayout.CENTER); + _rightPane.add(_seqAlignViewer, BorderLayout.SOUTH); + + _cartoViewer = new GraphicViewer(); + + JTabbedPane jtp; + + if (EZEnvironment.getOSType() == EZEnvironment.MAC_OS) { + jtp = new JTabbedPane(JTabbedPane.LEFT); + } else { + jtp = new JTabbedPane(JTabbedPane.TOP); + } + jtp.add("Hit Table", _rightPane); + jtp.add("Graphic Summary", _cartoViewer); + + this.setLayout(new BorderLayout()); + this.add(jtp, BorderLayout.CENTER); + + // listeners to the selection of a new BIteration + _summaryPane.addIterationListener(_hitListPane); + _summaryPane.addIterationListener(_cartoViewer); + // listeners to the change of data model + _hitListPane.addHitDataListener(_seqAlignViewer); + // listeners to selection within hit tables + _hitListPane.registerHitListSupport(_updateSupport); + _seqAlignViewer.registerHitListSupport(_updateSupport); + _updateSupport.addBlastHitListListener(_hitListPane); + _updateSupport.addBlastHitListListener(_seqAlignViewer); + this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + } + + private class LocalFeatureOrganizerManager implements FeatureOrganizerManager { + + private ColorPolicyConfig nc; + private SRHsp fakeHsp; + + private LocalFeatureOrganizerManager(){ + nc = (ColorPolicyConfig) ConfigManager.getConfig(ColorPolicyConfig.NAME); + fakeHsp = CoreSystemConfigurator.getSRFactory().createBHsp(); + fakeHsp.setScores(CoreSystemConfigurator.getSRFactory().createBHspScore()); + } + + private Color getColor(String score) { + Color clr = Color.BLACK; + int val = (int) Math.round(Double.valueOf(score)); + + if (nc == null) { + clr = DefaultHitColorPolicy.getColor(val); + } else { + fakeHsp.getScores().setBitScore(val); + clr = nc.getHitColor(fakeHsp, false); + } + return clr; + } + + @Override + public String[] getFeatureOrderingNames() { + return null; + } + + @Override + public FGraphics getFGraphics(Feature feat, FGraphics fg) { + if (feat.getKey().equals(GraphicViewer.BHIT_FEATURE_TYPE) == false) + return null; + + FGraphics fg2 = fg; + for (Qualifier qual : Collections.list(feat.enumQualifiers())) { + if (qual.getName().equals(GraphicViewer.SCORE_BITS_QUALIFIER)) { + fg2 = (FGraphics) fg.clone(); + fg2.setBackgroundColor(getColor(qual.getValue())); + } + } + return fg2; + } + + @Override + public FeaturePainter getFeaturePainter(Feature feat, FeaturePainter fp) { + return null; + } + + @Override + public String getReferenceFeatureName() { + return null; + } + } +} diff --git a/src/bzh/plealog/blastviewer/actions/EditColorPolicyAction.java b/src/bzh/plealog/blastviewer/actions/EditColorPolicyAction.java new file mode 100755 index 0000000..4c6f6a8 --- /dev/null +++ b/src/bzh/plealog/blastviewer/actions/EditColorPolicyAction.java @@ -0,0 +1,58 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.actions; + +import java.awt.event.ActionEvent; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JOptionPane; +import javax.swing.JTable; + +import bzh.plealog.blastviewer.config.color.HitPolicyEditorDialog; + +import com.plealog.genericapp.api.EZEnvironment; + +/** + * This class manages an action to start the Color Policy Editor. + * + * @author Patrick G. Durand + */ +public class EditColorPolicyAction extends AbstractAction { + private static final long serialVersionUID = 6933508753277672501L; + private JTable _parent; + + public EditColorPolicyAction(String name) { + super(name); + } + + public EditColorPolicyAction(String name, Icon icon) { + super(name, icon); + } + + public void setParent(JTable table) { + _parent = table; + } + + public void actionPerformed(ActionEvent event) { + HitPolicyEditorDialog dlg; + + dlg = new HitPolicyEditorDialog(JOptionPane.getFrameForComponent(EZEnvironment.getParentFrame())); + dlg.showDlg(); + _parent.repaint(); + } +} diff --git a/src/bzh/plealog/blastviewer/actions/FetchFromNcbiAction.java b/src/bzh/plealog/blastviewer/actions/FetchFromNcbiAction.java new file mode 100755 index 0000000..f0f9b9d --- /dev/null +++ b/src/bzh/plealog/blastviewer/actions/FetchFromNcbiAction.java @@ -0,0 +1,165 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.actions; + +import java.awt.event.ActionEvent; +import java.io.File; +import java.io.IOException; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.JOptionPane; + +import bzh.plealog.bioinfo.api.data.searchresult.SROutput; +import bzh.plealog.bioinfo.api.data.searchresult.io.SRLoader; +import bzh.plealog.bioinfo.io.searchresult.SerializerSystemFactory; +import bzh.plealog.bioinfo.ui.blast.config.ConfigManager; +import bzh.plealog.blastviewer.BlastViewerPanel; +import bzh.plealog.blastviewer.client.ncbi.QBlastRetriever; +import bzh.plealog.blastviewer.config.directory.DirManager; +import bzh.plealog.blastviewer.resources.BVMessages; +import bzh.plealog.blastviewer.util.BlastViewerOpener; + +import com.plealog.genericapp.api.EZApplicationBranding; +import com.plealog.genericapp.api.EZEnvironment; +import com.plealog.genericapp.api.file.EZFileUtils; +import com.plealog.genericapp.api.log.EZLogger; + +/** + * This class implements the action used to fetch a Blast results directly from + * the NCBI. + * + * @author Patrick G. Durand + */ +public class FetchFromNcbiAction extends AbstractAction { + private static final long serialVersionUID = -2654059939053088591L; + + private boolean _fetcherLocked = false; + + /** + * Action constructor. + * + * @param name + * the name of the action. + */ + public FetchFromNcbiAction(String name) { + super(name); + } + + /** + * Action constructor. + * + * @param name + * the name of the action. + * @param icon + * the icon of the action. + */ + public FetchFromNcbiAction(String name, Icon icon) { + super(name, icon); + } + + public void actionPerformed(ActionEvent event) { + String rid; + if (_fetcherLocked) + return; + rid = JOptionPane.showInputDialog(EZEnvironment.getParentFrame(), + BVMessages.getString("FetchFromNcbiAction.lbl"), + EZApplicationBranding.getAppName(), JOptionPane.QUESTION_MESSAGE); + if (rid == null || rid.length() == 0) + return; + new Fetcher(rid).start(); + } + + /** + * Handle the data retrieval using a separate thread. + */ + private class Fetcher extends Thread { + private String _rid; + + public Fetcher(String rid) { + _rid = rid; + } + + private String chooseFile() { + try { + DirManager dmgr = (DirManager) ConfigManager.getConfig(DirManager.NAME); + return dmgr.getBlastDataPath() + _rid + ".xml"; + } catch (IOException e) { + EZLogger.warn(BVMessages.getString("FetchFromNcbiAction.err2") + e); + } + return null; + } + + public void run() { + _fetcherLocked = true; + + QBlastRetriever qRet; + File tmpFile, resFile; + String resFileStr; + boolean bRet; + + // connect to the NCBI + BlastViewerOpener.setHelperMessage(BVMessages + .getString("FetchFromNcbiAction.msg1")); + qRet = new QBlastRetriever(); + EZEnvironment.setWaitCursor(); + bRet = qRet.getBlastResult(_rid); + EZEnvironment.setDefaultCursor(); + // error ? + if (bRet == false) { + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), + qRet.getErrorMsg()); + } else { + // ok, then ask the user for a file to save the Blast data + BlastViewerOpener.setHelperMessage(BVMessages + .getString("FetchFromNcbiAction.msg2")); + tmpFile = qRet.getResultFile(); + resFileStr = chooseFile(); + if (resFileStr != null) { + resFile = new File(resFileStr); + try { + EZFileUtils.copyFile(tmpFile, resFile); + EZLogger.info(BVMessages.getString("FetchFromNcbiAction.msg3") + + resFileStr); + // setup an NCBI Blast Loader (XML) + BlastViewerOpener.setHelperMessage(BVMessages + .getString("FetchFromNcbiAction.msg4")); + SRLoader ncbiBlastLoader = SerializerSystemFactory + .getLoaderInstance(SerializerSystemFactory.NCBI_LOADER); + // load data from file + SROutput so = ncbiBlastLoader.load(resFile); + // prepare the viewer + BlastViewerPanel viewer = new BlastViewerPanel(); + viewer.setContent(so); + // display the viewer + BlastViewerOpener.displayInternalFrame(viewer, resFile.getName(), + null); + } catch (IOException e) { + EZLogger.warn(BVMessages.getString("FetchFromNcbiAction.err1") + + ": " + e); + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), + BVMessages.getString("FetchFromNcbiAction.err1") + "."); + } + } + // discard the temporary file + tmpFile.delete(); + } + BlastViewerOpener.cleanHelperMessage(); + _fetcherLocked = false; + } + } +} diff --git a/src/bzh/plealog/blastviewer/actions/OpenFileAction.java b/src/bzh/plealog/blastviewer/actions/OpenFileAction.java new file mode 100644 index 0000000..f9fbf26 --- /dev/null +++ b/src/bzh/plealog/blastviewer/actions/OpenFileAction.java @@ -0,0 +1,104 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.actions; + +import java.awt.event.ActionEvent; +import java.io.File; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.SwingUtilities; + +import bzh.plealog.bioinfo.api.data.searchresult.SROutput; +import bzh.plealog.bioinfo.api.data.searchresult.io.SRLoader; +import bzh.plealog.bioinfo.io.searchresult.SerializerSystemFactory; +import bzh.plealog.blastviewer.BlastViewerPanel; +import bzh.plealog.blastviewer.resources.BVMessages; +import bzh.plealog.blastviewer.util.BlastViewerOpener; + +import com.plealog.genericapp.api.EZEnvironment; +import com.plealog.genericapp.api.file.EZFileManager; +import com.plealog.genericapp.api.log.EZLogger; + +/** + * This class implements the action to load a Blast XML results from a file. + * + * @author Patrick G. Durand + */ +public class OpenFileAction extends AbstractAction { + private static final long serialVersionUID = -3984245135396746453L; + + /** + * Action constructor. + * + * @param name + * the name of the action. + */ + public OpenFileAction(String name) { + super(name); + } + + /** + * Action constructor. + * + * @param name + * the name of the action. + * @param icon + * the icon of the action. + */ + public OpenFileAction(String name, Icon icon) { + super(name, icon); + } + + private SROutput readBlastFile(File f) { + // setup an NCBI Blast Loader (XML) + SRLoader ncbiBlastLoader = SerializerSystemFactory + .getLoaderInstance(SerializerSystemFactory.NCBI_LOADER); + return ncbiBlastLoader.load(f); + } + + private void doAction() { + File f = EZFileManager.chooseFileForOpenAction(BVMessages + .getString("OpenFileAction.lbl")); + if (f == null)// user canceled dlg box + return; + + EZEnvironment.setWaitCursor(); + + BlastViewerPanel viewer = new BlastViewerPanel(); + viewer.setContent(readBlastFile(f)); + + BlastViewerOpener.displayInternalFrame(viewer, f.getName(), null); + } + + public void actionPerformed(ActionEvent event) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + try { + doAction(); + } catch (Throwable t) { + EZLogger.warn(BVMessages.getString("OpenFileAction.err") + + t.toString()); + } finally { + EZEnvironment.setDefaultCursor(); + } + } + }); + } + +} diff --git a/src/bzh/plealog/blastviewer/client/ncbi/QBlastRetriever.java b/src/bzh/plealog/blastviewer/client/ncbi/QBlastRetriever.java new file mode 100755 index 0000000..1c91f0f --- /dev/null +++ b/src/bzh/plealog/blastviewer/client/ncbi/QBlastRetriever.java @@ -0,0 +1,101 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.client.ncbi; + +import java.io.File; +import java.text.MessageFormat; +import java.util.Map; + +import bzh.plealog.blastviewer.resources.BVMessages; +import bzh.plealog.blastviewer.util.HTTPBasicEngine; +import bzh.plealog.blastviewer.util.HTTPEngineException; + +/** + * This class implements a basic system to fetch a Blast results from the NCBI + * given a Request Identifier. + * + * @author Patrick G. Durand + */ +public class QBlastRetriever { + private String _errorMsg; + private File _resFile; + + public static final MessageFormat QBLAST_URL = new MessageFormat( + "https://blast.ncbi.nlm.nih.gov/Blast.cgi?RESULTS_FILE=on&RID={0}&FORMAT_TYPE=XML&FORMAT_OBJECT=Alignment&CMD=Get" + ); + // Note: old address was: + // "https://www.ncbi.nlm.nih.gov/blast/Blast.cgi?RID={0}&FORMAT_TYPE=XML&CMD=Get&ALIGNMENT_TYPE=Pairwise&FORMAT_OBJECT=Alignment" + // To get XML 2, use: FORMAT_TYPE=XML2_S + private static final String QUERY_NAME = "QBlastRetriever"; + + /** + * Call this method after a call to getBlastResult to get back some error + * message if any. + * + * @return an error message or null if no error was reported. + */ + public String getErrorMsg() { + return _errorMsg; + } + + /** + * Call this method after a call to getBlastResult to get back the result + * file. + * + * @return a result file or null if an error was reported. + */ + public File getResultFile() { + return _resFile; + } + + public boolean getBlastResult(String rid) { + QBlasterBase qb; + Map qBlastInfo; + String status; + String url; + File tmpFile; + + url = QBLAST_URL.format(new Object[] { rid.trim() }); + try { + tmpFile = HTTPBasicEngine.doGet(url); + } catch (HTTPEngineException ex) { + _errorMsg = ex.getMessage(); + return false; + } + qb = new QBlasterBase(); + qBlastInfo = qb.analyseOutput(QUERY_NAME, tmpFile, false, false); + if (qBlastInfo.size() == 0) { + // ok + _resFile = tmpFile; + return true; + } else { + // status different than WAITING: Blast error! + status = (String) qBlastInfo.get("Status"); + if (status != null && !status.equals("WAITING")) { + // we return an ERROR param, while NCBI not + _errorMsg = (String) qBlastInfo.get("ERROR"); + if (_errorMsg == null) + _errorMsg = status; + } else { + _errorMsg = BVMessages.getString("QBlastRetriever.err"); + } + tmpFile.delete(); + return false; + } + } + +} diff --git a/src/bzh/plealog/blastviewer/client/ncbi/QBlasterBase.java b/src/bzh/plealog/blastviewer/client/ncbi/QBlasterBase.java new file mode 100755 index 0000000..2a63d4c --- /dev/null +++ b/src/bzh/plealog/blastviewer/client/ncbi/QBlasterBase.java @@ -0,0 +1,111 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.client.ncbi; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.Hashtable; +import java.util.Map; + +import org.apache.commons.io.IOUtils; + +import bzh.plealog.blastviewer.resources.BVMessages; + +import com.plealog.genericapp.api.log.EZLogger; + +public class QBlasterBase { + private String _errorMsg; + + /** + * Analyze a file containing some data retrieved from the NCBI Blast server. + * Actually this method looks for the section QBlastInfo and retrieves the + * data available there. It gives the status of a query running on the server + * side. + * + * @param file + * the file to analyze + * @return a key/value pairs table, i.e. query status. More on that is + * available from the NCBI Blast server documentation. + */ + protected Map analyseOutput(String qName, File file, + boolean logInfo, boolean logError) { + Hashtable qBlastInfo; + BufferedReader br = null; + String line, key, value; + boolean readInfo = false; + int pos; + + qBlastInfo = new Hashtable<>(); + try { + if (file.length() < 30) { + qBlastInfo.put("LENGTH", "NOT_VALID"); + } else { + br = new BufferedReader(new FileReader(file)); + while ((line = br.readLine()) != null) { + if (line.indexOf("QBlastInfoBegin") != -1) { + readInfo = true; + } + if (logInfo && readInfo) { + EZLogger.info(line); + } + if (line.indexOf("QBlastInfoEnd") != -1) { + break; + } + pos = line.indexOf("ERROR:"); + if (pos != -1) { + value = line.substring(pos + 6).trim(); + pos = value.indexOf('<'); + if (pos != -1) + qBlastInfo.put("ERROR", value.substring(0, pos)); + else + qBlastInfo.put("ERROR", value); + } + pos = line.indexOf("INFO:"); + if (pos != -1) { + value = line.substring(pos + 5).trim(); + pos = value.indexOf('<'); + if (pos != -1) + qBlastInfo.put("INFO", value.substring(0, pos)); + else + qBlastInfo.put("INFO", value); + } + if (readInfo) { + pos = line.indexOf('='); + if (pos != -1) { + key = line.substring(0, pos).trim(); + value = line.substring(pos + 1).trim(); + qBlastInfo.put(key, value); + } + } + } + } + } catch (Exception ex) { + _errorMsg = BVMessages.getString("QBlaster.analyseFileError"); + if (logError) { + EZLogger.warn(qName + ": " + _errorMsg + ": " + ex.toString()); + } + } finally { + IOUtils.closeQuietly(br); + } + return (qBlastInfo); + } + + public String getErrorMsg() { + return _errorMsg; + } +} diff --git a/src/bzh/plealog/blastviewer/config/color/ColorPolicyConfigImplem.java b/src/bzh/plealog/blastviewer/config/color/ColorPolicyConfigImplem.java new file mode 100755 index 0000000..097f0e2 --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/color/ColorPolicyConfigImplem.java @@ -0,0 +1,666 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.color; + +import java.awt.Color; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.StringTokenizer; + +import javax.swing.ImageIcon; + +import org.apache.commons.io.IOUtils; + +import bzh.plealog.bioinfo.api.data.searchresult.SRHsp; +import bzh.plealog.bioinfo.api.data.searchresult.SRHspScore; +import bzh.plealog.bioinfo.ui.blast.config.color.ColorPolicyConfig; +import bzh.plealog.bioinfo.util.CoreUtil; + +import com.plealog.genericapp.api.EZEnvironment; +import com.plealog.genericapp.api.file.EZFileUtils; +import com.plealog.genericapp.api.log.EZLogger; + +/** + * This class contains the color policy used to display colored Blast alignment, + * scores and so on. + * + * @author Patrick G. Durand + */ +public class ColorPolicyConfigImplem extends ColorPolicyConfig { + /** contains the color policy */ + private HitColorPolicyAtom[] _hitListColorPolicy; + private HitQualityPolicyAtom[] _hitListQualityPolicy; + private int _hlcField; + private int _hlqField; + private Color _defFeatClr; + private boolean _useInvVideo; + private boolean _useAntialias = true; + private boolean _useTransparency = true; + private String _confPath; + + /** of this configuration */ + public static final String NAME = "ColorPolicyConfig"; + /** + * key used to retrieve the color configuration within a resource bundle file + */ + private static final String MSA_REVERSE_VIDEO_KEY = "inverse.video"; + private static final String TRANSPARENCY_KEY = "clr.transparency"; + private static final String ANTIALIAS_KEY = "antialias"; + private static final String TABLE_BK_COLOR_KEY = "table.bk.color"; + private static final String HLC_CLASSES = "hitListColorClasses"; + private static final String HLQ_CLASSES = "hitListQualityClasses"; + private static final String HLC_CLASS = "hlc."; + private static final String HLQ_CLASS = "hlq."; + private static final String HLC_FIELD = "hlc.field"; + private static final String HLQ_FIELD = "hlq.field"; + private static final String THRESH_SUFFIX = ".threshold"; + private static final String CLR_SUFFIX = ".color"; + private static final String QUAL_SUFFIX = ".qualityCode"; + private static final String DEF_FEAT_CLR = "feature.clr"; + + public static Color BK_COLOR = Color.WHITE; + public static final Color QUERY_CELL_BK_COLOR = new Color(184, 207, + 229); + public static final int TRANSPARENCY_FACTOR = 128; + + public static final ImageIcon[] QUALITY_SMILEY = new ImageIcon[] { + EZEnvironment.getImageIcon("smiley_g.png"), + EZEnvironment.getImageIcon("smiley_y.png"), + EZEnvironment.getImageIcon("smiley_o.png"), + EZEnvironment.getImageIcon("smiley_r.png") }; + + public static final String[] FIELDS = new String[] { + "Bit score", "E-Value", "Identity (%)", "Similarity (%)", "Gaps (%)", + "Query Coverage (%)", "Hit Coverage (%)", "Score" }; + + public static final int BITS_FIELD = 0; + public static final int EVAL_FIELD = 1; + public static final int IDENT_FIELD = 2; + public static final int SIMIL_FIELD = 3; + public static final int GAPS_FIELD = 4; + public static final int COVERAGE_FIELD = 5; + public static final int HCOVERAGE_FIELD = 6; + public static final int SCORE_FIELD = 7; + + public static final String CONFIG_FILE_NAME = "colorpolicy.cfg"; + + /** + * Default constructor. + */ + public ColorPolicyConfigImplem(String confPath) { + super(); + setName(NAME); + _confPath = EZFileUtils.terminatePath(confPath); + } + + /** + * Set on/off color transparency. + * + * @param useCT + * true of false + */ + public void useColorTransparency(boolean useCT) { + _useTransparency = useCT; + } + + /** + * Check if color transparency is used. + * + * @return true or false + */ + public boolean isUsingColorTransparency() { + return _useTransparency; + } + + /** + * Set on/off anti-alias. + * + * @param useAA + * true of false + */ + public void useAntialias(boolean useAA) { + _useAntialias = useAA; + } + + /** + * Check if anti-alias is used. + * + * @return true of false + */ + public boolean isUsingAntialias() { + return _useAntialias; + } + + /** + * Return the default color to use to display features. + * + * @return a Color + */ + public Color getDefFeatureClr() { + return _defFeatClr; + } + + /** + * Utility method used to create a HitColorPolicyAtom. + */ + private HitColorPolicyAtom createClrAtom(String key) { + HitColorPolicyAtom atom = null; + String thresh, clr; + + thresh = this.getProperty(HLC_CLASS + key + THRESH_SUFFIX); + clr = this.getProperty(HLC_CLASS + key + CLR_SUFFIX); + try { + atom = new HitColorPolicyAtom(); + atom.setThreshold(Double.valueOf(thresh)); + atom.setColor(convertColor(clr, ",")); + } catch (Exception ex) { + EZLogger.warn("Invalid HitColorPolicyAtom: " + key + ": " + ex); + } + return atom; + } + + /** + * Utility method used to create a HitColorPolicyAtom table. + */ + private void initHLCPolicyTable() { + String items; + String[] itemsKeys; + HitColorPolicyAtom atom; + int i; + + // read classes + items = this.getProperty(HLC_CLASSES); + itemsKeys = CoreUtil.tokenize(items); + _hlcField = Integer.valueOf(this.getProperty(HLC_FIELD)); + _hitListColorPolicy = new HitColorPolicyAtom[itemsKeys.length]; + for (i = 0; i < itemsKeys.length; i++) { + atom = createClrAtom(itemsKeys[i]); + if (atom == null) { + _hitListColorPolicy = null; + return; + } + _hitListColorPolicy[i] = atom; + } + } + + /** + * Utility method used to create a HitQualityPolicyAtom. + */ + private HitQualityPolicyAtom createQualAtom(String key) { + HitQualityPolicyAtom atom = null; + String thresh, code; + int idx; + + thresh = this.getProperty(HLQ_CLASS + key + THRESH_SUFFIX); + code = this.getProperty(HLQ_CLASS + key + QUAL_SUFFIX); + try { + atom = new HitQualityPolicyAtom(); + atom.setThreshold(Double.valueOf(thresh)); + idx = Integer.valueOf(code); + atom.setIconId(idx); + atom.setQualityIcon((idx < QUALITY_SMILEY.length ? QUALITY_SMILEY[idx] + : null)); + } catch (Exception ex) { + EZLogger.warn("Invalid HitQualityPolicyAtom: " + key + ": " + ex); + } + return atom; + } + + /** + * Utility method used to create a HitQualityPolicyAtom table. + */ + private void initHLQPolicyTable() { + String items; + String[] itemsKeys; + HitQualityPolicyAtom atom; + int i; + + // read classes + items = this.getProperty(HLQ_CLASSES); + itemsKeys = CoreUtil.tokenize(items); + _hlqField = Integer.valueOf(this.getProperty(HLQ_FIELD)); + _hitListQualityPolicy = new HitQualityPolicyAtom[itemsKeys.length]; + for (i = 0; i < itemsKeys.length; i++) { + atom = createQualAtom(itemsKeys[i]); + if (atom == null) { + _hitListQualityPolicy = null; + return; + } + _hitListQualityPolicy[i] = atom; + } + } + + /** + * Upload color policy from a stream. + * + * @param inStream + * the input stream to read color configuration + */ + public void load(InputStream inStream) throws IOException { + super.load(inStream); + String val; + + val = getProperty(TRANSPARENCY_KEY); + if (val != null) { + _useTransparency = val.equalsIgnoreCase("true"); + } + val = getProperty(ANTIALIAS_KEY); + if (val != null) { + _useAntialias = val.equalsIgnoreCase("true"); + } + + val = getProperty(MSA_REVERSE_VIDEO_KEY); + if (val != null) { + _useInvVideo = val.equalsIgnoreCase("true"); + } + val = getProperty(TABLE_BK_COLOR_KEY); + if (val != null) { + BK_COLOR = convertColor(val, ","); + } + + val = getProperty(DEF_FEAT_CLR); + if (val != null) { + _defFeatClr = convertColor(val, ","); + } else { + _defFeatClr = Color.DARK_GRAY; + } + _defFeatClr = new Color(_defFeatClr.getRed(), _defFeatClr.getGreen(), + _defFeatClr.getBlue(), 128); + if (getProperty(HLC_CLASSES) != null) { + initHLCPolicyTable(); + } + if (getProperty(HLQ_CLASSES) != null) { + initHLQPolicyTable(); + } + } + + /** + * Convert color (R,G,B) to Color object. + */ + private Color convertColor(String szColor, String sep) { + StringTokenizer tokenizer; + String token; + Color clr; + int r, g, b; + + tokenizer = new StringTokenizer(szColor, sep); + if (tokenizer.hasMoreTokens() == false) + return Color.black; + token = tokenizer.nextToken(); + r = Integer.valueOf(token).intValue(); + if (tokenizer.hasMoreTokens() == false) + return Color.black; + token = tokenizer.nextToken(); + g = Integer.valueOf(token).intValue(); + if (tokenizer.hasMoreTokens() == false) + return Color.black; + token = tokenizer.nextToken(); + b = Integer.valueOf(token).intValue(); + clr = new Color(r, g, b); + return clr; + } + + private double getValue(SRHsp hsp, int field) { + SRHspScore score; + + double value; + score = hsp.getScores(); + switch (field) { + case BITS_FIELD: + value = score.getBitScore(); + break; + case EVAL_FIELD: + value = score.getEvalue(); + break; + case IDENT_FIELD: + value = score.getIdentityP(); + break; + case SIMIL_FIELD: + value = score.getPositiveP(); + break; + case GAPS_FIELD: + value = score.getGapsP(); + break; + case COVERAGE_FIELD: + value = hsp.getQueryCoverage(); + break; + case HCOVERAGE_FIELD: + value = hsp.getHitCoverage(); + break; + case SCORE_FIELD: + value = score.getScore(); + break; + default: + value = score.getBitScore(); + break; + } + return value; + } + + /** + * Given a bitScore return the color defined by this color policy. + * + * @param hsp + * a SRHsp object + * @param alpha + * use alpha transparency or not + * + * @return a Color + */ + public Color getHitColor(SRHsp hsp, boolean alpha) { + HitColorPolicyAtom atom; + int i; + double value; + + if (_hitListColorPolicy == null || _hitListColorPolicy.length == 0) + return Color.BLACK; + value = getValue(hsp, _hlcField); + for (i = 0; i < _hitListColorPolicy.length; i++) { + atom = _hitListColorPolicy[i]; + if (value >= atom.getThreshold()) { + return atom.getColor(alpha); + } + } + return (Color.black); + } + + /** + * Given a bitScore return the quality defined by this color policy. + * + * @param hsp + * a SRHsp object + * + * @return a quality value + */ + public int getQualityValue(SRHsp hsp) { + HitQualityPolicyAtom atom; + int i; + double value; + + if (_hitListQualityPolicy == null || _hitListQualityPolicy.length == 0) + return 0; + value = getValue(hsp, _hlqField); + for (i = 0; i < _hitListQualityPolicy.length; i++) { + atom = _hitListQualityPolicy[i]; + if (value >= atom.getThreshold()) { + return _hitListQualityPolicy.length - i; + } + } + return (0); + } + + /** + * Given a bitScore returns the quality icon defined by this color policy. + * + * @param hsp + * a SRHsp object + * + * @return a quality icon + */ + public ImageIcon getQualityIcon(SRHsp hsp) { + HitQualityPolicyAtom atom; + int i; + double value; + + if (_hitListQualityPolicy == null || _hitListQualityPolicy.length == 0) + return null; + value = getValue(hsp, _hlqField); + for (i = 0; i < _hitListQualityPolicy.length; i++) { + atom = _hitListQualityPolicy[i]; + if (value >= atom.getThreshold()) { + return atom.getQualityIcon(); + } + } + return (QUALITY_SMILEY[QUALITY_SMILEY.length - 1]); + } + + /** + * Return the field identifier to use to get colors. Returned value is one of + * XXX_FIELD. Using such ID can be used to query the array FIELDS contained in + * this class to get a human readable representation of this ID. + */ + public int getFieldForColor() { + return _hlcField; + } + + /** + * Set the field identifier to use to get colors. + * + * @param val one of + * XXX_FIELD. Using such ID can be used to query the array FIELDS contained in + * this class to get a human readable representation of this ID. + */ + public void setFieldForColor(int val) { + _hlcField = val; + } + + /** + * Return the field identifier to use to get quality icons. Returned value is + * one of XXX_FIELD. Using such ID can be used to query the array FIELDS + * contained in this class to get a human readable representation of this ID. + */ + public int getFieldForQuality() { + return _hlqField; + } + + /** + * Set the field identifier to use to get quality icons. + * + * @param val + * one of XXX_FIELD. Using such ID can be used to query the array FIELDS + * contained in this class to get a human readable representation of this ID. + */ + public void setFieldForQuality(int val) { + _hlqField = val; + } + + /** + * Return the full color policy. + * + * @return a color policy instance + */ + public HitColorPolicyAtom[] getHitListColorPolicy() { + return _hitListColorPolicy; + } + + /** + * Set a full color policy. + * + * @param listColorPolicy a color policy instance + */ + public void setHitListColorPolicy(HitColorPolicyAtom[] listColorPolicy) { + _hitListColorPolicy = listColorPolicy; + } + + /** + * Return the full quality policy. + * + * @return a quality policy instance + */ + public HitQualityPolicyAtom[] getHitListQualityPolicy() { + return _hitListQualityPolicy; + } + + /** + * Set a full quality policy. + * + * @param listQualityPolicy a quality policy instance + */ + public void setHitListQualityPolicy(HitQualityPolicyAtom[] listQualityPolicy) { + _hitListQualityPolicy = listQualityPolicy; + } + + /** + * Dump the current color policy within this class logger. + */ + public void dumpConfig() { + int i; + + if (_hitListColorPolicy == null || _hitListColorPolicy.length == 0) { + EZLogger.info("Color Policy: config empty"); + } else { + EZLogger.info("Color Policy: " + FIELDS[_hlcField]); + for (i = 0; i < _hitListColorPolicy.length; i++) { + EZLogger.info(_hitListColorPolicy[i].toString()); + } + } + if (_hitListQualityPolicy == null || _hitListQualityPolicy.length == 0) { + EZLogger.info("Quality Policy: config empty"); + } else { + EZLogger.info("Quality Policy: " + FIELDS[_hlqField]); + for (i = 0; i < _hitListQualityPolicy.length; i++) { + EZLogger.info(_hitListQualityPolicy[i].toString()); + } + } + } + + private String getClrRepr(Color clr) { + StringBuffer szBuf; + szBuf = new StringBuffer(); + szBuf.append(clr.getRed()); + szBuf.append(","); + szBuf.append(clr.getGreen()); + szBuf.append(","); + szBuf.append(clr.getBlue()); + return szBuf.toString(); + } + + /** + * Figure out whether or not to use inverse video mode. + * + * @param useRV true or false + */ + public void setUseInverseVideo(boolean useRV) { + _useInvVideo = useRV; + } + + /** + * Figure out whether or not to use inverse video mode. + * + * @return true or false. + */ + public boolean useInverseVideo() { + return _useInvVideo; + } + + /** + * Save the content of this ColorConfigPolicy in its configuration file. + */ + public void save() throws IOException { + FileOutputStream fos = null; + fos = new FileOutputStream(_confPath + CONFIG_FILE_NAME); + try { + save(fos); + } catch (IOException e) { + throw e; + } finally { + IOUtils.closeQuietly(fos); + } + } + + /** + * Save the content of this ColorConfigPolicy. This method terminates with a + * flush on the OutputStream AND close it. + * + * @param os the output stream + */ + private void save(OutputStream os) throws IOException { + HitColorPolicyAtom atomClr; + HitQualityPolicyAtom atomQual; + PrintWriter writer; + String id; + int i; + + writer = new PrintWriter(new OutputStreamWriter(os)); + + // save HitColorPolicyTable name + if (_hitListColorPolicy != null) { + writer.print(HLC_CLASSES); + writer.print("="); + for (i = 0; i < _hitListColorPolicy.length; i++) { + writer.print("c" + (i + 1)); + if ((i + 1) < _hitListColorPolicy.length) { + writer.print(","); + } + } + writer.print("\n"); + writer.print(HLC_FIELD); + writer.print("="); + writer.print(_hlcField); + writer.print("\n"); + for (i = 0; i < _hitListColorPolicy.length; i++) { + atomClr = _hitListColorPolicy[i]; + id = "c" + String.valueOf(i + 1); + writer.print(HLC_CLASS + id + THRESH_SUFFIX + "="); + writer.print(atomClr.getThreshold()); + writer.print("\n"); + writer.print(HLC_CLASS + id + CLR_SUFFIX + "="); + writer.print(getClrRepr(atomClr.getColor(false))); + writer.print("\n"); + } + } + writer.print("\n"); + // save HitQualityPolicyTable name + if (_hitListQualityPolicy != null) { + writer.print(HLQ_CLASSES); + writer.print("="); + for (i = 0; i < _hitListQualityPolicy.length; i++) { + writer.print("c" + (i + 1)); + if ((i + 1) < _hitListQualityPolicy.length) { + writer.print(","); + } + } + writer.print("\n"); + writer.print(HLQ_FIELD); + writer.print("="); + writer.print(_hlqField); + writer.print("\n"); + for (i = 0; i < _hitListQualityPolicy.length; i++) { + atomQual = _hitListQualityPolicy[i]; + id = "c" + String.valueOf(i + 1); + writer.print(HLQ_CLASS + id + THRESH_SUFFIX + "="); + writer.print(atomQual.getThreshold()); + writer.print("\n"); + writer.print(HLQ_CLASS + id + QUAL_SUFFIX + "="); + writer.print(atomQual.getIconId()); + writer.print("\n"); + } + } + writer.print("\n"); + // save reverse video usage + writer.print(MSA_REVERSE_VIDEO_KEY); + writer.print("="); + writer.print(useInverseVideo() ? "true" : "false"); + writer.print("\n\n"); + // save table bk color + writer.print(TABLE_BK_COLOR_KEY); + writer.print("="); + writer.print(getClrRepr(BK_COLOR)); + writer.print("\n\n"); + // save transparency usage + writer.print(TRANSPARENCY_KEY); + writer.print("="); + writer.print(_useTransparency ? "true" : "false"); + writer.print("\n\n"); + writer.flush(); + writer.close(); + } +} diff --git a/src/bzh/plealog/blastviewer/config/color/HitColorPolicyAtom.java b/src/bzh/plealog/blastviewer/config/color/HitColorPolicyAtom.java new file mode 100755 index 0000000..7476ade --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/color/HitColorPolicyAtom.java @@ -0,0 +1,115 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.color; + +import java.awt.Color; + +/** + * This class stores information related to a single color policy. Such a policy + * corresponds to a bit score and its associated color. + * + * @author Patrick G. Durand + */ +public class HitColorPolicyAtom { + private double _threshold; + private Color _clr = Color.BLACK; + private Color _clrWithAlpha = Color.black; + + /** + * Default constructor. + */ + public HitColorPolicyAtom() { + } + + /** + * Constructor with a threshold and its associated color. + */ + public HitColorPolicyAtom(long threshold, Color clr) { + setThreshold(threshold); + setColor(clr); + } + + /** + * Return the bit score. + */ + public double getThreshold() { + return _threshold; + } + + /** + * Set the bit score. + */ + public void setThreshold(double val) { + _threshold = val; + } + + /** + * Return the color. + */ + public Color getColor(boolean alpha) { + if (alpha) + return _clrWithAlpha; + else + return _clr; + } + + /** + * Set the color. + * + * @param clr + * a color without alpha channel. This method will create a + * corresponding color with an alpha channel that can be retrieved + * using this getColor method. + */ + public void setColor(Color clr) { + if (clr == null) + _clr = Color.BLACK; + else + _clr = clr; + _clrWithAlpha = new Color(_clr.getRed(), _clr.getGreen(), _clr.getBlue(), + ColorPolicyConfigImplem.TRANSPARENCY_FACTOR); + } + + /** + * Return a string representation of this color policy. + * + * */ + public String getClrRepr() { + StringBuffer szBuf; + szBuf = new StringBuffer(); + szBuf.append(_clr.getRed()); + szBuf.append(","); + szBuf.append(_clr.getGreen()); + szBuf.append(","); + szBuf.append(_clr.getBlue()); + return szBuf.toString(); + } + + /** + * Return a string representation of this color policy. + * + * */ + public String toString() { + StringBuffer szBuf; + szBuf = new StringBuffer(); + szBuf.append(_threshold); + szBuf.append(": ["); + szBuf.append(getClrRepr()); + szBuf.append("]"); + return szBuf.toString(); + } +} diff --git a/src/bzh/plealog/blastviewer/config/color/HitColorPolicyEditorPanel.java b/src/bzh/plealog/blastviewer/config/color/HitColorPolicyEditorPanel.java new file mode 100755 index 0000000..34ffcce --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/color/HitColorPolicyEditorPanel.java @@ -0,0 +1,201 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.color; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.JComponent; + +import com.plealog.genericapp.api.EZEnvironment; + +/** + * This is the editor of color policy. + * + * @author Patrick G. Durand + */ +public class HitColorPolicyEditorPanel extends HitPolicyEditorBasePanel { + private static final long serialVersionUID = 9094467477284177517L; + + private JButton[] _clr; + + private static final String MSG_P1_TIP = "Click to change colour"; + private static final String MSG_HEAD = "Colour policy will be applied using"; + private static final String HELP_MSG = "This panel defines the value ranges used to set Hit colours. " + + "Values set for each range have to be defined by decreasing order. " + + "Only use positive real numbers; scientific notation is allowed (e.g. 1e-3). " + + "Click on a coloured button to change a colour."; + private static final String CHOOSE_MSG = "Choose a color"; + + /** + * Constructor. + * + * @param nb of color classes to use + */ + public HitColorPolicyEditorPanel(int nClasses) { + super(); + if (nClasses == 0) + nClasses = 4; + _nClasses = nClasses; + buildGUI(nClasses); + } + + /** + * Constructor. + * + * @param policy a color policy + * + * @param valueType one of ColorColicyConfig.XXX_FIELD + */ + public HitColorPolicyEditorPanel(HitColorPolicyAtom[] policy, int valueType) { + super(); + if (policy == null) + _nClasses = 4; + else + _nClasses = policy.length; + buildGUI(_nClasses); + setData(policy); + setValueType(valueType); + } + + /** + * Set a color policy. + * + * @param policy the color policy + * + * */ + public void setData(HitColorPolicyAtom[] policy) { + Color clr; + int i; + + if (policy == null || policy.length != _nClasses) + return; + for (i = 0; i < _nClasses; i++) { + _valuesTo[i].setText(String.valueOf(policy[i].getThreshold())); + clr = policy[i].getColor(false); + _clr[i].setBackground(clr); + } + } + + /** + * Get the color policy. + * + * @return the color policy + * + * */ + public HitColorPolicyAtom[] getData() { + HitColorPolicyAtom[] policy = null; + String val; + Color clr; + int i; + double[] thresholds; + + thresholds = new double[_nClasses]; + for (i = 0; i < _nClasses - 1; i++) { + val = _valuesTo[i].getText(); + if (val.length() == 0) { + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), MSG_ERR2); + _valuesTo[i].grabFocus(); + return null; + } + try { + thresholds[i] = Double.valueOf(val); + if (thresholds[i] < 0) + throw new NumberFormatException(); + } catch (Exception e) { + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), BAD_VALUE.format(new Object[] { val })); + _valuesTo[i].grabFocus(); + return null; + } + } + for (i = 0; i < _nClasses - 2; i++) { + if (thresholds[i + 1] > thresholds[i]) { + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), MSG_ERR1); + _valuesTo[i].grabFocus(); + return null; + } + } + policy = new HitColorPolicyAtom[_nClasses]; + for (i = 0; i < _nClasses - 1; i++) { + policy[i] = new HitColorPolicyAtom(); + policy[i].setThreshold(thresholds[i]); + clr = _clr[i].getBackground(); + policy[i].setColor(clr); + } + i = _nClasses - 1; + policy[i] = new HitColorPolicyAtom(); + policy[i].setThreshold(0); + clr = _clr[i].getBackground(); + policy[i].setColor(clr); + return policy; + } + + private JButton createClrButton() { + JButton btn; + FontMetrics fm; + Dimension dim; + int h; + + btn = new JButton(); + btn.setOpaque(true); + btn.setBorder(BorderFactory.createRaisedBevelBorder()); + btn.setFont(DEF_FNT); + btn.setToolTipText(MSG_P1_TIP); + btn.addActionListener(new ColorChooser()); + fm = btn.getFontMetrics(DEF_FNT); + h = fm.getHeight(); + dim = new Dimension(6 * h, h); + btn.setPreferredSize(dim); + return btn; + } + + protected void initSpecialComponents(int nClasses) { + _clr = new JButton[nClasses]; + for (int i = 0; i < nClasses; i++) { + _clr[i] = createClrButton(); + } + } + + protected JComponent getSpecialComponent(int i) { + return _clr[i]; + } + + protected String getHeaderMsg() { + return MSG_HEAD; + } + + protected String getHelpMsg() { + return HELP_MSG; + } + + private class ColorChooser implements ActionListener { + public void actionPerformed(ActionEvent e) { + Color bg; + + bg = JColorChooser.showDialog(HitColorPolicyEditorPanel.this, CHOOSE_MSG, + ((JButton) e.getSource()).getBackground()); + if (bg != null) + ((JButton) e.getSource()).setBackground(bg); + } + } +} diff --git a/src/bzh/plealog/blastviewer/config/color/HitPolicyEditorBasePanel.java b/src/bzh/plealog/blastviewer/config/color/HitPolicyEditorBasePanel.java new file mode 100755 index 0000000..a88a43a --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/color/HitPolicyEditorBasePanel.java @@ -0,0 +1,278 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.color; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.MessageFormat; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import com.jgoodies.forms.builder.DefaultFormBuilder; +import com.jgoodies.forms.layout.FormLayout; + +/** + * This is the base panel for color and quality policy editors. + * + * @author Patrick G. Durand + */ +public abstract class HitPolicyEditorBasePanel extends JPanel { + private static final long serialVersionUID = -5471357033799472849L; + protected JTextField[] _valuesFrom; + protected JTextField[] _valuesTo; + protected int _nClasses; + protected int _valueType;// one of ColorColicyConfig.XXX_FIELD + protected JComboBox _valueTypeChooser; + + protected static final String MSG_P1 = "Assign"; + protected static final String MSG_P2 = "if value is above"; + protected static final String MSG_P3 = "if value is less than"; + protected static final String MSG_P4 = "and above"; + protected static final String MSG_P5 = "in any other cases"; + protected static final String MSG_ERR1 = "Values are not given by descreasing order."; + protected static final String MSG_ERR2 = "Value is not defined."; + protected static final Font DEF_FNT = new Font("sans-serif", Font.PLAIN, 12); + protected static final MessageFormat BAD_VALUE = new MessageFormat("Value {0} is not a positive real number."); + + /** + * Constructor. + */ + public HitPolicyEditorBasePanel() { + super(); + } + + /** + * Set the type of data. + * + * @param valueType one of ColorColicyConfig.XXX_FIELD + */ + public void setValueType(int valueType) { + _valueType = valueType; + _valueTypeChooser.setSelectedIndex(valueType); + } + + /** + * Get the type of data. + * + * @return one of ColorColicyConfig.XXX_FIELD + */ + public int getValueType() { + return _valueType; + } + + /** + * Create a text field. + * + * @param editable true or false + * + * @return a text field + */ + protected JTextField createTextField(boolean editable) { + JTextField tf; + + tf = new JTextField(); + tf.setEditable(editable); + // tf.setBorder(null); + // tf.setOpaque(false); + tf.setFont(DEF_FNT); + + return tf; + } + + /** + * Create a label. + * + * @param msg the message of the label + * + * @return a label + */ + protected JLabel createLabel(String msg) { + JLabel btn; + + btn = new JLabel(msg); + btn.setFont(DEF_FNT); + return btn; + } + + /** + * Create a text area used to display help message. + * + * @param nLines number of lines + * @param defMsg default message + * + * @return a text area + */ + protected JTextArea createHelper(int nLines, String defMsg) { + JTextArea helpArea = new JTextArea(); + helpArea.setRows(nLines); + helpArea.setLineWrap(true); + helpArea.setWrapStyleWord(true); + helpArea.setEditable(false); + helpArea.setOpaque(false); + helpArea.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); + helpArea.setText(defMsg); + helpArea.setFont(DEF_FNT); + return helpArea; + } + + /** + * Implement this method to initialize specific components. + * + * @param nClasses nb of classes to use + */ + protected abstract void initSpecialComponents(int nClasses); + + /** + * Return a particular component. + * + * @param i ith component to return + * + * @return a component + */ + protected abstract JComponent getSpecialComponent(int i); + + /** + * Return the header message. + * + * @return header message + * */ + protected abstract String getHeaderMsg(); + + /** + * Return the help message. + * + * @return help message + * */ + protected abstract String getHelpMsg(); + + /** + * Create the UI. + * + * @param nClasses nb of classes to use + */ + protected void buildGUI(int nClasses) { + DefaultFormBuilder builder; + FormLayout layout; + JLabel emptyLbl; + JPanel pnl, pnl2, pnl3, pnl4; + int i; + + emptyLbl = new JLabel(); + _valuesFrom = new JTextField[nClasses]; + _valuesTo = new JTextField[nClasses]; + for (i = 0; i < nClasses; i++) { + _valuesFrom[i] = createTextField(false); + _valuesTo[i] = createTextField(true); + } + initSpecialComponents(nClasses); + nClasses--; + for (i = 0; i < nClasses; i++) { + _valuesTo[i].getDocument().addDocumentListener(new EditListener(_valuesTo[i], _valuesFrom[i + 1])); + } + nClasses++; + layout = new FormLayout("30dlu, 2dlu, 25dlu, 2dlu, 80dlu, 2dlu, 40dlu, 2dlu, 40dlu, 2dlu, 40dlu", ""); + builder = new DefaultFormBuilder(layout); + builder.setDefaultDialogBorder(); + for (i = 0; i < nClasses; i++) { + if (i == 0) { + builder.append(createLabel(MSG_P1)); + builder.append(getSpecialComponent(i)); + builder.append(createLabel(MSG_P2)); + builder.append(_valuesTo[i]); + builder.append(emptyLbl); + builder.append(emptyLbl); + } else if (i == nClasses - 1) { + builder.append(createLabel(MSG_P1)); + builder.append(getSpecialComponent(i)); + builder.append(createLabel(MSG_P5)); + builder.append(emptyLbl); + builder.append(emptyLbl); + builder.append(emptyLbl); + } else { + builder.append(createLabel(MSG_P1)); + builder.append(getSpecialComponent(i)); + builder.append(createLabel(MSG_P3)); + builder.append(_valuesFrom[i]); + builder.append(createLabel(MSG_P4)); + builder.append(_valuesTo[i]); + } + if ((i + 1) < nClasses) + builder.nextLine(); + } + pnl = new JPanel(); + _valueTypeChooser = new JComboBox<>(); + _valueTypeChooser.setFont(DEF_FNT); + _valueTypeChooser.addActionListener(new ValueTypeSelector()); + for (i = 0; i < ColorPolicyConfigImplem.FIELDS.length; i++) { + _valueTypeChooser.addItem(ColorPolicyConfigImplem.FIELDS[i]); + } + pnl.add(createLabel(getHeaderMsg())); + pnl.add(_valueTypeChooser); + pnl.add(createLabel("values")); + pnl2 = new JPanel(new BorderLayout()); + pnl2.add(pnl, BorderLayout.WEST); + pnl2.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + pnl3 = new JPanel(new BorderLayout()); + pnl3.add(createHelper(5, getHelpMsg()), BorderLayout.CENTER); + pnl4 = new JPanel(new BorderLayout()); + pnl4.add(pnl2, BorderLayout.NORTH); + pnl4.add(builder.getContainer(), BorderLayout.CENTER); + pnl4.add(pnl3, BorderLayout.SOUTH); + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(pnl4); + } + + protected class EditListener implements DocumentListener { + private JTextField _src; + private JTextField _tgt; + + public EditListener(JTextField src, JTextField tgt) { + _src = src; + _tgt = tgt; + } + + public void insertUpdate(DocumentEvent e) { + _tgt.setText(_src.getText()); + } + + public void removeUpdate(DocumentEvent e) { + _tgt.setText(_src.getText()); + } + + public void changedUpdate(DocumentEvent e) { + } + } + + protected class ValueTypeSelector implements ActionListener { + public void actionPerformed(ActionEvent e) { + _valueType = ((JComboBox) e.getSource()).getSelectedIndex(); + } + } + +} diff --git a/src/bzh/plealog/blastviewer/config/color/HitPolicyEditorDialog.java b/src/bzh/plealog/blastviewer/config/color/HitPolicyEditorDialog.java new file mode 100755 index 0000000..d1b3c88 --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/color/HitPolicyEditorDialog.java @@ -0,0 +1,189 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.color; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.io.IOException; + +import javax.swing.AbstractAction; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTabbedPane; + +import bzh.plealog.bioinfo.ui.blast.config.ConfigManager; +import bzh.plealog.blastviewer.resources.BVMessages; + +import com.plealog.genericapp.api.log.EZLogger; + +/** + * This is the color policy editor. + * + * @author Patrick G. Durand + */ +public class HitPolicyEditorDialog extends JDialog { + private static final long serialVersionUID = 812060132777071379L; + private HitColorPolicyEditorPanel _colorPolicy; + private HitQualityPolicyEditorPanel _qualityPolicy; + private JTabbedPane _jtp; + + /** + * Constructor. + * + * @param owner + * parent frame of this dialog box. + * */ + public HitPolicyEditorDialog(Frame owner) { + super(owner, BVMessages.getString("HitPolicyEditorDialog.header"), true); + buildGUI(); + this.pack(); + } + + /** + * Create the GUI. + */ + private void buildGUI() { + JPanel mainPnl, btnPnl; + JButton okBtn, cancelBtn; + ColorPolicyConfigImplem nc; + HitColorPolicyAtom[] clrPolicy; + HitQualityPolicyAtom[] qualPolicy; + + nc = (ColorPolicyConfigImplem) ConfigManager.getConfig(ColorPolicyConfigImplem.NAME); + if (nc == null) { + getContentPane().setLayout(new BorderLayout()); + getContentPane().add( + new JLabel(BVMessages.getString("HitPolicyEditorDialog.err")), + BorderLayout.CENTER); + return; + } + clrPolicy = nc.getHitListColorPolicy(); + qualPolicy = nc.getHitListQualityPolicy(); + _colorPolicy = new HitColorPolicyEditorPanel(clrPolicy == null ? 4 + : clrPolicy.length); + _colorPolicy.setData(clrPolicy); + _colorPolicy.setValueType(nc.getFieldForColor()); + _qualityPolicy = new HitQualityPolicyEditorPanel(qualPolicy == null ? 4 + : qualPolicy.length); + _qualityPolicy.setData(qualPolicy); + _qualityPolicy.setValueType(nc.getFieldForQuality()); + + _jtp = new JTabbedPane(); + _jtp.setFocusable(false); + _jtp.add(BVMessages.getString("HitPolicyEditorDialog.tab1"), _colorPolicy); + _jtp.add(BVMessages.getString("HitPolicyEditorDialog.tab2"), _qualityPolicy); + mainPnl = new JPanel(new BorderLayout()); + mainPnl.add(_jtp, BorderLayout.CENTER); + + okBtn = new JButton(BVMessages.getString("HitPolicyEditorDialog.btn1")); + okBtn.addActionListener(new OkDialogAction()); + cancelBtn = new JButton(BVMessages.getString("HitPolicyEditorDialog.btn2")); + cancelBtn.addActionListener(new CloseDialogAction()); + btnPnl = new JPanel(); + btnPnl.setLayout(new BoxLayout(btnPnl, BoxLayout.X_AXIS)); + btnPnl.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + btnPnl.add(Box.createHorizontalGlue()); + btnPnl.add(okBtn); + btnPnl.add(Box.createRigidArea(new Dimension(10, 0))); + btnPnl.add(cancelBtn); + btnPnl.add(Box.createHorizontalGlue()); + + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(mainPnl, BorderLayout.CENTER); + getContentPane().add(btnPnl, BorderLayout.SOUTH); + } + + /** + * Show the dialog box on screen. + */ + public void showDlg() { + centerOnScreen(); + setVisible(true); + } + + /** + * Center the frame on the screen. + */ + private void centerOnScreen() { + Dimension screenSize = this.getToolkit().getScreenSize(); + Dimension dlgSize = this.getSize(); + + this.setLocation(screenSize.width / 2 - dlgSize.width / 2, + screenSize.height / 2 - dlgSize.height / 2); + } + + /** + * This inner class manages actions coming from the JButton CloseDialog. + */ + private class CloseDialogAction extends AbstractAction { + private static final long serialVersionUID = -7737589249414570785L; + + /** + * Manages JButton action + */ + public void actionPerformed(ActionEvent e) { + dispose(); + } + } + + /** + * This inner class manages actions coming from the JButton OkDialog. + */ + private class OkDialogAction extends AbstractAction { + private static final long serialVersionUID = -3503165540629775725L; + + /** + * Manages JButton action + */ + public void actionPerformed(ActionEvent e) { + HitColorPolicyAtom[] clrPolicy; + HitQualityPolicyAtom[] qualPolicy; + ColorPolicyConfigImplem nc; + + nc = (ColorPolicyConfigImplem) ConfigManager.getConfig(ColorPolicyConfigImplem.NAME); + // check data + clrPolicy = _colorPolicy.getData(); + if (clrPolicy == null) { + _jtp.setSelectedIndex(0); + return; + } + qualPolicy = _qualityPolicy.getData(); + if (qualPolicy == null) { + _jtp.setSelectedIndex(1); + return; + } + // set and save new data + nc.setHitListColorPolicy(clrPolicy); + nc.setFieldForColor(_colorPolicy.getValueType()); + nc.setHitListQualityPolicy(qualPolicy); + nc.setFieldForQuality(_qualityPolicy.getValueType()); + try { + nc.save(); + } catch (IOException e1) { + EZLogger.warn("Unable to save Color Policy: " + e1); + } + dispose(); + } + } +} diff --git a/src/bzh/plealog/blastviewer/config/color/HitQualityPolicyAtom.java b/src/bzh/plealog/blastviewer/config/color/HitQualityPolicyAtom.java new file mode 100755 index 0000000..5c2462c --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/color/HitQualityPolicyAtom.java @@ -0,0 +1,115 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.color; + +import javax.swing.ImageIcon; + +/** + * This class stores information related to a single quality policy. Such a + * policy corresponds to a bit score and its associated quality icon. + * + * @author Patrick G. Durand + */ +public class HitQualityPolicyAtom { + private double _threshold; + private int _iconId; + private ImageIcon _qualityIcon; + + /** + * Default constructor. + */ + public HitQualityPolicyAtom() { + } + + /** + * Constructor. + * + * @param threshold + * threshold + * @param iconId + * icon id + * @param qIcon + * quality icon. + */ + public HitQualityPolicyAtom(double threshold, int iconId, ImageIcon qIcon) { + setThreshold(threshold); + setQualityIcon(qIcon); + setIconId(iconId); + } + + /** + * Return the threshold. + * + * @return a threshold + */ + public double getThreshold() { + return _threshold; + } + + /** + * Set the threshold. + * + * @param val + * threshold + */ + public void setThreshold(double val) { + _threshold = val; + } + + /** + * Return the quality icon + * + * @return an icon + * */ + public ImageIcon getQualityIcon() { + return _qualityIcon; + } + + /** + * Set the quality icon + * + * @param icon + * an icon + * */ + public void setQualityIcon(ImageIcon icon) { + _qualityIcon = icon; + } + + public int getIconId() { + return _iconId; + } + + /** + * Set the icon identifier. + * + * @param id + * an identifier + */ + public void setIconId(int id) { + _iconId = id; + } + + public String toString() { + StringBuffer szBuf; + szBuf = new StringBuffer(); + szBuf.append(_threshold); + szBuf.append(": ["); + szBuf.append(_iconId); + szBuf.append("]"); + return szBuf.toString(); + } +} diff --git a/src/bzh/plealog/blastviewer/config/color/HitQualityPolicyEditorPanel.java b/src/bzh/plealog/blastviewer/config/color/HitQualityPolicyEditorPanel.java new file mode 100755 index 0000000..e0b6291 --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/color/HitQualityPolicyEditorPanel.java @@ -0,0 +1,215 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.color; + +import java.awt.Component; +import java.awt.Dimension; + +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.ListCellRenderer; + +import com.plealog.genericapp.api.EZEnvironment; + +/** + * This is the editor of quality policy. + * + * @author Patrick G. Durand + */ +public class HitQualityPolicyEditorPanel extends HitPolicyEditorBasePanel { + private static final long serialVersionUID = 7552474180799736916L; + + private JComboBox[] _quality; + + private static final String MSG_HEAD = "Quality policy will be applied using"; + private static final String HELP_MSG = "This panel defines the value ranges used to set Hit quality. " + + "Values set for each range have to be defined by decreasing order. " + + "Only use positive real numbers; scientific notation is allowed (e.g. 1e-3)."; + + /** + * Constructor. + * + * @param nb + * of quality classes to use + */ + public HitQualityPolicyEditorPanel(int nClasses) { + super(); + if (nClasses == 0) + nClasses = 4; + _nClasses = nClasses; + buildGUI(nClasses); + } + + /** + * Constructor. + * + * @param policy + * a quality policy + * + * @param valueType + * one of ColorColicyConfig.XXX_FIELD + */ + public HitQualityPolicyEditorPanel(HitQualityPolicyAtom[] policy, + int valueType) { + super(); + if (policy == null) + _nClasses = 4; + else + _nClasses = policy.length; + buildGUI(_nClasses); + setData(policy); + setValueType(valueType); + } + + /** + * Set a quality policy. + * + * @param policy + * the quality policy + * + * */ + public void setData(HitQualityPolicyAtom[] policy) { + int i; + + if (policy == null || policy.length != _nClasses) + return; + for (i = 0; i < _nClasses; i++) { + _valuesTo[i].setText(String.valueOf(policy[i].getThreshold())); + _quality[i].setSelectedIndex(policy[i].getIconId()); + } + } + + /** + * Get the quality policy. + * + * @return the quality policy + * + * */ + public HitQualityPolicyAtom[] getData() { + HitQualityPolicyAtom[] policy = null; + String val; + int i, idx; + double[] thresholds; + + thresholds = new double[_nClasses]; + for (i = 0; i < _nClasses - 1; i++) { + val = _valuesTo[i].getText(); + if (val.length() == 0) { + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), + MSG_ERR2); + _valuesTo[i].grabFocus(); + return null; + } + try { + thresholds[i] = Double.valueOf(val); + if (thresholds[i] < 0) + throw new NumberFormatException(); + } catch (Exception e) { + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), + BAD_VALUE.format(new Object[] { val })); + _valuesTo[i].grabFocus(); + return null; + } + } + for (i = 0; i < _nClasses - 2; i++) { + if (thresholds[i + 1] > thresholds[i]) { + EZEnvironment.displayWarnMessage(EZEnvironment.getParentFrame(), + MSG_ERR1); + _valuesTo[i].grabFocus(); + return null; + } + } + policy = new HitQualityPolicyAtom[_nClasses]; + for (i = 0; i < _nClasses - 1; i++) { + policy[i] = new HitQualityPolicyAtom(); + policy[i].setThreshold(thresholds[i]); + idx = _quality[i].getSelectedIndex(); + policy[i].setQualityIcon(ColorPolicyConfigImplem.QUALITY_SMILEY[idx]); + policy[i].setIconId(idx); + + } + i = _nClasses - 1; + policy[i] = new HitQualityPolicyAtom(); + policy[i].setThreshold(0); + idx = _quality[i].getSelectedIndex(); + policy[i].setQualityIcon(ColorPolicyConfigImplem.QUALITY_SMILEY[idx]); + policy[i].setIconId(idx); + return policy; + } + + private JComboBox createQualityCombo() { + JComboBox c = new JComboBox<>(); + c.setFont(DEF_FNT); + c.setRenderer(new ComboBoxRenderer()); + for (int i = 0; i < ColorPolicyConfigImplem.QUALITY_SMILEY.length; i++) { + c.addItem(new Integer(i)); + } + return c; + } + + @SuppressWarnings("unchecked") + protected void initSpecialComponents(int nClasses) { + _quality = new JComboBox[nClasses]; + for (int i = 0; i < nClasses; i++) { + _quality[i] = createQualityCombo(); + } + } + + protected JComponent getSpecialComponent(int i) { + return _quality[i]; + } + + protected String getHeaderMsg() { + return MSG_HEAD; + } + + protected String getHelpMsg() { + return HELP_MSG; + } + + private class ComboBoxRenderer extends JLabel implements + ListCellRenderer { + private static final long serialVersionUID = -3429945853105749966L; + private Dimension DEF_DIM = new Dimension(20, 20); + + public ComboBoxRenderer() { + setOpaque(true); + setHorizontalAlignment(CENTER); + setVerticalAlignment(CENTER); + } + + public Dimension getPreferredSize() { + return DEF_DIM; + } + + public Component getListCellRendererComponent( + JList list, Integer value, int index, + boolean isSelected, boolean cellHasFocus) { + if (isSelected) { + setBackground(list.getSelectionBackground()); + setForeground(list.getSelectionForeground()); + } else { + setBackground(list.getBackground()); + setForeground(list.getForeground()); + } + setIcon(ColorPolicyConfigImplem.QUALITY_SMILEY[value]); + return this; + } + } +} diff --git a/src/bzh/plealog/blastviewer/config/directory/DirManager.java b/src/bzh/plealog/blastviewer/config/directory/DirManager.java new file mode 100644 index 0000000..5b29db2 --- /dev/null +++ b/src/bzh/plealog/blastviewer/config/directory/DirManager.java @@ -0,0 +1,120 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.config.directory; + +import java.io.File; +import java.io.IOException; + +import bzh.plealog.bioinfo.ui.blast.config.AbstractPropertiesConfig; +import bzh.plealog.bioinfo.util.CoreUtil; + +import com.plealog.genericapp.api.EZApplicationBranding; +import com.plealog.genericapp.api.file.EZFileUtils; + +/** + * This class handle the directories used by the software to store some internal + * stuffs. + * + * @author Patrick G. Durand + */ +public class DirManager extends AbstractPropertiesConfig { + public static final String NAME = "DirManager"; + + private static final String DOC_DIR = "documents"; + + private static final String BLAST_DOCS = "blast"; + + private String _appPath; + private String _blastDataPath; + + /** + * Default constructor. + * + * Such an object is supposed to be created at application startup and stored + * in the ConfigManager system. Then access this configuration using + * ConfigManager. + */ + public DirManager() { + setName(NAME); + } + + private void createPath(String path) throws IOException { + File f; + + f = new File(path); + if (f.exists()) { + return; + } + if (!f.mkdirs()) { + throw new IOException("unable to create: " + path); + } + } + + /** + * Get the full path to the directory where the application stores its stuffs. + * + * It is worth noting that the method will try to create that path if it does + * not exist. + * + * @return a path. Note that path is terminated with OS-dependent path + * separator character. + * + * @throws IOException + * if the method failed to create the path. + */ + public String getApplicationDataPath() throws IOException { + if (_appPath != null) + return _appPath; + + _appPath = EZFileUtils.terminatePath(System.getProperty("user.home")) + + "." + + EZFileUtils.terminatePath(CoreUtil.replaceAll( + EZApplicationBranding.getAppName(), " ", "_")); + + createPath(_appPath); + + return _appPath; + } + + /** + * Get the full path to the directory where the application stores BLAST + * results retrieved from a remote server. + * + * It is worth noting that the method will try to create that path if it does + * not exist. + * + * @return a path. Note that path is terminated with OS-dependent path + * separator character. + * + * @throws IOException + * if the method failed to create the path. + */ + public String getBlastDataPath() throws IOException { + if (_blastDataPath != null) + return _blastDataPath; + + _blastDataPath = getApplicationDataPath() + + EZFileUtils.terminatePath(DOC_DIR) + + EZFileUtils.terminatePath(BLAST_DOCS); + + createPath(_blastDataPath); + + return _blastDataPath; + } + + +} diff --git a/src/bzh/plealog/blastviewer/hittable/BVHitTable.java b/src/bzh/plealog/blastviewer/hittable/BVHitTable.java new file mode 100644 index 0000000..e6a29ef --- /dev/null +++ b/src/bzh/plealog/blastviewer/hittable/BVHitTable.java @@ -0,0 +1,54 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.hittable; + +import javax.swing.Action; + +import bzh.plealog.bioinfo.ui.blast.hittable.BlastHitTable; +import bzh.plealog.blastviewer.actions.EditColorPolicyAction; +import bzh.plealog.blastviewer.resources.BVMessages; + +/** + * Specific implementation of a BlastHitTable that adds some more controls. + * + * @author Patrick G. Durand + */ +public class BVHitTable extends BlastHitTable { + + private static final long serialVersionUID = -5195223880667175259L; + + public BVHitTable() { + super(); + } + + public BVHitTable(String id) { + super(id); + } + + @Override + protected Action[] getTableSpecialActionsForMenu() { + EditColorPolicyAction editAct; + Action[] acts; + + acts = new Action[1]; + editAct = new EditColorPolicyAction(BVMessages.getString("BVHitTable.tool.edt.clr")); + editAct.setParent(_blastList); + acts[0] = editAct; + return acts; + } + +} diff --git a/src/bzh/plealog/blastviewer/hittable/BVHitTableFactoryImplem.java b/src/bzh/plealog/blastviewer/hittable/BVHitTableFactoryImplem.java new file mode 100644 index 0000000..c0fb06a --- /dev/null +++ b/src/bzh/plealog/blastviewer/hittable/BVHitTableFactoryImplem.java @@ -0,0 +1,35 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.hittable; + +import bzh.plealog.bioinfo.ui.blast.config.HitTableFactory; +import bzh.plealog.bioinfo.ui.blast.hittable.BlastHitTable; + +/** + * Factory to use to create instances of BVHitTable. + * + * @author Patrick G. Durand + */ +public class BVHitTableFactoryImplem implements HitTableFactory{ + + /** + * Create a new instance of a BlastHitTable. + */ + public BlastHitTable createViewer(){ + return new BVHitTable(null); + } +} diff --git a/src/bzh/plealog/blastviewer/resources/BVMessages.java b/src/bzh/plealog/blastviewer/resources/BVMessages.java new file mode 100644 index 0000000..8bdc2ef --- /dev/null +++ b/src/bzh/plealog/blastviewer/resources/BVMessages.java @@ -0,0 +1,50 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.resources; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * This class defines a utility class used to read the content of a resource + * file where the GUI localized strings are saved. + * + * @author Patrick G. Durand + */ +public class BVMessages { + private static final String BUNDLE_NAME = + BVMessages.class.getPackage().getName()+".messages"; + + private static final ResourceBundle RESOURCE_BUNDLE = + ResourceBundle.getBundle(BUNDLE_NAME); + + /** + * Default constructor not available. Use this class as static. + */ + private BVMessages() {} + + /** + * Returns a value associated to a given key. + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/src/bzh/plealog/blastviewer/resources/circle_all.gif b/src/bzh/plealog/blastviewer/resources/circle_all.gif new file mode 100755 index 0000000..251df05 Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/circle_all.gif differ diff --git a/src/bzh/plealog/blastviewer/resources/colorpolicy.cfg b/src/bzh/plealog/blastviewer/resources/colorpolicy.cfg new file mode 100755 index 0000000..8c18cc8 --- /dev/null +++ b/src/bzh/plealog/blastviewer/resources/colorpolicy.cfg @@ -0,0 +1,74 @@ +# +# Colors Configuration for KoriBlast Data Table. +# +# This file relies on 'key=value' pairs. Keys are reserved words of the +# system and cannot be changed. Values on the other hand can be changed +# as needed. +# + +# Hit List color policy classes. Each class defined a value threshold +# and an associated graphical property (such as color). Classes have +# to be declared by decreasing order of the threshold value, so that +# class[i+1] and class[i] define a valid range. During table rendering, +# KoriBlast compares an HSP score value (see key hlc.field) with each +# threshold range to associate the corresponding graphical property. +hitListColorClasses=c1,c2,c3,c4,c5 +# Field used by the software to associate the graphical property. +# Accepted values range from 0 to 4, and correspond to the use of +# bit score, E-Value, identity, similarity, or gaps. +hlc.field=0 +hlc.c1.threshold=200.0 +hlc.c1.color=255,102,102 +hlc.c2.threshold=80.0 +hlc.c2.color=254,103,254 +hlc.c3.threshold=50.0 +hlc.c3.color=0,177,0 +hlc.c4.threshold=40.0 +hlc.c4.color=128,128,255 +hlc.c5.threshold=0.0 +hlc.c5.color=0,0,0 + +# Hit List quality policy classes. +hitListQualityClasses=c1,c2,c3,c4,c5 +hlq.field=0 +hlq.c1.threshold=200 +# associated quality icon (a smiley). This index refers to the type of +# quality smiley to be displayed in the hit list (0: green smiley, 1: +# yellow, 2: orange and 3: red). +hlq.c1.threshold=200.0 +hlq.c1.qualityCode=0 +hlq.c2.threshold=80.0 +hlq.c2.qualityCode=0 +hlq.c3.threshold=50.0 +hlq.c3.qualityCode=1 +hlq.c4.threshold=40.0 +hlq.c4.qualityCode=2 +hlq.c5.threshold=0.0 +hlq.c5.qualityCode=3 + +# +# Use reverse video mode for Multiple Sequence Alignment. +# +inverse.video=true + +# +# Color used in tables to set the background every two rows. +# +table.bk.color=228,236,236 + +# +# Color are generated with an alpha channel +# +clr.transparency=true + +# +# Use antialias for better graphics rendering +# +antialias=true + +# +# Default color to use to display features +# +feature.clr=0,102,102 + + diff --git a/src/bzh/plealog/blastviewer/resources/documents.png b/src/bzh/plealog/blastviewer/resources/documents.png new file mode 100755 index 0000000..e621681 Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/documents.png differ diff --git a/src/bzh/plealog/blastviewer/resources/download.png b/src/bzh/plealog/blastviewer/resources/download.png new file mode 100755 index 0000000..2dc1549 Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/download.png differ diff --git a/src/bzh/plealog/blastviewer/resources/logger.png b/src/bzh/plealog/blastviewer/resources/logger.png new file mode 100644 index 0000000..621ed91 Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/logger.png differ diff --git a/src/bzh/plealog/blastviewer/resources/messages.properties b/src/bzh/plealog/blastviewer/resources/messages.properties new file mode 100755 index 0000000..5b68ae1 --- /dev/null +++ b/src/bzh/plealog/blastviewer/resources/messages.properties @@ -0,0 +1,30 @@ +DocumentViewer.docs.mnu=Documents +DocumentViewer.docs.tab2=Log + +OpenBlastList.open.name=Open +OpenBlastList.open.tip=Open BLAST results +OpenBlastList.openrid.name=Fetch +OpenBlastList.openrid.tip=Fetch BLAST results from NCBI + +QBlaster.analyseFileError=Unable to get execution status from BLAST server +QBlastRetriever.err=Result file not yet available. + +FetchFromNcbiAction.err1=unable to save Blast results file +FetchFromNcbiAction.err2=Unable to create BLAST XML file\: +FetchFromNcbiAction.msg1=Connecting to NCBI... +FetchFromNcbiAction.msg2=Result retrieved... saving in a local file... +FetchFromNcbiAction.msg3=BLAST results save in\: +FetchFromNcbiAction.msg4=Opening viewer... +FetchFromNcbiAction.lbl=Enter an NCBI Blast Request ID\: + +OpenFileAction.lbl=Open BLAST file +OpenFileAction.err=Unable to load BLAST file: + +HitPolicyEditorDialog.btn1=Apply +HitPolicyEditorDialog.btn2=Cancel +HitPolicyEditorDialog.header=Hit List Graphics Properties +HitPolicyEditorDialog.tab1=Colors +HitPolicyEditorDialog.tab2=Quality +HitPolicyEditorDialog.err=No color policy configuration file available. + +BVHitTable.tool.edt.clr=Edit colors \ No newline at end of file diff --git a/src/bzh/plealog/blastviewer/resources/open.png b/src/bzh/plealog/blastviewer/resources/open.png new file mode 100755 index 0000000..1a5b0fc Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/open.png differ diff --git a/src/bzh/plealog/blastviewer/resources/smiley_g.png b/src/bzh/plealog/blastviewer/resources/smiley_g.png new file mode 100755 index 0000000..91d0f9b Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/smiley_g.png differ diff --git a/src/bzh/plealog/blastviewer/resources/smiley_o.png b/src/bzh/plealog/blastviewer/resources/smiley_o.png new file mode 100755 index 0000000..7ad5e3d Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/smiley_o.png differ diff --git a/src/bzh/plealog/blastviewer/resources/smiley_r.png b/src/bzh/plealog/blastviewer/resources/smiley_r.png new file mode 100755 index 0000000..20a2d06 Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/smiley_r.png differ diff --git a/src/bzh/plealog/blastviewer/resources/smiley_y.png b/src/bzh/plealog/blastviewer/resources/smiley_y.png new file mode 100755 index 0000000..616a6e4 Binary files /dev/null and b/src/bzh/plealog/blastviewer/resources/smiley_y.png differ diff --git a/src/bzh/plealog/blastviewer/util/BlastViewerOpener.java b/src/bzh/plealog/blastviewer/util/BlastViewerOpener.java new file mode 100644 index 0000000..538b7d6 --- /dev/null +++ b/src/bzh/plealog/blastviewer/util/BlastViewerOpener.java @@ -0,0 +1,125 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.util; + +import java.awt.Color; +import java.awt.Dimension; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JLabel; + +import com.plealog.genericapp.api.EZEnvironment; +import com.plealog.genericapp.ui.desktop.GDesktopPane; +import com.plealog.genericapp.ui.desktop.GInternalFrame; + +/** + * Utility class to enable interaction with the GDesktopPane. + * + * @author Patrick G. Durand + */ +public class BlastViewerOpener { + private static GDesktopPane _desktop; + private static JLabel _helperField; + + public static ImageIcon WORKING_ICON = EZEnvironment + .getImageIcon("circle_all.gif"); + private static Color RUNNING_TASK_COLOR = Color.GREEN.darker(); + private static Color NOT_RUNNING_TASK_COLOR; + + /** + * Register the desktop to this component. + */ + public static void setDesktop(GDesktopPane desktop) { + _desktop = desktop; + } + + /** + * Return the help field. + */ + public static JComponent getHelperField() { + if (_helperField == null) { + _helperField = new JLabel(); + _helperField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); + _helperField.setOpaque(true); + _helperField.setFocusable(false); + NOT_RUNNING_TASK_COLOR = _helperField.getBackground(); + } + return _helperField; + } + + /** + * Set a message during some operation. + */ + public static void setHelperMessage(String msg) { + if (msg == null) { + cleanHelperMessage(); + } + _helperField.setText(msg); + _helperField.setIcon(WORKING_ICON); + _helperField.setBackground(RUNNING_TASK_COLOR); + } + + /** + * Clear the message. + */ + public static void cleanHelperMessage() { + _helperField.setText(""); + _helperField.setIcon(null); + _helperField.setBackground(NOT_RUNNING_TASK_COLOR); + } + + /** + * Add a new BlastViewer to this desktop. + * + * @param viewer the viewer to add. Should be a Blast Viewer component. + * Cannot be null. + * @param title the internal frame title. Cannot be null. + * @param icon the internal frame icon. Can be null. + */ + public static void displayInternalFrame(JComponent viewer, String title, + ImageIcon icon) { + int delta = 20; + + GInternalFrame iFrame = new GInternalFrame(viewer, // the viewer + title, // iFrame title will be the entry ID + true, true, true, // resizable, closable, maximizable: allowed + false);// does not allow iconifiable: not working with JRE1.7+ on OSX ! + // Known bug. + if (icon != null) + iFrame.setFrameIcon(icon); + Dimension dim = _desktop.getSize(); + iFrame.setVisible(false); + _desktop.addGInternalFrame(iFrame); + iFrame.setSize(dim); + iFrame.setBounds(delta, delta, dim.width - 2 * delta, dim.height - 2 + * delta); + // for future use... + // iFrame.setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE); + // iFrame.addInternalFrameListener(new IFrameListener(navigator)); + iFrame.setVisible(true); + } + + /** + * Add a new BlastViewer to this desktop. + */ + public static void displayInternalFrame(JComponent viewer) { + displayInternalFrame(viewer, "Blast Results", null); + } + +} diff --git a/src/bzh/plealog/blastviewer/util/HTTPBasicEngine.java b/src/bzh/plealog/blastviewer/util/HTTPBasicEngine.java new file mode 100644 index 0000000..815da30 --- /dev/null +++ b/src/bzh/plealog/blastviewer/util/HTTPBasicEngine.java @@ -0,0 +1,169 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.util; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.util.Iterator; +import java.util.Map; + +import com.plealog.genericapp.api.log.EZLogger; + +/** + * A very basic HTTPclient. + * + * @author Patrick G. Durand + */ +public class HTTPBasicEngine { + public static String TMP_FILE_PREFIX = "http"; + public static String TMP_FILE_SUFIX = ".tmp"; + + public static int CONNECT_TIMEOUT = 5000; // 5 seconds + public static int SOCKET_TIMEOUT = 60000; // 1 minute + + private static void closeConnection(InputStream ins) { + if (ins != null) { + try { + ins.close(); + } catch (IOException e) { + } + } + } + + public static File doGet(String url) { + return doGet(url, null); + } + /** + * Do a HTTP GET using the provided url. + * + * @param url + * the URL. HTTP and HTTPS are supported. + * + * @param header_attrs + * attributes to set in header connection + * @return a file containing the result. Returned file is set to deleteOnExit, + * so you do not have to worry about deleting it. + * + * @throws HTTPEngineException + * if something wrong occurs. + */ + // Tutorial: + // http://stackoverflow.com/questions/2793150/using-java-net-urlconnection-to-fire-and-handle-http-requests + public static File doGet(String url, Map header_attrs) { + InputStream ins = null; + byte[] buffer = new byte[4096]; + int n = -1; + + // this is a very, very basic implementation to handle HTTP Get transactions + // using URL APIs (e.g. NCBI eUtils, Ensembl, etc.). May need optimization + // for more powerful needs... + // Possible upgrade: use Jersey to deal with web services? + + // 1. prepare a temporary file to receive answer + File answerFile = null; + + EZLogger.debug(url); + try { + answerFile = File.createTempFile(TMP_FILE_PREFIX, TMP_FILE_SUFIX); + answerFile.deleteOnExit(); + EZLogger.debug(answerFile.getAbsolutePath()); + } catch (IOException e) { + EZLogger.warn(e.toString()); + throw new HTTPEngineException("Failed to create response file", url, HTTPEngineException.HTTPEX_TMP_FILE_ERROR); + } + + // 2. run the HTTP GET method + try (OutputStream output = new FileOutputStream(answerFile)) { + // open connection to the remote server + URL myurl = new URL(url); + HttpURLConnection con = (HttpURLConnection) myurl.openConnection(); + if (header_attrs!=null){ + Iterator attrIter = header_attrs.keySet().iterator(); + String key; + while(attrIter.hasNext()){ + key = attrIter.next(); + //con.setRequestProperty("Accept", "text/xml"); + con.setRequestProperty(key, header_attrs.get(key)); + } + } + con.setConnectTimeout(CONNECT_TIMEOUT); + con.setReadTimeout(SOCKET_TIMEOUT); + + // ensembl and ebi provides additional header fields. + // see + // http://www.ebi.ac.uk/Tools/webservices/services/eb-eye_rest#additional_information_in_http_response_header + // https://github.com/Ensembl/ensembl-rest/wiki/HTTP-Response-Codes + // some of these header values can be used to adapt connection to remote + // server. For now, we just monitor them... TODO: use them! + EZLogger.debug(con.getHeaderFields().toString()); + + // response code is checked before opening input stream + if (con.getResponseCode() != HttpURLConnection.HTTP_OK) { + throw new HTTPEngineException("Failed to connect to server", url, con.getResponseCode()); + } + + // 200 OK: read server answer + ins = con.getInputStream(); + while ((n = ins.read(buffer)) != -1) { + output.write(buffer, 0, n); + } + output.flush(); + } catch (HTTPEngineException hee) { + throw hee; + } catch (SocketTimeoutException ste) { + throw new HTTPEngineException("Server does not answer (time out)", url, HTTPEngineException.HTTPEX_TIMEOUT); + } catch (Exception e) { + // we Log the HTTP or IO error since message is usually out of concern + // for the end user. However, a log trace is always useful. + EZLogger.warn(e.toString()); + // then raises a "generic" exception + throw new HTTPEngineException("Unable to write in response file", url, HTTPEngineException.HTTPEX_WRITE_FILE_ERROR); + } + finally { + // 3. close HTTP connection + closeConnection(ins); + } + // 4. return answer + return answerFile; + } + + /** + * Figures out whether or not a particular web server is available. + */ + public static boolean isServerAvailable(String url) { + try { + URL myurl = new URL(url); + HttpURLConnection httpConn = (HttpURLConnection)myurl.openConnection(); + httpConn.setInstanceFollowRedirects(false); + httpConn.setRequestMethod("HEAD"); + httpConn.setConnectTimeout(CONNECT_TIMEOUT); + httpConn.connect(); + EZLogger.debug(httpConn.getHeaderFields().toString()); + } catch (Exception e) { + EZLogger.warn(e.toString()); + return false; + } + //if we hit this line, server is available + return true; + } +} diff --git a/src/bzh/plealog/blastviewer/util/HTTPEngineException.java b/src/bzh/plealog/blastviewer/util/HTTPEngineException.java new file mode 100644 index 0000000..137d966 --- /dev/null +++ b/src/bzh/plealog/blastviewer/util/HTTPEngineException.java @@ -0,0 +1,87 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package bzh.plealog.blastviewer.util; + +public class HTTPEngineException extends RuntimeException { + + private static final long serialVersionUID = 4332507260541550768L; + + private int httpCode; + private String url; + + /** 1001: unable to create response file, i.e. the file in which HTTPBasicEngine + * writes server answer. + */ + public static final int HTTPEX_TMP_FILE_ERROR = 1001; + /** 1002: unable to write in response file. + */ + public static final int HTTPEX_WRITE_FILE_ERROR = 1002; + + /** 1003: time out. + */ + public static final int HTTPEX_TIMEOUT = 1003; + + @SuppressWarnings("unused") + private HTTPEngineException() { } + + public HTTPEngineException(String message, String url, int httpcode) { + super(message); + this.url = url; + this.httpCode = httpcode; + } + + /** + * Return the URL responsible for the exception. + */ + public String getUrl(){ + return url; + } + + /** + * Return standard HTTP code. In addition, we define some additional values using + * HTTPEX_xxx constants. + * */ + public int getHttpCode() { + return httpCode; + } + + /** + * Figures out whether or not we have a problem with response file. + */ + public boolean isTmpFileError(){ + return httpCode>=1000; + } + + /** + * Figures out whether or not we have an HTTP error code of class 5xx. + */ + public boolean isServerError(){ + return httpCode>=500; + } + /** + * Figures out whether or not we have an HTTP error code 400. + */ + public boolean isBadRequest(){ + return httpCode==400; + } + /** + * Figures out whether or not we have an HTTP error code 404. + */ + public boolean isWrongUrl(){ + return httpCode==400; + } +} diff --git a/src/bzh/plealog/blastviewer/version.properties b/src/bzh/plealog/blastviewer/version.properties new file mode 100644 index 0000000..a57e0ae --- /dev/null +++ b/src/bzh/plealog/blastviewer/version.properties @@ -0,0 +1,13 @@ +# package name +prg.name=blastviewer +# UI name +prg.app.name=BLAST-Viewer +# release prior to 5: KoriBlast/ngKLAST suite of software +prg.version=5.0.0 +# Who did what and when +prg.copyright=(c) 2003-2016, Patrick G. Durand +prg.provider=Plealog +# Place of the source code +prg.url=https://github.com/pgdurand +# Affero-GPL license +prg.license=Licensed under the the GNU Affero General Public License, Version 3.0. https://www.gnu.org/licenses/agpl-3.0.txt diff --git a/src/test/HitColorPolicyEditorPanelTest.java b/src/test/HitColorPolicyEditorPanelTest.java new file mode 100755 index 0000000..524edd7 --- /dev/null +++ b/src/test/HitColorPolicyEditorPanelTest.java @@ -0,0 +1,72 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package test; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + +import bzh.plealog.blastviewer.config.color.ColorPolicyConfigImplem; +import bzh.plealog.blastviewer.config.color.HitColorPolicyAtom; +import bzh.plealog.blastviewer.config.color.HitColorPolicyEditorPanel; + +public class HitColorPolicyEditorPanelTest { + public static void main(String[] args) { + JFrame frame = new JFrame("Hello"); + JPanel pnl = new JPanel(new BorderLayout()); + frame.addWindowListener(new ApplicationCloser()); + Container contentPane = frame.getContentPane(); + final HitColorPolicyEditorPanel toto = new HitColorPolicyEditorPanel(4); + toto.setValueType(ColorPolicyConfigImplem.GAPS_FIELD); + pnl.add(toto, BorderLayout.CENTER); + JButton checker = new JButton("check values!"); + checker.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + HitColorPolicyAtom[] policy = toto.getData(); + if (policy == null) { + return; + } + System.out.println("Value type: " + + ColorPolicyConfigImplem.FIELDS[toto.getValueType()]); + System.out.println("Policy: "); + for (int i = 0; i < policy.length; i++) { + System.out.println("[" + i + "] Threshold = " + + policy[i].getThreshold()); + System.out.println(" Color = " + policy[i].getClrRepr()); + } + } + }); + pnl.add(checker, BorderLayout.SOUTH); + contentPane.add(pnl); + frame.pack(); + // frame.setSize(200, 600); + frame.setVisible(true); + } + + private static class ApplicationCloser extends WindowAdapter { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + } +} diff --git a/src/test/HitQualityPolicyEditorPanelTest.java b/src/test/HitQualityPolicyEditorPanelTest.java new file mode 100755 index 0000000..3e71429 --- /dev/null +++ b/src/test/HitQualityPolicyEditorPanelTest.java @@ -0,0 +1,74 @@ +/* Copyright (C) 2003-2016 Patrick G. Durand + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * You may obtain a copy of the License at + * + * https://www.gnu.org/licenses/agpl-3.0.txt + * + * 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 Affero General Public License for more details. + */ +package test; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + +import bzh.plealog.bioinfo.ui.config.UISystemConfigurator; +import bzh.plealog.blastviewer.config.color.ColorPolicyConfigImplem; +import bzh.plealog.blastviewer.config.color.HitQualityPolicyAtom; +import bzh.plealog.blastviewer.config.color.HitQualityPolicyEditorPanel; + +public class HitQualityPolicyEditorPanelTest { + public static void main(String[] args) { + UISystemConfigurator.initializeSystem(); + JFrame frame = new JFrame("Hello"); + JPanel pnl = new JPanel(new BorderLayout()); + frame.addWindowListener(new ApplicationCloser()); + Container contentPane = frame.getContentPane(); + final HitQualityPolicyEditorPanel toto = new HitQualityPolicyEditorPanel(4); + toto.setValueType(ColorPolicyConfigImplem.GAPS_FIELD); + pnl.add(toto, BorderLayout.CENTER); + JButton checker = new JButton("check values!"); + checker.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + HitQualityPolicyAtom[] policy = toto.getData(); + if (policy == null) { + return; + } + System.out.println("Value type: " + + ColorPolicyConfigImplem.FIELDS[toto.getValueType()]); + System.out.println("Policy: "); + for (int i = 0; i < policy.length; i++) { + System.out.println("[" + i + "] Threshold = " + + policy[i].getThreshold()); + System.out.println(" Icon Id = " + policy[i].getIconId()); + } + } + }); + pnl.add(checker, BorderLayout.SOUTH); + contentPane.add(pnl); + frame.pack(); + // frame.setSize(200, 600); + frame.setVisible(true); + } + + private static class ApplicationCloser extends WindowAdapter { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + } +} diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..c826be7 --- /dev/null +++ b/start.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Script used to start BlastViewer during development cycles. It requires +# BlastViewer be compiled using: ant makejar + +V_PROVIDER=EBI + +# *** Application home +PL_APP_HOME=. +PL_MAIN_CLASS=bzh.plealog.blastviewer.BlastViewer + +# *** Java VM +PL_JAVA_VM=$JAVA_HOME/bin/java +PL_JAVA_ARGS="-Xms2048m -Xmx2048m -DV_DEBUG=true " + +# *** JARs section +PL_JAR_LIST_TMP=`\ls $PL_APP_HOME/jar/*.jar` +PL_JAR_LIST=`echo $PL_JAR_LIST_TMP | sed 's/ /:/g'` +PL_JAR_LIST2_TMP=`\ls $PL_APP_HOME/distrib/*.jar` +PL_JAR_LIST=${PL_JAR_LIST}:`echo $PL_JAR_LIST2_TMP | sed 's/ /:/g'` + +# *** start application +$PL_JAVA_VM $PL_JAVA_ARGS -classpath $PL_JAR_LIST $PL_MAIN_CLASS +