diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..e236767d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +bin/ +target/ +build/ +.gradle/ +.settings/ +*.classpath +*.project +lib/ +**/test-processes/**/*.properties +*.checkstyle +config/checkstyle/checkstyle.xml +config/checkstyle/checkstyle.xsl +*.pmd +config/pmd/* +.idea/ +*.iml diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..2def0e883 --- /dev/null +++ b/LICENSE @@ -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 +. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 000000000..359d7a86f --- /dev/null +++ b/build.gradle @@ -0,0 +1,134 @@ +buildscript { + repositories { + jcenter() + maven { url 'https://maven.rapidminer.com/content/groups/public/' } + } + dependencies { + classpath 'com.rapidminer.gradle:java-basics:0.3.3' + classpath 'com.rapidminer.gradle:java-publishing:0.2.0' + classpath 'com.rapidminer.gradle:java-signing:0.1.0' + } +} + +apply plugin: 'com.rapidminer.java-basics' +apply plugin: 'com.rapidminer.java-signing' +apply plugin: 'com.rapidminer.java-publishing.agpl-v3' + +repositories { + jcenter() + maven { url 'https://maven.rapidminer.com/content/groups/public/' } +} + +dependencies { + + // OS X adapter to add platform specific UI + compile 'com.rapidminer.studio:rapidminer-studio-osx-adapter:1.0.1' + + // RapidMiner license framework for license management + compile 'com.rapidminer.license:rapidminer-license-api:3.1.0' + compile 'com.rapidminer.license:rapidminer-license-commons:3.1.0' + + // RapidMiner API + compile 'com.rapidminer:rapidminer-api:0.2.0' + + // VLDocking as docking framework (https://code.google.com/p/vldocking/) + compile 'com.rapidminer.external:vldocking:1.1.1' + + // Freehep for vector graphic export (http://java.freehep.org/) + compile('org.freehep:freehep-graphicsio-ps:2.3') { + exclude group:'junit', module: 'junit' + exclude group: 'org.freehep',module: 'freehep-graphicsio-tests' + } + compile('org.freehep:freehep-graphicsio-svg:2.3') { + exclude group:'junit', module: 'junit' + exclude group: 'org.freehep', module: 'freehep-graphicsio-tests' + } + + // iText for PDF export (http://www.lowagie.com/iText/) + compile('com.lowagie:itext:2.1.7'){ + exclude group: 'bouncycastle', module: 'bcmail-jdk14' + exclude group: 'bouncycastle', module: 'bcprov-jdk14' + exclude group: 'bouncycastle', module: 'bctsp-jdk14' + } + + // RSyntaxTextArea adds text fields with syntax highlighting (http://fifesoft.com/rsyntaxtextarea/) + compile 'com.fifesoft:rsyntaxtextarea:2.5.0' + compile 'com.fifesoft:autocomplete:2.5.0' + + // JXL for the ability to read, write, and modify old format Microsoft Excel spreadsheets (http://www.jexcelapi.org) + compile('net.sourceforge.jexcelapi:jxl:2.6.12') { exclude group: 'log4j', module: 'log4j' } + + // Apache POI for manipulating various file formats based upon Office Open XML standards (http://poi.apache.org/) + compile 'org.apache.poi:poi-ooxml:3.10-FINAL' + compile 'org.apache.poi:poi-scratchpad:3.10-FINAL' + + // JGoodies Looks for TODO (http://www.jgoodies.com/freeware/libraries/looks/) + compile 'com.jgoodies:looks:2.2.2' + + // JUNG for displaying graphs and trees (http://jung.sourceforge.net/) + compile 'net.sf.jung:jung-visualization:2.0.1' + compile 'net.sf.jung:jung-graph-impl:2.0.1' + + // JFreeChart for chart rendering (http://www.jfree.org/jfreechart/) + compile 'org.jfree:jfreechart:1.0.17' + + // Java Mail API for mail sending + compile 'javax.mail:mail:1.4.7' + + // Groovy for 'Execute Script' operator (http://groovy.codehaus.org/) + compile 'org.codehaus.groovy:groovy-all:2.3.3' + + // SwingX for various Swing components (https://swingx.java.net/) + compile 'org.swinglabs.swingx:swingx-all:1.6.5' + + // XStreams for generic XML serialization (http://xstream.codehaus.org/) + compile 'com.thoughtworks.xstream:xstream:1.4.7' + + // XMLRPC for XMLRPC connections to Bugzilla (http://ws.apache.org/xmlrpc/) + compile('org.apache.xmlrpc:xmlrpc-client:3.1.3') { exclude group: 'junit', module: 'junit' } + + // HttpClient used by the Bugzilla XML RPC client (http://hc.apache.org/httpcomponents-client) + compile 'commons-httpclient:commons-httpclient:3.1' + + // JAMA for matrix calculations (http://math.nist.gov/javanumerics/jama/) + compile 'gov.nist.math:jama:1.0.3' + + // commons-math for matrix calculations (http://commons.apache.org/proper/commons-math/) + compile 'org.apache.commons:commons-math3:3.3' + + // commons-lang for different String utility functions (http://commons.apache.org/proper/commons-lang/) + compile 'commons-lang:commons-lang:2.6' + + // bouncycastle for encryption algorithms (https://www.bouncycastle.org/) + compile 'org.bouncycastle:bcprov-jdk15on:1.50' + + // jasypt for simplified encryption (http://www.jasypt.org/) + compile 'org.jasypt:jasypt:1.9.1:lite' + + // antlr for parsing expressions (http://www.antlr.org/) + compile 'org.antlr:antlr4-runtime:4.5' + + // SLF4J API (http://www.slf4j.org) + compile 'org.slf4j:slf4j-api:1.7.12' + + // add testing suite + //TODO should be test compile but RapidMiner src/main contains code that references JUnit + compile 'junit:junit:4.12' + + // JGraphx for automatic operator arrangement (https://github.com/jgraph/jgraphx) + compile 'com.rapidminer.external:jgraphx:2.1.0.2' + + // JMathPlot for 2D and 3D plots like Box plot, Stick plot, etc. (https://code.google.com/p/jmathplot/) + compile 'com.rapidminer.external:jmathplot:1.0.0' + + // Microba adds a Swing date picker (http://microba.sf.net/) + compile 'com.github.tdbear:microba:0.4.4.3' + + // Apache Tika for file MIME type detection (https://tika.apache.org/) + compile 'org.apache.tika:tika-core:1.11' +} + +task wrapper(type: Wrapper) { gradleVersion = '2.8' } + +apply from: 'gradle/wsimport.gradle' +apply from: 'gradle/props.gradle' diff --git a/config/HEADER b/config/HEADER new file mode 100644 index 000000000..1ed224f01 --- /dev/null +++ b/config/HEADER @@ -0,0 +1,16 @@ +Copyright (C) 2001-2016 by RapidMiner and the contributors + +Complete list of developers available at our web site: + +http://rapidminer.com + +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 http://www.gnu.org/licenses/. \ No newline at end of file diff --git a/doc/doc/AbstractOperatorDocGenerator.java b/doc/doc/AbstractOperatorDocGenerator.java new file mode 100644 index 000000000..5378b9c73 --- /dev/null +++ b/doc/doc/AbstractOperatorDocGenerator.java @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.PrintWriter; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +// +//import weka.core.TechnicalInformation; +//import weka.core.TechnicalInformationHandler; + +import com.rapidminer.operator.IOObject; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorChain; +import com.rapidminer.operator.OperatorCreationException; +import com.rapidminer.operator.Value; +import com.rapidminer.operator.condition.InnerOperatorCondition; +import com.rapidminer.operator.learner.Learner; +import com.rapidminer.operator.OperatorCapability; +import com.rapidminer.parameter.ParameterType; +import com.rapidminer.parameter.ParameterTypeCategory; +import com.rapidminer.parameter.ParameterTypeStringCategory; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.OperatorService; +import com.rapidminer.tools.Tools; +import com.sun.javadoc.ClassDoc; +import com.sun.javadoc.RootDoc; +import com.sun.javadoc.SeeTag; +import com.sun.javadoc.Tag; +import com.sun.tools.doclets.Taglet; + + +/** + * This generator provides useful methods to generate documentation from the Javadoc comments and abstract methods of an + * operator. Subclasses can be implemented to deliver different target formats like LaTeX or HTML. + * + * @author Simon Fischer, Ingo Mierswa + */ +public abstract class AbstractOperatorDocGenerator implements OperatorDocGenerator { + + public final static int OPERATOR = 0; + + public final static int OPERATOR_NAME = 1; + + public final static int GROUP_NAME = 2; + + public final static int PARAMETER_LIST = 3; + + public final static int PARAMETER_ITEM = 4; + + public final static int PARAMETER_NAME_REQ = 5; + + public final static int PARAMETER_NAME_OPT = 6; + + public final static int PARAMETER_DESCRIPTION = 7; + + public final static int SHORT_DESCRIPTION = 8; + + public final static int OPERATOR_DESCRIPTION = 9; + + public final static int INPUT_CLASSES_LIST = 10; + + public final static int OUTPUT_CLASSES_LIST = 11; + + public final static int IO_CLASS = 12; + + public final static int INNER_OPERATOR = 13; + + public final static int VALUE_LIST = 14; + + public final static int VALUE_ITEM = 15; + + public final static int VALUE_NAME = 16; + + public final static int VALUE_DESCRIPTION = 17; + + public final static int INDEX_ENTRY = 18; + + public final static int REFERENCE_SECTION = 19; + + public final static int REFERENCE_ENTRY = 20; + + public final static int TECHNICAL_INFORMATION = 21; + + public final static int DEPRECATION_INFO = 22; + + public final static int LEARNER_CAPABILITIES = 23; + + private Map tagletMap = new HashMap(); + + /** + * Transform the HTML-comment to the respective output language. The class and operator name are only given for + * debugging purposes. + */ + public abstract String transformHTMLJavadocComment(String comment, Class clazz, String operatorName); + + /** Replace any special characters by an escaped version. */ + public abstract String escape(String toEscape); + + public abstract String getOpenTag(int tagNo); + + public abstract String getCloseTag(int tagNo); + + public abstract String marginIcon(String iconName); + + public AbstractOperatorDocGenerator() { + CiteTaglet.register(tagletMap); + MathTaglet.register(tagletMap); + RefTaglet.register(tagletMap); + XMLExampleTaglet.register(tagletMap); + } + + public void generateDoc(Operator op, RootDoc rootDoc, PrintWriter out) { + ClassDoc opDoc = rootDoc.classNamed(op.getClass().getName()); + + out.println(getOpenTag(OPERATOR)); + printTags(out, op.getOperatorDescription().getName(), OPERATOR_NAME); + out.println(); + + //TODO: Generation does not work anymore because of translation between icon name and image + if (op.getOperatorDescription().getIconName() != null) + out.println(marginIcon(op.getOperatorDescription().getIconName())); + + if ((op.getOperatorDescription().getGroup() != null) && (op.getOperatorDescription().getGroup().trim().length() > 0)) + printTags(out, op.getOperatorDescription().getGroup(), GROUP_NAME); + + if (opDoc != null) { + Tag[] indexTags = opDoc.tags("rapidminer.index"); + for (int i = 0; i < indexTags.length; i++) { + printTags(out, indexTags[i].text(), INDEX_ENTRY); + } + } + + if (op.getOperatorDescription().getDeprecationInfo() != null) { + printTags(out, op.getOperatorDescription().getDeprecationInfo(), DEPRECATION_INFO); + out.println(); + } + + Class[] input = op.getInputClasses(); + if ((input != null) && (input.length > 0)) { + out.println(getOpenTag(INPUT_CLASSES_LIST)); + for (int i = 0; i < input.length; i++) { + printTags(out, input[i].getSimpleName(), IO_CLASS); + out.println(); + } + out.println(getCloseTag(INPUT_CLASSES_LIST)); + } + + Class[] output = op.getOutputClasses(); + if ((output != null) && (output.length > 0)) { + out.println(getOpenTag(OUTPUT_CLASSES_LIST)); + for (int i = 0; i < output.length; i++) { + printTags(out, output[i].getSimpleName(), IO_CLASS); + out.println(); + } + out.println(getCloseTag(OUTPUT_CLASSES_LIST)); + } + + List parameters = op.getParameterTypes(); + if (parameters.size() > 0) { + out.println(getOpenTag(PARAMETER_LIST)); + Iterator i = parameters.iterator(); + while (i.hasNext()) { + ParameterType type = (ParameterType) i.next(); + out.print(getOpenTag(PARAMETER_ITEM)); + if (type.isOptional()) { + printTags(out, type.getKey(), PARAMETER_NAME_OPT); + } else { + printTags(out, type.getKey(), PARAMETER_NAME_REQ); + } + if ((type instanceof ParameterTypeCategory) || (type instanceof ParameterTypeStringCategory)) { + printTags(out, type.getDescription(), PARAMETER_DESCRIPTION); + } else { + printTags(out, type.getDescription() + (type.showRange() && type.getRange() != null ? " (" + type.getRange() + ")" : ""), PARAMETER_DESCRIPTION); + } + out.println(getCloseTag(PARAMETER_ITEM)); + } + out.println(getCloseTag(PARAMETER_LIST)); + } + + Collection values = op.getValues(); + if (values.size() > 0) { + out.println(getOpenTag(VALUE_LIST)); + Iterator i = values.iterator(); + while (i.hasNext()) { + Value value = i.next(); + // if (!value.isDocumented()) continue; + out.print(getOpenTag(VALUE_ITEM)); + printTags(out, value.getKey(), VALUE_NAME); + printTags(out, value.getDescription(), VALUE_DESCRIPTION); + out.println(getCloseTag(VALUE_ITEM)); + } + out.println(getCloseTag(VALUE_LIST)); + } + + if (op instanceof Learner) { + Learner learner = (Learner) op; + StringBuffer learnerCapabilities = new StringBuffer(); + boolean first = true; + for (OperatorCapability capability : OperatorCapability.values()) { + try { + if (learner.supportsCapability(capability)) { + if (!first) + learnerCapabilities.append(", "); + learnerCapabilities.append(capability.getDescription()); + first = false; + } + } catch (Exception e) { + break; + } + } + String result = learnerCapabilities.toString(); + if (result.length() > 0) { + out.print(getOpenTag(LEARNER_CAPABILITIES)); + out.print(result); + out.print(getCloseTag(LEARNER_CAPABILITIES)); + } + } + + StringBuffer classComment = new StringBuffer(); + if (opDoc != null) { + Tag[] inlineTags = opDoc.inlineTags(); + for (int i = 0; i < inlineTags.length; i++) { + if (inlineTags[i] instanceof SeeTag) { + try { + Class referencedClass = Class.forName(((SeeTag) inlineTags[i]).referencedClass().qualifiedName()); + if (Operator.class.isAssignableFrom(referencedClass)) { + if (java.lang.reflect.Modifier.isAbstract(referencedClass.getModifiers())) { + classComment.append("\\op{" + referencedClass.getSimpleName() + "}"); + } else { + try { + Operator refOp = OperatorService.createOperator(referencedClass); + classComment.append("\\refop{" + refOp.getOperatorDescription().getName() + "}"); + } catch (OperatorCreationException e) { + classComment.append("\\op{" + referencedClass.getSimpleName() + "}"); + } + } + } else if (IOObject.class.isAssignableFrom(referencedClass)) { + classComment.append("\\ioobj{" + referencedClass.getSimpleName() + "}"); + } else { + classComment.append("\\java{" + referencedClass.getSimpleName() + "}"); + } + } catch (Throwable e) { + LogService.getGlobal().log("In see tag '" + inlineTags[i] + "' of " + op.getClass().getName() + ": " + e, LogService.ERROR); + } + } else { + Taglet taglet = tagletMap.get(inlineTags[i].name().substring(1)); + if (taglet instanceof TexTaglet) { + classComment.append(((TexTaglet) taglet).toTex(inlineTags[i])); + } else { + classComment.append(escape(inlineTags[i].text())); + } + } + } + } + +// if (op instanceof OperatorChain) { +// InnerOperatorCondition condition = ((OperatorChain) op).getInnerOperatorCondition(); +// if (condition != null) { +// out.println(getOpenTag(INNER_OPERATOR)); +// out.print(transformHTMLJavadocComment(condition.toHTML(), op.getClass(), op.getName())); +// out.println(getCloseTag(INNER_OPERATOR)); +// } +// } + + out.println(getOpenTag(SHORT_DESCRIPTION) + + transformHTMLJavadocComment(op.getOperatorDescription().getShortDescription(), op.getClass(), op.getOperatorDescription().getName()) + + getCloseTag(SHORT_DESCRIPTION)); + out.println(); + + out.print(getOpenTag(OPERATOR_DESCRIPTION) + + transformHTMLJavadocComment(classComment.toString(), op.getClass(), op.getOperatorDescription().getName()) + + getCloseTag(OPERATOR_DESCRIPTION)); + out.println(); + +// if (op instanceof TechnicalInformationHandler) { +// TechnicalInformation information = ((TechnicalInformationHandler) op).getTechnicalInformation(); +// if (information != null) { +// out.println(getOpenTag(TECHNICAL_INFORMATION) +// + transformHTMLJavadocComment(information.toString(), op.getClass(), op.getOperatorDescription().getName()) +// + getCloseTag(TECHNICAL_INFORMATION)); +// out.println(); +// } +// } + + if (opDoc != null) { + Tag[] citeTags = opDoc.tags("rapidminer.cite"); + if (citeTags.length > 0) + out.println(getOpenTag(REFERENCE_SECTION)); + for (int i = 0; i < citeTags.length; i++) { + printTags(out, citeTags[i].text(), REFERENCE_ENTRY); + } + } + + out.println(getCloseTag(OPERATOR)); + } + + private void printTags(PrintWriter out, String text, int tagNo) { + out.print(getOpenTag(tagNo) + escape(text) + getCloseTag(tagNo)); + } + +} diff --git a/doc/doc/CiteTaglet.java b/doc/doc/CiteTaglet.java new file mode 100644 index 000000000..b96d427aa --- /dev/null +++ b/doc/doc/CiteTaglet.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.util.Map; + +import com.sun.javadoc.Tag; +import com.sun.tools.doclets.Taglet; + +/** + * A taglet with name "@rapidminer.cite" can be used in the Javadoc comments of an operator to produce a reference + * to literature. Example: "@rapidminer.cite Mierswa/etal/2003a". This will include a LaTeX cite command to your + * document. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class CiteTaglet implements TexTaglet { + + private static final String NAME = "rapidminer.cite"; + + public String getName() { + return NAME; + } + + public boolean inField() { + return true; + } + + public boolean inConstructor() { + return true; + } + + public boolean inMethod() { + return true; + } + + public boolean inOverview() { + return true; + } + + public boolean inPackage() { + return true; + } + + public boolean inType() { + return true; + } + + public boolean isInlineTag() { + return true; + } + + public static void register(Map tagletMap) { + CiteTaglet tag = new CiteTaglet(); + Taglet t = tagletMap.get(tag.getName()); + if (t != null) { + tagletMap.remove(tag.getName()); + } + tagletMap.put(tag.getName(), tag); + } + + public String toString(Tag tag) { + return "[" + tag.text() + "]"; + } + + public String toString(Tag[] tags) { + return null; + } + + public String toTex(Tag tag) { + return "\\cite{" + tag.text() + "}"; + } + + public String toTex(Tag[] tag) { + return null; + } +} diff --git a/doc/doc/CommentStripper.java b/doc/doc/CommentStripper.java new file mode 100644 index 000000000..ac0a47c61 --- /dev/null +++ b/doc/doc/CommentStripper.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +import com.rapidminer.tools.Tools; + + +/** + * Delivers the class comments of the Javadoc comments of an operator class. + * + * @author Simon Fischer + */ +public class CommentStripper { + + private File sourceDir; + + public CommentStripper(File sourceDir) { + this.sourceDir = sourceDir; + } + + @SuppressWarnings("fallthrough") + public String stripClassComment(Class clazz) throws IOException { + File sourceFile = new File(sourceDir, clazz.getName().replaceAll("\\.", File.separator) + ".java"); + if (!sourceFile.exists()) + throw new FileNotFoundException("No source file found for class " + clazz.getName() + "; source was expected in '" + sourceFile + "'."); + StringBuffer comment = null; + BufferedReader reader = new BufferedReader(new FileReader(sourceFile)); + try { + String line = null; + + final int SCANNING_FOR_COMMENT = 0; + final int READING_COMMENT = 1; + final int FINISHED_COMMENT = 2; + int currentState = SCANNING_FOR_COMMENT; + while ((line = reader.readLine()) != null) { + line = line.trim(); + switch (currentState) { + case SCANNING_FOR_COMMENT: + if (line.startsWith("/**")) { + comment = new StringBuffer(); + line = line.substring("/**".length()); + currentState = READING_COMMENT; + // ATTENTION (in case someone wants to read this code): there is no break here! + // Hence the fallthrough is ok and we add a warning suppression + } else { + break; + } + case READING_COMMENT: + int end = line.indexOf("*/"); + if (end != -1) { + line = line.substring(0, end); + currentState = FINISHED_COMMENT; + } + line = stripAsteriks(line); + if (line.startsWith("@")) + continue; + comment.append(line + " "); + break; + case FINISHED_COMMENT: + if (line.length() > 0) { + int classIndex = line.indexOf("class"); + int nameIndex = line.indexOf(clazz.getSimpleName()); + if ((classIndex != -1) && (nameIndex > classIndex + "class".length())) { + return comment.toString().trim(); + } else { + // this is not what we want + comment = null; + } + } + break; + } + } + } + finally { + /* Close the stream even if we return early. */ + reader.close(); + } + return null; + } + + private static String stripAsteriks(String string) { + while (string.startsWith("*")) + string = string.substring(1).trim(); + return string.trim(); + } + +} diff --git a/doc/doc/DocumentationGenerator.java b/doc/doc/DocumentationGenerator.java new file mode 100644 index 000000000..dc262fe9f --- /dev/null +++ b/doc/doc/DocumentationGenerator.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Collection; +import java.util.Iterator; + +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorDescription; +import com.rapidminer.tools.GroupTree; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.OperatorService; +import com.rapidminer.tools.ParameterService; +import com.rapidminer.tools.Tools; +import com.sun.javadoc.RootDoc; + + +/** + * This is the main class of documentation generation for RapidMiner operators. The target format is LaTeX, therefore a + * {@link LatexOperatorDocGenerator} is used. If no arguments are given to the main method, the LaTeX documentation of + * the RapidMiner core is generated. If arguments are specified other documentation may be also generated, e.g. for plugin + * operators. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class DocumentationGenerator { + + private OperatorDocGenerator generator; + + private static RootDoc rootDoc = null; + + public DocumentationGenerator(OperatorDocGenerator generator) { + this.generator = generator; + } + + /** Use only classes beneath the operator package. */ + private void getRootDoc() { + try { + getRootDoc(new File(ParameterService.getRapidMinerHome(), "src" + File.separator), "com.rapidminer.operator"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void getRootDoc(File srcDir, String subpackages) { + LogService.getGlobal().log("Starting javadoc!", LogService.STATUS); + String[] javadocargs = { "-sourcepath", srcDir.getAbsolutePath(), "-doclet", this.getClass().getName(), "-breakiterator", "-subpackages", + subpackages }; + com.sun.tools.javadoc.Main.execute(javadocargs); + if (rootDoc == null) + LogService.getGlobal().log("RootDoc not set!", LogService.ERROR); + } + + public static boolean start(RootDoc rootDoc) { + LogService.getGlobal().log("RootDoc generated!", LogService.STATUS); + DocumentationGenerator.rootDoc = rootDoc; + return true; + } + + public void generateAll(PrintWriter out) { + generateAll(out, false); + } + + public void generateAll(PrintWriter out, boolean generateSubgroups) { + GroupTree root = OperatorService.getGroups(); + if (root.getOperatorDescriptions().size() > 0) { + // print main operators + generator.beginGroup(null, out); + generateOperators(out, root.getOperatorDescriptions()); + generator.endGroup(null, out); + } + + // print subgroups + Collection groups = root.getSubGroups(); + Iterator i = groups.iterator(); + while (i.hasNext()) { + GroupTree group = (GroupTree) i.next(); + generateGroup(out, group, generateSubgroups); + } + out.println(); + out.flush(); + } + + public void generateGroup(PrintWriter out, GroupTree group, boolean generateSubgroups) { + generator.beginGroup(group.getName(), out); + if (generateSubgroups) { + generateOperators(out, group.getOperatorDescriptions()); + Collection groups = group.getSubGroups(); + Iterator i = groups.iterator(); + while (i.hasNext()) { + GroupTree subgroup = (GroupTree) i.next(); + generateGroup(out, subgroup, generateSubgroups); + } + } else { + generateOperators(out, group.getAllOperatorDescriptions()); + } + generator.endGroup(group.getName(), out); + } + + public void generateOperators(PrintWriter out, Collection operators) { + Iterator ops = operators.iterator(); + while (ops.hasNext()) { + OperatorDescription description = ops.next(); + try { + Operator operator = description.createOperatorInstance(); + generator.generateDoc(operator, rootDoc, out); + } catch (Exception e) { + e.printStackTrace(out); + System.err.println("Error in " + description.getName() + ": " + e.getMessage()); + } + + } + out.println(); + } + + /** + * If no arguments are given, the LaTeX documentation of the RapidMiner core is generated. Otherwise this documentation + * generator can be used to generated the documentation of arbitrary RapidMiner operators, e.g. for plugins. In this case + * the arguments are:
<operators.xml> <sourcedir> <packages> <with_subgroups> + */ + public static void main(String[] argv) throws IOException { + if (argv.length == 1) { + OperatorDocGenerator opDocGen = null; + if (argv[0].equals("LATEX")) + opDocGen = new LatexOperatorDocGenerator(); + else + opDocGen = new ProgramHTMLOperatorDocGenerator(); + + ParameterService.init(); + File file = new File(ParameterService.getRapidMinerHome(), "tutorial" + File.separator + "OperatorsGenerated.tex"); + LogService.getGlobal().log("Generating class documentation to '" + file + "'.", LogService.STATUS); + DocumentationGenerator docGen = new DocumentationGenerator(opDocGen); + docGen.getRootDoc(); + docGen.generateAll(new PrintWriter(new FileWriter(file))); + } else if (argv.length == 2) { + OperatorDocGenerator opDocGen = null; + if (argv[0].equals("LATEX")) + opDocGen = new LatexOperatorDocGenerator(); + else + opDocGen = new ProgramHTMLOperatorDocGenerator(); + + ParameterService.init(); + File file = new File(argv[1]); + LogService.getGlobal().log("Generating class documentation to '" + file + "'.", LogService.STATUS); + DocumentationGenerator docGen = new DocumentationGenerator(opDocGen); + docGen.getRootDoc(); + docGen.generateAll(new PrintWriter(new FileWriter(file))); + } else if (argv.length >= 5) { + OperatorDocGenerator opDocGen = null; + if (argv[0].equals("LATEX")) + opDocGen = new LatexOperatorDocGenerator(); + else + opDocGen = new ProgramHTMLOperatorDocGenerator(); + + try { + OperatorService.registerOperators(argv[1], new FileInputStream(argv[1]), null); + } catch (IOException e) { + LogService.getGlobal().log("Cannot read 'operators.xml'.", LogService.ERROR); + } + File file = new File(argv[4]); + LogService.getGlobal().log("Generating class documentation to '" + file + "'.", LogService.STATUS); + PrintWriter out = new PrintWriter(new FileWriter(file)); + + DocumentationGenerator docGen = new DocumentationGenerator(opDocGen); + boolean generateSubgroups = false; + if (argv.length == 6) { + if (argv[5].equals("true")) + generateSubgroups = true; + } + docGen.getRootDoc(new File(argv[2]), argv[3]); + docGen.generateAll(new PrintWriter(new FileWriter(file)), generateSubgroups); + + out.close(); + } else { + LogService.getGlobal().log("usage: java com.rapidminer.doc.DocumentationGenerator or" + Tools.getLineSeparator() + + " java com.rapidminer.doc.DocumentationGenerator operatordesc srcdir subpackages outputfile [generate subgroups (true/false)]", + LogService.WARNING); + } + } +} diff --git a/doc/doc/LatexOperatorDocGenerator.java b/doc/doc/LatexOperatorDocGenerator.java new file mode 100644 index 000000000..4a3c69648 --- /dev/null +++ b/doc/doc/LatexOperatorDocGenerator.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.PrintWriter; +import java.io.StringReader; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Tools; + + +/** + * Formats operator documentation in LaTeX style. + * + * @rapidminer.todo Lookup class when link is found and decide which tag to use (op, ioobj, ...) + * @author Simon Fischer, Ingo Mierswa + */ +public class LatexOperatorDocGenerator extends AbstractOperatorDocGenerator { + + public static final String[][] TAGS = { { "", "" }, // operator + { "\\operator{", "}" }, // operator name + { "\\group{", "}" }, // group + { Tools.getLineSeparator() + "\\begin{parameters}", "\\end{parameters}" }, // parameter list + { "", "" }, // parameter item + { "\\reqpar[", "]" }, // required parameter + { "\\optpar[", "]" }, // optional parameter + { "", "" }, // parameter description + { "\\paragraph{Short description:} ", "" }, // short description + { "\\opdescr ", "" }, // operator description + { "\\begin{opin} ", "\\end{opin}" }, // input classes list + { "\\begin{opout} ", "\\end{opout}" }, // output classes list + { "\\item[", "]" }, // IO class + { Tools.getLineSeparator() + "\\paragraph{Inner operators:}", Tools.getLineSeparator() }, // inner operators + { Tools.getLineSeparator() + "\\begin{values}", "\\end{values}" }, // value list + { "", "" }, // value item + { "\\val[", "]" }, // value name + { "", "" }, // value description + { "\\index{", "}" }, // index entry + { "\\par References: ", "" }, // reference section + { "\\cite{", "}" }, // reference entry + { Tools.getLineSeparator() + "\\paragraph{Further information:}", Tools.getLineSeparator() }, // technical information (external references) + { "\\emph{", "}" + Tools.getLineSeparator() }, // deprecation info + { Tools.getLineSeparator() + "\\paragraph{Learner capabilities:}", Tools.getLineSeparator() } // learner capabilities + }; + + public String getOpenTag(int tagNo) { + return TAGS[tagNo][0]; + } + + public String getCloseTag(int tagNo) { + return TAGS[tagNo][1]; + } + + public String marginIcon(String iconName) { + String fig = "\\includegraphics{graphics/" + iconName + "}"; + return "\\marginpar[\\flushright" + fig + "]{" + fig + "}"; + } + + public String escape(String toEscape) { + String escaped = toEscape; + escaped = escaped.replaceAll("MACRO_START", "\\\\% \\\\{"); // hack for macro definitions + escaped = escaped.replaceAll("MACRO_END", "\\\\}"); // hack for macro definitions + escaped = escaped.replaceAll("_", "\\\\_"); + escaped = escaped.replaceAll("\\$", "\\\\\\$"); + escaped = escaped.replaceAll("\u221E", "\\$\\\\infty\\$"); + escaped = escaped.replaceAll("ä", "\\\\\"a"); + escaped = escaped.replaceAll("ö", "\\\\\"o"); + escaped = escaped.replaceAll("ü", "\\\\\"u"); + escaped = escaped.replaceAll("Ä", "\\\\\"A"); + escaped = escaped.replaceAll("Ö", "\\\\\"O"); + escaped = escaped.replaceAll("Ü", "\\\\\"U"); + escaped = escaped.replaceAll("ß", "\\\\\"s"); + escaped = escaped.replaceAll(" ", "\\\\ "); + escaped = escaped.replaceAll("(\\w)"", "$1''"); + escaped = escaped.replaceAll(""", "``"); + escaped = escaped.replaceAll("#", "\\\\#"); + escaped = escaped.replaceAll("\\[", "\\{\\[\\}"); + escaped = escaped.replaceAll("\\]", "\\{\\]\\}"); + escaped = escaped.replaceAll("RapidMiner", "\\\\RAPIDMINER"); + escaped = escaped.replaceAll("\\\\s", "\\$\\\\backslash\\$s"); // hack for regular expressions (ExampleSource) + escaped = escaped.replaceAll("\\\\t", "\\$\\\\backslash\\$t"); // hack for regular expressions (ExampleSource) + escaped = escaped.replaceAll("\\|", "\\$|\\$"); + escaped = escaped.replaceAll("\\^", ""); + return escaped; + } + + public void beginGroup(String groupName, PrintWriter out) { + out.println("\\pagebreak[4]"); + if (groupName != null) { + groupName = groupName.replace(' ', '_'); + out.println("\\input{OpGroup" + groupName + ".tex}"); + } else { + out.println("\\section{Basic operators}"); + } + } + + public void endGroup(String groupName, PrintWriter out) { + out.println("\\vfill"); + } + + public String transformHTMLJavadocComment(String comment, final Class clazz, final String operatorName) { + try { + SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); + comment = "" + comment + ""; + final StringBuffer transformed = new StringBuffer(); + final Stack closingTagStack = new Stack(); + parser.parse(new InputSource(new StringReader(comment)), new DefaultHandler() { + + public void characters(char[] ch, int start, int length) throws SAXException { + transformed.append(ch, start, length); + } + + public InputSource resolveEntity(String publicId, String systemId) throws SAXException { + LogService.getGlobal().log("Entity: " + publicId, LogService.STATUS); + String latex; + if (systemId.equals(""")) { + latex = "``"; + } else if (systemId.equals("ä")) { + latex = "\\\"a"; + } else if (systemId.equals("ö")) { + latex = "\\\"o"; + } else if (systemId.equals("ü")) { + latex = "\\\"u"; + } else if (systemId.equals("Ä")) { + latex = "\\\"A"; + } else if (systemId.equals("Ö")) { + latex = "\\\"O"; + } else if (systemId.equals("Ü")) { + latex = "\\\"U"; + } else if (systemId.equals("ß")) { + latex = "\\\"s"; + } else if (systemId.equals(" ")) { + latex = "\\ "; + } else { + LogService.getGlobal().log("Unknown entity: " + systemId, LogService.WARNING); + latex = systemId; + } + return new InputSource(new StringReader(latex)); + } + + public void endElement(String uri, String localName, String qName) { + transformed.append(closingTagStack.pop()); + } + + public void startElement(String uri, String localName, String qName, Attributes attributes) { + qName = qName.toLowerCase(); + if (qName.equals("code")) { + transformed.append("\\java{"); + closingTagStack.push("}"); + } else if (qName.equals("em")) { + transformed.append("\\emph{"); + closingTagStack.push("}"); + } else if (qName.equals("var")) { + transformed.append("\\para{"); + closingTagStack.push("}"); + + } else if (qName.equals("b")) { + LogService.getGlobal().log(operatorName + " (" + clazz.getName() + "): physical markup used (b,i, or tt).", LogService.WARNING); + transformed.append("\\textbf{"); + closingTagStack.push("}"); + } else if (qName.equals("i")) { + LogService.getGlobal().log(operatorName + " (" + clazz.getName() + "): physical markup used (b,i, or tt).", LogService.WARNING); + transformed.append("\\textit{"); + closingTagStack.push("}"); + } else if (qName.equals("tt")) { + LogService.getGlobal().log(operatorName + " (" + clazz.getName() + "): physical markup used (b,i, or tt).", LogService.WARNING); + transformed.append("\\texttt{"); + closingTagStack.push("}"); + + } else if (qName.equals("center")) { + transformed.append(Tools.getLineSeparator() + "\\begin{center}" + Tools.getLineSeparator()); + closingTagStack.push(Tools.getLineSeparator() + "\\end{center}" + Tools.getLineSeparator()); + } else if (qName.equals("ol")) { + transformed.append(Tools.getLineSeparator() + "\\begin{enumerate}" + Tools.getLineSeparator()); + closingTagStack.push(Tools.getLineSeparator() + "\\end{enumerate}" + Tools.getLineSeparator()); + } else if (qName.equals("ul")) { + transformed.append(Tools.getLineSeparator() + "\\begin{itemize}" + Tools.getLineSeparator()); + closingTagStack.push(Tools.getLineSeparator() + "\\end{itemize}" + Tools.getLineSeparator()); + } else if (qName.equals("li")) { + transformed.append(Tools.getLineSeparator() + "\\item "); + closingTagStack.push(""); + } else if (qName.equals("dl")) { + transformed.append(Tools.getLineSeparator() + "\\begin{description}" + Tools.getLineSeparator()); + closingTagStack.push(Tools.getLineSeparator() + "\\end{description}" + Tools.getLineSeparator()); + } else if (qName.equals("dt")) { + transformed.append(Tools.getLineSeparator() + "\\item["); + closingTagStack.push("]"); + } else if (qName.equals("dd")) { + // nothing for dd + closingTagStack.push(""); + } else if (qName.equals("body")) { + transformed.append(""); + closingTagStack.push(""); + } else if (qName.equals("sup")) { + transformed.append("$^{"); + closingTagStack.push("}$"); + } else if (qName.equals("sub")) { + transformed.append("$_{"); + closingTagStack.push("}$"); + } else if (qName.equals("br")) { + transformed.append("\\par" + Tools.getLineSeparator()); + closingTagStack.push(""); + } else if (qName.equals("p")) { + transformed.append("\\par" + Tools.getLineSeparator()); + closingTagStack.push(""); + } else if (qName.equals("a")) { + closingTagStack.push("\\footnote{\\url{" + attributes.getValue("href") + "}}"); + } else if (qName.equals("h1") || qName.equals("h2") || qName.equals("h3") || qName.equals("h4") || qName.equals("h5")) { + transformed.append(Tools.getLineSeparator() + "\\paragraph{"); + closingTagStack.push("}"); + } else if (qName.equals("pre")) { + transformed.append("\\begin{verbatim}"); + closingTagStack.push("\\end{verbatim}"); + } else { + transformed.append(""); + closingTagStack.push(""); + LogService.getGlobal().log("Unknown tag: " + qName + " (" + operatorName + " (" + clazz.getName() + "))", LogService.WARNING); + } + } + + }); + StringBuffer linksReplaced = new StringBuffer(); + Pattern pattern = Pattern.compile("\\{@link (.*?)\\}"); + Matcher matcher = pattern.matcher(transformed); + while (matcher.find()) { + String classname = matcher.group(1); + int period = classname.lastIndexOf("."); + if (period != -1) + classname = classname.substring(period + 1); + matcher.appendReplacement(linksReplaced, "\\\\op{" + classname + "}"); + } + matcher.appendTail(linksReplaced); + return linksReplaced.toString(); + } catch (Throwable e) { + LogService.getGlobal().log(operatorName + " (" + clazz.getName() + "): " + e, LogService.ERROR); + return "Cannot parse class comment: " + e; + } + } +} diff --git a/doc/doc/MathTaglet.java b/doc/doc/MathTaglet.java new file mode 100644 index 000000000..199e42f5c --- /dev/null +++ b/doc/doc/MathTaglet.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.util.Map; + +import com.sun.javadoc.Tag; +import com.sun.tools.doclets.Taglet; + +/** + * A taglet with name "@rapidminer.math" can be used in the Javadoc comments of an operator to produce mathematical + * code. Example: "@rapidminer.math 1/(n+1)". This will include a LaTeX math environment to you documentation. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class MathTaglet implements TexTaglet { + + private static final String NAME = "rapidminer.math"; + + public String getName() { + return NAME; + } + + public boolean inField() { + return true; + } + + public boolean inConstructor() { + return true; + } + + public boolean inMethod() { + return true; + } + + public boolean inOverview() { + return true; + } + + public boolean inPackage() { + return true; + } + + public boolean inType() { + return true; + } + + public boolean isInlineTag() { + return true; + } + + public static void register(Map tagletMap) { + MathTaglet tag = new MathTaglet(); + Taglet t = tagletMap.get(tag.getName()); + if (t != null) { + tagletMap.remove(tag.getName()); + } + tagletMap.put(tag.getName(), tag); + } + + public String toString(Tag tag) { + return "" + tag.text() + ""; + } + + public String toString(Tag[] tags) { + return null; + } + + public String toTex(Tag tag) { + return "$" + tag.text() + "$"; + } + + public String toTex(Tag[] tag) { + return null; + } +} diff --git a/doc/doc/OperatorDocGenerator.java b/doc/doc/OperatorDocGenerator.java new file mode 100644 index 000000000..560a48e7d --- /dev/null +++ b/doc/doc/OperatorDocGenerator.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.PrintWriter; + +import com.rapidminer.operator.Operator; +import com.sun.javadoc.RootDoc; + + +/** + * Generates the documentation for operators. + * + * @author Simon Fischer + */ +public interface OperatorDocGenerator { + + /** Generates the documentation for this operator and writes it to the given writer. */ + public void generateDoc(Operator operator, RootDoc rootDoc, PrintWriter out); + + /** Generates the header for the group with the given name. The name might be null. */ + public void beginGroup(String groupName, PrintWriter out); + + /** Generates the footer for the group with the given name. The name might be null. */ + public void endGroup(String groupName, PrintWriter out); +} diff --git a/doc/doc/ProgramHTMLOperatorDocGenerator.java b/doc/doc/ProgramHTMLOperatorDocGenerator.java new file mode 100644 index 000000000..7676044f2 --- /dev/null +++ b/doc/doc/ProgramHTMLOperatorDocGenerator.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.PrintWriter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.rapidminer.operator.Operator; +import com.rapidminer.tools.LogService; +import com.sun.javadoc.ClassDoc; +import com.sun.javadoc.RootDoc; + +/** + * Formats operator documentation in HTML style. + * + * @author Ingo Mierswa + */ +public class ProgramHTMLOperatorDocGenerator implements OperatorDocGenerator { + + public void generateDoc(Operator op, RootDoc rootDoc, PrintWriter out) { + ClassDoc opDoc = rootDoc.classNamed(op.getClass().getName()); + + // name + out.println(op.getOperatorDescription().getName()); + + // Description + out.println(transformHTMLJavadocComment(opDoc.commentText(), op.getClass(), op.getOperatorDescription().getName())); + + out.println("#####"); + } + + public String transformHTMLJavadocComment(String comment, final Class clazz, final String operatorName) { + try { + // Links + StringBuffer linksReplaced = new StringBuffer(); + Pattern linkPattern = Pattern.compile("\\{@link (.*?)\\}"); + Matcher linkMatcher = linkPattern.matcher(comment); + while (linkMatcher.find()) { + String classname = linkMatcher.group(1); + int period = classname.lastIndexOf("."); + if (period != -1) + classname = classname.substring(period + 1); + linkMatcher.appendReplacement(linksReplaced, "" + classname + ""); + } + linkMatcher.appendTail(linksReplaced); + + // RapidMiner Ref + StringBuffer refReplaced = new StringBuffer(); + Pattern refPattern = Pattern.compile("\\{@rapidminer.ref (.*?)\\}"); + Matcher refMatcher = refPattern.matcher(linksReplaced.toString()); + while (refMatcher.find()) { + String refName = refMatcher.group(1); + int period = refName.lastIndexOf("|"); + if (period != -1) + refName = refName.substring(period + 1); + refMatcher.appendReplacement(refReplaced, "" + refName + ""); + } + refMatcher.appendTail(refReplaced); + + // RapidMiner Math + StringBuffer mathReplaced = new StringBuffer(); + Pattern mathPattern = Pattern.compile("\\{@rapidminer.math (.*?)\\}"); + Matcher mathMatcher = mathPattern.matcher(refReplaced.toString()); + while (mathMatcher.find()) { + String mathName = mathMatcher.group(1); + mathMatcher.appendReplacement(mathReplaced, "" + mathName + ""); + } + mathMatcher.appendTail(mathReplaced); + + return mathReplaced.toString(); + } catch (Throwable e) { + LogService.getGlobal().log(operatorName + " (" + clazz.getName() + "): " + e, LogService.ERROR); + return "Cannot parse class comment: " + e; + } + } + + /** Does nothing. */ + public void beginGroup(String groupName, PrintWriter out) {} + + /** Does nothing. */ + public void endGroup(String groupName, PrintWriter out) {} +} diff --git a/doc/doc/RefTaglet.java b/doc/doc/RefTaglet.java new file mode 100644 index 000000000..077bf2c13 --- /dev/null +++ b/doc/doc/RefTaglet.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.util.Map; + +import com.sun.javadoc.Tag; +import com.sun.tools.doclets.Taglet; + +/** + * A taglet with name "@rapidminer.ref" can be used in the Javadoc comments of an operator to produce textual + * references. Example: "@rapidminer.ref figure1|A figure for this". This will include a LaTeX reference to your + * documentation. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class RefTaglet implements TexTaglet { + + private static final String NAME = "rapidminer.ref"; + + public String getName() { + return NAME; + } + + public boolean inField() { + return true; + } + + public boolean inConstructor() { + return true; + } + + public boolean inMethod() { + return true; + } + + public boolean inOverview() { + return true; + } + + public boolean inPackage() { + return true; + } + + public boolean inType() { + return true; + } + + public boolean isInlineTag() { + return true; + } + + public static void register(Map tagletMap) { + RefTaglet tag = new RefTaglet(); + Taglet t = tagletMap.get(tag.getName()); + if (t != null) { + tagletMap.remove(tag.getName()); + } + tagletMap.put(tag.getName(), tag); + } + + private String[] split(Tag tag) { + String[] splitted = tag.text().split("\\|"); + if (splitted.length != 2) { + System.err.println("Usage: {@" + getName() + " latexref|html_human_readable_ref} (" + tag.position() + ")"); + return new String[] { tag.text(), tag.text() }; + } else { + return splitted; + } + } + + public String toString(Tag tag) { + return split(tag)[1]; + } + + public String toString(Tag[] tags) { + return null; + } + + public String toTex(Tag tag) { + return "\\ref{" + split(tag)[0] + "}"; + } + + public String toTex(Tag[] tag) { + return null; + } +} diff --git a/doc/doc/ReferenceTaglet.java b/doc/doc/ReferenceTaglet.java new file mode 100644 index 000000000..525649c8b --- /dev/null +++ b/doc/doc/ReferenceTaglet.java @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Map; + +import org.kobjects.jdbc.TableManager; + +import com.sun.javadoc.Tag; +import com.sun.tools.doclets.Taglet; + +/** + * A taglet with name "@rapidminer.reference" can be used in the Javadoc comments of an operator to produce a + * reference to literature including the bibtex entry. Unfortunately this can only be used in the Artificial + * Intelligence Unit of the University of Dortmund. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class ReferenceTaglet implements Taglet { + + //private static final String[] DOCUMENT_EXTENSIONS = { "ps", "ps.gz", "pdf", "pdf.gz", "ppt" }; + + private static final String NAME = "rapidminer.reference"; + + public String getName() { + return NAME; + } + + public boolean inField() { + return true; + } + + public boolean inConstructor() { + return true; + } + + public boolean inMethod() { + return true; + } + + public boolean inOverview() { + return true; + } + + public boolean inPackage() { + return true; + } + + public boolean inType() { + return true; + } + + public boolean isInlineTag() { + return true; + } + + private static Method getResultSetMethod; + + private static File rapidMinerHome; + + /** + * Find TableManager.getResultSet() method by reflection, since as far as we know it is not possible to include + * kdb.jar in the classpath. + */ + static { + String rapidMinerHomeName = System.getProperty("rapidminer.home"); // TODO [property] + if (rapidMinerHomeName == null) { + File buildDir = new File(ReferenceTaglet.class.getResource(".."+File.separator+".." + File.separator + "..").getFile()); + rapidMinerHome = buildDir.getParentFile(); + System.err.println("rapidminer.home is not set! Assuming " + rapidMinerHome); + } else { + rapidMinerHome = new File(rapidMinerHomeName); + } + + if (rapidMinerHome != null) { + try { + URL url = new URL("file", null, new File(rapidMinerHome, "lib" + File.separator + "kdb.jar").getAbsolutePath()); + ClassLoader classLoader = new URLClassLoader(new URL[] { url }); + Class tableManagerClass = classLoader.loadClass("org.kobjects.jdbc.TableManager"); + getResultSetMethod = tableManagerClass.getMethod("getResultSet", new Class[] { String.class, int.class }); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + System.err.println("Cannot find class org.kobjects.jdbc.TableManager"); + } catch (NoSuchMethodException e) { + System.err.println("Cannot find method org.kobjects.jdbc.TableManager.getResultSet(String,int)"); + } + } + } + + public static void register(Map tagletMap) { + ReferenceTaglet tag = new ReferenceTaglet(); + Taglet t = tagletMap.get(tag.getName()); + if (t != null) { + tagletMap.remove(tag.getName()); + } + tagletMap.put(tag.getName(), tag); + } + + public String toString(Tag tag) { + return toString(new Tag[] { tag }); + } + + public String toString(Tag[] tags) { + if (tags.length == 0) { + return null; + } + String result = "
Bibliography:
"; + result += "
    "; + for (int i = 0; i < tags.length; i++) { + String key = tags[i].text().trim(); + String entry = getBibEntry(key); + result += "
  • " + ((entry != null) ? entry : key) + "
  • "; + } + result += "
"; + return result; + } + + private static String getBibEntry(String key) { + if (getResultSetMethod == null) + return null; + + File bibFile = new File(rapidMinerHome, "tutorial" + File.separator + "RapidMinerTutorial.bib"); + if (!bibFile.exists()) { + System.err.println("rapidminer.home is not set! Cannot find RapidMinerTutorial.bib"); + return null; + } + ResultSet literatur = null; + try { + literatur = (ResultSet) getResultSetMethod.invoke(null, new Object[] { "bibtex:" + bibFile, Integer.valueOf(TableManager.READ) }); + } catch (IllegalAccessException e) { + System.err.println("Cannot access TableManager.getResultSet(): " + e); + getResultSetMethod = null; + return null; + } catch (InvocationTargetException e) { + System.err.println("Exception in TableManager.getResultSet(): " + e.getCause()); + } + + if (literatur == null) + return null; + + try { + while (literatur.next()) { + String bibkey = literatur.getString("bibkey"); + if (bibkey == null) + continue; + if (bibkey.equals(key)) { + String result = "[" + key + "] "; + result += escape(literatur.getString("author")) + ": " + "" + escape(literatur.getString("title")) + " "; + String in = literatur.getString("booktitle"); + if (in != null) { + result += "In " + escape(in) + " "; + } + result += "(" + literatur.getString("year") + ")"; + result += ""; + return result; + } + } + System.err.println("Bibkey not found: " + key); + return null; + } catch (SQLException e) { + System.err.println("SQLException occured: " + e.getMessage()); + return null; + } + } + + private static String escape(String str) { + if (str == null) + return null; + String escaped = str; + escaped = escaped.replaceAll("<", "<"); + escaped = escaped.replaceAll(">", ">"); + escaped = escaped.replaceAll("\\{", ""); + escaped = escaped.replaceAll("\\}", ""); + return escaped; + } +} diff --git a/doc/doc/TexTaglet.java b/doc/doc/TexTaglet.java new file mode 100644 index 000000000..b7a9210c0 --- /dev/null +++ b/doc/doc/TexTaglet.java @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import com.sun.javadoc.Tag; +import com.sun.tools.doclets.Taglet; + +/** + * Creates the LaTeX code from a html taglet. + * + * @author Simon Fischer + */ +public interface TexTaglet extends Taglet { + + public String toTex(Tag tag); + + public String toTex(Tag[] tag); + +} diff --git a/doc/doc/XMLExampleTaglet.java b/doc/doc/XMLExampleTaglet.java new file mode 100644 index 000000000..c5a2aeed6 --- /dev/null +++ b/doc/doc/XMLExampleTaglet.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2001-2014 RapidMiner GmbH + */ +package com.rapidminer.doc; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import com.rapidminer.tools.Tools; +import com.sun.javadoc.SourcePosition; +import com.sun.javadoc.Tag; +import com.sun.tools.doclets.Taglet; + + +/** + * A taglet with name "@rapidminer.xmlinput" can be used in the Javadoc comments of an operator to include an XML + * file into the documentation. Example: "@rapidminer.xmlinput filename|label|caption". This may be useful to + * provide the XML code for an operator's usage. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class XMLExampleTaglet implements TexTaglet { + + private static final String NAME = "rapidminer.xmlinput"; + + public String getName() { + return NAME; + } + + public boolean inField() { + return true; + } + + public boolean inConstructor() { + return true; + } + + public boolean inMethod() { + return true; + } + + public boolean inOverview() { + return true; + } + + public boolean inPackage() { + return true; + } + + public boolean inType() { + return true; + } + + public boolean isInlineTag() { + return true; + } + + public static void register(Map tagletMap) { + XMLExampleTaglet tag = new XMLExampleTaglet(); + Taglet t = tagletMap.get(tag.getName()); + if (t != null) { + tagletMap.remove(tag.getName()); + } + tagletMap.put(tag.getName(), tag); + } + + private String[] split(Tag tag) { + String[] result = tag.text().split("\\|"); + if (result.length != 3) { + System.err.println("Usage: {@" + getName() + " filename|label|caption} (was: " + tag.text() + ") (" + tag.position() + ")"); + return null; + } + return result; + } + + private File resolve(String file, SourcePosition source) { + return new File(source.file().getParentFile(), file); + } + + public String toString(Tag tag) { + String[] splitted = split(tag); + if (splitted == null) + return ""; + File file = resolve(splitted[0], tag.position()); + String contents = null; + if (file.exists()) { + try { + contents = Tools.readTextFile(file); + contents = contents.replaceAll("<", "<"); + contents = contents.replaceAll(">", ">"); + } catch (IOException e) { + contents = "Cannot read file '" + file + "': " + e; + System.err.println(tag.position() + ": cannot read file '" + file + "'!"); + } + } else { + contents = "File '" + file + "' does not exist!"; + System.err.println(tag.position() + ": File '" + file + "' does not exist!"); + } + return "
" + contents + "

Figure: " + splitted[2] + "
"; + } + + public String toString(Tag[] tags) { + return null; + } + + public String toTex(Tag tag) { + String[] splitted = split(tag); + if (splitted == null) + return ""; + File file = resolve(splitted[0], tag.position()); + if (!file.exists()) { + System.err.println(tag.position() + ": File '" + file + "' does not exist!"); + return ""; + } else { + return "\\examplefile{" + file.getAbsolutePath() + "}{" + splitted[1] + "}{" + splitted[2] + "}"; + } + } + + public String toTex(Tag[] tag) { + return null; + } +} diff --git a/doc/doc/package.html b/doc/doc/package.html new file mode 100644 index 000000000..4ceec9dab --- /dev/null +++ b/doc/doc/package.html @@ -0,0 +1,12 @@ + + + + + + + + +The documentation generator of RapidMiner. This generator can also be used to automatically construct the documentation of your own operators or plugins. + + + diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..348d06808 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +version=7.1.0 +group=com.rapidminer.studio \ No newline at end of file diff --git a/gradle/props.gradle b/gradle/props.gradle new file mode 100644 index 000000000..91dc8e460 --- /dev/null +++ b/gradle/props.gradle @@ -0,0 +1,51 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'org.ajoberstar:grgit:0.3.+' + } +} + +import org.ajoberstar.grgit.Grgit + +// Generates a file containing the current Git revision +task generateGitRevFile() { + + ext { outputFile = file("$buildDir/tmp/generateGitRev/gitrev") } + + outputs.file outputFile + outputs.upToDateWhen { false } + + doLast { + def repo = Grgit.open(rootProject.file('.')) + if (!outputFile.parentFile.isDirectory()) { outputFile.parentFile.mkdirs() } + outputFile.text = repo.head().id + } +} + +// Define a tasks that creates the version.properties file and stores it in the resources +task generateVersionProperties { + + // define version properties file location + ext { versionPropFile = file("$buildDir/tmp/generateVersionProperties/version.properties") } + + // configure version properties generation task input and output + inputs.property "version", version + inputs.file generateGitRevFile + outputs.files versionPropFile + + // check if file exists and create it if necessary + doLast { + if(!versionPropFile.isFile()){ + versionPropFile.parentFile.mkdirs() + versionPropFile.createNewFile() + } + Properties props = new Properties() + props.version = version + props.revision = inputs.files[0].text + props.store(versionPropFile.newWriter(), null) + } +} + +jar { into('com/rapidminer/tools/') { from generateVersionProperties } } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 000000000..05ef575b0 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..e7b65f76e --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Nov 05 09:40:00 CET 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip diff --git a/gradle/wsimport.gradle b/gradle/wsimport.gradle new file mode 100644 index 000000000..1cad1b109 --- /dev/null +++ b/gradle/wsimport.gradle @@ -0,0 +1,76 @@ +configurations { jaxws } + +dependencies { + // Needed for wsimport Ant task + // see https://jax-ws.java.net/2.2.8/docs/ch04.html#tools-wsimport-ant-task + jaxws 'com.sun.xml.ws:jaxws-rt:2.2.8' + jaxws 'com.sun.xml.ws:jaxws-tools:2.2.8' +} + +class GenerateFromWSDL extends DefaultTask { + + def authFile = project.file('wsimportAuth') + def packageName = 'com.rapidminer.wsimport' + def wsdlFile = null + def srcDir = 'src/generated/java/' + + @TaskAction + public doWork() { + // ensure src dir available + project.file(srcDir).mkdirs() + assert wsdlFile + + // ensure JavaDoc is in english + System.properties['user.language'] = 'en' + System.properties['user.country'] = 'EN' + System.properties['javax.xml.accessExternalSchema'] = 'file' + Locale.setDefault(Locale.UK) + + def jaxwsClasspath = project.configurations.jaxws.asPath + project.ant { + + taskdef(name:'wsimport', classname:'com.sun.tools.ws.ant.WsImport', classpath: jaxwsClasspath) + wsimport( + wsdl: wsdlFile, + sourcedestdir: srcDir, + package: packageName, + keep: true, + extension: true, + xadditionalHeaders: true, + xnocompile: true, + xdebug: true, + xauthfile: authFile + ) + } + } + +} + +task wsimportRepositoryService(type: GenerateFromWSDL) { + wsdlFile 'http://localhost:8080/RAWS/RepositoryService?wsdl' + packageName 'com.rapid_i.repository.wsimport' +} + +task wsimportProcessService(type: GenerateFromWSDL) { + wsdlFile 'http://localhost:8080/RAWS/ProcessService?wsdl' + packageName 'com.rapid_i.repository.wsimport' +} + +task wsimportManagementService(type: GenerateFromWSDL) { + wsdlFile 'http://localhost:8080/RAWS/ManagementService?wsdl' + packageName 'com.rapid_i.repository.wsimport.mgt' +} + +task wsimportProcessService_1_3(type: GenerateFromWSDL) { + wsdlFile 'http://localhost:8080/RAWS/ProcessService_1_3?wsdl' + packageName 'com.rapid_i.repository.wsimport' +} + +task wsimportRAInfoService(type: GenerateFromWSDL) { + wsdlFile 'http://localhost:8080/RAWS/RAInfoService?wsdl' + packageName 'com.rapid_i.repository.wsimport' +} + +task wsimport { + dependsOn tasks.findAll { Task t -> t.name.startsWith('wsimport') && t.name != 'wsimport' } +} \ No newline at end of file diff --git a/gradlew b/gradlew new file mode 100644 index 000000000..9d82f7891 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 000000000..8a0b282aa --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/generated/java/com/rapid_i/repository/wsimport/AccessRights.java b/src/generated/java/com/rapid_i/repository/wsimport/AccessRights.java new file mode 100644 index 000000000..b1e6de114 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/AccessRights.java @@ -0,0 +1,158 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for accessRights complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="accessRights">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="execute" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="group" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="read" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="write" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "accessRights", propOrder = { + "execute", + "group", + "read", + "write" +}) +public class AccessRights { + + protected String execute; + protected String group; + protected String read; + protected String write; + + /** + * Gets the value of the execute property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getExecute() { + return execute; + } + + /** + * Sets the value of the execute property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setExecute(String value) { + this.execute = value; + } + + /** + * Gets the value of the group property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getGroup() { + return group; + } + + /** + * Sets the value of the group property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setGroup(String value) { + this.group = value; + } + + /** + * Gets the value of the read property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getRead() { + return read; + } + + /** + * Sets the value of the read property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setRead(String value) { + this.read = value; + } + + /** + * Gets the value of the write property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getWrite() { + return write; + } + + /** + * Sets the value of the write property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setWrite(String value) { + this.write = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/CancelTrigger.java b/src/generated/java/com/rapid_i/repository/wsimport/CancelTrigger.java new file mode 100644 index 000000000..f807414ce --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/CancelTrigger.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for cancelTrigger complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="cancelTrigger">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="triggerName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "cancelTrigger", propOrder = { + "triggerName" +}) +public class CancelTrigger { + + protected String triggerName; + + /** + * Gets the value of the triggerName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getTriggerName() { + return triggerName; + } + + /** + * Sets the value of the triggerName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setTriggerName(String value) { + this.triggerName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/CancelTriggerResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/CancelTriggerResponse.java new file mode 100644 index 000000000..f19db41e0 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/CancelTriggerResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for cancelTriggerResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="cancelTriggerResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}response" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "cancelTriggerResponse", propOrder = { + "_return" +}) +public class CancelTriggerResponse { + + @XmlElement(name = "return") + protected Response _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link Response } + * + */ + public Response getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link Response } + * + */ + public void setReturn(Response value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/CreateBlob.java b/src/generated/java/com/rapid_i/repository/wsimport/CreateBlob.java new file mode 100644 index 000000000..6d3270780 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/CreateBlob.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for createBlob complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="createBlob">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="parentLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="blobName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "createBlob", propOrder = { + "parentLocation", + "blobName" +}) +public class CreateBlob { + + protected String parentLocation; + protected String blobName; + + /** + * Gets the value of the parentLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getParentLocation() { + return parentLocation; + } + + /** + * Sets the value of the parentLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setParentLocation(String value) { + this.parentLocation = value; + } + + /** + * Gets the value of the blobName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getBlobName() { + return blobName; + } + + /** + * Sets the value of the blobName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setBlobName(String value) { + this.blobName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/CreateBlobResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/CreateBlobResponse.java new file mode 100644 index 000000000..b4dddf487 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/CreateBlobResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for createBlobResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="createBlobResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}entryResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "createBlobResponse", propOrder = { + "_return" +}) +public class CreateBlobResponse { + + @XmlElement(name = "return") + protected EntryResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link EntryResponse } + * + */ + public EntryResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link EntryResponse } + * + */ + public void setReturn(EntryResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/DeleteEntry.java b/src/generated/java/com/rapid_i/repository/wsimport/DeleteEntry.java new file mode 100644 index 000000000..58a962cf9 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/DeleteEntry.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for deleteEntry complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="deleteEntry">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="entryLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "deleteEntry", propOrder = { + "entryLocation" +}) +public class DeleteEntry { + + protected String entryLocation; + + /** + * Gets the value of the entryLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEntryLocation() { + return entryLocation; + } + + /** + * Sets the value of the entryLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEntryLocation(String value) { + this.entryLocation = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/DeleteEntryResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/DeleteEntryResponse.java new file mode 100644 index 000000000..5176932ab --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/DeleteEntryResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for deleteEntryResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="deleteEntryResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}response" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "deleteEntryResponse", propOrder = { + "_return" +}) +public class DeleteEntryResponse { + + @XmlElement(name = "return") + protected Response _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link Response } + * + */ + public Response getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link Response } + * + */ + public void setReturn(Response value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/EntryResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/EntryResponse.java new file mode 100644 index 000000000..1af03af8e --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/EntryResponse.java @@ -0,0 +1,217 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for entryResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="entryResponse">
+ *   <complexContent>
+ *     <extension base="{http://service.web.rapidanalytics.de/}response">
+ *       <sequence>
+ *         <element name="date" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <element name="ioObjectClassName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="latestRevision" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *         <element name="location" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="size" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *         <element name="type" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="user" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </extension>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "entryResponse", propOrder = { + "date", + "ioObjectClassName", + "latestRevision", + "location", + "size", + "type", + "user" +}) +public class EntryResponse + extends Response +{ + + protected long date; + protected String ioObjectClassName; + protected int latestRevision; + protected String location; + protected int size; + protected String type; + protected String user; + + /** + * Gets the value of the date property. + * + */ + public long getDate() { + return date; + } + + /** + * Sets the value of the date property. + * + */ + public void setDate(long value) { + this.date = value; + } + + /** + * Gets the value of the ioObjectClassName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getIoObjectClassName() { + return ioObjectClassName; + } + + /** + * Sets the value of the ioObjectClassName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setIoObjectClassName(String value) { + this.ioObjectClassName = value; + } + + /** + * Gets the value of the latestRevision property. + * + */ + public int getLatestRevision() { + return latestRevision; + } + + /** + * Sets the value of the latestRevision property. + * + */ + public void setLatestRevision(int value) { + this.latestRevision = value; + } + + /** + * Gets the value of the location property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLocation() { + return location; + } + + /** + * Sets the value of the location property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLocation(String value) { + this.location = value; + } + + /** + * Gets the value of the size property. + * + */ + public int getSize() { + return size; + } + + /** + * Sets the value of the size property. + * + */ + public void setSize(int value) { + this.size = value; + } + + /** + * Gets the value of the type property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getType() { + return type; + } + + /** + * Sets the value of the type property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setType(String value) { + this.type = value; + } + + /** + * Gets the value of the user property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getUser() { + return user; + } + + /** + * Sets the value of the user property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setUser(String value) { + this.user = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron.java new file mode 100644 index 000000000..8bfbb7629 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron.java @@ -0,0 +1,189 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for executeProcessCron complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessCron">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="processLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="cronExpression" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="start" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="end" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="processContext" type="{http://service.web.rapidanalytics.de/}processContextWrapper" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessCron", propOrder = { + "processLocation", + "cronExpression", + "start", + "end", + "processContext" +}) +public class ExecuteProcessCron { + + protected String processLocation; + protected String cronExpression; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar start; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar end; + protected ProcessContextWrapper processContext; + + /** + * Gets the value of the processLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessLocation() { + return processLocation; + } + + /** + * Sets the value of the processLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessLocation(String value) { + this.processLocation = value; + } + + /** + * Gets the value of the cronExpression property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCronExpression() { + return cronExpression; + } + + /** + * Sets the value of the cronExpression property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCronExpression(String value) { + this.cronExpression = value; + } + + /** + * Gets the value of the start property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getStart() { + return start; + } + + /** + * Sets the value of the start property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setStart(XMLGregorianCalendar value) { + this.start = value; + } + + /** + * Gets the value of the end property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getEnd() { + return end; + } + + /** + * Sets the value of the end property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setEnd(XMLGregorianCalendar value) { + this.end = value; + } + + /** + * Gets the value of the processContext property. + * + * @return + * possible object is + * {@link ProcessContextWrapper } + * + */ + public ProcessContextWrapper getProcessContext() { + return processContext; + } + + /** + * Sets the value of the processContext property. + * + * @param value + * allowed object is + * {@link ProcessContextWrapper } + * + */ + public void setProcessContext(ProcessContextWrapper value) { + this.processContext = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron13.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron13.java new file mode 100644 index 000000000..e0f6f4b52 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron13.java @@ -0,0 +1,216 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for executeProcessCron_1_3 complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessCron_1_3">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="processLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="cronExpression" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="start" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="end" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="processContext" type="{http://service.web.rapidanalytics.de/}processContextWrapper" minOccurs="0"/>
+ *         <element name="queueName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessCron_1_3", propOrder = { + "processLocation", + "cronExpression", + "start", + "end", + "processContext", + "queueName" +}) +public class ExecuteProcessCron13 { + + protected String processLocation; + protected String cronExpression; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar start; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar end; + protected ProcessContextWrapper processContext; + protected String queueName; + + /** + * Gets the value of the processLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessLocation() { + return processLocation; + } + + /** + * Sets the value of the processLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessLocation(String value) { + this.processLocation = value; + } + + /** + * Gets the value of the cronExpression property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getCronExpression() { + return cronExpression; + } + + /** + * Sets the value of the cronExpression property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setCronExpression(String value) { + this.cronExpression = value; + } + + /** + * Gets the value of the start property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getStart() { + return start; + } + + /** + * Sets the value of the start property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setStart(XMLGregorianCalendar value) { + this.start = value; + } + + /** + * Gets the value of the end property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getEnd() { + return end; + } + + /** + * Sets the value of the end property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setEnd(XMLGregorianCalendar value) { + this.end = value; + } + + /** + * Gets the value of the processContext property. + * + * @return + * possible object is + * {@link ProcessContextWrapper } + * + */ + public ProcessContextWrapper getProcessContext() { + return processContext; + } + + /** + * Sets the value of the processContext property. + * + * @param value + * allowed object is + * {@link ProcessContextWrapper } + * + */ + public void setProcessContext(ProcessContextWrapper value) { + this.processContext = value; + } + + /** + * Gets the value of the queueName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getQueueName() { + return queueName; + } + + /** + * Sets the value of the queueName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setQueueName(String value) { + this.queueName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron13Response.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron13Response.java new file mode 100644 index 000000000..023a6ccc3 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCron13Response.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for executeProcessCron_1_3Response complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessCron_1_3Response">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}executionResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessCron_1_3Response", propOrder = { + "_return" +}) +public class ExecuteProcessCron13Response { + + @XmlElement(name = "return") + protected ExecutionResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link ExecutionResponse } + * + */ + public ExecutionResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link ExecutionResponse } + * + */ + public void setReturn(ExecutionResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCronResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCronResponse.java new file mode 100644 index 000000000..d01531d40 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessCronResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for executeProcessCronResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessCronResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}executionResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessCronResponse", propOrder = { + "_return" +}) +public class ExecuteProcessCronResponse { + + @XmlElement(name = "return") + protected ExecutionResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link ExecutionResponse } + * + */ + public ExecutionResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link ExecutionResponse } + * + */ + public void setReturn(ExecutionResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple.java new file mode 100644 index 000000000..62da3c4a7 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple.java @@ -0,0 +1,134 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for executeProcessSimple complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessSimple">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="processLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="executionTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="processContext" type="{http://service.web.rapidanalytics.de/}processContextWrapper" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessSimple", propOrder = { + "processLocation", + "executionTime", + "processContext" +}) +public class ExecuteProcessSimple { + + protected String processLocation; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar executionTime; + protected ProcessContextWrapper processContext; + + /** + * Gets the value of the processLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessLocation() { + return processLocation; + } + + /** + * Sets the value of the processLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessLocation(String value) { + this.processLocation = value; + } + + /** + * Gets the value of the executionTime property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getExecutionTime() { + return executionTime; + } + + /** + * Sets the value of the executionTime property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setExecutionTime(XMLGregorianCalendar value) { + this.executionTime = value; + } + + /** + * Gets the value of the processContext property. + * + * @return + * possible object is + * {@link ProcessContextWrapper } + * + */ + public ProcessContextWrapper getProcessContext() { + return processContext; + } + + /** + * Sets the value of the processContext property. + * + * @param value + * allowed object is + * {@link ProcessContextWrapper } + * + */ + public void setProcessContext(ProcessContextWrapper value) { + this.processContext = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple13.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple13.java new file mode 100644 index 000000000..87aac64da --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple13.java @@ -0,0 +1,161 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for executeProcessSimple_1_3 complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessSimple_1_3">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="processLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="executionTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="processContext" type="{http://service.web.rapidanalytics.de/}processContextWrapper" minOccurs="0"/>
+ *         <element name="queueName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessSimple_1_3", propOrder = { + "processLocation", + "executionTime", + "processContext", + "queueName" +}) +public class ExecuteProcessSimple13 { + + protected String processLocation; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar executionTime; + protected ProcessContextWrapper processContext; + protected String queueName; + + /** + * Gets the value of the processLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessLocation() { + return processLocation; + } + + /** + * Sets the value of the processLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessLocation(String value) { + this.processLocation = value; + } + + /** + * Gets the value of the executionTime property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getExecutionTime() { + return executionTime; + } + + /** + * Sets the value of the executionTime property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setExecutionTime(XMLGregorianCalendar value) { + this.executionTime = value; + } + + /** + * Gets the value of the processContext property. + * + * @return + * possible object is + * {@link ProcessContextWrapper } + * + */ + public ProcessContextWrapper getProcessContext() { + return processContext; + } + + /** + * Sets the value of the processContext property. + * + * @param value + * allowed object is + * {@link ProcessContextWrapper } + * + */ + public void setProcessContext(ProcessContextWrapper value) { + this.processContext = value; + } + + /** + * Gets the value of the queueName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getQueueName() { + return queueName; + } + + /** + * Sets the value of the queueName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setQueueName(String value) { + this.queueName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple13Response.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple13Response.java new file mode 100644 index 000000000..895e416c0 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimple13Response.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for executeProcessSimple_1_3Response complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessSimple_1_3Response">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}executionResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessSimple_1_3Response", propOrder = { + "_return" +}) +public class ExecuteProcessSimple13Response { + + @XmlElement(name = "return") + protected ExecutionResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link ExecutionResponse } + * + */ + public ExecutionResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link ExecutionResponse } + * + */ + public void setReturn(ExecutionResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimpleResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimpleResponse.java new file mode 100644 index 000000000..e9cd867c2 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessSimpleResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for executeProcessSimpleResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessSimpleResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}executionResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessSimpleResponse", propOrder = { + "_return" +}) +public class ExecuteProcessSimpleResponse { + + @XmlElement(name = "return") + protected ExecutionResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link ExecutionResponse } + * + */ + public ExecutionResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link ExecutionResponse } + * + */ + public void setReturn(ExecutionResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessWithOffset.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessWithOffset.java new file mode 100644 index 000000000..075762a2a --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessWithOffset.java @@ -0,0 +1,158 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for executeProcessWithOffset complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessWithOffset">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="processLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="executionTime" type="{http://www.w3.org/2001/XMLSchema}long" minOccurs="0"/>
+ *         <element name="processContext" type="{http://service.web.rapidanalytics.de/}processContextWrapper" minOccurs="0"/>
+ *         <element name="queueName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessWithOffset", propOrder = { + "processLocation", + "executionTime", + "processContext", + "queueName" +}) +public class ExecuteProcessWithOffset { + + protected String processLocation; + protected Long executionTime; + protected ProcessContextWrapper processContext; + protected String queueName; + + /** + * Gets the value of the processLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessLocation() { + return processLocation; + } + + /** + * Sets the value of the processLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessLocation(String value) { + this.processLocation = value; + } + + /** + * Gets the value of the executionTime property. + * + * @return + * possible object is + * {@link Long } + * + */ + public Long getExecutionTime() { + return executionTime; + } + + /** + * Sets the value of the executionTime property. + * + * @param value + * allowed object is + * {@link Long } + * + */ + public void setExecutionTime(Long value) { + this.executionTime = value; + } + + /** + * Gets the value of the processContext property. + * + * @return + * possible object is + * {@link ProcessContextWrapper } + * + */ + public ProcessContextWrapper getProcessContext() { + return processContext; + } + + /** + * Sets the value of the processContext property. + * + * @param value + * allowed object is + * {@link ProcessContextWrapper } + * + */ + public void setProcessContext(ProcessContextWrapper value) { + this.processContext = value; + } + + /** + * Gets the value of the queueName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getQueueName() { + return queueName; + } + + /** + * Sets the value of the queueName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setQueueName(String value) { + this.queueName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessWithOffsetResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessWithOffsetResponse.java new file mode 100644 index 000000000..32ca89b0a --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecuteProcessWithOffsetResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for executeProcessWithOffsetResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executeProcessWithOffsetResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}executionResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executeProcessWithOffsetResponse", propOrder = { + "_return" +}) +public class ExecuteProcessWithOffsetResponse { + + @XmlElement(name = "return") + protected ExecutionResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link ExecutionResponse } + * + */ + public ExecutionResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link ExecutionResponse } + * + */ + public void setReturn(ExecutionResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ExecutionResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/ExecutionResponse.java new file mode 100644 index 000000000..341d0092b --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ExecutionResponse.java @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for executionResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="executionResponse">
+ *   <complexContent>
+ *     <extension base="{http://service.web.rapidanalytics.de/}response">
+ *       <sequence>
+ *         <element name="firstExecution" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="jobId" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </extension>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "executionResponse", propOrder = { + "firstExecution", + "jobId" +}) +public class ExecutionResponse + extends Response +{ + + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar firstExecution; + protected int jobId; + + /** + * Gets the value of the firstExecution property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getFirstExecution() { + return firstExecution; + } + + /** + * Sets the value of the firstExecution property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setFirstExecution(XMLGregorianCalendar value) { + this.firstExecution = value; + } + + /** + * Gets the value of the jobId property. + * + */ + public int getJobId() { + return jobId; + } + + /** + * Sets the value of the jobId property. + * + */ + public void setJobId(int value) { + this.jobId = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/FolderContentsResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/FolderContentsResponse.java new file mode 100644 index 000000000..37bd2ca1f --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/FolderContentsResponse.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for folderContentsResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="folderContentsResponse">
+ *   <complexContent>
+ *     <extension base="{http://service.web.rapidanalytics.de/}response">
+ *       <sequence>
+ *         <element name="entries" type="{http://service.web.rapidanalytics.de/}entryResponse" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element name="location" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </extension>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "folderContentsResponse", propOrder = { + "entries", + "location" +}) +public class FolderContentsResponse + extends Response +{ + + @XmlElement(nillable = true) + protected List entries; + protected String location; + + /** + * Gets the value of the entries property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the entries property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getEntries().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link EntryResponse } + * + * + */ + public List getEntries() { + if (entries == null) { + entries = new ArrayList(); + } + return this.entries; + } + + /** + * Gets the value of the location property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLocation() { + return location; + } + + /** + * Sets the value of the location property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLocation(String value) { + this.location = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetAccessRights.java b/src/generated/java/com/rapid_i/repository/wsimport/GetAccessRights.java new file mode 100644 index 000000000..9c1c1cb7c --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetAccessRights.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getAccessRights complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getAccessRights">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="entryLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getAccessRights", propOrder = { + "entryLocation" +}) +public class GetAccessRights { + + protected String entryLocation; + + /** + * Gets the value of the entryLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEntryLocation() { + return entryLocation; + } + + /** + * Sets the value of the entryLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEntryLocation(String value) { + this.entryLocation = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetAccessRightsResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetAccessRightsResponse.java new file mode 100644 index 000000000..9b1d593e3 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetAccessRightsResponse.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getAccessRightsResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getAccessRightsResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}accessRights" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getAccessRightsResponse", propOrder = { + "_return" +}) +public class GetAccessRightsResponse { + + @XmlElement(name = "return") + protected List _return; + + /** + * Gets the value of the return property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the return property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReturn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AccessRights } + * + * + */ + public List getReturn() { + if (_return == null) { + _return = new ArrayList(); + } + return this._return; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetAllGroupNames.java b/src/generated/java/com/rapid_i/repository/wsimport/GetAllGroupNames.java new file mode 100644 index 000000000..fb9194af8 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetAllGroupNames.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getAllGroupNames complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getAllGroupNames">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getAllGroupNames") +public class GetAllGroupNames { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetAllGroupNamesResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetAllGroupNamesResponse.java new file mode 100644 index 000000000..b20747d7f --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetAllGroupNamesResponse.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getAllGroupNamesResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getAllGroupNamesResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getAllGroupNamesResponse", propOrder = { + "_return" +}) +public class GetAllGroupNamesResponse { + + @XmlElement(name = "return") + protected List _return; + + /** + * Gets the value of the return property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the return property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReturn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getReturn() { + if (_return == null) { + _return = new ArrayList(); + } + return this._return; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetEntry.java b/src/generated/java/com/rapid_i/repository/wsimport/GetEntry.java new file mode 100644 index 000000000..35d81c40c --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetEntry.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getEntry complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getEntry">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="entryLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getEntry", propOrder = { + "entryLocation" +}) +public class GetEntry { + + protected String entryLocation; + + /** + * Gets the value of the entryLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEntryLocation() { + return entryLocation; + } + + /** + * Sets the value of the entryLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEntryLocation(String value) { + this.entryLocation = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetEntryResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetEntryResponse.java new file mode 100644 index 000000000..7c6919ae0 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetEntryResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getEntryResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getEntryResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}entryResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getEntryResponse", propOrder = { + "_return" +}) +public class GetEntryResponse { + + @XmlElement(name = "return") + protected EntryResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link EntryResponse } + * + */ + public EntryResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link EntryResponse } + * + */ + public void setReturn(EntryResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetFolderContents.java b/src/generated/java/com/rapid_i/repository/wsimport/GetFolderContents.java new file mode 100644 index 000000000..6a4ddb88a --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetFolderContents.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getFolderContents complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getFolderContents">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="folderLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getFolderContents", propOrder = { + "folderLocation" +}) +public class GetFolderContents { + + protected String folderLocation; + + /** + * Gets the value of the folderLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getFolderLocation() { + return folderLocation; + } + + /** + * Sets the value of the folderLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setFolderLocation(String value) { + this.folderLocation = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetFolderContentsResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetFolderContentsResponse.java new file mode 100644 index 000000000..63328046b --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetFolderContentsResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getFolderContentsResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getFolderContentsResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}folderContentsResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getFolderContentsResponse", propOrder = { + "_return" +}) +public class GetFolderContentsResponse { + + @XmlElement(name = "return") + protected FolderContentsResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link FolderContentsResponse } + * + */ + public FolderContentsResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link FolderContentsResponse } + * + */ + public void setReturn(FolderContentsResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetFreeMemory.java b/src/generated/java/com/rapid_i/repository/wsimport/GetFreeMemory.java new file mode 100644 index 000000000..c58ea1f98 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetFreeMemory.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getFreeMemory complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getFreeMemory">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getFreeMemory") +public class GetFreeMemory { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetFreeMemoryResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetFreeMemoryResponse.java new file mode 100644 index 000000000..42c729cba --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetFreeMemoryResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getFreeMemoryResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getFreeMemoryResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getFreeMemoryResponse", propOrder = { + "_return" +}) +public class GetFreeMemoryResponse { + + @XmlElement(name = "return") + protected String _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setReturn(String value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetInstalledPlugins.java b/src/generated/java/com/rapid_i/repository/wsimport/GetInstalledPlugins.java new file mode 100644 index 000000000..84f9762a1 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetInstalledPlugins.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getInstalledPlugins complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getInstalledPlugins">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getInstalledPlugins") +public class GetInstalledPlugins { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetInstalledPluginsResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetInstalledPluginsResponse.java new file mode 100644 index 000000000..bf8fa6cb3 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetInstalledPluginsResponse.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getInstalledPluginsResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getInstalledPluginsResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}pluginInfo" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getInstalledPluginsResponse", propOrder = { + "_return" +}) +public class GetInstalledPluginsResponse { + + @XmlElement(name = "return") + protected List _return; + + /** + * Gets the value of the return property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the return property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReturn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link PluginInfo } + * + * + */ + public List getReturn() { + if (_return == null) { + _return = new ArrayList(); + } + return this._return; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetMaxMemory.java b/src/generated/java/com/rapid_i/repository/wsimport/GetMaxMemory.java new file mode 100644 index 000000000..fe30e3271 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetMaxMemory.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getMaxMemory complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getMaxMemory">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getMaxMemory") +public class GetMaxMemory { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetMaxMemoryResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetMaxMemoryResponse.java new file mode 100644 index 000000000..cb1c13ea0 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetMaxMemoryResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getMaxMemoryResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getMaxMemoryResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getMaxMemoryResponse", propOrder = { + "_return" +}) +public class GetMaxMemoryResponse { + + @XmlElement(name = "return") + protected String _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setReturn(String value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetProcessContents.java b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessContents.java new file mode 100644 index 000000000..dcf4a2465 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessContents.java @@ -0,0 +1,96 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getProcessContents complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getProcessContents">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="entryLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="revisionNumber" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getProcessContents", propOrder = { + "entryLocation", + "revisionNumber" +}) +public class GetProcessContents { + + protected String entryLocation; + protected int revisionNumber; + + /** + * Gets the value of the entryLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEntryLocation() { + return entryLocation; + } + + /** + * Sets the value of the entryLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEntryLocation(String value) { + this.entryLocation = value; + } + + /** + * Gets the value of the revisionNumber property. + * + */ + public int getRevisionNumber() { + return revisionNumber; + } + + /** + * Sets the value of the revisionNumber property. + * + */ + public void setRevisionNumber(int value) { + this.revisionNumber = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetProcessContentsResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessContentsResponse.java new file mode 100644 index 000000000..ce7750576 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessContentsResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getProcessContentsResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getProcessContentsResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}processContentsResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getProcessContentsResponse", propOrder = { + "_return" +}) +public class GetProcessContentsResponse { + + @XmlElement(name = "return") + protected ProcessContentsResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link ProcessContentsResponse } + * + */ + public ProcessContentsResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link ProcessContentsResponse } + * + */ + public void setReturn(ProcessContentsResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetProcessIdsForJobId.java b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessIdsForJobId.java new file mode 100644 index 000000000..6a23428de --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessIdsForJobId.java @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getProcessIdsForJobId complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getProcessIdsForJobId">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="jobId" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getProcessIdsForJobId", propOrder = { + "jobId" +}) +public class GetProcessIdsForJobId { + + protected int jobId; + + /** + * Gets the value of the jobId property. + * + */ + public int getJobId() { + return jobId; + } + + /** + * Sets the value of the jobId property. + * + */ + public void setJobId(int value) { + this.jobId = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetProcessIdsForJobIdResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessIdsForJobIdResponse.java new file mode 100644 index 000000000..1509f298d --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetProcessIdsForJobIdResponse.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getProcessIdsForJobIdResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getProcessIdsForJobIdResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getProcessIdsForJobIdResponse", propOrder = { + "_return" +}) +public class GetProcessIdsForJobIdResponse { + + @XmlElement(name = "return", type = Integer.class) + protected List _return; + + /** + * Gets the value of the return property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the return property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReturn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Integer } + * + * + */ + public List getReturn() { + if (_return == null) { + _return = new ArrayList(); + } + return this._return; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetQueueInfo.java b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueInfo.java new file mode 100644 index 000000000..1c756d69d --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueInfo.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getQueueInfo complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getQueueInfo">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="queueName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getQueueInfo", propOrder = { + "queueName" +}) +public class GetQueueInfo { + + protected String queueName; + + /** + * Gets the value of the queueName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getQueueName() { + return queueName; + } + + /** + * Sets the value of the queueName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setQueueName(String value) { + this.queueName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetQueueInfoResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueInfoResponse.java new file mode 100644 index 000000000..1b98d2e06 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueInfoResponse.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getQueueInfoResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getQueueInfoResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}queueProperty" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getQueueInfoResponse", propOrder = { + "_return" +}) +public class GetQueueInfoResponse { + + @XmlElement(name = "return") + protected List _return; + + /** + * Gets the value of the return property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the return property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReturn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link QueueProperty } + * + * + */ + public List getReturn() { + if (_return == null) { + _return = new ArrayList(); + } + return this._return; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetQueueNames.java b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueNames.java new file mode 100644 index 000000000..e9fa7db3f --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueNames.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getQueueNames complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getQueueNames">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getQueueNames") +public class GetQueueNames { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetQueueNamesResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueNamesResponse.java new file mode 100644 index 000000000..19a51bf39 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueNamesResponse.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getQueueNamesResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getQueueNamesResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getQueueNamesResponse", propOrder = { + "_return" +}) +public class GetQueueNamesResponse { + + @XmlElement(name = "return") + protected List _return; + + /** + * Gets the value of the return property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the return property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReturn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getReturn() { + if (_return == null) { + _return = new ArrayList(); + } + return this._return; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetQueueState.java b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueState.java new file mode 100644 index 000000000..1a326caca --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueState.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getQueueState complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getQueueState">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="queueName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getQueueState", propOrder = { + "queueName" +}) +public class GetQueueState { + + protected String queueName; + + /** + * Gets the value of the queueName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getQueueName() { + return queueName; + } + + /** + * Sets the value of the queueName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setQueueName(String value) { + this.queueName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetQueueStateResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueStateResponse.java new file mode 100644 index 000000000..d62dc5631 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetQueueStateResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getQueueStateResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getQueueStateResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}queueState" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getQueueStateResponse", propOrder = { + "_return" +}) +public class GetQueueStateResponse { + + @XmlElement(name = "return") + protected QueueState _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link QueueState } + * + */ + public QueueState getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link QueueState } + * + */ + public void setReturn(QueueState value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcesses.java b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcesses.java new file mode 100644 index 000000000..4be38e5a7 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcesses.java @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for getRunningProcesses complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getRunningProcesses">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="since" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getRunningProcesses", propOrder = { + "since" +}) +public class GetRunningProcesses { + + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar since; + + /** + * Gets the value of the since property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getSince() { + return since; + } + + /** + * Sets the value of the since property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setSince(XMLGregorianCalendar value) { + this.since = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesInfo.java b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesInfo.java new file mode 100644 index 000000000..9a2c0b8fc --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesInfo.java @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getRunningProcessesInfo complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getRunningProcessesInfo">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="scheduledProcessId" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getRunningProcessesInfo", propOrder = { + "scheduledProcessId" +}) +public class GetRunningProcessesInfo { + + protected int scheduledProcessId; + + /** + * Gets the value of the scheduledProcessId property. + * + */ + public int getScheduledProcessId() { + return scheduledProcessId; + } + + /** + * Sets the value of the scheduledProcessId property. + * + */ + public void setScheduledProcessId(int value) { + this.scheduledProcessId = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesInfoResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesInfoResponse.java new file mode 100644 index 000000000..fc9e1a331 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesInfoResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getRunningProcessesInfoResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getRunningProcessesInfoResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}processResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getRunningProcessesInfoResponse", propOrder = { + "_return" +}) +public class GetRunningProcessesInfoResponse { + + @XmlElement(name = "return") + protected ProcessResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link ProcessResponse } + * + */ + public ProcessResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link ProcessResponse } + * + */ + public void setReturn(ProcessResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesResponse.java new file mode 100644 index 000000000..8af1abfd2 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetRunningProcessesResponse.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getRunningProcessesResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getRunningProcessesResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}int" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getRunningProcessesResponse", propOrder = { + "_return" +}) +public class GetRunningProcessesResponse { + + @XmlElement(name = "return", type = Integer.class) + protected List _return; + + /** + * Gets the value of the return property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the return property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getReturn().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link Integer } + * + * + */ + public List getReturn() { + if (_return == null) { + _return = new ArrayList(); + } + return this._return; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetSystemLoadAverage.java b/src/generated/java/com/rapid_i/repository/wsimport/GetSystemLoadAverage.java new file mode 100644 index 000000000..5cd57a328 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetSystemLoadAverage.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getSystemLoadAverage complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getSystemLoadAverage">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getSystemLoadAverage") +public class GetSystemLoadAverage { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetSystemLoadAverageResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetSystemLoadAverageResponse.java new file mode 100644 index 000000000..135d52b51 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetSystemLoadAverageResponse.java @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getSystemLoadAverageResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getSystemLoadAverageResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}double"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getSystemLoadAverageResponse", propOrder = { + "_return" +}) +public class GetSystemLoadAverageResponse { + + @XmlElement(name = "return") + protected double _return; + + /** + * Gets the value of the return property. + * + */ + public double getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + */ + public void setReturn(double value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetTotalMemory.java b/src/generated/java/com/rapid_i/repository/wsimport/GetTotalMemory.java new file mode 100644 index 000000000..96c5f20cc --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetTotalMemory.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getTotalMemory complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getTotalMemory">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getTotalMemory") +public class GetTotalMemory { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetTotalMemoryResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetTotalMemoryResponse.java new file mode 100644 index 000000000..70f9a0d49 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetTotalMemoryResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getTotalMemoryResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getTotalMemoryResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getTotalMemoryResponse", propOrder = { + "_return" +}) +public class GetTotalMemoryResponse { + + @XmlElement(name = "return") + protected String _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setReturn(String value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetUpSince.java b/src/generated/java/com/rapid_i/repository/wsimport/GetUpSince.java new file mode 100644 index 000000000..9107feb56 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetUpSince.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getUpSince complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getUpSince">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getUpSince") +public class GetUpSince { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetUpSinceResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetUpSinceResponse.java new file mode 100644 index 000000000..a1d30ca29 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetUpSinceResponse.java @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for getUpSinceResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getUpSinceResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getUpSinceResponse", propOrder = { + "_return" +}) +public class GetUpSinceResponse { + + @XmlElement(name = "return") + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setReturn(XMLGregorianCalendar value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetVersionNumber.java b/src/generated/java/com/rapid_i/repository/wsimport/GetVersionNumber.java new file mode 100644 index 000000000..a473933da --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetVersionNumber.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getVersionNumber complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getVersionNumber">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getVersionNumber") +public class GetVersionNumber { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/GetVersionNumberResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/GetVersionNumberResponse.java new file mode 100644 index 000000000..3b72afba0 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/GetVersionNumberResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getVersionNumberResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getVersionNumberResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getVersionNumberResponse", propOrder = { + "_return" +}) +public class GetVersionNumberResponse { + + @XmlElement(name = "return") + protected String _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setReturn(String value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/MacroDefinition.java b/src/generated/java/com/rapid_i/repository/wsimport/MacroDefinition.java new file mode 100644 index 000000000..bf365b2bf --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/MacroDefinition.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for macroDefinition complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="macroDefinition">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="key" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="value" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "macroDefinition", propOrder = { + "key", + "value" +}) +public class MacroDefinition { + + protected String key; + protected String value; + + /** + * Gets the value of the key property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getKey() { + return key; + } + + /** + * Sets the value of the key property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setKey(String value) { + this.key = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/MakeFolder.java b/src/generated/java/com/rapid_i/repository/wsimport/MakeFolder.java new file mode 100644 index 000000000..7653b0b70 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/MakeFolder.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for makeFolder complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="makeFolder">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="parentLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="subfolderName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "makeFolder", propOrder = { + "parentLocation", + "subfolderName" +}) +public class MakeFolder { + + protected String parentLocation; + protected String subfolderName; + + /** + * Gets the value of the parentLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getParentLocation() { + return parentLocation; + } + + /** + * Sets the value of the parentLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setParentLocation(String value) { + this.parentLocation = value; + } + + /** + * Gets the value of the subfolderName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSubfolderName() { + return subfolderName; + } + + /** + * Sets the value of the subfolderName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSubfolderName(String value) { + this.subfolderName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/MakeFolderResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/MakeFolderResponse.java new file mode 100644 index 000000000..588654f91 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/MakeFolderResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for makeFolderResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="makeFolderResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}entryResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "makeFolderResponse", propOrder = { + "_return" +}) +public class MakeFolderResponse { + + @XmlElement(name = "return") + protected EntryResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link EntryResponse } + * + */ + public EntryResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link EntryResponse } + * + */ + public void setReturn(EntryResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/Move.java b/src/generated/java/com/rapid_i/repository/wsimport/Move.java new file mode 100644 index 000000000..761210503 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/Move.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for move complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="move">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="location" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="newParentFolder" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "move", propOrder = { + "location", + "newParentFolder" +}) +public class Move { + + protected String location; + protected String newParentFolder; + + /** + * Gets the value of the location property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLocation() { + return location; + } + + /** + * Sets the value of the location property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLocation(String value) { + this.location = value; + } + + /** + * Gets the value of the newParentFolder property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNewParentFolder() { + return newParentFolder; + } + + /** + * Sets the value of the newParentFolder property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNewParentFolder(String value) { + this.newParentFolder = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/MoveResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/MoveResponse.java new file mode 100644 index 000000000..ed46e75b9 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/MoveResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for moveResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="moveResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}entryResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "moveResponse", propOrder = { + "_return" +}) +public class MoveResponse { + + @XmlElement(name = "return") + protected EntryResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link EntryResponse } + * + */ + public EntryResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link EntryResponse } + * + */ + public void setReturn(EntryResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ObjectFactory.java b/src/generated/java/com/rapid_i/repository/wsimport/ObjectFactory.java new file mode 100644 index 000000000..228b2ba48 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ObjectFactory.java @@ -0,0 +1,560 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.rapid_i.repository.wsimport package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _GetProcessContents_QNAME = new QName("http://service.web.rapidanalytics.de/", "getProcessContents"); + private final static QName _GetAccessRightsResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "getAccessRightsResponse"); + private final static QName _GetEntry_QNAME = new QName("http://service.web.rapidanalytics.de/", "getEntry"); + private final static QName _DeleteEntry_QNAME = new QName("http://service.web.rapidanalytics.de/", "deleteEntry"); + private final static QName _StoreProcess_QNAME = new QName("http://service.web.rapidanalytics.de/", "storeProcess"); + private final static QName _StartNewRevisionResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "startNewRevisionResponse"); + private final static QName _RenameResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "renameResponse"); + private final static QName _GetAccessRights_QNAME = new QName("http://service.web.rapidanalytics.de/", "getAccessRights"); + private final static QName _MakeFolderResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "makeFolderResponse"); + private final static QName _MakeFolder_QNAME = new QName("http://service.web.rapidanalytics.de/", "makeFolder"); + private final static QName _Move_QNAME = new QName("http://service.web.rapidanalytics.de/", "move"); + private final static QName _GetFolderContentsResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "getFolderContentsResponse"); + private final static QName _DeleteEntryResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "deleteEntryResponse"); + private final static QName _Rename_QNAME = new QName("http://service.web.rapidanalytics.de/", "rename"); + private final static QName _SetAccessRightsResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "setAccessRightsResponse"); + private final static QName _GetProcessContentsResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "getProcessContentsResponse"); + private final static QName _GetFolderContents_QNAME = new QName("http://service.web.rapidanalytics.de/", "getFolderContents"); + private final static QName _GetEntryResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "getEntryResponse"); + private final static QName _StoreProcessResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "storeProcessResponse"); + private final static QName _GetAllGroupNames_QNAME = new QName("http://service.web.rapidanalytics.de/", "getAllGroupNames"); + private final static QName _CreateBlobResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "createBlobResponse"); + private final static QName _MoveResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "moveResponse"); + private final static QName _CreateBlob_QNAME = new QName("http://service.web.rapidanalytics.de/", "createBlob"); + private final static QName _StartNewRevision_QNAME = new QName("http://service.web.rapidanalytics.de/", "startNewRevision"); + private final static QName _SetAccessRights_QNAME = new QName("http://service.web.rapidanalytics.de/", "setAccessRights"); + private final static QName _GetAllGroupNamesResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "getAllGroupNamesResponse"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.rapid_i.repository.wsimport + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link GetFolderContentsResponse } + * + */ + public GetFolderContentsResponse createGetFolderContentsResponse() { + return new GetFolderContentsResponse(); + } + + /** + * Create an instance of {@link DeleteEntryResponse } + * + */ + public DeleteEntryResponse createDeleteEntryResponse() { + return new DeleteEntryResponse(); + } + + /** + * Create an instance of {@link Rename } + * + */ + public Rename createRename() { + return new Rename(); + } + + /** + * Create an instance of {@link GetFolderContents } + * + */ + public GetFolderContents createGetFolderContents() { + return new GetFolderContents(); + } + + /** + * Create an instance of {@link GetProcessContentsResponse } + * + */ + public GetProcessContentsResponse createGetProcessContentsResponse() { + return new GetProcessContentsResponse(); + } + + /** + * Create an instance of {@link SetAccessRightsResponse } + * + */ + public SetAccessRightsResponse createSetAccessRightsResponse() { + return new SetAccessRightsResponse(); + } + + /** + * Create an instance of {@link StoreProcessResponse } + * + */ + public StoreProcessResponse createStoreProcessResponse() { + return new StoreProcessResponse(); + } + + /** + * Create an instance of {@link GetEntryResponse } + * + */ + public GetEntryResponse createGetEntryResponse() { + return new GetEntryResponse(); + } + + /** + * Create an instance of {@link GetEntry } + * + */ + public GetEntry createGetEntry() { + return new GetEntry(); + } + + /** + * Create an instance of {@link GetAccessRightsResponse } + * + */ + public GetAccessRightsResponse createGetAccessRightsResponse() { + return new GetAccessRightsResponse(); + } + + /** + * Create an instance of {@link GetProcessContents } + * + */ + public GetProcessContents createGetProcessContents() { + return new GetProcessContents(); + } + + /** + * Create an instance of {@link DeleteEntry } + * + */ + public DeleteEntry createDeleteEntry() { + return new DeleteEntry(); + } + + /** + * Create an instance of {@link StoreProcess } + * + */ + public StoreProcess createStoreProcess() { + return new StoreProcess(); + } + + /** + * Create an instance of {@link StartNewRevisionResponse } + * + */ + public StartNewRevisionResponse createStartNewRevisionResponse() { + return new StartNewRevisionResponse(); + } + + /** + * Create an instance of {@link RenameResponse } + * + */ + public RenameResponse createRenameResponse() { + return new RenameResponse(); + } + + /** + * Create an instance of {@link GetAccessRights } + * + */ + public GetAccessRights createGetAccessRights() { + return new GetAccessRights(); + } + + /** + * Create an instance of {@link MakeFolderResponse } + * + */ + public MakeFolderResponse createMakeFolderResponse() { + return new MakeFolderResponse(); + } + + /** + * Create an instance of {@link MakeFolder } + * + */ + public MakeFolder createMakeFolder() { + return new MakeFolder(); + } + + /** + * Create an instance of {@link Move } + * + */ + public Move createMove() { + return new Move(); + } + + /** + * Create an instance of {@link StartNewRevision } + * + */ + public StartNewRevision createStartNewRevision() { + return new StartNewRevision(); + } + + /** + * Create an instance of {@link SetAccessRights } + * + */ + public SetAccessRights createSetAccessRights() { + return new SetAccessRights(); + } + + /** + * Create an instance of {@link GetAllGroupNamesResponse } + * + */ + public GetAllGroupNamesResponse createGetAllGroupNamesResponse() { + return new GetAllGroupNamesResponse(); + } + + /** + * Create an instance of {@link GetAllGroupNames } + * + */ + public GetAllGroupNames createGetAllGroupNames() { + return new GetAllGroupNames(); + } + + /** + * Create an instance of {@link CreateBlobResponse } + * + */ + public CreateBlobResponse createCreateBlobResponse() { + return new CreateBlobResponse(); + } + + /** + * Create an instance of {@link MoveResponse } + * + */ + public MoveResponse createMoveResponse() { + return new MoveResponse(); + } + + /** + * Create an instance of {@link CreateBlob } + * + */ + public CreateBlob createCreateBlob() { + return new CreateBlob(); + } + + /** + * Create an instance of {@link EntryResponse } + * + */ + public EntryResponse createEntryResponse() { + return new EntryResponse(); + } + + /** + * Create an instance of {@link Response } + * + */ + public Response createResponse() { + return new Response(); + } + + /** + * Create an instance of {@link ProcessContentsResponse } + * + */ + public ProcessContentsResponse createProcessContentsResponse() { + return new ProcessContentsResponse(); + } + + /** + * Create an instance of {@link AccessRights } + * + */ + public AccessRights createAccessRights() { + return new AccessRights(); + } + + /** + * Create an instance of {@link FolderContentsResponse } + * + */ + public FolderContentsResponse createFolderContentsResponse() { + return new FolderContentsResponse(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetProcessContents }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getProcessContents") + public JAXBElement createGetProcessContents(GetProcessContents value) { + return new JAXBElement(_GetProcessContents_QNAME, GetProcessContents.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetAccessRightsResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getAccessRightsResponse") + public JAXBElement createGetAccessRightsResponse(GetAccessRightsResponse value) { + return new JAXBElement(_GetAccessRightsResponse_QNAME, GetAccessRightsResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetEntry }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getEntry") + public JAXBElement createGetEntry(GetEntry value) { + return new JAXBElement(_GetEntry_QNAME, GetEntry.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link DeleteEntry }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "deleteEntry") + public JAXBElement createDeleteEntry(DeleteEntry value) { + return new JAXBElement(_DeleteEntry_QNAME, DeleteEntry.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link StoreProcess }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "storeProcess") + public JAXBElement createStoreProcess(StoreProcess value) { + return new JAXBElement(_StoreProcess_QNAME, StoreProcess.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link StartNewRevisionResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "startNewRevisionResponse") + public JAXBElement createStartNewRevisionResponse(StartNewRevisionResponse value) { + return new JAXBElement(_StartNewRevisionResponse_QNAME, StartNewRevisionResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link RenameResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "renameResponse") + public JAXBElement createRenameResponse(RenameResponse value) { + return new JAXBElement(_RenameResponse_QNAME, RenameResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetAccessRights }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getAccessRights") + public JAXBElement createGetAccessRights(GetAccessRights value) { + return new JAXBElement(_GetAccessRights_QNAME, GetAccessRights.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link MakeFolderResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "makeFolderResponse") + public JAXBElement createMakeFolderResponse(MakeFolderResponse value) { + return new JAXBElement(_MakeFolderResponse_QNAME, MakeFolderResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link MakeFolder }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "makeFolder") + public JAXBElement createMakeFolder(MakeFolder value) { + return new JAXBElement(_MakeFolder_QNAME, MakeFolder.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Move }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "move") + public JAXBElement createMove(Move value) { + return new JAXBElement(_Move_QNAME, Move.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetFolderContentsResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getFolderContentsResponse") + public JAXBElement createGetFolderContentsResponse(GetFolderContentsResponse value) { + return new JAXBElement(_GetFolderContentsResponse_QNAME, GetFolderContentsResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link DeleteEntryResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "deleteEntryResponse") + public JAXBElement createDeleteEntryResponse(DeleteEntryResponse value) { + return new JAXBElement(_DeleteEntryResponse_QNAME, DeleteEntryResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link Rename }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "rename") + public JAXBElement createRename(Rename value) { + return new JAXBElement(_Rename_QNAME, Rename.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link SetAccessRightsResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "setAccessRightsResponse") + public JAXBElement createSetAccessRightsResponse(SetAccessRightsResponse value) { + return new JAXBElement(_SetAccessRightsResponse_QNAME, SetAccessRightsResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetProcessContentsResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getProcessContentsResponse") + public JAXBElement createGetProcessContentsResponse(GetProcessContentsResponse value) { + return new JAXBElement(_GetProcessContentsResponse_QNAME, GetProcessContentsResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetFolderContents }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getFolderContents") + public JAXBElement createGetFolderContents(GetFolderContents value) { + return new JAXBElement(_GetFolderContents_QNAME, GetFolderContents.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetEntryResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getEntryResponse") + public JAXBElement createGetEntryResponse(GetEntryResponse value) { + return new JAXBElement(_GetEntryResponse_QNAME, GetEntryResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link StoreProcessResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "storeProcessResponse") + public JAXBElement createStoreProcessResponse(StoreProcessResponse value) { + return new JAXBElement(_StoreProcessResponse_QNAME, StoreProcessResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetAllGroupNames }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getAllGroupNames") + public JAXBElement createGetAllGroupNames(GetAllGroupNames value) { + return new JAXBElement(_GetAllGroupNames_QNAME, GetAllGroupNames.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CreateBlobResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "createBlobResponse") + public JAXBElement createCreateBlobResponse(CreateBlobResponse value) { + return new JAXBElement(_CreateBlobResponse_QNAME, CreateBlobResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link MoveResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "moveResponse") + public JAXBElement createMoveResponse(MoveResponse value) { + return new JAXBElement(_MoveResponse_QNAME, MoveResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CreateBlob }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "createBlob") + public JAXBElement createCreateBlob(CreateBlob value) { + return new JAXBElement(_CreateBlob_QNAME, CreateBlob.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link StartNewRevision }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "startNewRevision") + public JAXBElement createStartNewRevision(StartNewRevision value) { + return new JAXBElement(_StartNewRevision_QNAME, StartNewRevision.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link SetAccessRights }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "setAccessRights") + public JAXBElement createSetAccessRights(SetAccessRights value) { + return new JAXBElement(_SetAccessRights_QNAME, SetAccessRights.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetAllGroupNamesResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getAllGroupNamesResponse") + public JAXBElement createGetAllGroupNamesResponse(GetAllGroupNamesResponse value) { + return new JAXBElement(_GetAllGroupNamesResponse_QNAME, GetAllGroupNamesResponse.class, null, value); + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/PluginInfo.java b/src/generated/java/com/rapid_i/repository/wsimport/PluginInfo.java new file mode 100644 index 000000000..e9f112ab8 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/PluginInfo.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for pluginInfo complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="pluginInfo">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="version" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "pluginInfo", propOrder = { + "name", + "version" +}) +public class PluginInfo { + + protected String name; + protected String version; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the version property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getVersion() { + return version; + } + + /** + * Sets the value of the version property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setVersion(String value) { + this.version = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessContentsResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessContentsResponse.java new file mode 100644 index 000000000..97ad5c763 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessContentsResponse.java @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for processContentsResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="processContentsResponse">
+ *   <complexContent>
+ *     <extension base="{http://service.web.rapidanalytics.de/}response">
+ *       <sequence>
+ *         <element name="contents" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="location" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </extension>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "processContentsResponse", propOrder = { + "contents", + "location" +}) +public class ProcessContentsResponse + extends Response +{ + + protected String contents; + protected String location; + + /** + * Gets the value of the contents property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getContents() { + return contents; + } + + /** + * Sets the value of the contents property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setContents(String value) { + this.contents = value; + } + + /** + * Gets the value of the location property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLocation() { + return location; + } + + /** + * Sets the value of the location property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLocation(String value) { + this.location = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessContextWrapper.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessContextWrapper.java new file mode 100644 index 000000000..4b4cb36fa --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessContextWrapper.java @@ -0,0 +1,152 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for processContextWrapper complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="processContextWrapper">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="inputRepositoryLocations" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element name="macros" type="{http://service.web.rapidanalytics.de/}macroDefinition" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element name="outputRepositoryLocations" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "processContextWrapper", propOrder = { + "inputRepositoryLocations", + "macros", + "outputRepositoryLocations" +}) +public class ProcessContextWrapper { + + @XmlElement(nillable = true) + protected List inputRepositoryLocations; + @XmlElement(nillable = true) + protected List macros; + @XmlElement(nillable = true) + protected List outputRepositoryLocations; + + /** + * Gets the value of the inputRepositoryLocations property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the inputRepositoryLocations property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getInputRepositoryLocations().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getInputRepositoryLocations() { + if (inputRepositoryLocations == null) { + inputRepositoryLocations = new ArrayList(); + } + return this.inputRepositoryLocations; + } + + /** + * Gets the value of the macros property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the macros property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getMacros().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link MacroDefinition } + * + * + */ + public List getMacros() { + if (macros == null) { + macros = new ArrayList(); + } + return this.macros; + } + + /** + * Gets the value of the outputRepositoryLocations property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the outputRepositoryLocations property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getOutputRepositoryLocations().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getOutputRepositoryLocations() { + if (outputRepositoryLocations == null) { + outputRepositoryLocations = new ArrayList(); + } + return this.outputRepositoryLocations; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessResponse.java new file mode 100644 index 000000000..beedb2a85 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessResponse.java @@ -0,0 +1,271 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for processResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="processResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="completionTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="exception" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="id" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *         <element name="outputLocations" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *         <element name="processLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="startTime" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *         <element name="state" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="trace" type="{http://service.web.rapidanalytics.de/}processStackTrace" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "processResponse", propOrder = { + "completionTime", + "exception", + "id", + "outputLocations", + "processLocation", + "startTime", + "state", + "trace" +}) +public class ProcessResponse { + + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar completionTime; + protected String exception; + protected int id; + @XmlElement(nillable = true) + protected List outputLocations; + protected String processLocation; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar startTime; + protected String state; + protected ProcessStackTrace trace; + + /** + * Gets the value of the completionTime property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getCompletionTime() { + return completionTime; + } + + /** + * Sets the value of the completionTime property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setCompletionTime(XMLGregorianCalendar value) { + this.completionTime = value; + } + + /** + * Gets the value of the exception property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getException() { + return exception; + } + + /** + * Sets the value of the exception property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setException(String value) { + this.exception = value; + } + + /** + * Gets the value of the id property. + * + */ + public int getId() { + return id; + } + + /** + * Sets the value of the id property. + * + */ + public void setId(int value) { + this.id = value; + } + + /** + * Gets the value of the outputLocations property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the outputLocations property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getOutputLocations().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getOutputLocations() { + if (outputLocations == null) { + outputLocations = new ArrayList(); + } + return this.outputLocations; + } + + /** + * Gets the value of the processLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessLocation() { + return processLocation; + } + + /** + * Sets the value of the processLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessLocation(String value) { + this.processLocation = value; + } + + /** + * Gets the value of the startTime property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getStartTime() { + return startTime; + } + + /** + * Sets the value of the startTime property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setStartTime(XMLGregorianCalendar value) { + this.startTime = value; + } + + /** + * Gets the value of the state property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getState() { + return state; + } + + /** + * Sets the value of the state property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setState(String value) { + this.state = value; + } + + /** + * Gets the value of the trace property. + * + * @return + * possible object is + * {@link ProcessStackTrace } + * + */ + public ProcessStackTrace getTrace() { + return trace; + } + + /** + * Sets the value of the trace property. + * + * @param value + * allowed object is + * {@link ProcessStackTrace } + * + */ + public void setTrace(ProcessStackTrace value) { + this.trace = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessService.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService.java new file mode 100644 index 000000000..91f557596 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService.java @@ -0,0 +1,161 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.List; +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebResult; +import javax.jws.WebService; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebService(name = "ProcessService", targetNamespace = "http://service.web.rapidanalytics.de/") +@XmlSeeAlso({ + ObjectFactory.class +}) +public interface ProcessService { + + + /** + * + * @param processLocation + * @param start + * @param processContext + * @param cronExpression + * @param end + * @return + * returns com.rapid_i.repository.wsimport.ExecutionResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "executeProcessCron", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessCron") + @ResponseWrapper(localName = "executeProcessCronResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessCronResponse") + public ExecutionResponse executeProcessCron( + @WebParam(name = "processLocation", targetNamespace = "") + String processLocation, + @WebParam(name = "cronExpression", targetNamespace = "") + String cronExpression, + @WebParam(name = "start", targetNamespace = "") + XMLGregorianCalendar start, + @WebParam(name = "end", targetNamespace = "") + XMLGregorianCalendar end, + @WebParam(name = "processContext", targetNamespace = "") + ProcessContextWrapper processContext); + + /** + * + * @param jobId + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getProcessIdsForJobId", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetProcessIdsForJobId") + @ResponseWrapper(localName = "getProcessIdsForJobIdResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetProcessIdsForJobIdResponse") + public List getProcessIdsForJobId( + @WebParam(name = "jobId", targetNamespace = "") + int jobId); + + /** + * + * @param scheduledProcessId + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "stopProcess", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StopProcess") + @ResponseWrapper(localName = "stopProcessResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StopProcessResponse") + public Response stopProcess( + @WebParam(name = "scheduledProcessId", targetNamespace = "") + int scheduledProcessId); + + /** + * + * @param scheduledProcessId + * @return + * returns com.rapid_i.repository.wsimport.ProcessResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getRunningProcessesInfo", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcessesInfo") + @ResponseWrapper(localName = "getRunningProcessesInfoResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcessesInfoResponse") + public ProcessResponse getRunningProcessesInfo( + @WebParam(name = "scheduledProcessId", targetNamespace = "") + int scheduledProcessId); + + /** + * + * @param processLocation + * @param executionTime + * @param processContext + * @return + * returns com.rapid_i.repository.wsimport.ExecutionResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "executeProcessSimple", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessSimple") + @ResponseWrapper(localName = "executeProcessSimpleResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessSimpleResponse") + public ExecutionResponse executeProcessSimple( + @WebParam(name = "processLocation", targetNamespace = "") + String processLocation, + @WebParam(name = "executionTime", targetNamespace = "") + XMLGregorianCalendar executionTime, + @WebParam(name = "processContext", targetNamespace = "") + ProcessContextWrapper processContext); + + /** + * + * @param since + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getRunningProcesses", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcesses") + @ResponseWrapper(localName = "getRunningProcessesResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcessesResponse") + public List getRunningProcesses( + @WebParam(name = "since", targetNamespace = "") + XMLGregorianCalendar since); + + /** + * + * @param triggerName + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "cancelTrigger", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.CancelTrigger") + @ResponseWrapper(localName = "cancelTriggerResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.CancelTriggerResponse") + public Response cancelTrigger( + @WebParam(name = "triggerName", targetNamespace = "") + String triggerName); + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessService13.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService13.java new file mode 100644 index 000000000..4289a4cf7 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService13.java @@ -0,0 +1,229 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.List; +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebResult; +import javax.jws.WebService; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebService(name = "ProcessService_1_3", targetNamespace = "http://service.web.rapidanalytics.de/") +@XmlSeeAlso({ + ObjectFactory.class +}) +public interface ProcessService13 { + + + /** + * + * @param processLocation + * @param executionTime + * @param processContext + * @param queueName + * @return + * returns com.rapid_i.repository.wsimport.ExecutionResponse + */ + @WebMethod(operationName = "executeProcessSimple_1_3") + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "executeProcessSimple_1_3", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessSimple13") + @ResponseWrapper(localName = "executeProcessSimple_1_3Response", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessSimple13Response") + public ExecutionResponse executeProcessSimple13( + @WebParam(name = "processLocation", targetNamespace = "") + String processLocation, + @WebParam(name = "executionTime", targetNamespace = "") + XMLGregorianCalendar executionTime, + @WebParam(name = "processContext", targetNamespace = "") + ProcessContextWrapper processContext, + @WebParam(name = "queueName", targetNamespace = "") + String queueName); + + /** + * + * @param queueName + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getQueueInfo", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetQueueInfo") + @ResponseWrapper(localName = "getQueueInfoResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetQueueInfoResponse") + public List getQueueInfo( + @WebParam(name = "queueName", targetNamespace = "") + String queueName); + + /** + * + * @param jobId + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getProcessIdsForJobId", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetProcessIdsForJobId") + @ResponseWrapper(localName = "getProcessIdsForJobIdResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetProcessIdsForJobIdResponse") + public List getProcessIdsForJobId( + @WebParam(name = "jobId", targetNamespace = "") + int jobId); + + /** + * + * @param scheduledProcessId + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "stopProcess", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StopProcess") + @ResponseWrapper(localName = "stopProcessResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StopProcessResponse") + public Response stopProcess( + @WebParam(name = "scheduledProcessId", targetNamespace = "") + int scheduledProcessId); + + /** + * + * @param queueName + * @return + * returns com.rapid_i.repository.wsimport.QueueState + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getQueueState", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetQueueState") + @ResponseWrapper(localName = "getQueueStateResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetQueueStateResponse") + public QueueState getQueueState( + @WebParam(name = "queueName", targetNamespace = "") + String queueName); + + /** + * + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getQueueNames", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetQueueNames") + @ResponseWrapper(localName = "getQueueNamesResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetQueueNamesResponse") + public List getQueueNames(); + + /** + * + * @param processLocation + * @param start + * @param processContext + * @param queueName + * @param cronExpression + * @param end + * @return + * returns com.rapid_i.repository.wsimport.ExecutionResponse + */ + @WebMethod(operationName = "executeProcessCron_1_3") + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "executeProcessCron_1_3", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessCron13") + @ResponseWrapper(localName = "executeProcessCron_1_3Response", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessCron13Response") + public ExecutionResponse executeProcessCron13( + @WebParam(name = "processLocation", targetNamespace = "") + String processLocation, + @WebParam(name = "cronExpression", targetNamespace = "") + String cronExpression, + @WebParam(name = "start", targetNamespace = "") + XMLGregorianCalendar start, + @WebParam(name = "end", targetNamespace = "") + XMLGregorianCalendar end, + @WebParam(name = "processContext", targetNamespace = "") + ProcessContextWrapper processContext, + @WebParam(name = "queueName", targetNamespace = "") + String queueName); + + /** + * + * @param scheduledProcessId + * @return + * returns com.rapid_i.repository.wsimport.ProcessResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getRunningProcessesInfo", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcessesInfo") + @ResponseWrapper(localName = "getRunningProcessesInfoResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcessesInfoResponse") + public ProcessResponse getRunningProcessesInfo( + @WebParam(name = "scheduledProcessId", targetNamespace = "") + int scheduledProcessId); + + /** + * + * @param processLocation + * @param executionTime + * @param processContext + * @param queueName + * @return + * returns com.rapid_i.repository.wsimport.ExecutionResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "executeProcessWithOffset", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessWithOffset") + @ResponseWrapper(localName = "executeProcessWithOffsetResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.ExecuteProcessWithOffsetResponse") + public ExecutionResponse executeProcessWithOffset( + @WebParam(name = "processLocation", targetNamespace = "") + String processLocation, + @WebParam(name = "executionTime", targetNamespace = "") + Long executionTime, + @WebParam(name = "processContext", targetNamespace = "") + ProcessContextWrapper processContext, + @WebParam(name = "queueName", targetNamespace = "") + String queueName); + + /** + * + * @param since + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getRunningProcesses", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcesses") + @ResponseWrapper(localName = "getRunningProcessesResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetRunningProcessesResponse") + public List getRunningProcesses( + @WebParam(name = "since", targetNamespace = "") + XMLGregorianCalendar since); + + /** + * + * @param triggerName + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "cancelTrigger", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.CancelTrigger") + @ResponseWrapper(localName = "cancelTriggerResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.CancelTriggerResponse") + public Response cancelTrigger( + @WebParam(name = "triggerName", targetNamespace = "") + String triggerName); + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessService13_Service.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService13_Service.java new file mode 100644 index 000000000..0634c008a --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService13_Service.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceException; +import javax.xml.ws.WebServiceFeature; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebServiceClient(name = "ProcessService_1_3", targetNamespace = "http://service.web.rapidanalytics.de/", wsdlLocation = "http://localhost:8080/RAWS/ProcessService_1_3?wsdl") +public class ProcessService13_Service + extends Service +{ + + private final static URL PROCESSSERVICE13_WSDL_LOCATION; + private final static WebServiceException PROCESSSERVICE13_EXCEPTION; + private final static QName PROCESSSERVICE13_QNAME = new QName("http://service.web.rapidanalytics.de/", "ProcessService_1_3"); + + static { + URL url = null; + WebServiceException e = null; + try { + url = new URL("http://localhost:8080/RAWS/ProcessService_1_3?wsdl"); + } catch (MalformedURLException ex) { + e = new WebServiceException(ex); + } + PROCESSSERVICE13_WSDL_LOCATION = url; + PROCESSSERVICE13_EXCEPTION = e; + } + + public ProcessService13_Service() { + super(__getWsdlLocation(), PROCESSSERVICE13_QNAME); + } + + public ProcessService13_Service(WebServiceFeature... features) { + super(__getWsdlLocation(), PROCESSSERVICE13_QNAME, features); + } + + public ProcessService13_Service(URL wsdlLocation) { + super(wsdlLocation, PROCESSSERVICE13_QNAME); + } + + public ProcessService13_Service(URL wsdlLocation, WebServiceFeature... features) { + super(wsdlLocation, PROCESSSERVICE13_QNAME, features); + } + + public ProcessService13_Service(URL wsdlLocation, QName serviceName) { + super(wsdlLocation, serviceName); + } + + public ProcessService13_Service(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { + super(wsdlLocation, serviceName, features); + } + + /** + * + * @return + * returns ProcessService13 + */ + @WebEndpoint(name = "ProcessService_1_3Port") + public ProcessService13 getProcessService13Port() { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "ProcessService_1_3Port"), ProcessService13.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns ProcessService13 + */ + @WebEndpoint(name = "ProcessService_1_3Port") + public ProcessService13 getProcessService13Port(WebServiceFeature... features) { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "ProcessService_1_3Port"), ProcessService13.class, features); + } + + private static URL __getWsdlLocation() { + if (PROCESSSERVICE13_EXCEPTION!= null) { + throw PROCESSSERVICE13_EXCEPTION; + } + return PROCESSSERVICE13_WSDL_LOCATION; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessService_Service.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService_Service.java new file mode 100644 index 000000000..84324ec8d --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessService_Service.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceException; +import javax.xml.ws.WebServiceFeature; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebServiceClient(name = "ProcessService", targetNamespace = "http://service.web.rapidanalytics.de/", wsdlLocation = "http://localhost:8080/RAWS/ProcessService?wsdl") +public class ProcessService_Service + extends Service +{ + + private final static URL PROCESSSERVICE_WSDL_LOCATION; + private final static WebServiceException PROCESSSERVICE_EXCEPTION; + private final static QName PROCESSSERVICE_QNAME = new QName("http://service.web.rapidanalytics.de/", "ProcessService"); + + static { + URL url = null; + WebServiceException e = null; + try { + url = new URL("http://localhost:8080/RAWS/ProcessService?wsdl"); + } catch (MalformedURLException ex) { + e = new WebServiceException(ex); + } + PROCESSSERVICE_WSDL_LOCATION = url; + PROCESSSERVICE_EXCEPTION = e; + } + + public ProcessService_Service() { + super(__getWsdlLocation(), PROCESSSERVICE_QNAME); + } + + public ProcessService_Service(WebServiceFeature... features) { + super(__getWsdlLocation(), PROCESSSERVICE_QNAME, features); + } + + public ProcessService_Service(URL wsdlLocation) { + super(wsdlLocation, PROCESSSERVICE_QNAME); + } + + public ProcessService_Service(URL wsdlLocation, WebServiceFeature... features) { + super(wsdlLocation, PROCESSSERVICE_QNAME, features); + } + + public ProcessService_Service(URL wsdlLocation, QName serviceName) { + super(wsdlLocation, serviceName); + } + + public ProcessService_Service(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { + super(wsdlLocation, serviceName, features); + } + + /** + * + * @return + * returns ProcessService + */ + @WebEndpoint(name = "ProcessServicePort") + public ProcessService getProcessServicePort() { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "ProcessServicePort"), ProcessService.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns ProcessService + */ + @WebEndpoint(name = "ProcessServicePort") + public ProcessService getProcessServicePort(WebServiceFeature... features) { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "ProcessServicePort"), ProcessService.class, features); + } + + private static URL __getWsdlLocation() { + if (PROCESSSERVICE_EXCEPTION!= null) { + throw PROCESSSERVICE_EXCEPTION; + } + return PROCESSSERVICE_WSDL_LOCATION; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessStackTrace.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessStackTrace.java new file mode 100644 index 000000000..f2865e4d4 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessStackTrace.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for processStackTrace complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="processStackTrace">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="elements" type="{http://service.web.rapidanalytics.de/}processStackTraceElement" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "processStackTrace", propOrder = { + "elements" +}) +public class ProcessStackTrace { + + @XmlElement(nillable = true) + protected List elements; + + /** + * Gets the value of the elements property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the elements property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getElements().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link ProcessStackTraceElement } + * + * + */ + public List getElements() { + if (elements == null) { + elements = new ArrayList(); + } + return this.elements; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/ProcessStackTraceElement.java b/src/generated/java/com/rapid_i/repository/wsimport/ProcessStackTraceElement.java new file mode 100644 index 000000000..7e8f143b1 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/ProcessStackTraceElement.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for processStackTraceElement complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="processStackTraceElement">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="applyCount" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *         <element name="executionTime" type="{http://www.w3.org/2001/XMLSchema}long"/>
+ *         <element name="operatorName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "processStackTraceElement", propOrder = { + "applyCount", + "executionTime", + "operatorName" +}) +public class ProcessStackTraceElement { + + protected int applyCount; + protected long executionTime; + protected String operatorName; + + /** + * Gets the value of the applyCount property. + * + */ + public int getApplyCount() { + return applyCount; + } + + /** + * Sets the value of the applyCount property. + * + */ + public void setApplyCount(int value) { + this.applyCount = value; + } + + /** + * Gets the value of the executionTime property. + * + */ + public long getExecutionTime() { + return executionTime; + } + + /** + * Sets the value of the executionTime property. + * + */ + public void setExecutionTime(long value) { + this.executionTime = value; + } + + /** + * Gets the value of the operatorName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getOperatorName() { + return operatorName; + } + + /** + * Sets the value of the operatorName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setOperatorName(String value) { + this.operatorName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/QueueProperty.java b/src/generated/java/com/rapid_i/repository/wsimport/QueueProperty.java new file mode 100644 index 000000000..9f82d0b08 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/QueueProperty.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for queueProperty complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="queueProperty">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="key" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="value" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "queueProperty", propOrder = { + "key", + "value" +}) +public class QueueProperty { + + protected String key; + protected String value; + + /** + * Gets the value of the key property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getKey() { + return key; + } + + /** + * Sets the value of the key property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setKey(String value) { + this.key = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/QueueState.java b/src/generated/java/com/rapid_i/repository/wsimport/QueueState.java new file mode 100644 index 000000000..b7cdba717 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/QueueState.java @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for queueState complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="queueState">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="backlog" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *         <element name="numberOfRunningProcesses" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "queueState", propOrder = { + "backlog", + "numberOfRunningProcesses" +}) +public class QueueState { + + protected int backlog; + protected int numberOfRunningProcesses; + + /** + * Gets the value of the backlog property. + * + */ + public int getBacklog() { + return backlog; + } + + /** + * Sets the value of the backlog property. + * + */ + public void setBacklog(int value) { + this.backlog = value; + } + + /** + * Gets the value of the numberOfRunningProcesses property. + * + */ + public int getNumberOfRunningProcesses() { + return numberOfRunningProcesses; + } + + /** + * Sets the value of the numberOfRunningProcesses property. + * + */ + public void setNumberOfRunningProcesses(int value) { + this.numberOfRunningProcesses = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/RAInfoService.java b/src/generated/java/com/rapid_i/repository/wsimport/RAInfoService.java new file mode 100644 index 000000000..a89b6cb37 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/RAInfoService.java @@ -0,0 +1,121 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.List; +import javax.jws.WebMethod; +import javax.jws.WebResult; +import javax.jws.WebService; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebService(name = "RAInfoService", targetNamespace = "http://service.web.rapidanalytics.de/") +@XmlSeeAlso({ + ObjectFactory.class +}) +public interface RAInfoService { + + + /** + * + * @return + * returns java.lang.String + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getFreeMemory", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetFreeMemory") + @ResponseWrapper(localName = "getFreeMemoryResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetFreeMemoryResponse") + public String getFreeMemory(); + + /** + * + * @return + * returns double + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getSystemLoadAverage", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetSystemLoadAverage") + @ResponseWrapper(localName = "getSystemLoadAverageResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetSystemLoadAverageResponse") + public double getSystemLoadAverage(); + + /** + * + * @return + * returns java.lang.String + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getTotalMemory", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetTotalMemory") + @ResponseWrapper(localName = "getTotalMemoryResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetTotalMemoryResponse") + public String getTotalMemory(); + + /** + * + * @return + * returns java.lang.String + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getMaxMemory", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetMaxMemory") + @ResponseWrapper(localName = "getMaxMemoryResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetMaxMemoryResponse") + public String getMaxMemory(); + + /** + * + * @return + * returns java.lang.String + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getVersionNumber", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetVersionNumber") + @ResponseWrapper(localName = "getVersionNumberResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetVersionNumberResponse") + public String getVersionNumber(); + + /** + * + * @return + * returns javax.xml.datatype.XMLGregorianCalendar + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getUpSince", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetUpSince") + @ResponseWrapper(localName = "getUpSinceResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetUpSinceResponse") + public XMLGregorianCalendar getUpSince(); + + /** + * + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getInstalledPlugins", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetInstalledPlugins") + @ResponseWrapper(localName = "getInstalledPluginsResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetInstalledPluginsResponse") + public List getInstalledPlugins(); + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/RAInfoService_Service.java b/src/generated/java/com/rapid_i/repository/wsimport/RAInfoService_Service.java new file mode 100644 index 000000000..32771df28 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/RAInfoService_Service.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceException; +import javax.xml.ws.WebServiceFeature; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebServiceClient(name = "RAInfoService", targetNamespace = "http://service.web.rapidanalytics.de/", wsdlLocation = "http://localhost:8080/RAWS/RAInfoService?wsdl") +public class RAInfoService_Service + extends Service +{ + + private final static URL RAINFOSERVICE_WSDL_LOCATION; + private final static WebServiceException RAINFOSERVICE_EXCEPTION; + private final static QName RAINFOSERVICE_QNAME = new QName("http://service.web.rapidanalytics.de/", "RAInfoService"); + + static { + URL url = null; + WebServiceException e = null; + try { + url = new URL("http://localhost:8080/RAWS/RAInfoService?wsdl"); + } catch (MalformedURLException ex) { + e = new WebServiceException(ex); + } + RAINFOSERVICE_WSDL_LOCATION = url; + RAINFOSERVICE_EXCEPTION = e; + } + + public RAInfoService_Service() { + super(__getWsdlLocation(), RAINFOSERVICE_QNAME); + } + + public RAInfoService_Service(WebServiceFeature... features) { + super(__getWsdlLocation(), RAINFOSERVICE_QNAME, features); + } + + public RAInfoService_Service(URL wsdlLocation) { + super(wsdlLocation, RAINFOSERVICE_QNAME); + } + + public RAInfoService_Service(URL wsdlLocation, WebServiceFeature... features) { + super(wsdlLocation, RAINFOSERVICE_QNAME, features); + } + + public RAInfoService_Service(URL wsdlLocation, QName serviceName) { + super(wsdlLocation, serviceName); + } + + public RAInfoService_Service(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { + super(wsdlLocation, serviceName, features); + } + + /** + * + * @return + * returns RAInfoService + */ + @WebEndpoint(name = "RAInfoServicePort") + public RAInfoService getRAInfoServicePort() { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "RAInfoServicePort"), RAInfoService.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns RAInfoService + */ + @WebEndpoint(name = "RAInfoServicePort") + public RAInfoService getRAInfoServicePort(WebServiceFeature... features) { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "RAInfoServicePort"), RAInfoService.class, features); + } + + private static URL __getWsdlLocation() { + if (RAINFOSERVICE_EXCEPTION!= null) { + throw RAINFOSERVICE_EXCEPTION; + } + return RAINFOSERVICE_WSDL_LOCATION; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/Rename.java b/src/generated/java/com/rapid_i/repository/wsimport/Rename.java new file mode 100644 index 000000000..dacc00cb1 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/Rename.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for rename complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="rename">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="location" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="newName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "rename", propOrder = { + "location", + "newName" +}) +public class Rename { + + protected String location; + protected String newName; + + /** + * Gets the value of the location property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getLocation() { + return location; + } + + /** + * Sets the value of the location property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setLocation(String value) { + this.location = value; + } + + /** + * Gets the value of the newName property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getNewName() { + return newName; + } + + /** + * Sets the value of the newName property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setNewName(String value) { + this.newName = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/RenameResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/RenameResponse.java new file mode 100644 index 000000000..fa4d2e50d --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/RenameResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for renameResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="renameResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}entryResponse" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "renameResponse", propOrder = { + "_return" +}) +public class RenameResponse { + + @XmlElement(name = "return") + protected EntryResponse _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link EntryResponse } + * + */ + public EntryResponse getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link EntryResponse } + * + */ + public void setReturn(EntryResponse value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/RepositoryService.java b/src/generated/java/com/rapid_i/repository/wsimport/RepositoryService.java new file mode 100644 index 000000000..d43ec701b --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/RepositoryService.java @@ -0,0 +1,248 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.List; +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebResult; +import javax.jws.WebService; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.datatype.XMLGregorianCalendar; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebService(name = "RepositoryService", targetNamespace = "http://service.web.rapidanalytics.de/") +@XmlSeeAlso({ + ObjectFactory.class +}) +public interface RepositoryService { + + + /** + * + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getAllGroupNames", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetAllGroupNames") + @ResponseWrapper(localName = "getAllGroupNamesResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetAllGroupNamesResponse") + public List getAllGroupNames(); + + /** + * + * @param parentLocation + * @param blobName + * @return + * returns com.rapid_i.repository.wsimport.EntryResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "createBlob", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.CreateBlob") + @ResponseWrapper(localName = "createBlobResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.CreateBlobResponse") + public EntryResponse createBlob( + @WebParam(name = "parentLocation", targetNamespace = "") + String parentLocation, + @WebParam(name = "blobName", targetNamespace = "") + String blobName); + + /** + * + * @param processLocation + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "startNewRevision", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StartNewRevision") + @ResponseWrapper(localName = "startNewRevisionResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StartNewRevisionResponse") + public Response startNewRevision( + @WebParam(name = "processLocation", targetNamespace = "") + String processLocation); + + /** + * + * @param folderLocation + * @return + * returns com.rapid_i.repository.wsimport.FolderContentsResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getFolderContents", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetFolderContents") + @ResponseWrapper(localName = "getFolderContentsResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetFolderContentsResponse") + public FolderContentsResponse getFolderContents( + @WebParam(name = "folderLocation", targetNamespace = "") + String folderLocation); + + /** + * + * @param entryLocation + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "deleteEntry", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.DeleteEntry") + @ResponseWrapper(localName = "deleteEntryResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.DeleteEntryResponse") + public Response deleteEntry( + @WebParam(name = "entryLocation", targetNamespace = "") + String entryLocation); + + /** + * + * @param parentLocation + * @param subfolderName + * @return + * returns com.rapid_i.repository.wsimport.EntryResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "makeFolder", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.MakeFolder") + @ResponseWrapper(localName = "makeFolderResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.MakeFolderResponse") + public EntryResponse makeFolder( + @WebParam(name = "parentLocation", targetNamespace = "") + String parentLocation, + @WebParam(name = "subfolderName", targetNamespace = "") + String subfolderName); + + /** + * + * @param revisionNumber + * @param entryLocation + * @return + * returns com.rapid_i.repository.wsimport.ProcessContentsResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getProcessContents", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetProcessContents") + @ResponseWrapper(localName = "getProcessContentsResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetProcessContentsResponse") + public ProcessContentsResponse getProcessContents( + @WebParam(name = "entryLocation", targetNamespace = "") + String entryLocation, + @WebParam(name = "revisionNumber", targetNamespace = "") + int revisionNumber); + + /** + * + * @param processXML + * @param lastTimestamp + * @param entryLocation + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "storeProcess", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StoreProcess") + @ResponseWrapper(localName = "storeProcessResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.StoreProcessResponse") + public Response storeProcess( + @WebParam(name = "entryLocation", targetNamespace = "") + String entryLocation, + @WebParam(name = "processXML", targetNamespace = "") + String processXML, + @WebParam(name = "lastTimestamp", targetNamespace = "") + XMLGregorianCalendar lastTimestamp); + + /** + * + * @param newParentFolder + * @param location + * @return + * returns com.rapid_i.repository.wsimport.EntryResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "move", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.Move") + @ResponseWrapper(localName = "moveResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.MoveResponse") + public EntryResponse move( + @WebParam(name = "location", targetNamespace = "") + String location, + @WebParam(name = "newParentFolder", targetNamespace = "") + String newParentFolder); + + /** + * + * @param entryLocation + * @return + * returns java.util.List + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getAccessRights", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetAccessRights") + @ResponseWrapper(localName = "getAccessRightsResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetAccessRightsResponse") + public List getAccessRights( + @WebParam(name = "entryLocation", targetNamespace = "") + String entryLocation); + + /** + * + * @param accessRights + * @param entryLocation + * @return + * returns com.rapid_i.repository.wsimport.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "setAccessRights", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.SetAccessRights") + @ResponseWrapper(localName = "setAccessRightsResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.SetAccessRightsResponse") + public Response setAccessRights( + @WebParam(name = "entryLocation", targetNamespace = "") + String entryLocation, + @WebParam(name = "accessRights", targetNamespace = "") + List accessRights); + + /** + * + * @param location + * @param newName + * @return + * returns com.rapid_i.repository.wsimport.EntryResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "rename", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.Rename") + @ResponseWrapper(localName = "renameResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.RenameResponse") + public EntryResponse rename( + @WebParam(name = "location", targetNamespace = "") + String location, + @WebParam(name = "newName", targetNamespace = "") + String newName); + + /** + * + * @param entryLocation + * @return + * returns com.rapid_i.repository.wsimport.EntryResponse + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getEntry", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetEntry") + @ResponseWrapper(localName = "getEntryResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.GetEntryResponse") + public EntryResponse getEntry( + @WebParam(name = "entryLocation", targetNamespace = "") + String entryLocation); + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/RepositoryService_Service.java b/src/generated/java/com/rapid_i/repository/wsimport/RepositoryService_Service.java new file mode 100644 index 000000000..624333f69 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/RepositoryService_Service.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceException; +import javax.xml.ws.WebServiceFeature; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebServiceClient(name = "RepositoryService", targetNamespace = "http://service.web.rapidanalytics.de/", wsdlLocation = "http://localhost:8080/RAWS/RepositoryService?wsdl") +public class RepositoryService_Service + extends Service +{ + + private final static URL REPOSITORYSERVICE_WSDL_LOCATION; + private final static WebServiceException REPOSITORYSERVICE_EXCEPTION; + private final static QName REPOSITORYSERVICE_QNAME = new QName("http://service.web.rapidanalytics.de/", "RepositoryService"); + + static { + URL url = null; + WebServiceException e = null; + try { + url = new URL("http://localhost:8080/RAWS/RepositoryService?wsdl"); + } catch (MalformedURLException ex) { + e = new WebServiceException(ex); + } + REPOSITORYSERVICE_WSDL_LOCATION = url; + REPOSITORYSERVICE_EXCEPTION = e; + } + + public RepositoryService_Service() { + super(__getWsdlLocation(), REPOSITORYSERVICE_QNAME); + } + + public RepositoryService_Service(WebServiceFeature... features) { + super(__getWsdlLocation(), REPOSITORYSERVICE_QNAME, features); + } + + public RepositoryService_Service(URL wsdlLocation) { + super(wsdlLocation, REPOSITORYSERVICE_QNAME); + } + + public RepositoryService_Service(URL wsdlLocation, WebServiceFeature... features) { + super(wsdlLocation, REPOSITORYSERVICE_QNAME, features); + } + + public RepositoryService_Service(URL wsdlLocation, QName serviceName) { + super(wsdlLocation, serviceName); + } + + public RepositoryService_Service(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { + super(wsdlLocation, serviceName, features); + } + + /** + * + * @return + * returns RepositoryService + */ + @WebEndpoint(name = "RepositoryServicePort") + public RepositoryService getRepositoryServicePort() { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "RepositoryServicePort"), RepositoryService.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns RepositoryService + */ + @WebEndpoint(name = "RepositoryServicePort") + public RepositoryService getRepositoryServicePort(WebServiceFeature... features) { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "RepositoryServicePort"), RepositoryService.class, features); + } + + private static URL __getWsdlLocation() { + if (REPOSITORYSERVICE_EXCEPTION!= null) { + throw REPOSITORYSERVICE_EXCEPTION; + } + return REPOSITORYSERVICE_WSDL_LOCATION; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/Response.java b/src/generated/java/com/rapid_i/repository/wsimport/Response.java new file mode 100644 index 000000000..0b3416b15 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/Response.java @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for response complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="response">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="errorMessage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="status" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "response", propOrder = { + "errorMessage", + "status" +}) +@XmlSeeAlso({ + EntryResponse.class, + ProcessContentsResponse.class, + FolderContentsResponse.class +}) +public class Response { + + protected String errorMessage; + protected int status; + + /** + * Gets the value of the errorMessage property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * Sets the value of the errorMessage property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setErrorMessage(String value) { + this.errorMessage = value; + } + + /** + * Gets the value of the status property. + * + */ + public int getStatus() { + return status; + } + + /** + * Sets the value of the status property. + * + */ + public void setStatus(int value) { + this.status = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/SetAccessRights.java b/src/generated/java/com/rapid_i/repository/wsimport/SetAccessRights.java new file mode 100644 index 000000000..a04088467 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/SetAccessRights.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for setAccessRights complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="setAccessRights">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="entryLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="accessRights" type="{http://service.web.rapidanalytics.de/}accessRights" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "setAccessRights", propOrder = { + "entryLocation", + "accessRights" +}) +public class SetAccessRights { + + protected String entryLocation; + protected List accessRights; + + /** + * Gets the value of the entryLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEntryLocation() { + return entryLocation; + } + + /** + * Sets the value of the entryLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEntryLocation(String value) { + this.entryLocation = value; + } + + /** + * Gets the value of the accessRights property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the accessRights property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getAccessRights().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link AccessRights } + * + * + */ + public List getAccessRights() { + if (accessRights == null) { + accessRights = new ArrayList(); + } + return this.accessRights; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/SetAccessRightsResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/SetAccessRightsResponse.java new file mode 100644 index 000000000..19665f109 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/SetAccessRightsResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for setAccessRightsResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="setAccessRightsResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}response" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "setAccessRightsResponse", propOrder = { + "_return" +}) +public class SetAccessRightsResponse { + + @XmlElement(name = "return") + protected Response _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link Response } + * + */ + public Response getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link Response } + * + */ + public void setReturn(Response value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/StartNewRevision.java b/src/generated/java/com/rapid_i/repository/wsimport/StartNewRevision.java new file mode 100644 index 000000000..c8a0067c0 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/StartNewRevision.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for startNewRevision complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="startNewRevision">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="processLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "startNewRevision", propOrder = { + "processLocation" +}) +public class StartNewRevision { + + protected String processLocation; + + /** + * Gets the value of the processLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessLocation() { + return processLocation; + } + + /** + * Sets the value of the processLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessLocation(String value) { + this.processLocation = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/StartNewRevisionResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/StartNewRevisionResponse.java new file mode 100644 index 000000000..eea4a206c --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/StartNewRevisionResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for startNewRevisionResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="startNewRevisionResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}response" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "startNewRevisionResponse", propOrder = { + "_return" +}) +public class StartNewRevisionResponse { + + @XmlElement(name = "return") + protected Response _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link Response } + * + */ + public Response getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link Response } + * + */ + public void setReturn(Response value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/StopProcess.java b/src/generated/java/com/rapid_i/repository/wsimport/StopProcess.java new file mode 100644 index 000000000..f862f0aff --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/StopProcess.java @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for stopProcess complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="stopProcess">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="scheduledProcessId" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "stopProcess", propOrder = { + "scheduledProcessId" +}) +public class StopProcess { + + protected int scheduledProcessId; + + /** + * Gets the value of the scheduledProcessId property. + * + */ + public int getScheduledProcessId() { + return scheduledProcessId; + } + + /** + * Sets the value of the scheduledProcessId property. + * + */ + public void setScheduledProcessId(int value) { + this.scheduledProcessId = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/StopProcessResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/StopProcessResponse.java new file mode 100644 index 000000000..a727a166d --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/StopProcessResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for stopProcessResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="stopProcessResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}response" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "stopProcessResponse", propOrder = { + "_return" +}) +public class StopProcessResponse { + + @XmlElement(name = "return") + protected Response _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link Response } + * + */ + public Response getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link Response } + * + */ + public void setReturn(Response value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/StoreProcess.java b/src/generated/java/com/rapid_i/repository/wsimport/StoreProcess.java new file mode 100644 index 000000000..498de27a7 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/StoreProcess.java @@ -0,0 +1,134 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlSchemaType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.datatype.XMLGregorianCalendar; + + +/** + *

Java class for storeProcess complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="storeProcess">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="entryLocation" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="processXML" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="lastTimestamp" type="{http://www.w3.org/2001/XMLSchema}dateTime" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "storeProcess", propOrder = { + "entryLocation", + "processXML", + "lastTimestamp" +}) +public class StoreProcess { + + protected String entryLocation; + protected String processXML; + @XmlSchemaType(name = "dateTime") + protected XMLGregorianCalendar lastTimestamp; + + /** + * Gets the value of the entryLocation property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getEntryLocation() { + return entryLocation; + } + + /** + * Sets the value of the entryLocation property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setEntryLocation(String value) { + this.entryLocation = value; + } + + /** + * Gets the value of the processXML property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getProcessXML() { + return processXML; + } + + /** + * Sets the value of the processXML property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setProcessXML(String value) { + this.processXML = value; + } + + /** + * Gets the value of the lastTimestamp property. + * + * @return + * possible object is + * {@link XMLGregorianCalendar } + * + */ + public XMLGregorianCalendar getLastTimestamp() { + return lastTimestamp; + } + + /** + * Sets the value of the lastTimestamp property. + * + * @param value + * allowed object is + * {@link XMLGregorianCalendar } + * + */ + public void setLastTimestamp(XMLGregorianCalendar value) { + this.lastTimestamp = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/StoreProcessResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/StoreProcessResponse.java new file mode 100644 index 000000000..160a71d45 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/StoreProcessResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for storeProcessResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="storeProcessResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}response" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "storeProcessResponse", propOrder = { + "_return" +}) +public class StoreProcessResponse { + + @XmlElement(name = "return") + protected Response _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link Response } + * + */ + public Response getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link Response } + * + */ + public void setReturn(Response value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/CheckSetup.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CheckSetup.java new file mode 100644 index 000000000..f894fdd77 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CheckSetup.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for checkSetup complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="checkSetup">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "checkSetup") +public class CheckSetup { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/CheckSetupResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CheckSetupResponse.java new file mode 100644 index 000000000..566035f2e --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CheckSetupResponse.java @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for checkSetupResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="checkSetupResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "checkSetupResponse", propOrder = { + "_return" +}) +public class CheckSetupResponse { + + @XmlElement(name = "return") + protected boolean _return; + + /** + * Gets the value of the return property. + * + */ + public boolean isReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + */ + public void setReturn(boolean value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/CreateDBConnection.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CreateDBConnection.java new file mode 100644 index 000000000..a4627406e --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CreateDBConnection.java @@ -0,0 +1,273 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import java.util.ArrayList; +import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for createDBConnection complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="createDBConnection">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="name" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="host" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="port" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="user" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="pwd" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="schema" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="system" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="permittedGroups" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "createDBConnection", propOrder = { + "name", + "host", + "port", + "user", + "pwd", + "schema", + "system", + "permittedGroups" +}) +public class CreateDBConnection { + + protected String name; + protected String host; + protected String port; + protected String user; + protected String pwd; + protected String schema; + protected String system; + protected List permittedGroups; + + /** + * Gets the value of the name property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getName() { + return name; + } + + /** + * Sets the value of the name property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setName(String value) { + this.name = value; + } + + /** + * Gets the value of the host property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getHost() { + return host; + } + + /** + * Sets the value of the host property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setHost(String value) { + this.host = value; + } + + /** + * Gets the value of the port property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPort() { + return port; + } + + /** + * Sets the value of the port property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPort(String value) { + this.port = value; + } + + /** + * Gets the value of the user property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getUser() { + return user; + } + + /** + * Sets the value of the user property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setUser(String value) { + this.user = value; + } + + /** + * Gets the value of the pwd property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getPwd() { + return pwd; + } + + /** + * Sets the value of the pwd property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setPwd(String value) { + this.pwd = value; + } + + /** + * Gets the value of the schema property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSchema() { + return schema; + } + + /** + * Sets the value of the schema property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSchema(String value) { + this.schema = value; + } + + /** + * Gets the value of the system property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getSystem() { + return system; + } + + /** + * Sets the value of the system property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setSystem(String value) { + this.system = value; + } + + /** + * Gets the value of the permittedGroups property. + * + *

+ * This accessor method returns a reference to the live list, + * not a snapshot. Therefore any modification you make to the + * returned list will be present inside the JAXB object. + * This is why there is not a set method for the permittedGroups property. + * + *

+ * For example, to add a new item, do as follows: + *

+     *    getPermittedGroups().add(newItem);
+     * 
+ * + * + *

+ * Objects of the following type(s) are allowed in the list + * {@link String } + * + * + */ + public List getPermittedGroups() { + if (permittedGroups == null) { + permittedGroups = new ArrayList(); + } + return this.permittedGroups; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/CreateDBConnectionResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CreateDBConnectionResponse.java new file mode 100644 index 000000000..420769ceb --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/CreateDBConnectionResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for createDBConnectionResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="createDBConnectionResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://service.web.rapidanalytics.de/}response" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "createDBConnectionResponse", propOrder = { + "_return" +}) +public class CreateDBConnectionResponse { + + @XmlElement(name = "return") + protected Response _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link Response } + * + */ + public Response getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link Response } + * + */ + public void setReturn(Response value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/GetGlobalProperty.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/GetGlobalProperty.java new file mode 100644 index 000000000..459bbc0b7 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/GetGlobalProperty.java @@ -0,0 +1,77 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getGlobalProperty complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getGlobalProperty">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="key" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getGlobalProperty", propOrder = { + "key" +}) +public class GetGlobalProperty { + + protected String key; + + /** + * Gets the value of the key property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getKey() { + return key; + } + + /** + * Sets the value of the key property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setKey(String value) { + this.key = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/GetGlobalPropertyResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/GetGlobalPropertyResponse.java new file mode 100644 index 000000000..a7762e77e --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/GetGlobalPropertyResponse.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for getGlobalPropertyResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="getGlobalPropertyResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="return" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "getGlobalPropertyResponse", propOrder = { + "_return" +}) +public class GetGlobalPropertyResponse { + + @XmlElement(name = "return") + protected String _return; + + /** + * Gets the value of the return property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getReturn() { + return _return; + } + + /** + * Sets the value of the return property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setReturn(String value) { + this._return = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/ManagementService.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/ManagementService.java new file mode 100644 index 000000000..14a629633 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/ManagementService.java @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import java.util.List; +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebResult; +import javax.jws.WebService; +import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.ws.RequestWrapper; +import javax.xml.ws.ResponseWrapper; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebService(name = "ManagementService", targetNamespace = "http://service.web.rapidanalytics.de/") +@XmlSeeAlso({ + ObjectFactory.class +}) +public interface ManagementService { + + + /** + * + * @return + * returns boolean + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "checkSetup", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.CheckSetup") + @ResponseWrapper(localName = "checkSetupResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.CheckSetupResponse") + public boolean checkSetup(); + + /** + * + * @param key + * @return + * returns java.lang.String + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "getGlobalProperty", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.GetGlobalProperty") + @ResponseWrapper(localName = "getGlobalPropertyResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.GetGlobalPropertyResponse") + public String getGlobalProperty( + @WebParam(name = "key", targetNamespace = "") + String key); + + /** + * + * @param value + * @param key + */ + @WebMethod + @RequestWrapper(localName = "setGlobalProperty", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.SetGlobalProperty") + @ResponseWrapper(localName = "setGlobalPropertyResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.SetGlobalPropertyResponse") + public void setGlobalProperty( + @WebParam(name = "key", targetNamespace = "") + String key, + @WebParam(name = "value", targetNamespace = "") + String value); + + /** + * + * @param schema + * @param port + * @param system + * @param pwd + * @param host + * @param permittedGroups + * @param name + * @param user + * @return + * returns com.rapid_i.repository.wsimport.mgt.Response + */ + @WebMethod + @WebResult(targetNamespace = "") + @RequestWrapper(localName = "createDBConnection", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.CreateDBConnection") + @ResponseWrapper(localName = "createDBConnectionResponse", targetNamespace = "http://service.web.rapidanalytics.de/", className = "com.rapid_i.repository.wsimport.mgt.CreateDBConnectionResponse") + public Response createDBConnection( + @WebParam(name = "name", targetNamespace = "") + String name, + @WebParam(name = "host", targetNamespace = "") + String host, + @WebParam(name = "port", targetNamespace = "") + String port, + @WebParam(name = "user", targetNamespace = "") + String user, + @WebParam(name = "pwd", targetNamespace = "") + String pwd, + @WebParam(name = "schema", targetNamespace = "") + String schema, + @WebParam(name = "system", targetNamespace = "") + String system, + @WebParam(name = "permittedGroups", targetNamespace = "") + List permittedGroups); + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/ManagementServiceService.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/ManagementServiceService.java new file mode 100644 index 000000000..194c80509 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/ManagementServiceService.java @@ -0,0 +1,111 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import java.net.MalformedURLException; +import java.net.URL; +import javax.xml.namespace.QName; +import javax.xml.ws.Service; +import javax.xml.ws.WebEndpoint; +import javax.xml.ws.WebServiceClient; +import javax.xml.ws.WebServiceException; +import javax.xml.ws.WebServiceFeature; + + +/** + * This class was generated by the JAX-WS RI. + * JAX-WS RI 2.2.8 + * Generated source version: 2.2 + * + */ +@WebServiceClient(name = "ManagementServiceService", targetNamespace = "http://service.web.rapidanalytics.de/", wsdlLocation = "http://localhost:8080/RAWS/ManagementService?wsdl") +public class ManagementServiceService + extends Service +{ + + private final static URL MANAGEMENTSERVICESERVICE_WSDL_LOCATION; + private final static WebServiceException MANAGEMENTSERVICESERVICE_EXCEPTION; + private final static QName MANAGEMENTSERVICESERVICE_QNAME = new QName("http://service.web.rapidanalytics.de/", "ManagementServiceService"); + + static { + URL url = null; + WebServiceException e = null; + try { + url = new URL("http://localhost:8080/RAWS/ManagementService?wsdl"); + } catch (MalformedURLException ex) { + e = new WebServiceException(ex); + } + MANAGEMENTSERVICESERVICE_WSDL_LOCATION = url; + MANAGEMENTSERVICESERVICE_EXCEPTION = e; + } + + public ManagementServiceService() { + super(__getWsdlLocation(), MANAGEMENTSERVICESERVICE_QNAME); + } + + public ManagementServiceService(WebServiceFeature... features) { + super(__getWsdlLocation(), MANAGEMENTSERVICESERVICE_QNAME, features); + } + + public ManagementServiceService(URL wsdlLocation) { + super(wsdlLocation, MANAGEMENTSERVICESERVICE_QNAME); + } + + public ManagementServiceService(URL wsdlLocation, WebServiceFeature... features) { + super(wsdlLocation, MANAGEMENTSERVICESERVICE_QNAME, features); + } + + public ManagementServiceService(URL wsdlLocation, QName serviceName) { + super(wsdlLocation, serviceName); + } + + public ManagementServiceService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) { + super(wsdlLocation, serviceName, features); + } + + /** + * + * @return + * returns ManagementService + */ + @WebEndpoint(name = "ManagementServicePort") + public ManagementService getManagementServicePort() { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "ManagementServicePort"), ManagementService.class); + } + + /** + * + * @param features + * A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the features parameter will have their default values. + * @return + * returns ManagementService + */ + @WebEndpoint(name = "ManagementServicePort") + public ManagementService getManagementServicePort(WebServiceFeature... features) { + return super.getPort(new QName("http://service.web.rapidanalytics.de/", "ManagementServicePort"), ManagementService.class, features); + } + + private static URL __getWsdlLocation() { + if (MANAGEMENTSERVICESERVICE_EXCEPTION!= null) { + throw MANAGEMENTSERVICESERVICE_EXCEPTION; + } + return MANAGEMENTSERVICESERVICE_WSDL_LOCATION; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/ObjectFactory.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/ObjectFactory.java new file mode 100644 index 000000000..391f65335 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/ObjectFactory.java @@ -0,0 +1,204 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlRegistry; +import javax.xml.namespace.QName; + + +/** + * This object contains factory methods for each + * Java content interface and Java element interface + * generated in the com.rapid_i.repository.wsimport.mgt package. + *

An ObjectFactory allows you to programatically + * construct new instances of the Java representation + * for XML content. The Java representation of XML + * content can consist of schema derived interfaces + * and classes representing the binding of schema + * type definitions, element declarations and model + * groups. Factory methods for each of these are + * provided in this class. + * + */ +@XmlRegistry +public class ObjectFactory { + + private final static QName _CheckSetupResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "checkSetupResponse"); + private final static QName _GetGlobalPropertyResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "getGlobalPropertyResponse"); + private final static QName _CreateDBConnectionResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "createDBConnectionResponse"); + private final static QName _GetGlobalProperty_QNAME = new QName("http://service.web.rapidanalytics.de/", "getGlobalProperty"); + private final static QName _CheckSetup_QNAME = new QName("http://service.web.rapidanalytics.de/", "checkSetup"); + private final static QName _CreateDBConnection_QNAME = new QName("http://service.web.rapidanalytics.de/", "createDBConnection"); + private final static QName _SetGlobalPropertyResponse_QNAME = new QName("http://service.web.rapidanalytics.de/", "setGlobalPropertyResponse"); + private final static QName _SetGlobalProperty_QNAME = new QName("http://service.web.rapidanalytics.de/", "setGlobalProperty"); + + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.rapid_i.repository.wsimport.mgt + * + */ + public ObjectFactory() { + } + + /** + * Create an instance of {@link CheckSetupResponse } + * + */ + public CheckSetupResponse createCheckSetupResponse() { + return new CheckSetupResponse(); + } + + /** + * Create an instance of {@link GetGlobalPropertyResponse } + * + */ + public GetGlobalPropertyResponse createGetGlobalPropertyResponse() { + return new GetGlobalPropertyResponse(); + } + + /** + * Create an instance of {@link CreateDBConnectionResponse } + * + */ + public CreateDBConnectionResponse createCreateDBConnectionResponse() { + return new CreateDBConnectionResponse(); + } + + /** + * Create an instance of {@link GetGlobalProperty } + * + */ + public GetGlobalProperty createGetGlobalProperty() { + return new GetGlobalProperty(); + } + + /** + * Create an instance of {@link CreateDBConnection } + * + */ + public CreateDBConnection createCreateDBConnection() { + return new CreateDBConnection(); + } + + /** + * Create an instance of {@link CheckSetup } + * + */ + public CheckSetup createCheckSetup() { + return new CheckSetup(); + } + + /** + * Create an instance of {@link SetGlobalPropertyResponse } + * + */ + public SetGlobalPropertyResponse createSetGlobalPropertyResponse() { + return new SetGlobalPropertyResponse(); + } + + /** + * Create an instance of {@link SetGlobalProperty } + * + */ + public SetGlobalProperty createSetGlobalProperty() { + return new SetGlobalProperty(); + } + + /** + * Create an instance of {@link Response } + * + */ + public Response createResponse() { + return new Response(); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CheckSetupResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "checkSetupResponse") + public JAXBElement createCheckSetupResponse(CheckSetupResponse value) { + return new JAXBElement(_CheckSetupResponse_QNAME, CheckSetupResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetGlobalPropertyResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getGlobalPropertyResponse") + public JAXBElement createGetGlobalPropertyResponse(GetGlobalPropertyResponse value) { + return new JAXBElement(_GetGlobalPropertyResponse_QNAME, GetGlobalPropertyResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CreateDBConnectionResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "createDBConnectionResponse") + public JAXBElement createCreateDBConnectionResponse(CreateDBConnectionResponse value) { + return new JAXBElement(_CreateDBConnectionResponse_QNAME, CreateDBConnectionResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link GetGlobalProperty }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "getGlobalProperty") + public JAXBElement createGetGlobalProperty(GetGlobalProperty value) { + return new JAXBElement(_GetGlobalProperty_QNAME, GetGlobalProperty.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CheckSetup }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "checkSetup") + public JAXBElement createCheckSetup(CheckSetup value) { + return new JAXBElement(_CheckSetup_QNAME, CheckSetup.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link CreateDBConnection }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "createDBConnection") + public JAXBElement createCreateDBConnection(CreateDBConnection value) { + return new JAXBElement(_CreateDBConnection_QNAME, CreateDBConnection.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link SetGlobalPropertyResponse }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "setGlobalPropertyResponse") + public JAXBElement createSetGlobalPropertyResponse(SetGlobalPropertyResponse value) { + return new JAXBElement(_SetGlobalPropertyResponse_QNAME, SetGlobalPropertyResponse.class, null, value); + } + + /** + * Create an instance of {@link JAXBElement }{@code <}{@link SetGlobalProperty }{@code >}} + * + */ + @XmlElementDecl(namespace = "http://service.web.rapidanalytics.de/", name = "setGlobalProperty") + public JAXBElement createSetGlobalProperty(SetGlobalProperty value) { + return new JAXBElement(_SetGlobalProperty_QNAME, SetGlobalProperty.class, null, value); + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/Response.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/Response.java new file mode 100644 index 000000000..9c2b6e764 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/Response.java @@ -0,0 +1,96 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for response complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="response">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="errorMessage" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="status" type="{http://www.w3.org/2001/XMLSchema}int"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "response", propOrder = { + "errorMessage", + "status" +}) +public class Response { + + protected String errorMessage; + protected int status; + + /** + * Gets the value of the errorMessage property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getErrorMessage() { + return errorMessage; + } + + /** + * Sets the value of the errorMessage property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setErrorMessage(String value) { + this.errorMessage = value; + } + + /** + * Gets the value of the status property. + * + */ + public int getStatus() { + return status; + } + + /** + * Sets the value of the status property. + * + */ + public void setStatus(int value) { + this.status = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/SetGlobalProperty.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/SetGlobalProperty.java new file mode 100644 index 000000000..1af18d872 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/SetGlobalProperty.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for setGlobalProperty complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="setGlobalProperty">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *         <element name="key" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="value" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "setGlobalProperty", propOrder = { + "key", + "value" +}) +public class SetGlobalProperty { + + protected String key; + protected String value; + + /** + * Gets the value of the key property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getKey() { + return key; + } + + /** + * Sets the value of the key property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setKey(String value) { + this.key = value; + } + + /** + * Gets the value of the value property. + * + * @return + * possible object is + * {@link String } + * + */ + public String getValue() { + return value; + } + + /** + * Sets the value of the value property. + * + * @param value + * allowed object is + * {@link String } + * + */ + public void setValue(String value) { + this.value = value; + } + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/SetGlobalPropertyResponse.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/SetGlobalPropertyResponse.java new file mode 100644 index 000000000..661c3fe60 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/SetGlobalPropertyResponse.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapid_i.repository.wsimport.mgt; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for setGlobalPropertyResponse complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="setGlobalPropertyResponse">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <sequence>
+ *       </sequence>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "setGlobalPropertyResponse") +public class SetGlobalPropertyResponse { + + +} diff --git a/src/generated/java/com/rapid_i/repository/wsimport/mgt/package-info.java b/src/generated/java/com/rapid_i/repository/wsimport/mgt/package-info.java new file mode 100644 index 000000000..e1fdd25b2 --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/mgt/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +@javax.xml.bind.annotation.XmlSchema(namespace = "http://service.web.rapidanalytics.de/") +package com.rapid_i.repository.wsimport.mgt; diff --git a/src/generated/java/com/rapid_i/repository/wsimport/package-info.java b/src/generated/java/com/rapid_i/repository/wsimport/package-info.java new file mode 100644 index 000000000..e9d5e359e --- /dev/null +++ b/src/generated/java/com/rapid_i/repository/wsimport/package-info.java @@ -0,0 +1,20 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +@javax.xml.bind.annotation.XmlSchema(namespace = "http://service.web.rapidanalytics.de/") +package com.rapid_i.repository.wsimport; diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionLexer.java b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionLexer.java new file mode 100644 index 000000000..6e1507d54 --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionLexer.java @@ -0,0 +1,218 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +// Generated from FunctionExpressionLexer.g4 by ANTLR 4.5 +package com.rapidminer.tools.expression.internal.antlr; + +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.RuntimeMetaData; +import org.antlr.v4.runtime.Vocabulary; +import org.antlr.v4.runtime.VocabularyImpl; +import org.antlr.v4.runtime.atn.ATN; +import org.antlr.v4.runtime.atn.ATNDeserializer; +import org.antlr.v4.runtime.atn.LexerATNSimulator; +import org.antlr.v4.runtime.atn.PredictionContextCache; +import org.antlr.v4.runtime.dfa.DFA; + + +@SuppressWarnings({ "all", "warnings", "unchecked", "unused", "cast" }) +public class FunctionExpressionLexer extends Lexer { + + static { + RuntimeMetaData.checkVersion("4.5", RuntimeMetaData.VERSION); + } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = new PredictionContextCache(); + public static final int PLUS = 1, MINUS = 2, MULTIPLY = 3, DIVIDE = 4, MODULO = 5, POWER = 6, LESS = 7, LEQ = 8, + GREATER = 9, GEQ = 10, EQUALS = 11, NOT_EQUALS = 12, NOT = 13, OR = 14, AND = 15, LPARENTHESIS = 16, + RPARENTHESIS = 17, COMMA = 18, NAME = 19, INTEGER = 20, REAL = 21, ATTRIBUTE = 22, STRING = 23, + SCOPE_CONSTANT = 24, INDIRECT_SCOPE_CONSTANT = 25, LSQUARE_BRACKET = 26, OPENING_QOUTES = 27, SCOPE_OPEN = 28, + INDIRECT_SCOPE_OPEN = 29, WHITESPACES = 30, SCOPE_CLOSE = 31, RSQUARE_BRACKET = 32, CLOSING_QUOTES = 33; + public static final int INSIDE_SCOPE = 1; + public static final int INSIDE_ATTRIBUTE = 2; + public static final int INSIDE_STRING = 3; + public static String[] modeNames = { "DEFAULT_MODE", "INSIDE_SCOPE", "INSIDE_ATTRIBUTE", "INSIDE_STRING" }; + + public static final String[] ruleNames = { "PLUS", "MINUS", "MULTIPLY", "DIVIDE", "MODULO", "POWER", "LESS", "LEQ", + "GREATER", "GEQ", "EQUALS", "NOT_EQUALS", "NOT", "OR", "AND", "LPARENTHESIS", "RPARENTHESIS", "COMMA", "NAME", + "INTEGER", "REAL", "DIGITS", "EXPONENT", "ATTRIBUTE", "STRING", "SCOPE_CONSTANT", "INDIRECT_SCOPE_CONSTANT", + "INSIDE_ATTRIBUTE", "INSIDE_SCOPE", "INSIDE_STRING", "UNICODE", "UNICODE_CHAR", "LSQUARE_BRACKET", + "OPENING_QOUTES", "SCOPE_OPEN", "INDIRECT_SCOPE_OPEN", "WHITESPACES", "SCOPE_CLOSE", "RSQUARE_BRACKET", + "CLOSING_QUOTES" }; + + private static final String[] _LITERAL_NAMES = { null, "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "'<'", "'<='", "'>'", + "'>='", "'=='", "'!='", "'!'", "'||'", "'&&'", "'('", "')'", "','", null, null, null, null, null, null, null, + "'['", null, "'%{'", "'#{'", null, "'}'", "']'" }; + private static final String[] _SYMBOLIC_NAMES = { null, "PLUS", "MINUS", "MULTIPLY", "DIVIDE", "MODULO", "POWER", + "LESS", "LEQ", "GREATER", "GEQ", "EQUALS", "NOT_EQUALS", "NOT", "OR", "AND", "LPARENTHESIS", "RPARENTHESIS", + "COMMA", "NAME", "INTEGER", "REAL", "ATTRIBUTE", "STRING", "SCOPE_CONSTANT", "INDIRECT_SCOPE_CONSTANT", + "LSQUARE_BRACKET", "OPENING_QOUTES", "SCOPE_OPEN", "INDIRECT_SCOPE_OPEN", "WHITESPACES", "SCOPE_CLOSE", + "RSQUARE_BRACKET", "CLOSING_QUOTES" }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + public FunctionExpressionLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this, _ATN, _decisionToDFA, _sharedContextCache); + } + + @Override + public String getGrammarFileName() { + return "FunctionExpressionLexer.g4"; + } + + @Override + public String[] getRuleNames() { + return ruleNames; + } + + @Override + public String getSerializedATN() { + return _serializedATN; + } + + @Override + public String[] getModeNames() { + return modeNames; + } + + @Override + public ATN getATN() { + return _ATN; + } + + public static final String _serializedATN = "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2#\u00fa\b\1\b\1\b" + + "\1\b\1\4\2\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t" + + "\4\n\t\n\4\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21" + + "\t\21\4\22\t\22\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30" + + "\t\30\4\31\t\31\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37" + + "\t\37\4 \t \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)" + + "\3\2\3\2\3\3\3\3\3\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\t\3" + + "\n\3\n\3\13\3\13\3\13\3\f\3\f\3\f\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\17" + + "\3\20\3\20\3\20\3\21\3\21\3\22\3\22\3\23\3\23\3\24\6\24\u0082\n\24\r\24" + + "\16\24\u0083\3\24\7\24\u0087\n\24\f\24\16\24\u008a\13\24\3\25\3\25\3\26" + + "\3\26\3\26\5\26\u0091\n\26\3\26\3\26\5\26\u0095\n\26\3\26\5\26\u0098\n" + + "\26\3\27\6\27\u009b\n\27\r\27\16\27\u009c\3\30\3\30\5\30\u00a1\n\30\3" + + "\30\3\30\3\31\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3" + + "\34\3\34\3\34\3\34\3\35\3\35\3\35\6\35\u00b8\n\35\r\35\16\35\u00b9\3\36" + + "\3\36\3\36\6\36\u00bf\n\36\r\36\16\36\u00c0\3\37\3\37\3\37\3\37\3\37\7" + + "\37\u00c8\n\37\f\37\16\37\u00cb\13\37\3 \3 \3 \3 \3 \3 \3 \3!\3!\3\"\3" + + "\"\3\"\3\"\3#\3#\3#\3#\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3&\6&\u00e9\n&\r" + + "&\16&\u00ea\3&\3&\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3)\3)\3)\3)\2\2*\6\3\b\4" + + "\n\5\f\6\16\7\20\b\22\t\24\n\26\13\30\f\32\r\34\16\36\17 \20\"\21$\22" + + "&\23(\24*\25,\26.\27\60\2\62\2\64\30\66\318\32:\33<\2>\2@\2B\2D\2F\34" + + "H\35J\36L\37N P!R\"T#\6\2\3\4\5\r\4\2C\\c|\6\2\62;C\\aac|\4\2GGgg\4\2" + + "--//\4\2\13\f]_\6\2\13\f^^}}\177\177\5\2^^}}\177\177\4\2$$^^\4\2\13\f" + + "\17\17\5\2\62;CHch\5\2\13\f\17\17\"\"\u00ff\2\6\3\2\2\2\2\b\3\2\2\2\2" + + "\n\3\2\2\2\2\f\3\2\2\2\2\16\3\2\2\2\2\20\3\2\2\2\2\22\3\2\2\2\2\24\3\2" + + "\2\2\2\26\3\2\2\2\2\30\3\2\2\2\2\32\3\2\2\2\2\34\3\2\2\2\2\36\3\2\2\2" + + "\2 \3\2\2\2\2\"\3\2\2\2\2$\3\2\2\2\2&\3\2\2\2\2(\3\2\2\2\2*\3\2\2\2\2" + + ",\3\2\2\2\2.\3\2\2\2\2\64\3\2\2\2\2\66\3\2\2\2\28\3\2\2\2\2:\3\2\2\2\2" + + "F\3\2\2\2\2H\3\2\2\2\2J\3\2\2\2\2L\3\2\2\2\2N\3\2\2\2\3P\3\2\2\2\4R\3" + + "\2\2\2\5T\3\2\2\2\6V\3\2\2\2\bX\3\2\2\2\nZ\3\2\2\2\f\\\3\2\2\2\16^\3\2" + + "\2\2\20`\3\2\2\2\22b\3\2\2\2\24d\3\2\2\2\26g\3\2\2\2\30i\3\2\2\2\32l\3" + + "\2\2\2\34o\3\2\2\2\36r\3\2\2\2 t\3\2\2\2\"w\3\2\2\2$z\3\2\2\2&|\3\2\2" + + "\2(~\3\2\2\2*\u0081\3\2\2\2,\u008b\3\2\2\2.\u0094\3\2\2\2\60\u009a\3\2" + + "\2\2\62\u009e\3\2\2\2\64\u00a4\3\2\2\2\66\u00a8\3\2\2\28\u00ac\3\2\2\2" + + ":\u00b0\3\2\2\2<\u00b7\3\2\2\2>\u00be\3\2\2\2@\u00c9\3\2\2\2B\u00cc\3" + + "\2\2\2D\u00d3\3\2\2\2F\u00d5\3\2\2\2H\u00d9\3\2\2\2J\u00dd\3\2\2\2L\u00e2" + + "\3\2\2\2N\u00e8\3\2\2\2P\u00ee\3\2\2\2R\u00f2\3\2\2\2T\u00f6\3\2\2\2V" + + "W\7-\2\2W\7\3\2\2\2XY\7/\2\2Y\t\3\2\2\2Z[\7,\2\2[\13\3\2\2\2\\]\7\61\2" + + "\2]\r\3\2\2\2^_\7\'\2\2_\17\3\2\2\2`a\7`\2\2a\21\3\2\2\2bc\7>\2\2c\23" + + "\3\2\2\2de\7>\2\2ef\7?\2\2f\25\3\2\2\2gh\7@\2\2h\27\3\2\2\2ij\7@\2\2j" + + "k\7?\2\2k\31\3\2\2\2lm\7?\2\2mn\7?\2\2n\33\3\2\2\2op\7#\2\2pq\7?\2\2q" + + "\35\3\2\2\2rs\7#\2\2s\37\3\2\2\2tu\7~\2\2uv\7~\2\2v!\3\2\2\2wx\7(\2\2" + + "xy\7(\2\2y#\3\2\2\2z{\7*\2\2{%\3\2\2\2|}\7+\2\2}\'\3\2\2\2~\177\7.\2\2" + + "\177)\3\2\2\2\u0080\u0082\t\2\2\2\u0081\u0080\3\2\2\2\u0082\u0083\3\2" + + "\2\2\u0083\u0081\3\2\2\2\u0083\u0084\3\2\2\2\u0084\u0088\3\2\2\2\u0085" + + "\u0087\t\3\2\2\u0086\u0085\3\2\2\2\u0087\u008a\3\2\2\2\u0088\u0086\3\2" + + "\2\2\u0088\u0089\3\2\2\2\u0089+\3\2\2\2\u008a\u0088\3\2\2\2\u008b\u008c" + + "\5\60\27\2\u008c-\3\2\2\2\u008d\u0090\5\60\27\2\u008e\u008f\7\60\2\2\u008f" + + "\u0091\5\60\27\2\u0090\u008e\3\2\2\2\u0090\u0091\3\2\2\2\u0091\u0095\3" + + "\2\2\2\u0092\u0093\7\60\2\2\u0093\u0095\5\60\27\2\u0094\u008d\3\2\2\2" + + "\u0094\u0092\3\2\2\2\u0095\u0097\3\2\2\2\u0096\u0098\5\62\30\2\u0097\u0096" + + "\3\2\2\2\u0097\u0098\3\2\2\2\u0098/\3\2\2\2\u0099\u009b\4\62;\2\u009a" + + "\u0099\3\2\2\2\u009b\u009c\3\2\2\2\u009c\u009a\3\2\2\2\u009c\u009d\3\2" + + "\2\2\u009d\61\3\2\2\2\u009e\u00a0\t\4\2\2\u009f\u00a1\t\5\2\2\u00a0\u009f" + + "\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1\u00a2\3\2\2\2\u00a2\u00a3\5\60\27\2" + + "\u00a3\63\3\2\2\2\u00a4\u00a5\5F\"\2\u00a5\u00a6\5<\35\2\u00a6\u00a7\5" + + "R(\2\u00a7\65\3\2\2\2\u00a8\u00a9\5H#\2\u00a9\u00aa\5@\37\2\u00aa\u00ab" + + "\5T)\2\u00ab\67\3\2\2\2\u00ac\u00ad\5J$\2\u00ad\u00ae\5>\36\2\u00ae\u00af" + + "\5P\'\2\u00af9\3\2\2\2\u00b0\u00b1\5L%\2\u00b1\u00b2\5>\36\2\u00b2\u00b3" + + "\5P\'\2\u00b3;\3\2\2\2\u00b4\u00b8\n\6\2\2\u00b5\u00b6\7^\2\2\u00b6\u00b8" + + "\4]_\2\u00b7\u00b4\3\2\2\2\u00b7\u00b5\3\2\2\2\u00b8\u00b9\3\2\2\2\u00b9" + + "\u00b7\3\2\2\2\u00b9\u00ba\3\2\2\2\u00ba=\3\2\2\2\u00bb\u00bf\n\7\2\2" + + "\u00bc\u00bd\7^\2\2\u00bd\u00bf\t\b\2\2\u00be\u00bb\3\2\2\2\u00be\u00bc" + + "\3\2\2\2\u00bf\u00c0\3\2\2\2\u00c0\u00be\3\2\2\2\u00c0\u00c1\3\2\2\2\u00c1" + + "?\3\2\2\2\u00c2\u00c8\n\t\2\2\u00c3\u00c8\t\n\2\2\u00c4\u00c5\7^\2\2\u00c5" + + "\u00c8\t\t\2\2\u00c6\u00c8\5B \2\u00c7\u00c2\3\2\2\2\u00c7\u00c3\3\2\2" + + "\2\u00c7\u00c4\3\2\2\2\u00c7\u00c6\3\2\2\2\u00c8\u00cb\3\2\2\2\u00c9\u00c7" + + "\3\2\2\2\u00c9\u00ca\3\2\2\2\u00caA\3\2\2\2\u00cb\u00c9\3\2\2\2\u00cc" + + "\u00cd\7^\2\2\u00cd\u00ce\7w\2\2\u00ce\u00cf\5D!\2\u00cf\u00d0\5D!\2\u00d0" + + "\u00d1\5D!\2\u00d1\u00d2\5D!\2\u00d2C\3\2\2\2\u00d3\u00d4\t\13\2\2\u00d4" + + "E\3\2\2\2\u00d5\u00d6\7]\2\2\u00d6\u00d7\3\2\2\2\u00d7\u00d8\b\"\2\2\u00d8" + + "G\3\2\2\2\u00d9\u00da\7$\2\2\u00da\u00db\3\2\2\2\u00db\u00dc\b#\3\2\u00dc" + + "I\3\2\2\2\u00dd\u00de\7\'\2\2\u00de\u00df\7}\2\2\u00df\u00e0\3\2\2\2\u00e0" + + "\u00e1\b$\4\2\u00e1K\3\2\2\2\u00e2\u00e3\7%\2\2\u00e3\u00e4\7}\2\2\u00e4" + + "\u00e5\3\2\2\2\u00e5\u00e6\b%\4\2\u00e6M\3\2\2\2\u00e7\u00e9\t\f\2\2\u00e8" + + "\u00e7\3\2\2\2\u00e9\u00ea\3\2\2\2\u00ea\u00e8\3\2\2\2\u00ea\u00eb\3\2" + + "\2\2\u00eb\u00ec\3\2\2\2\u00ec\u00ed\b&\5\2\u00edO\3\2\2\2\u00ee\u00ef" + + "\7\177\2\2\u00ef\u00f0\3\2\2\2\u00f0\u00f1\b\'\6\2\u00f1Q\3\2\2\2\u00f2" + + "\u00f3\7_\2\2\u00f3\u00f4\3\2\2\2\u00f4\u00f5\b(\6\2\u00f5S\3\2\2\2\u00f6" + + "\u00f7\7$\2\2\u00f7\u00f8\3\2\2\2\u00f8\u00f9\b)\6\2\u00f9U\3\2\2\2\24" + + "\2\3\4\5\u0083\u0088\u0090\u0094\u0097\u009c\u00a0\u00b7\u00b9\u00be\u00c0" + + "\u00c7\u00c9\u00ea\7\4\4\2\4\5\2\4\3\2\b\2\2\4\2\2"; + public static final ATN _ATN = new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionLexer.tokens b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionLexer.tokens new file mode 100644 index 000000000..9558e0a80 --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionLexer.tokens @@ -0,0 +1,56 @@ +PLUS=1 +MINUS=2 +MULTIPLY=3 +DIVIDE=4 +MODULO=5 +POWER=6 +LESS=7 +LEQ=8 +GREATER=9 +GEQ=10 +EQUALS=11 +NOT_EQUALS=12 +NOT=13 +OR=14 +AND=15 +LPARENTHESIS=16 +RPARENTHESIS=17 +COMMA=18 +NAME=19 +INTEGER=20 +REAL=21 +ATTRIBUTE=22 +STRING=23 +SCOPE_CONSTANT=24 +INDIRECT_SCOPE_CONSTANT=25 +LSQUARE_BRACKET=26 +OPENING_QOUTES=27 +SCOPE_OPEN=28 +INDIRECT_SCOPE_OPEN=29 +WHITESPACES=30 +SCOPE_CLOSE=31 +RSQUARE_BRACKET=32 +CLOSING_QUOTES=33 +'+'=1 +'-'=2 +'*'=3 +'/'=4 +'%'=5 +'^'=6 +'<'=7 +'<='=8 +'>'=9 +'>='=10 +'=='=11 +'!='=12 +'!'=13 +'||'=14 +'&&'=15 +'('=16 +')'=17 +','=18 +'['=26 +'%{'=28 +'#{'=29 +'}'=31 +']'=32 diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParser.java b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParser.java new file mode 100644 index 000000000..53b979315 --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParser.java @@ -0,0 +1,992 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +// Generated from FunctionExpressionParser.g4 by ANTLR 4.5 +package com.rapidminer.tools.expression.internal.antlr; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"}) +public class FunctionExpressionParser extends Parser { + static { RuntimeMetaData.checkVersion("4.5", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + PLUS=1, MINUS=2, MULTIPLY=3, DIVIDE=4, MODULO=5, POWER=6, LESS=7, LEQ=8, + GREATER=9, GEQ=10, EQUALS=11, NOT_EQUALS=12, NOT=13, OR=14, AND=15, LPARENTHESIS=16, + RPARENTHESIS=17, COMMA=18, NAME=19, INTEGER=20, REAL=21, ATTRIBUTE=22, + STRING=23, SCOPE_CONSTANT=24, INDIRECT_SCOPE_CONSTANT=25, LSQUARE_BRACKET=26, + OPENING_QOUTES=27, SCOPE_OPEN=28, INDIRECT_SCOPE_OPEN=29, WHITESPACES=30, + SCOPE_CLOSE=31, RSQUARE_BRACKET=32, CLOSING_QUOTES=33; + public static final int + RULE_operationExp = 0, RULE_atomExp = 1, RULE_lowerExp = 2, RULE_function = 3, + RULE_attribute = 4, RULE_scopeConstant = 5, RULE_indirectScopeConstant = 6, + RULE_string = 7, RULE_variable = 8, RULE_real = 9, RULE_integer = 10; + public static final String[] ruleNames = { + "operationExp", "atomExp", "lowerExp", "function", "attribute", "scopeConstant", + "indirectScopeConstant", "string", "variable", "real", "integer" + }; + + private static final String[] _LITERAL_NAMES = { + null, "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "'<'", "'<='", "'>'", + "'>='", "'=='", "'!='", "'!'", "'||'", "'&&'", "'('", "')'", "','", null, + null, null, null, null, null, null, "'['", null, "'%{'", "'#{'", null, + "'}'", "']'" + }; + private static final String[] _SYMBOLIC_NAMES = { + null, "PLUS", "MINUS", "MULTIPLY", "DIVIDE", "MODULO", "POWER", "LESS", + "LEQ", "GREATER", "GEQ", "EQUALS", "NOT_EQUALS", "NOT", "OR", "AND", "LPARENTHESIS", + "RPARENTHESIS", "COMMA", "NAME", "INTEGER", "REAL", "ATTRIBUTE", "STRING", + "SCOPE_CONSTANT", "INDIRECT_SCOPE_CONSTANT", "LSQUARE_BRACKET", "OPENING_QOUTES", + "SCOPE_OPEN", "INDIRECT_SCOPE_OPEN", "WHITESPACES", "SCOPE_CLOSE", "RSQUARE_BRACKET", + "CLOSING_QUOTES" + }; + public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); + + /** + * @deprecated Use {@link #VOCABULARY} instead. + */ + @Deprecated + public static final String[] tokenNames; + static { + tokenNames = new String[_SYMBOLIC_NAMES.length]; + for (int i = 0; i < tokenNames.length; i++) { + tokenNames[i] = VOCABULARY.getLiteralName(i); + if (tokenNames[i] == null) { + tokenNames[i] = VOCABULARY.getSymbolicName(i); + } + + if (tokenNames[i] == null) { + tokenNames[i] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "FunctionExpressionParser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public FunctionExpressionParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + public static class OperationExpContext extends ParserRuleContext { + public Token op; + public List operationExp() { + return getRuleContexts(OperationExpContext.class); + } + public OperationExpContext operationExp(int i) { + return getRuleContext(OperationExpContext.class,i); + } + public TerminalNode NOT() { return getToken(FunctionExpressionParser.NOT, 0); } + public TerminalNode PLUS() { return getToken(FunctionExpressionParser.PLUS, 0); } + public TerminalNode MINUS() { return getToken(FunctionExpressionParser.MINUS, 0); } + public AtomExpContext atomExp() { + return getRuleContext(AtomExpContext.class,0); + } + public TerminalNode POWER() { return getToken(FunctionExpressionParser.POWER, 0); } + public TerminalNode MULTIPLY() { return getToken(FunctionExpressionParser.MULTIPLY, 0); } + public TerminalNode DIVIDE() { return getToken(FunctionExpressionParser.DIVIDE, 0); } + public TerminalNode MODULO() { return getToken(FunctionExpressionParser.MODULO, 0); } + public TerminalNode LESS() { return getToken(FunctionExpressionParser.LESS, 0); } + public TerminalNode LEQ() { return getToken(FunctionExpressionParser.LEQ, 0); } + public TerminalNode GREATER() { return getToken(FunctionExpressionParser.GREATER, 0); } + public TerminalNode GEQ() { return getToken(FunctionExpressionParser.GEQ, 0); } + public TerminalNode EQUALS() { return getToken(FunctionExpressionParser.EQUALS, 0); } + public TerminalNode NOT_EQUALS() { return getToken(FunctionExpressionParser.NOT_EQUALS, 0); } + public TerminalNode AND() { return getToken(FunctionExpressionParser.AND, 0); } + public TerminalNode OR() { return getToken(FunctionExpressionParser.OR, 0); } + public OperationExpContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_operationExp; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterOperationExp(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitOperationExp(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitOperationExp(this); + else return visitor.visitChildren(this); + } + } + + public final OperationExpContext operationExp() throws RecognitionException { + return operationExp(0); + } + + private OperationExpContext operationExp(int _p) throws RecognitionException { + ParserRuleContext _parentctx = _ctx; + int _parentState = getState(); + OperationExpContext _localctx = new OperationExpContext(_ctx, _parentState); + OperationExpContext _prevctx = _localctx; + int _startState = 0; + enterRecursionRule(_localctx, 0, RULE_operationExp, _p); + int _la; + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(28); + switch (_input.LA(1)) { + case NOT: + { + setState(23); + ((OperationExpContext)_localctx).op = match(NOT); + setState(24); + operationExp(10); + } + break; + case PLUS: + case MINUS: + { + setState(25); + ((OperationExpContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + ((OperationExpContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } else { + consume(); + } + setState(26); + operationExp(9); + } + break; + case LPARENTHESIS: + case NAME: + case INTEGER: + case REAL: + case ATTRIBUTE: + case STRING: + case SCOPE_CONSTANT: + case INDIRECT_SCOPE_CONSTANT: + { + setState(27); + atomExp(); + } + break; + default: + throw new NoViableAltException(this); + } + _ctx.stop = _input.LT(-1); + setState(53); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { + if ( _alt==1 ) { + if ( _parseListeners!=null ) triggerExitRuleEvent(); + _prevctx = _localctx; + { + setState(51); + switch ( getInterpreter().adaptivePredict(_input,1,_ctx) ) { + case 1: + { + _localctx = new OperationExpContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_operationExp); + setState(30); + if (!(precpred(_ctx, 8))) throw new FailedPredicateException(this, "precpred(_ctx, 8)"); + setState(31); + ((OperationExpContext)_localctx).op = match(POWER); + setState(32); + operationExp(8); + } + break; + case 2: + { + _localctx = new OperationExpContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_operationExp); + setState(33); + if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)"); + setState(34); + ((OperationExpContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << MULTIPLY) | (1L << DIVIDE) | (1L << MODULO))) != 0)) ) { + ((OperationExpContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } else { + consume(); + } + setState(35); + operationExp(8); + } + break; + case 3: + { + _localctx = new OperationExpContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_operationExp); + setState(36); + if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)"); + setState(37); + ((OperationExpContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==PLUS || _la==MINUS) ) { + ((OperationExpContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } else { + consume(); + } + setState(38); + operationExp(7); + } + break; + case 4: + { + _localctx = new OperationExpContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_operationExp); + setState(39); + if (!(precpred(_ctx, 5))) throw new FailedPredicateException(this, "precpred(_ctx, 5)"); + setState(40); + ((OperationExpContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LESS) | (1L << LEQ) | (1L << GREATER) | (1L << GEQ))) != 0)) ) { + ((OperationExpContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } else { + consume(); + } + setState(41); + operationExp(6); + } + break; + case 5: + { + _localctx = new OperationExpContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_operationExp); + setState(42); + if (!(precpred(_ctx, 4))) throw new FailedPredicateException(this, "precpred(_ctx, 4)"); + setState(43); + ((OperationExpContext)_localctx).op = _input.LT(1); + _la = _input.LA(1); + if ( !(_la==EQUALS || _la==NOT_EQUALS) ) { + ((OperationExpContext)_localctx).op = (Token)_errHandler.recoverInline(this); + } else { + consume(); + } + setState(44); + operationExp(5); + } + break; + case 6: + { + _localctx = new OperationExpContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_operationExp); + setState(45); + if (!(precpred(_ctx, 3))) throw new FailedPredicateException(this, "precpred(_ctx, 3)"); + setState(46); + ((OperationExpContext)_localctx).op = match(AND); + setState(47); + operationExp(4); + } + break; + case 7: + { + _localctx = new OperationExpContext(_parentctx, _parentState); + pushNewRecursionContext(_localctx, _startState, RULE_operationExp); + setState(48); + if (!(precpred(_ctx, 2))) throw new FailedPredicateException(this, "precpred(_ctx, 2)"); + setState(49); + ((OperationExpContext)_localctx).op = match(OR); + setState(50); + operationExp(3); + } + break; + } + } + } + setState(55); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,2,_ctx); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + unrollRecursionContexts(_parentctx); + } + return _localctx; + } + + public static class AtomExpContext extends ParserRuleContext { + public FunctionContext function() { + return getRuleContext(FunctionContext.class,0); + } + public AttributeContext attribute() { + return getRuleContext(AttributeContext.class,0); + } + public ScopeConstantContext scopeConstant() { + return getRuleContext(ScopeConstantContext.class,0); + } + public IndirectScopeConstantContext indirectScopeConstant() { + return getRuleContext(IndirectScopeConstantContext.class,0); + } + public StringContext string() { + return getRuleContext(StringContext.class,0); + } + public VariableContext variable() { + return getRuleContext(VariableContext.class,0); + } + public RealContext real() { + return getRuleContext(RealContext.class,0); + } + public IntegerContext integer() { + return getRuleContext(IntegerContext.class,0); + } + public LowerExpContext lowerExp() { + return getRuleContext(LowerExpContext.class,0); + } + public AtomExpContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_atomExp; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterAtomExp(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitAtomExp(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitAtomExp(this); + else return visitor.visitChildren(this); + } + } + + public final AtomExpContext atomExp() throws RecognitionException { + AtomExpContext _localctx = new AtomExpContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_atomExp); + try { + setState(65); + switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(56); + function(); + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(57); + attribute(); + } + break; + case 3: + enterOuterAlt(_localctx, 3); + { + setState(58); + scopeConstant(); + } + break; + case 4: + enterOuterAlt(_localctx, 4); + { + setState(59); + indirectScopeConstant(); + } + break; + case 5: + enterOuterAlt(_localctx, 5); + { + setState(60); + string(); + } + break; + case 6: + enterOuterAlt(_localctx, 6); + { + setState(61); + variable(); + } + break; + case 7: + enterOuterAlt(_localctx, 7); + { + setState(62); + real(); + } + break; + case 8: + enterOuterAlt(_localctx, 8); + { + setState(63); + integer(); + } + break; + case 9: + enterOuterAlt(_localctx, 9); + { + setState(64); + lowerExp(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class LowerExpContext extends ParserRuleContext { + public TerminalNode LPARENTHESIS() { return getToken(FunctionExpressionParser.LPARENTHESIS, 0); } + public OperationExpContext operationExp() { + return getRuleContext(OperationExpContext.class,0); + } + public TerminalNode RPARENTHESIS() { return getToken(FunctionExpressionParser.RPARENTHESIS, 0); } + public LowerExpContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_lowerExp; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterLowerExp(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitLowerExp(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitLowerExp(this); + else return visitor.visitChildren(this); + } + } + + public final LowerExpContext lowerExp() throws RecognitionException { + LowerExpContext _localctx = new LowerExpContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_lowerExp); + try { + enterOuterAlt(_localctx, 1); + { + setState(67); + match(LPARENTHESIS); + setState(68); + operationExp(0); + setState(69); + match(RPARENTHESIS); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class FunctionContext extends ParserRuleContext { + public TerminalNode NAME() { return getToken(FunctionExpressionParser.NAME, 0); } + public TerminalNode LPARENTHESIS() { return getToken(FunctionExpressionParser.LPARENTHESIS, 0); } + public TerminalNode RPARENTHESIS() { return getToken(FunctionExpressionParser.RPARENTHESIS, 0); } + public List operationExp() { + return getRuleContexts(OperationExpContext.class); + } + public OperationExpContext operationExp(int i) { + return getRuleContext(OperationExpContext.class,i); + } + public List COMMA() { return getTokens(FunctionExpressionParser.COMMA); } + public TerminalNode COMMA(int i) { + return getToken(FunctionExpressionParser.COMMA, i); + } + public FunctionContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_function; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterFunction(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitFunction(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitFunction(this); + else return visitor.visitChildren(this); + } + } + + public final FunctionContext function() throws RecognitionException { + FunctionContext _localctx = new FunctionContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_function); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(71); + match(NAME); + setState(72); + match(LPARENTHESIS); + setState(82); + switch (_input.LA(1)) { + case RPARENTHESIS: + { + } + break; + case PLUS: + case MINUS: + case NOT: + case LPARENTHESIS: + case NAME: + case INTEGER: + case REAL: + case ATTRIBUTE: + case STRING: + case SCOPE_CONSTANT: + case INDIRECT_SCOPE_CONSTANT: + { + setState(74); + operationExp(0); + setState(79); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==COMMA) { + { + { + setState(75); + match(COMMA); + setState(76); + operationExp(0); + } + } + setState(81); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(84); + match(RPARENTHESIS); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class AttributeContext extends ParserRuleContext { + public TerminalNode ATTRIBUTE() { return getToken(FunctionExpressionParser.ATTRIBUTE, 0); } + public AttributeContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_attribute; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterAttribute(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitAttribute(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitAttribute(this); + else return visitor.visitChildren(this); + } + } + + public final AttributeContext attribute() throws RecognitionException { + AttributeContext _localctx = new AttributeContext(_ctx, getState()); + enterRule(_localctx, 8, RULE_attribute); + try { + enterOuterAlt(_localctx, 1); + { + setState(86); + match(ATTRIBUTE); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ScopeConstantContext extends ParserRuleContext { + public TerminalNode SCOPE_CONSTANT() { return getToken(FunctionExpressionParser.SCOPE_CONSTANT, 0); } + public ScopeConstantContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_scopeConstant; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterScopeConstant(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitScopeConstant(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitScopeConstant(this); + else return visitor.visitChildren(this); + } + } + + public final ScopeConstantContext scopeConstant() throws RecognitionException { + ScopeConstantContext _localctx = new ScopeConstantContext(_ctx, getState()); + enterRule(_localctx, 10, RULE_scopeConstant); + try { + enterOuterAlt(_localctx, 1); + { + setState(88); + match(SCOPE_CONSTANT); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IndirectScopeConstantContext extends ParserRuleContext { + public TerminalNode INDIRECT_SCOPE_CONSTANT() { return getToken(FunctionExpressionParser.INDIRECT_SCOPE_CONSTANT, 0); } + public IndirectScopeConstantContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_indirectScopeConstant; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterIndirectScopeConstant(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitIndirectScopeConstant(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitIndirectScopeConstant(this); + else return visitor.visitChildren(this); + } + } + + public final IndirectScopeConstantContext indirectScopeConstant() throws RecognitionException { + IndirectScopeConstantContext _localctx = new IndirectScopeConstantContext(_ctx, getState()); + enterRule(_localctx, 12, RULE_indirectScopeConstant); + try { + enterOuterAlt(_localctx, 1); + { + setState(90); + match(INDIRECT_SCOPE_CONSTANT); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class StringContext extends ParserRuleContext { + public TerminalNode STRING() { return getToken(FunctionExpressionParser.STRING, 0); } + public StringContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_string; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterString(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitString(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitString(this); + else return visitor.visitChildren(this); + } + } + + public final StringContext string() throws RecognitionException { + StringContext _localctx = new StringContext(_ctx, getState()); + enterRule(_localctx, 14, RULE_string); + try { + enterOuterAlt(_localctx, 1); + { + setState(92); + match(STRING); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class VariableContext extends ParserRuleContext { + public TerminalNode NAME() { return getToken(FunctionExpressionParser.NAME, 0); } + public VariableContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_variable; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterVariable(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitVariable(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitVariable(this); + else return visitor.visitChildren(this); + } + } + + public final VariableContext variable() throws RecognitionException { + VariableContext _localctx = new VariableContext(_ctx, getState()); + enterRule(_localctx, 16, RULE_variable); + try { + enterOuterAlt(_localctx, 1); + { + setState(94); + match(NAME); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RealContext extends ParserRuleContext { + public TerminalNode REAL() { return getToken(FunctionExpressionParser.REAL, 0); } + public RealContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_real; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterReal(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitReal(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitReal(this); + else return visitor.visitChildren(this); + } + } + + public final RealContext real() throws RecognitionException { + RealContext _localctx = new RealContext(_ctx, getState()); + enterRule(_localctx, 18, RULE_real); + try { + enterOuterAlt(_localctx, 1); + { + setState(96); + match(REAL); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class IntegerContext extends ParserRuleContext { + public TerminalNode INTEGER() { return getToken(FunctionExpressionParser.INTEGER, 0); } + public IntegerContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_integer; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).enterInteger(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof FunctionExpressionParserListener ) ((FunctionExpressionParserListener)listener).exitInteger(this); + } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof FunctionExpressionParserVisitor ) return ((FunctionExpressionParserVisitor)visitor).visitInteger(this); + else return visitor.visitChildren(this); + } + } + + public final IntegerContext integer() throws RecognitionException { + IntegerContext _localctx = new IntegerContext(_ctx, getState()); + enterRule(_localctx, 20, RULE_integer); + try { + enterOuterAlt(_localctx, 1); + { + setState(98); + match(INTEGER); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) { + switch (ruleIndex) { + case 0: + return operationExp_sempred((OperationExpContext)_localctx, predIndex); + } + return true; + } + private boolean operationExp_sempred(OperationExpContext _localctx, int predIndex) { + switch (predIndex) { + case 0: + return precpred(_ctx, 8); + case 1: + return precpred(_ctx, 7); + case 2: + return precpred(_ctx, 6); + case 3: + return precpred(_ctx, 5); + case 4: + return precpred(_ctx, 4); + case 5: + return precpred(_ctx, 3); + case 6: + return precpred(_ctx, 2); + } + return true; + } + + public static final String _serializedATN = + "\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\3#g\4\2\t\2\4\3\t\3"+ + "\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4\f"+ + "\t\f\3\2\3\2\3\2\3\2\3\2\3\2\5\2\37\n\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3"+ + "\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\7\2\66\n\2\f\2"+ + "\16\29\13\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\5\3D\n\3\3\4\3\4\3\4\3"+ + "\4\3\5\3\5\3\5\3\5\3\5\3\5\7\5P\n\5\f\5\16\5S\13\5\5\5U\n\5\3\5\3\5\3"+ + "\6\3\6\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\f\3\f\3\f\2\3\2\r\2"+ + "\4\6\b\n\f\16\20\22\24\26\2\6\3\2\3\4\3\2\5\7\3\2\t\f\3\2\r\16n\2\36\3"+ + "\2\2\2\4C\3\2\2\2\6E\3\2\2\2\bI\3\2\2\2\nX\3\2\2\2\fZ\3\2\2\2\16\\\3\2"+ + "\2\2\20^\3\2\2\2\22`\3\2\2\2\24b\3\2\2\2\26d\3\2\2\2\30\31\b\2\1\2\31"+ + "\32\7\17\2\2\32\37\5\2\2\f\33\34\t\2\2\2\34\37\5\2\2\13\35\37\5\4\3\2"+ + "\36\30\3\2\2\2\36\33\3\2\2\2\36\35\3\2\2\2\37\67\3\2\2\2 !\f\n\2\2!\""+ + "\7\b\2\2\"\66\5\2\2\n#$\f\t\2\2$%\t\3\2\2%\66\5\2\2\n&\'\f\b\2\2\'(\t"+ + "\2\2\2(\66\5\2\2\t)*\f\7\2\2*+\t\4\2\2+\66\5\2\2\b,-\f\6\2\2-.\t\5\2\2"+ + ".\66\5\2\2\7/\60\f\5\2\2\60\61\7\21\2\2\61\66\5\2\2\6\62\63\f\4\2\2\63"+ + "\64\7\20\2\2\64\66\5\2\2\5\65 \3\2\2\2\65#\3\2\2\2\65&\3\2\2\2\65)\3\2"+ + "\2\2\65,\3\2\2\2\65/\3\2\2\2\65\62\3\2\2\2\669\3\2\2\2\67\65\3\2\2\2\67"+ + "8\3\2\2\28\3\3\2\2\29\67\3\2\2\2:D\5\b\5\2;D\5\n\6\2D\5\20\t\2?D\5\22\n\2@D\5\24\13\2AD\5\26\f\2BD\5\6\4\2C:\3\2\2\2"+ + "C;\3\2\2\2C<\3\2\2\2C=\3\2\2\2C>\3\2\2\2C?\3\2\2\2C@\3\2\2\2CA\3\2\2\2"+ + "CB\3\2\2\2D\5\3\2\2\2EF\7\22\2\2FG\5\2\2\2GH\7\23\2\2H\7\3\2\2\2IJ\7\25"+ + "\2\2JT\7\22\2\2KU\3\2\2\2LQ\5\2\2\2MN\7\24\2\2NP\5\2\2\2OM\3\2\2\2PS\3"+ + "\2\2\2QO\3\2\2\2QR\3\2\2\2RU\3\2\2\2SQ\3\2\2\2TK\3\2\2\2TL\3\2\2\2UV\3"+ + "\2\2\2VW\7\23\2\2W\t\3\2\2\2XY\7\30\2\2Y\13\3\2\2\2Z[\7\32\2\2[\r\3\2"+ + "\2\2\\]\7\33\2\2]\17\3\2\2\2^_\7\31\2\2_\21\3\2\2\2`a\7\25\2\2a\23\3\2"+ + "\2\2bc\7\27\2\2c\25\3\2\2\2de\7\26\2\2e\27\3\2\2\2\b\36\65\67CQT"; + public static final ATN _ATN = + new ATNDeserializer().deserialize(_serializedATN.toCharArray()); + static { + _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()]; + for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) { + _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i); + } + } +} \ No newline at end of file diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParser.tokens b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParser.tokens new file mode 100644 index 000000000..9558e0a80 --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParser.tokens @@ -0,0 +1,56 @@ +PLUS=1 +MINUS=2 +MULTIPLY=3 +DIVIDE=4 +MODULO=5 +POWER=6 +LESS=7 +LEQ=8 +GREATER=9 +GEQ=10 +EQUALS=11 +NOT_EQUALS=12 +NOT=13 +OR=14 +AND=15 +LPARENTHESIS=16 +RPARENTHESIS=17 +COMMA=18 +NAME=19 +INTEGER=20 +REAL=21 +ATTRIBUTE=22 +STRING=23 +SCOPE_CONSTANT=24 +INDIRECT_SCOPE_CONSTANT=25 +LSQUARE_BRACKET=26 +OPENING_QOUTES=27 +SCOPE_OPEN=28 +INDIRECT_SCOPE_OPEN=29 +WHITESPACES=30 +SCOPE_CLOSE=31 +RSQUARE_BRACKET=32 +CLOSING_QUOTES=33 +'+'=1 +'-'=2 +'*'=3 +'/'=4 +'%'=5 +'^'=6 +'<'=7 +'<='=8 +'>'=9 +'>='=10 +'=='=11 +'!='=12 +'!'=13 +'||'=14 +'&&'=15 +'('=16 +')'=17 +','=18 +'['=26 +'%{'=28 +'#{'=29 +'}'=31 +']'=32 diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserBaseListener.java b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserBaseListener.java new file mode 100644 index 000000000..50a03fda1 --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserBaseListener.java @@ -0,0 +1,293 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +// Generated from FunctionExpressionParser.g4 by ANTLR 4.5 +package com.rapidminer.tools.expression.internal.antlr; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + + +/** + * This class provides an empty implementation of {@link FunctionExpressionParserListener}, which + * can be extended to create a listener which only needs to handle a subset of the available + * methods. + */ +public class FunctionExpressionParserBaseListener implements FunctionExpressionParserListener { + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterOperationExp(FunctionExpressionParser.OperationExpContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitOperationExp(FunctionExpressionParser.OperationExpContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterAtomExp(FunctionExpressionParser.AtomExpContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitAtomExp(FunctionExpressionParser.AtomExpContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterLowerExp(FunctionExpressionParser.LowerExpContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitLowerExp(FunctionExpressionParser.LowerExpContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterFunction(FunctionExpressionParser.FunctionContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitFunction(FunctionExpressionParser.FunctionContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterAttribute(FunctionExpressionParser.AttributeContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitAttribute(FunctionExpressionParser.AttributeContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterScopeConstant(FunctionExpressionParser.ScopeConstantContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitScopeConstant(FunctionExpressionParser.ScopeConstantContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterIndirectScopeConstant(FunctionExpressionParser.IndirectScopeConstantContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitIndirectScopeConstant(FunctionExpressionParser.IndirectScopeConstantContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterString(FunctionExpressionParser.StringContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitString(FunctionExpressionParser.StringContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterVariable(FunctionExpressionParser.VariableContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitVariable(FunctionExpressionParser.VariableContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterReal(FunctionExpressionParser.RealContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitReal(FunctionExpressionParser.RealContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterInteger(FunctionExpressionParser.IntegerContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitInteger(FunctionExpressionParser.IntegerContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void enterEveryRule(ParserRuleContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void exitEveryRule(ParserRuleContext ctx) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void visitTerminal(TerminalNode node) {} + + /** + * {@inheritDoc} + * + *

+ * The default implementation does nothing. + *

+ */ + @Override + public void visitErrorNode(ErrorNode node) {} +} diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserBaseVisitor.java b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserBaseVisitor.java new file mode 100644 index 000000000..ac4156dfb --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserBaseVisitor.java @@ -0,0 +1,178 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +// Generated from FunctionExpressionParser.g4 by ANTLR 4.5 +package com.rapidminer.tools.expression.internal.antlr; + +import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; + + +/** + * This class provides an empty implementation of {@link FunctionExpressionParserVisitor}, which can + * be extended to create a visitor which only needs to handle a subset of the available methods. + * + * @param + * The return type of the visit operation. Use {@link Void} for operations with no return + * type. + */ +public class FunctionExpressionParserBaseVisitor extends AbstractParseTreeVisitor implements + FunctionExpressionParserVisitor { + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitOperationExp(FunctionExpressionParser.OperationExpContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitAtomExp(FunctionExpressionParser.AtomExpContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitLowerExp(FunctionExpressionParser.LowerExpContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitFunction(FunctionExpressionParser.FunctionContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitAttribute(FunctionExpressionParser.AttributeContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitScopeConstant(FunctionExpressionParser.ScopeConstantContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitIndirectScopeConstant(FunctionExpressionParser.IndirectScopeConstantContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitString(FunctionExpressionParser.StringContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitVariable(FunctionExpressionParser.VariableContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitReal(FunctionExpressionParser.RealContext ctx) { + return visitChildren(ctx); + } + + /** + * {@inheritDoc} + * + *

+ * The default implementation returns the result of calling {@link #visitChildren} on + * {@code ctx}. + *

+ */ + @Override + public T visitInteger(FunctionExpressionParser.IntegerContext ctx) { + return visitChildren(ctx); + } +} diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserListener.java b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserListener.java new file mode 100644 index 000000000..62f22c1d4 --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserListener.java @@ -0,0 +1,206 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +// Generated from FunctionExpressionParser.g4 by ANTLR 4.5 +package com.rapidminer.tools.expression.internal.antlr; + +import org.antlr.v4.runtime.tree.ParseTreeListener; + + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link FunctionExpressionParser}. + */ +public interface FunctionExpressionParserListener extends ParseTreeListener { + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#operationExp}. + * + * @param ctx + * the parse tree + */ + void enterOperationExp(FunctionExpressionParser.OperationExpContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#operationExp}. + * + * @param ctx + * the parse tree + */ + void exitOperationExp(FunctionExpressionParser.OperationExpContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#atomExp}. + * + * @param ctx + * the parse tree + */ + void enterAtomExp(FunctionExpressionParser.AtomExpContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#atomExp}. + * + * @param ctx + * the parse tree + */ + void exitAtomExp(FunctionExpressionParser.AtomExpContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#lowerExp}. + * + * @param ctx + * the parse tree + */ + void enterLowerExp(FunctionExpressionParser.LowerExpContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#lowerExp}. + * + * @param ctx + * the parse tree + */ + void exitLowerExp(FunctionExpressionParser.LowerExpContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#function}. + * + * @param ctx + * the parse tree + */ + void enterFunction(FunctionExpressionParser.FunctionContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#function}. + * + * @param ctx + * the parse tree + */ + void exitFunction(FunctionExpressionParser.FunctionContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#attribute}. + * + * @param ctx + * the parse tree + */ + void enterAttribute(FunctionExpressionParser.AttributeContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#attribute}. + * + * @param ctx + * the parse tree + */ + void exitAttribute(FunctionExpressionParser.AttributeContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#scopeConstant}. + * + * @param ctx + * the parse tree + */ + void enterScopeConstant(FunctionExpressionParser.ScopeConstantContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#scopeConstant}. + * + * @param ctx + * the parse tree + */ + void exitScopeConstant(FunctionExpressionParser.ScopeConstantContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#indirectScopeConstant}. + * + * @param ctx + * the parse tree + */ + void enterIndirectScopeConstant(FunctionExpressionParser.IndirectScopeConstantContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#indirectScopeConstant}. + * + * @param ctx + * the parse tree + */ + void exitIndirectScopeConstant(FunctionExpressionParser.IndirectScopeConstantContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#string}. + * + * @param ctx + * the parse tree + */ + void enterString(FunctionExpressionParser.StringContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#string}. + * + * @param ctx + * the parse tree + */ + void exitString(FunctionExpressionParser.StringContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#variable}. + * + * @param ctx + * the parse tree + */ + void enterVariable(FunctionExpressionParser.VariableContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#variable}. + * + * @param ctx + * the parse tree + */ + void exitVariable(FunctionExpressionParser.VariableContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#real}. + * + * @param ctx + * the parse tree + */ + void enterReal(FunctionExpressionParser.RealContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#real}. + * + * @param ctx + * the parse tree + */ + void exitReal(FunctionExpressionParser.RealContext ctx); + + /** + * Enter a parse tree produced by {@link FunctionExpressionParser#integer}. + * + * @param ctx + * the parse tree + */ + void enterInteger(FunctionExpressionParser.IntegerContext ctx); + + /** + * Exit a parse tree produced by {@link FunctionExpressionParser#integer}. + * + * @param ctx + * the parse tree + */ + void exitInteger(FunctionExpressionParser.IntegerContext ctx); +} diff --git a/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserVisitor.java b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserVisitor.java new file mode 100644 index 000000000..009e9866a --- /dev/null +++ b/src/generated/java/com/rapidminer/tools/expression/internal/antlr/FunctionExpressionParserVisitor.java @@ -0,0 +1,133 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +// Generated from FunctionExpressionParser.g4 by ANTLR 4.5 +package com.rapidminer.tools.expression.internal.antlr; + +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + + +/** + * This interface defines a complete generic visitor for a parse tree produced by + * {@link FunctionExpressionParser}. + * + * @param + * The return type of the visit operation. Use {@link Void} for operations with no return + * type. + */ +public interface FunctionExpressionParserVisitor extends ParseTreeVisitor { + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#operationExp}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitOperationExp(FunctionExpressionParser.OperationExpContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#atomExp}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitAtomExp(FunctionExpressionParser.AtomExpContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#lowerExp}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitLowerExp(FunctionExpressionParser.LowerExpContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#function}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitFunction(FunctionExpressionParser.FunctionContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#attribute}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitAttribute(FunctionExpressionParser.AttributeContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#scopeConstant}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitScopeConstant(FunctionExpressionParser.ScopeConstantContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#indirectScopeConstant}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitIndirectScopeConstant(FunctionExpressionParser.IndirectScopeConstantContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#string}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitString(FunctionExpressionParser.StringContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#variable}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitVariable(FunctionExpressionParser.VariableContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#real}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitReal(FunctionExpressionParser.RealContext ctx); + + /** + * Visit a parse tree produced by {@link FunctionExpressionParser#integer}. + * + * @param ctx + * the parse tree + * @return the visitor result + */ + T visitInteger(FunctionExpressionParser.IntegerContext ctx); +} diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..5e9495128 --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/src/main/java/com/rapidminer/BreakpointListener.java b/src/main/java/com/rapidminer/BreakpointListener.java new file mode 100644 index 000000000..1412973fe --- /dev/null +++ b/src/main/java/com/rapidminer/BreakpointListener.java @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.operator.IOContainer; +import com.rapidminer.operator.Operator; + + +/** + * The method {@link #breakpointReached(Process, Operator, IOContainer, int)} is invoked every time + * a breakpoint is reached during a process run. + * + * @author Ingo Mierswa, Simon Fischer + */ +public interface BreakpointListener { + + /** Indicates a breakpoint before the operator. */ + public static final int BREAKPOINT_BEFORE = 0; + + /** Indicates a breakpoint after the operator. */ + public static final int BREAKPOINT_AFTER = 1; + + public static final String[] BREAKPOINT_POS_NAME = { "before", "after" }; + public static final String[] BREAKPOINT_POS_NAME_UPPERCASE = { "Before", "After" }; + + /** + * This method is invoked every time a breakpoint is reached during the process. The location is + * one out of BREAKPOINT_BEFORE or BREAKPOINT_AFTER. + */ + public void breakpointReached(Process process, Operator op, IOContainer iocontainer, int location); + + /** This method is invoked after the process was resumed. */ + public void resume(); + +} diff --git a/src/main/java/com/rapidminer/ConsoleInputHandler.java b/src/main/java/com/rapidminer/ConsoleInputHandler.java new file mode 100644 index 000000000..f0c507dfd --- /dev/null +++ b/src/main/java/com/rapidminer/ConsoleInputHandler.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import java.io.IOException; + + +/** + * Reads input from console, e.g. a password in case of database reading. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class ConsoleInputHandler implements InputHandler { + + @Override + public String inputPassword(String messageText) { + try { + System.out.println(messageText); + StringBuffer password = new StringBuffer(); + while (true) { + char character = (char) System.in.read(); + if ((character == 0x0a) || (character == 0x0d)) { + return password.toString(); + } + password.append(character); + } + } catch (IOException e) { + return null; + } + } +} diff --git a/src/main/java/com/rapidminer/Experiment.java b/src/main/java/com/rapidminer/Experiment.java new file mode 100644 index 000000000..3aeb33f6d --- /dev/null +++ b/src/main/java/com/rapidminer/Experiment.java @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.tools.XMLException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + + +/** + *

+ * WARNING: This class is now deprecated. Please use the class {@link Process} instead!. + *

+ * + *

+ * This class was introduced to avoid confusing handling of operator maps and other stuff when a new + * experiment is created. It is also necessary for file name resolving and breakpoint handling. + *

+ * + *

+ * If you want to use RapidMiner from your own application the best way is often to create an + * experiment from the scratch (by adding the complete operator tree to the experiment root + * operator) or from a file (for example created with the GUI beforehand) and start it by invoking + * the {@link #run()} method. + *

+ * + * @deprecated Please use the new class {@link Process} instead + * @author Ingo Mierswa + */ +@Deprecated +public class Experiment extends Process { + + /** + * Constructs an experiment consisting only of a SimpleOperatorChain. + * + * @deprecated Please use class {@link Process} now + */ + @Deprecated + public Experiment() { + super(); + } + + /** + * Creates a new experiment from the given URL. # + * + * @deprecated Please use class {@link Process} now + */ + @Deprecated + public Experiment(URL url) throws IOException, XMLException { + super(url); + } + + /** + * Creates a new experiment from the given experiment file. This might have been created with + * the GUI beforehand. + * + * @deprecated Please use class {@link Process} now + */ + @Deprecated + public Experiment(File file) throws IOException, XMLException { + super(file); + } + + /** + * Reads an experiment configuration from an XML String. + * + * @deprecated Please use class {@link Process} now + */ + @Deprecated + public Experiment(String xmlString) throws IOException, XMLException { + super(xmlString); + } + + /** + * Reads an experiment configuration from the given file. + * + * @deprecated Please use class {@link Process} now + */ + @Deprecated + public Experiment(InputStream in) throws IOException, XMLException { + super(in); + } +} diff --git a/src/main/java/com/rapidminer/FileProcessLocation.java b/src/main/java/com/rapidminer/FileProcessLocation.java new file mode 100644 index 000000000..bcc13a2f9 --- /dev/null +++ b/src/main/java/com/rapidminer/FileProcessLocation.java @@ -0,0 +1,132 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.io.process.XMLImporter; +import com.rapidminer.io.process.XMLTools; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.ProgressListener; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.XMLException; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStream; +import java.util.logging.Level; + +import org.w3c.dom.Document; + + +/** + * + * @author Simon Fischer + */ +public class FileProcessLocation implements ProcessLocation { + + private final File file; + + public FileProcessLocation(File file) { + this.file = file; + } + + @Override + public Process load(ProgressListener l) throws IOException, XMLException { + if (!file.exists()) { + throw new IOException("Process file '" + file + "' does not exist."); + } + if (!file.canRead()) { + throw new IOException("Process file '" + file + "' is not readable."); + } + return new Process(file, l); + } + + @Override + public String toHistoryFileString() { + return "file " + file.getAbsolutePath(); + } + + @Override + public String getRawXML() throws IOException { + return Tools.readOutput(new BufferedReader(new FileReader(file))); + } + + @Override + public void store(Process process, ProgressListener listener) throws IOException { + OutputStream out = null; + try { + if (listener != null) { + listener.setCompleted(33); + } + Document document = process.getRootOperator().getDOMRepresentation(); + out = new FileOutputStream(file); + XMLTools.stream(document, out, XMLImporter.PROCESS_FILE_CHARSET); + if (listener != null) { + listener.setCompleted(100); + } + // LogService.getRoot().info("Saved process definition file at '" + file + "'."); + LogService.getRoot().log(Level.INFO, "com.rapidminer.FileProcessLocation.saved_process_definition_file", file); + } catch (XMLException e) { + throw new IOException("Cannot save process: " + e, e); + } finally { + if (listener != null) { + listener.setCompleted(100); + listener.complete(); + } + if (out != null) { + out.close(); + } + } + } + + public File getFile() { + return file; + } + + @Override + public String toMenuString() { + return file.getName(); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof FileProcessLocation)) { + return false; + } else { + return ((FileProcessLocation) o).file.equals(this.file); + } + } + + @Override + public int hashCode() { + return file.hashCode(); + } + + @Override + public String toString() { + return file.toString(); + } + + @Override + public String getShortName() { + return file.getName(); + } +} diff --git a/src/main/java/com/rapidminer/InputHandler.java b/src/main/java/com/rapidminer/InputHandler.java new file mode 100644 index 000000000..bff2d6eec --- /dev/null +++ b/src/main/java/com/rapidminer/InputHandler.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +/** + * Handles user input in a way dependent on the execution mode. Currently, it is only used to query + * passwords. + * + * @author Simon Fischer, Ingo Mierswa + */ +public interface InputHandler { + + public String inputPassword(String messageText); + +} diff --git a/src/main/java/com/rapidminer/LoggingListener.java b/src/main/java/com/rapidminer/LoggingListener.java new file mode 100644 index 000000000..6ad73b84f --- /dev/null +++ b/src/main/java/com/rapidminer/LoggingListener.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.datatable.DataTable; + + +/** + * This listener can be used to register to process log changes (adding, removing, and changing data + * tables). + * + * @author Ingo Mierswa + */ +public interface LoggingListener { + + public void addDataTable(DataTable dataTable); + + public void removeDataTable(DataTable dataTable); + +} diff --git a/src/main/java/com/rapidminer/MacroHandler.java b/src/main/java/com/rapidminer/MacroHandler.java new file mode 100644 index 000000000..a5d60a0d0 --- /dev/null +++ b/src/main/java/com/rapidminer/MacroHandler.java @@ -0,0 +1,508 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import java.util.Arrays; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Observable; +import java.util.Set; + +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorVersion; +import com.rapidminer.operator.Value; +import com.rapidminer.parameter.UndefinedMacroError; +import com.rapidminer.parameter.UndefinedParameterError; +import com.rapidminer.tools.Tools; + + +/** + * This class can be used to store macros for an process which can be defined by the operator + * {@link com.rapidminer.operator.MacroDefinitionOperator}. It also defines some standard macros + * like the process path or file name. + * + * @author Ingo Mierswa + */ +public class MacroHandler extends Observable { + + private static final String PROCESS_NAME = "process_name"; + private static final String PROCESS_FILE = "process_file"; + private static final String PROCESS_PATH = "process_path"; + + /** + * Remaining problem is that predefined macros that are overridden by custom macros are + * evaluated first. The result is the predefined value. + */ + private static final String[] ALL_PREDEFINED_MACROS = { "process_name", "process_file", "process_path", "a", + "execution_count", "b", "c", "n", "operator_name", "t", "p[]", "v[]" }; + + /** all predefined macros that do not depend on an operator except for v[] */ + private static final Set PREDEFINED_OPERATOR_INDEPENDENT_MACROS = new HashSet<>( + Arrays.asList(new String[] { PROCESS_NAME, PROCESS_FILE, PROCESS_PATH, Operator.STRING_EXPANSION_MACRO_TIME })); + + /** all predefined macros that depend on an operator except for p[] */ + private static final Set PREDEFINED_OPERATOR_DEPENDENT_MACROS = new HashSet<>( + Arrays.asList(new String[] { Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_USER_FRIENDLY, + Operator.STRING_EXPANSION_MACRO_OPERATORNAME_USER_FRIENDLY, Operator.STRING_EXPANSION_MACRO_OPERATORNAME, + Operator.STRING_EXPANSION_MACRO_OPERATORCLASS, Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES, + Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_PLUS_ONE })); + + private static final String[] ALL_USER_FRIENDLY_PREDEFINED_MACROS = { "process_name", "process_file", "process_path", + Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_USER_FRIENDLY, + Operator.STRING_EXPANSION_MACRO_OPERATORNAME_USER_FRIENDLY }; + + private static final OperatorVersion THROW_ERROR_ON_UNDEFINED_MACRO = new OperatorVersion(6, 0, 3); + + /** + * This HashSet contains the keys of legacy macros which will be replaced while string + * expansion. CAUTION: Do NOT add any new content to this set. + */ + private static final HashSet LEGACY_STRING_EXPANSION_MACRO_KEYS = new HashSet<>(); + + static { + LEGACY_STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_OPERATORNAME); + LEGACY_STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_OPERATORCLASS); + LEGACY_STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES); + LEGACY_STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_PLUS_ONE); + LEGACY_STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_TIME); + LEGACY_STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_PERCENT_SIGN); + + LEGACY_STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_SHIFTED + + Operator.STRING_EXPANSION_MACRO_PARAMETER_START); + LEGACY_STRING_EXPANSION_MACRO_KEYS + .add(Operator.STRING_EXPANSION_MACRO_OPERATORVALUE + Operator.STRING_EXPANSION_MACRO_PARAMETER_START); + } + + /** + * This HashSet contains the keys of macros which will be replaced while string expansion. Each + * macro item might have an arbitrary length. + */ + private static final HashSet STRING_EXPANSION_MACRO_KEYS = new HashSet<>(); + + static { + STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_OPERATORNAME_USER_FRIENDLY); + STRING_EXPANSION_MACRO_KEYS.add(Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_USER_FRIENDLY); + } + + private final Process process; + + private final Map macroMap = new HashMap<>(); + + private final Object LOCK = new Object(); + + public MacroHandler(Process process) { + this.process = process; + } + + public void clear() { + setChanged(); + synchronized (LOCK) { + macroMap.clear(); + } + notifyObservers(this); + } + + public Iterator getDefinedMacroNames() { + Iterator iterator = null; + synchronized (LOCK) { + iterator = new HashMap<>(macroMap).keySet().iterator(); + } + return iterator; + } + + /** + * @return an array with the names of all user-friendly predefined macros available in + * RapidMiner + */ + public String[] getAllGraphicallySupportedPredefinedMacros() { + return ALL_USER_FRIENDLY_PREDEFINED_MACROS; + } + + /** + * @return an array with the names of ALL predefined macros available in RapidMiner + */ + public String[] getAllPredefinedMacros() { + return ALL_PREDEFINED_MACROS; + } + + /** + * Adds a macro to this MacroHandler. If a macro with this name is already present, it will be + * overwritten. + * + * @param macro + * The name of the macro. + * @param value + * The new value of the macro. + */ + public void addMacro(String macro, String value) { + if (macro != null && !macro.isEmpty()) { + setChanged(); + synchronized (LOCK) { + macroMap.put(macro, value); + } + notifyObservers(this); + } + } + + public void removeMacro(String macro) { + setChanged(); + synchronized (LOCK) { + macroMap.remove(macro); + } + notifyObservers(this); + } + + /** + * Checks whether a provided macro was set. + * + * @param macro + * the macro key + * @param operator + * the operator that can be used to resolve the macro + * @return true in case it was set, false otherwise + */ + public boolean isMacroSet(String macro, Operator operator) { + synchronized (LOCK) { + if (macroMap.containsKey(macro) || PREDEFINED_OPERATOR_INDEPENDENT_MACROS.contains(macro)) { + return true; + } + } + return operator != null && PREDEFINED_OPERATOR_DEPENDENT_MACROS.contains(macro); + + } + + /** + * Resolves the macros "process_name", "process_file", "process_path", "t" and user defined + * macros. + */ + public String getMacro(String macro) { + if (PREDEFINED_OPERATOR_INDEPENDENT_MACROS.contains(macro)) { + switch (macro) { + case PROCESS_NAME: + ProcessLocation processLocation = process.getProcessLocation(); + if (processLocation == null) { + return null; + } + if (processLocation instanceof FileProcessLocation) { + return processLocation.getShortName().substring(0, processLocation.getShortName().lastIndexOf(".")); + } + return processLocation.getShortName(); + case PROCESS_FILE: + return process.getProcessLocation() != null ? process.getProcessLocation().getShortName() : null; + case PROCESS_PATH: + return process.getProcessLocation() != null ? process.getProcessLocation().toString() : null; + case Operator.STRING_EXPANSION_MACRO_TIME: + StringBuffer buffer = new StringBuffer(); + resolveTimeMacro(buffer); + return buffer.toString(); + default: + return null; + } + } + return this.macroMap.get(macro); + } + + /** + * Resolves the macro. + * + *

+ * Resolves following predefined macros: + *

+ *
    + *
  • process_name with the name of the process
  • + *
  • process_file with the file name of the process
  • + *
  • process_path with the path to the process
  • + *
  • t with the current system date and time
  • + *
+ *

+ * Resolves following predefined macros if operator is non-null: + *

+ *
    + *
  • n or operator_name with the name of this operator
  • + *
  • c with the class of this operator
  • + *
  • a or execution_count with the number of times the operator was applied
  • + *
  • b with the number of times the operator was applied plus one
  • + *
+ *

+ * Resolves user defined macros. + *

+ * + * @param macro + * the macro to resolve + * @param operator + * the operator to use for resolving, may be {@code null} + * @return the macro value + */ + public String getMacro(String macro, Operator operator) { + if (operator != null) { + String value = resolveUnshiftedOperatorMacros(macro, operator); + if (value != null) { + return value; + } + } + return getMacro(macro); + } + + @Override + public String toString() { + return this.macroMap.toString(); + } + + /** + * This method replaces all Macros in a given String through their real values and returns a the + * String with replaced Macros. If the CompabililtyLevel of the RootOperator is lower than + * 6.0.3, undefined macros will be ignored. + * + * @param parameterValue + * the whole ParameterType value String + * @return the complete parameter value with replaced Macros + * @throws UndefinedParameterError + * this error will be thrown if the CompabilityLevel of the RootOperator is at least + * 6.0.3 and a macro is undefined + */ + public String resolveMacros(String parameterKey, String parameterValue) throws UndefinedMacroError { + int startIndex = parameterValue.indexOf(Operator.MACRO_STRING_START); + if (startIndex == -1) { + return parameterValue; + } + StringBuffer result = new StringBuffer(); + while (startIndex >= 0) { + result.append(parameterValue.substring(0, startIndex)); + int endIndex = parameterValue.indexOf(Operator.MACRO_STRING_END, startIndex + 2); + if (endIndex == -1) { + return parameterValue; + } + String macroString = parameterValue.substring(startIndex + 2, endIndex); + // check whether macroString is a predefined macro which will be resolved at String + // expansion + if (STRING_EXPANSION_MACRO_KEYS.contains(macroString) || LEGACY_STRING_EXPANSION_MACRO_KEYS + .contains(macroString.length() > 1 ? macroString.substring(0, 2) : macroString)) { + // skip macro because it will be replaced during the string expansion + result.append(Operator.MACRO_STRING_START + macroString + Operator.MACRO_STRING_END); + } else { + // resolve macro + String macroValue = this.getMacro(macroString); + if (macroValue != null) { + result.append(macroValue); + } else { + if (this.process.getRootOperator().getCompatibilityLevel().isAtLeast(THROW_ERROR_ON_UNDEFINED_MACRO)) { + throw new UndefinedMacroError(parameterKey, macroString); + } else { + result.append(Operator.MACRO_STRING_START + macroString + Operator.MACRO_STRING_END); + } + } + } + parameterValue = parameterValue.substring(endIndex + 1); + startIndex = parameterValue.indexOf(Operator.MACRO_STRING_START); + } + result.append(parameterValue); + return result.toString(); + } + + /** + *

+ * Replaces following predefined macros: + *

+ *
    + *
  • %{n} or %{operator_name} with the name of this operator
  • + *
  • %{c} with the class of this operator
  • + *
  • %{t} with the current system date and time + *
  • %{a} or %{execution_count} with the number of times the operator was + * applied
  • + *
  • %{b} with the number of times the operator was applied plus one (a shortcut for + * %{p[1]})
  • + *
  • %{p[number]} with the number of times the operator was applied plus number
  • + *
  • %{v[OperatorName.ValueName]} with the value "ValueName" of the operator + * "OperatorName"
  • + *
  • %{%} with %
  • + *
+ * + * @return The String with resolved predefined macros. Returns {@code null} in case provided + * parameter str is {@code null}. + */ + public String resolvePredefinedMacros(String str, Operator operator) throws UndefinedParameterError { + if (str == null) { + return null; + } + StringBuffer result = new StringBuffer(); + int totalStart = 0; + int start = 0; + while ((start = str.indexOf(Operator.MACRO_STRING_START, totalStart)) >= 0) { + result.append(str.substring(totalStart, start)); + int end = str.indexOf(Operator.MACRO_STRING_END, start); + if (end == -1) { + return str; + } + if (end >= start) { + String command = str.substring(start + 2, end); + String unshiftedOperatorMacroResult = resolveUnshiftedOperatorMacros(command, operator); + if (unshiftedOperatorMacroResult != null) { + result.append(unshiftedOperatorMacroResult); + } else if (command.startsWith(Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_SHIFTED + + Operator.STRING_EXPANSION_MACRO_PARAMETER_START)) { + int openNumberIndex = command.indexOf(Operator.STRING_EXPANSION_MACRO_PARAMETER_START); + int closeNumberIndex = command.indexOf(Operator.STRING_EXPANSION_MACRO_PARAMETER_END, openNumberIndex); + if (closeNumberIndex < 0 || closeNumberIndex <= openNumberIndex + 1) { + throw new UndefinedMacroError(operator, "predefinedMacro_shiftedExecutionCounter_format", ""); + } + String numberString = command.substring(openNumberIndex + 1, closeNumberIndex); + int number; + try { + number = Integer.parseInt(numberString); + } catch (NumberFormatException e) { + throw new UndefinedMacroError(operator, "946", numberString); + } + result.append(operator.getApplyCount() + number); + } else if (Operator.STRING_EXPANSION_MACRO_TIME.equals(command)) { + resolveTimeMacro(result); + } else if (command.startsWith( + Operator.STRING_EXPANSION_MACRO_OPERATORVALUE + Operator.STRING_EXPANSION_MACRO_PARAMETER_START)) { + int openNumberIndex = command.indexOf(Operator.STRING_EXPANSION_MACRO_PARAMETER_START); + int closeNumberIndex = command.indexOf(Operator.STRING_EXPANSION_MACRO_PARAMETER_END, openNumberIndex); + if (closeNumberIndex < 0 || closeNumberIndex <= openNumberIndex + 1) { + throw new UndefinedMacroError(operator, "predefinedMacro_OperatorValue_format", ""); + } + String operatorValueString = command.substring(openNumberIndex + 1, closeNumberIndex); + String[] operatorValuePair = operatorValueString.split("\\."); + if (operatorValuePair.length != 2) { + throw new UndefinedMacroError(operator, "predefinedMacro_OperatorValue_format", ""); + } + Operator op = process.getOperator(operatorValuePair[0]); + if (op == null) { + throw new UndefinedMacroError(operator, "predefinedMacro_OperatorValue_wrongOperator", + operatorValuePair[0]); + } + Value value = op.getValue(operatorValuePair[1]); + if (value == null) { + throw new UndefinedMacroError(operator, "predefinedMacro_OperatorValue_noValue", + operatorValuePair[1]); + } else { + if (value.isNominal()) { + Object valueObject = value.getValue(); + if (valueObject != null) { + result.append(valueObject.toString()); + } else { + throw new UndefinedMacroError(operator, "predefinedMacro_OperatorValue_noValue", + operatorValuePair[1]); + } + } else { + double doubleValue = ((Double) value.getValue()).doubleValue(); + if (!Double.isNaN(doubleValue)) { + result.append(Tools.formatIntegerIfPossible(doubleValue)); + } else { + operator.logError("Value '" + operatorValuePair[1] + "' of the operator '" + + operatorValuePair[0] + "' not found!"); + } + } + } + } else if (Operator.STRING_EXPANSION_MACRO_PERCENT_SIGN.equals(command)) { + result.append('%'); + } else { + result.append(command); + } + } else { + end = start + 2; + result.append(Operator.MACRO_STRING_START); + } + totalStart = end + 1; + } + result.append(str.substring(totalStart)); + return result.toString(); + } + + /** + * Resolves the macro t by writing the current date and time in the result buffer. + */ + private void resolveTimeMacro(StringBuffer result) { + // Please note that Date and DateFormat cannot be used since Windows does not + // support the resulting file names + // TODO: Well, it can and should be used. Just use a custom SimpleDateFormat + Calendar calendar = new GregorianCalendar(); + // year + result.append(calendar.get(Calendar.YEAR) + "_"); + // month + String month = calendar.get(Calendar.MONTH) + 1 + ""; + if (month.length() < 2) { + month = "0" + month; + } + result.append(month + "_"); + // day + String day = calendar.get(Calendar.DAY_OF_MONTH) + ""; + if (day.length() < 2) { + day = "0" + day; + } + result.append(day + "-"); + // am - pm + int amPm = calendar.get(Calendar.AM_PM); + String amPmString = amPm == Calendar.AM ? "AM" : "PM"; + result.append(amPmString + "_"); + // hour + String hour = calendar.get(Calendar.HOUR) + ""; + if (hour.length() < 2) { + hour = "0" + hour; + } + result.append(hour + "_"); + // minute + String minute = calendar.get(Calendar.MINUTE) + ""; + if (minute.length() < 2) { + minute = "0" + minute; + } + result.append(minute + "_"); + // second + String second = calendar.get(Calendar.SECOND) + ""; + if (second.length() < 2) { + second = "0" + second; + } + result.append(second); + } + + /** + *

+ * Resolves following predefined macros: + *

+ *
    + *
  • n or operator_name with the name of this operator
  • + *
  • c with the class of this operator
  • + *
  • a or execution_count with the number of times the operator was applied
  • + *
  • b with the number of times the operator was applied plus one
  • + *
+ * + * Does not resolve p[]. + */ + private String resolveUnshiftedOperatorMacros(String command, Operator operator) { + if (Operator.STRING_EXPANSION_MACRO_OPERATORNAME.equals(command) + || Operator.STRING_EXPANSION_MACRO_OPERATORNAME_USER_FRIENDLY.equals(command)) { + return operator.getName(); + } else if (Operator.STRING_EXPANSION_MACRO_OPERATORCLASS.equals(command)) { + return operator.getClass().getName(); + } else if (Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES.equals(command) + || Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_USER_FRIENDLY.equals(command)) { + return operator.getApplyCount() + ""; + } else if (Operator.STRING_EXPANSION_MACRO_NUMBER_APPLIED_TIMES_PLUS_ONE.equals(command)) { + return operator.getApplyCount() + 1 + ""; + } else { + return null; + } + } + +} diff --git a/src/main/java/com/rapidminer/NoBugError.java b/src/main/java/com/rapidminer/NoBugError.java new file mode 100644 index 000000000..c41500619 --- /dev/null +++ b/src/main/java/com/rapidminer/NoBugError.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +/** + * All exceptions that are no bugs (but caused by an error of the user) should implement this + * interface in order to indicate that this should not issue a bug report. + * + * @author Simon Fischer, Ingo Mierswa + */ +public interface NoBugError { + + /** Returns a html message. */ + public String getHTMLMessage(); + + /** Returns the error details/description. */ + public String getDetails(); + + /** Returns the error name. */ + public String getErrorName(); + + /** Returns the error code. */ + public int getCode(); + +} diff --git a/src/main/java/com/rapidminer/NoOpUserError.java b/src/main/java/com/rapidminer/NoOpUserError.java new file mode 100644 index 000000000..e9195068d --- /dev/null +++ b/src/main/java/com/rapidminer/NoOpUserError.java @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.operator.UserError; +import com.rapidminer.tools.Tools; + + +/** + * An exception caused outside an operator which is not a bug, but caused by the user. + * + * Unfortunately, this class doubles most of the code of {@link UserError}. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class NoOpUserError extends Exception implements NoBugError { + + private static final long serialVersionUID = -686838060355434724L; + + private int code; + + /** + * Creates a new NoOpUserError. + * + * @param cause + * The exception that caused the user error. May be null. Using this makes debugging + * a lot easier. + * @param code + * The error code referring to a message in the file + * UserErrorMessages.properties + * @param arguments + * Arguments for the short message. + */ + public NoOpUserError(Throwable cause, int code, Object[] arguments) { + super(UserError.getErrorMessage(code, arguments), cause); + this.code = code; + } + + /** Convenience constructor for messages with no arguments and cause. */ + public NoOpUserError(Throwable cause, int code) { + this(code, new Object[0], cause); + } + + public NoOpUserError(int code, Object[] arguments) { + this(null, code, arguments); + } + + /** Convenience constructor for messages with no arguments. */ + public NoOpUserError(int code) { + this(null, code, new Object[0]); + } + + /** Convenience constructor for messages with exactly one argument. */ + public NoOpUserError(int code, Object argument1) { + this(null, code, new Object[] { argument1 }); + } + + /** + * Convenience constructor for messages with exactly one arguments and cause. + */ + public NoOpUserError(Throwable cause, int code, Object argument1) { + this(cause, code, new Object[] { argument1 }); + } + + /** Convenience constructor for messages with exactly two arguments. */ + public NoOpUserError(int code, Object argument1, Object argument2) { + this(null, code, new Object[] { argument1, argument2 }); + } + + @Override + public String getDetails() { + return UserError.getResourceString(code, "long", "Description missing."); + } + + @Override + public String getErrorName() { + return UserError.getResourceString(code, "name", "Unnamed error."); + } + + @Override + public int getCode() { + return code; + } + + @Override + public String getHTMLMessage() { + return "Error occured:
" + Tools.escapeXML(getMessage()) + "
" + Tools.escapeXML(getDetails()) + + ""; + } +} diff --git a/src/main/java/com/rapidminer/ObjectVisualizer.java b/src/main/java/com/rapidminer/ObjectVisualizer.java new file mode 100644 index 000000000..963de956d --- /dev/null +++ b/src/main/java/com/rapidminer/ObjectVisualizer.java @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +/** + * Interface managing the visualization of objects. This might be a dialog showing the feature + * values ({@link com.rapidminer.gui.ExampleVisualizer}) or more sophisticated methods like + * displaying a text or playing a piece of music. Please note that GUI components should not be + * constructed in the contstructor but in the method {@link #startVisualization(Object)} in order to + * ensure that the visualizer can be constructed also in environments where graphical user + * interfaces are not allowed. + * + * @author Michael Wurst, Ingo Mierswa + */ +public interface ObjectVisualizer { + + public void startVisualization(Object objId); + + public void stopVisualization(Object objId); + + public String getTitle(Object objId); + + public boolean isCapableToVisualize(Object objId); + + public String getDetailData(Object objId, String fieldName); + + public String[] getFieldNames(Object objId); + +} diff --git a/src/main/java/com/rapidminer/OperatorLibraryService.java b/src/main/java/com/rapidminer/OperatorLibraryService.java new file mode 100644 index 000000000..9486f1f0c --- /dev/null +++ b/src/main/java/com/rapidminer/OperatorLibraryService.java @@ -0,0 +1,231 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.gui.tools.actions.SelectionDependentAction; +import com.rapidminer.gui.tools.actions.SelectionDependentAction.SelectionDependency; +import com.rapidminer.operator.OperatorCreationException; +import com.rapidminer.operator.libraries.LibraryOperatorDescription; +import com.rapidminer.operator.libraries.OperatorLibrary; +import com.rapidminer.tools.OperatorService; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + + +/** + * This singleton Service keeps track of all currently loaded {@link OperatorLibrary}s. It provides + * methods for loading and unloading {@link OperatorLibrary}s. + * + * Currently this is a singleton implementation with a static method for accessing the singleton but + * in future this might be replaced by a per process definition. + * + * Additionally it holds information for editing the Libraries. Actions can be added to the toolbar + * as well as to the context menu. They are only available on entries of the according class. + * + * @author Sebastian Land + */ +public class OperatorLibraryService { + + /** + * Classes implementing this interface and having added with + * {@link OperatorLibraryService#registerOperatorLibraryListener(OperatorLibraryListener)} will + * be informed whenever an {@link OperatorLibrary} is added or removed. + * + * @author Sebastian Land + */ + public interface OperatorLibraryListener { + + public void informLibraryLoaded(OperatorLibrary library); + + public void informLibraryUnloaded(OperatorLibrary library); + + public void informLibraryChanged(OperatorLibrary library); + } + + private static List toolbarActions = new LinkedList(); + private static Map, List> contextMenuActions = new HashMap, List>(); + + private static OperatorLibraryService serviceSingleton = new OperatorLibraryService(); + + private List libraries = new ArrayList(); + private List listeners = new LinkedList(); + + /** + * This method loads the given library and registers all contained operators. + */ + public void loadLibrary(OperatorLibrary library) { + libraries.add(library); + + // register operators + + // TODO: Check if we need this at all! + // for (String operatorKey: library.getOperatorKeys()) { + // try { + // OperatorService.registerOperator(library.getDescription(operatorKey), + // library.getDocumentationBundle()); + // } catch (OperatorCreationException e) { + // // TODO: after removing instanciation. + // e.printStackTrace(); + // } + // } + // I think can be replaced by: + try { + library.registerOperators(); + } catch (OperatorCreationException e) { + // TODO: after removing instanciation. + e.printStackTrace(); + } + + // inform listener + for (OperatorLibraryListener listener : listeners) { + listener.informLibraryLoaded(library); + } + } + + /** + * This method loads the given library and registers all contained operators. + */ + public void unloadLibrary(OperatorLibrary library) { + libraries.remove(library); + + // register operators + for (String operatorKey : library.getOperatorKeys()) { + OperatorService.unregisterOperator(library.getDescription(operatorKey)); + } + + // inform listener + for (OperatorLibraryListener listener : listeners) { + listener.informLibraryUnloaded(library); + } + } + + /** + * This adds a listener to the operator library Service that is informed of any registered or + * unregistered OperatorLibrary. + */ + public void registerOperatorLibraryListener(OperatorLibraryListener listener) { + this.listeners.add(listener); + } + + /** + * This returns the number of the currently loaded libraries. + */ + public int getNumberOfLibraries() { + return libraries.size(); + } + + /** + * This returns the library with the given index. + */ + public OperatorLibrary getLibrary(int index) { + return libraries.get(index); + } + + /** + * This returns the index of the given OperatorLibrary. Returns -1 if it can't be found. + */ + public int getIndexOf(OperatorLibrary child) { + return libraries.indexOf(child); + } + + /* + * STATIC METHODS + */ + + /** + * This returns the service singleton. + */ + public static OperatorLibraryService getService() { + return serviceSingleton; + } + + /** + * This simply returns a list of all registered actions for the toolbar of the operator library + * view. + */ + public static List getToolbarActions(SelectionDependency dependency) { + List result = new LinkedList(); + for (SelectionDependentAction action : toolbarActions) { + SelectionDependentAction clone = (SelectionDependentAction) action.clone(); + clone.setDependency(dependency); + result.add(clone); + } + return result; + } + + /** + * This registers the given action for the toolbar; + */ + public static void registerToolbarAction(SelectionDependentAction action) { + toolbarActions.add(action); + } + + /** + * This returns all actions that refer to an object of the given class. + */ + public static List getContextMenuActions(Class objectClass, SelectionDependency dependency) { + List result = new LinkedList(); + for (Entry, List> entry : contextMenuActions.entrySet()) { + if (entry.getKey().isAssignableFrom(objectClass)) { + for (SelectionDependentAction action : entry.getValue()) { + SelectionDependentAction clone = (SelectionDependentAction) action.clone(); + clone.setDependency(dependency); + result.add(clone); + } + } + } + + return result; + } + + /** + * This registers the given action for the given class. Actions in context menu will depend on + * the class the current item has. + */ + public static void registerContextMenuAction(Class associatedClass, SelectionDependentAction action) { + List actions = contextMenuActions.get(associatedClass); + if (actions == null) { + actions = new LinkedList(); + contextMenuActions.put(associatedClass, actions); + } + actions.add(action); + } + + /** + * This notifies that the given operator has changed + */ + public void notifiyOperatorChanged(LibraryOperatorDescription libraryOperatorDescription) { + notifyLibraryChanged(libraryOperatorDescription.getLibrary()); + } + + /** + * This notifies that the given library has changed. + */ + public void notifyLibraryChanged(OperatorLibrary operatorLibrary) { + // inform listener + for (OperatorLibraryListener listener : listeners) { + listener.informLibraryChanged(operatorLibrary); + } + } +} diff --git a/src/main/java/com/rapidminer/Process.java b/src/main/java/com/rapidminer/Process.java new file mode 100644 index 000000000..bf33c29d9 --- /dev/null +++ b/src/main/java/com/rapidminer/Process.java @@ -0,0 +1,1570 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.URL; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.logging.FileHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.logging.SimpleFormatter; + +import javax.swing.event.EventListenerList; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.rapidminer.core.license.LicenseViolationException; +import com.rapidminer.core.license.ProductConstraintManager; +import com.rapidminer.datatable.DataTable; +import com.rapidminer.datatable.SimpleDataTable; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.io.process.XMLImporter; +import com.rapidminer.license.violation.LicenseViolation; +import com.rapidminer.operator.Annotations; +import com.rapidminer.operator.DebugMode; +import com.rapidminer.operator.DummyOperator; +import com.rapidminer.operator.ExecutionMode; +import com.rapidminer.operator.ExecutionUnit; +import com.rapidminer.operator.IOContainer; +import com.rapidminer.operator.IOObject; +import com.rapidminer.operator.IOObjectMap; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorException; +import com.rapidminer.operator.PortUserError; +import com.rapidminer.operator.ProcessRootOperator; +import com.rapidminer.operator.ProcessStoppedException; +import com.rapidminer.operator.UnknownParameterInformation; +import com.rapidminer.operator.UserError; +import com.rapidminer.operator.nio.file.RepositoryBlobObject; +import com.rapidminer.operator.ports.InputPort; +import com.rapidminer.operator.ports.OutputPort; +import com.rapidminer.operator.ports.Port; +import com.rapidminer.report.ReportStream; +import com.rapidminer.repository.BlobEntry; +import com.rapidminer.repository.Entry; +import com.rapidminer.repository.IOObjectEntry; +import com.rapidminer.repository.MalformedRepositoryLocationException; +import com.rapidminer.repository.RepositoryAccessor; +import com.rapidminer.repository.RepositoryException; +import com.rapidminer.repository.RepositoryLocation; +import com.rapidminer.repository.RepositoryManager; +import com.rapidminer.tools.AbstractObservable; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.LoggingHandler; +import com.rapidminer.tools.Observable; +import com.rapidminer.tools.Observer; +import com.rapidminer.tools.OperatorService; +import com.rapidminer.tools.ParameterService; +import com.rapidminer.tools.ProgressListener; +import com.rapidminer.tools.RandomGenerator; +import com.rapidminer.tools.ResultService; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.WebServiceTools; +import com.rapidminer.tools.WrapperLoggingHandler; +import com.rapidminer.tools.XMLException; +import com.rapidminer.tools.container.Pair; +import com.rapidminer.tools.usagestats.ActionStatisticsCollector; + + +/** + *

+ * This class was introduced to avoid confusing handling of operator maps and other stuff when a new + * process definition is created. It is also necessary for file name resolving and breakpoint + * handling. + *

+ * + *

+ * If you want to use RapidMiner from your own application the best way is often to create a process + * definition from scratch (by adding the complete operator tree to the process' root operator) or + * from a file (for example created with the GUI beforehand) and start it by invoking the + * {@link #run()} method. + *

+ * + *

+ * Observers can listen to changes of the associated file, repository location, and context. + *

+ * TODO: Add reasonable class comment + * + * @author Ingo Mierswa + */ +public class Process extends AbstractObservable implements Cloneable { + + public static final int PROCESS_STATE_UNKNOWN = -1; + public static final int PROCESS_STATE_STOPPED = 0; + public static final int PROCESS_STATE_PAUSED = 1; + public static final int PROCESS_STATE_RUNNING = 2; + + /** The root operator of the process. */ + private ProcessRootOperator rootOperator = null; + + /** This is the operator which is currently applied. */ + private Operator currentOperator; + + /** + * The process might be connected to this file or repository location which is then used to + * resolve relative file names which might be defined as parameters. + */ + private ProcessLocation processLocation; + + /** + * Indicates if the original process file has been changed by import rules. If this happens, + * overwriting will destroy the backward compatibility. This flag indicates that this would + * happen during saving. + */ + private boolean isProcessConverted = false; + + /** + * Indicates how deeply nested the current process is. The original process itself has a depth + * of {@code 0}. If that process spawns a new one via an Execute Process operator, the depth of + * the new one will be {@code 1}. If the new process also contains an Execute Process operator, + * the depth will be {@code 2} and so on. Used to prevent {@link StackOverflowError} when + * recursion is too deep (mostly to prevent accidents). + */ + private int nestingDepth = 0; + + /** + * This list contains all unknown parameter information which existed during the loading of the + * process. + */ + private final List unknownParameterInformation = new LinkedList<>(); + + /** The listeners for breakpoints. */ + private final List breakpointListeners = new LinkedList<>(); + + /** The listeners for logging (data tables). */ + private final List loggingListeners = new LinkedList<>(); + + private final List processStateListeners = new LinkedList<>(); + + /** The macro handler can be used to replace (user defined) macro strings. */ + private final MacroHandler macroHandler = new MacroHandler(this); + + /** + * This map holds the names of all operators in the process. Operators are automatically + * registered during adding and unregistered after removal. + */ + private Map operatorNameMap = new HashMap<>(); + + /** + * Maps names of ProcessLog operators to Objects, that these Operators use for collecting + * statistics (objects of type {@link DataTable}). + */ + private final Map dataTableMap = new HashMap<>(); + + /** + * Maps names of report streams to reportStream objects + */ + private final Map reportStreamMap = new HashMap<>(); + + /** + * Stores IOObjects according to a specified name for the runtime of the process. + */ + private final Map storageMap = new HashMap<>(); + + /** + * Stores IOObjects according to a specified name for a long-term scope like the session of + * RapidMiner or a RapidMiner Server app session + */ + private IOObjectMap ioObjectCache = RapidMiner.getGlobalIOObjectCache(); + + /** Indicates the current process state. */ + private int processState = PROCESS_STATE_STOPPED; + + /** Indicates whether operators should be executed always or only when dirty. */ + private transient ExecutionMode executionMode = ExecutionMode.ALWAYS; + + /** Indicates whether we are updating meta data. */ + private transient DebugMode debugMode = DebugMode.DEBUG_OFF; + + private transient final Logger logger = makeLogger(); + + /** @deprecated Use {@link #getLogger()} */ + @Deprecated + private transient final LoggingHandler logService = new WrapperLoggingHandler(logger); + + private ProcessContext context = new ProcessContext(); + + /** Message generated during import by {@link XMLImporter}. */ + private String importMessage; + + private final Annotations annotations = new Annotations(); + + private RepositoryAccessor repositoryAccessor; + + /** + * Indicates whether the {@link IOContainer} returned by {@link #run()} might contain + * null values for empty results. + */ + private boolean omitNullResults = true; + + // ------------------- + // Constructors + // ------------------- + + /** Constructs an process consisting only of a SimpleOperatorChain. */ + public Process() { + try { + ProcessRootOperator root = OperatorService.createOperator(ProcessRootOperator.class); + root.rename(root.getOperatorDescription().getName()); + setRootOperator(root); + } catch (Exception e) { + throw new RuntimeException("Cannot initialize root operator of the process: " + e.getMessage(), e); + } + initContext(); + } + + public Process(final File file) throws IOException, XMLException { + this(file, null); + } + + /** + * Creates a new process from the given process file. This might have been created with the GUI + * beforehand. + */ + public Process(final File file, final ProgressListener progressListener) throws IOException, XMLException { + this.processLocation = new FileProcessLocation(file); + initContext(); + Reader in = null; + try { + in = new InputStreamReader(new FileInputStream(file), "UTF-8"); + readProcess(in, progressListener); + } catch (IOException e) { + throw e; + } finally { + if (in != null) { + in.close(); + } + } + } + + /** + * Creates a new process from the given XML copying state information not covered by the XML + * from the parameter process. + */ + public Process(final String xml, final Process process) throws IOException, XMLException { + this(xml); + this.processLocation = process.processLocation; + } + + /** Reads an process configuration from an XML String. */ + public Process(final String xmlString) throws IOException, XMLException { + initContext(); + StringReader in = new StringReader(xmlString); + readProcess(in); + in.close(); + } + + /** Reads an process configuration from the given reader. */ + public Process(final Reader in) throws IOException, XMLException { + initContext(); + readProcess(in); + } + + /** Reads an process configuration from the given stream. */ + public Process(final InputStream in) throws IOException, XMLException { + initContext(); + readProcess(new InputStreamReader(in, XMLImporter.PROCESS_FILE_CHARSET)); + } + + /** Reads an process configuration from the given URL. */ + public Process(final URL url) throws IOException, XMLException { + initContext(); + Reader in = new InputStreamReader(WebServiceTools.openStreamFromURL(url), getEncoding(null)); + readProcess(in); + in.close(); + } + + protected Logger makeLogger() { + return Logger.getLogger(Process.class.getName()); + } + + private void initContext() { + getContext().addObserver(delegatingContextObserver, false); + } + + /** + * Clone constructor. Makes a deep clone of the operator tree and the process file. The same + * applies for the operatorNameMap. The breakpoint listeners are copied by reference and all + * other fields are initialized like for a fresh process. + */ + private Process(final Process other) { + this(); + setRootOperator((ProcessRootOperator) other.rootOperator.cloneOperator(other.rootOperator.getName(), false)); + this.currentOperator = null; + if (other.processLocation != null) { + this.processLocation = other.processLocation; + } else { + this.processLocation = null; + } + } + + private void initLogging(final int logVerbosity) { + if (logVerbosity >= 0) { + logger.setLevel(WrapperLoggingHandler.LEVELS[logVerbosity]); + } else { + logger.setLevel(Level.INFO); + } + } + + @Override + public Object clone() { + return new Process(this); + } + + /** + * @deprecated Use {@link #setProcessState(int)} instead + */ + @Deprecated + public synchronized void setExperimentState(final int state) { + setProcessState(state); + } + + private void setProcessState(final int state) { + int oldState = this.processState; + this.processState = state; + fireProcessStateChanged(oldState, state); + } + + /** + * @deprecated Use {@link #getProcessState()} instead + */ + @Deprecated + public synchronized int getExperimentState() { + return getProcessState(); + } + + public int getProcessState() { + return this.processState; + } + + // ------------------------- + // User initiated state changes + // --------------------------- + /** Adds the given process state listener. */ + public void addProcessStateListener(ProcessStateListener processStateListener) { + this.processStateListeners.add(processStateListener); + } + + /** Removes the given process state listener. */ + public void removeProcessStateListener(ProcessStateListener processStateListener) { + this.processStateListeners.remove(processStateListener); + } + + private void fireProcessStateChanged(int stateBefore, int newState) { + // sanity check + if (stateBefore == newState) { + return; + } + List listeners = new LinkedList<>(processStateListeners); + for (ProcessStateListener listener : listeners) { + switch (newState) { + case PROCESS_STATE_PAUSED: + listener.paused(this); + break; + case PROCESS_STATE_STOPPED: + listener.stopped(this); + break; + default: + if (stateBefore == PROCESS_STATE_STOPPED) { + listener.started(this); + } else { + listener.resumed(this); + } + break; + } + } + + } + + // ------------------------- + // Logging + // ------------------------- + + public LoggingHandler getLog() { + return this.logService; + } + + public Logger getLogger() { + return this.logger; + } + + // ------------------------- + // Macro Handler + // ------------------------- + + /** Returns the macro handler. */ + public MacroHandler getMacroHandler() { + return this.macroHandler; + } + + /** Clears all macros. */ + public void clearMacros() { + this.getMacroHandler().clear(); + } + + // ------------------------- + // IOObject Storage + // ------------------------- + + /** Returns the macro handler. */ + public void store(final String name, final IOObject object) { + this.storageMap.put(name, object); + } + + /** Retrieves the stored object. */ + public IOObject retrieve(final String name, final boolean remove) { + if (remove) { + return this.storageMap.remove(name); + } else { + return this.storageMap.get(name); + } + } + + /** Clears all macros. */ + public void clearStorage() { + this.storageMap.clear(); + } + + // ------------------------- + // State storage + // ------------------------- + + /** + * Injects another {@link IOObject} cache (to remember and recall {@link IOObject}s during a + * long-term scope) + * + * If {@link #ioObjectCache} is null, the setter does not have any effect + */ + public void setIOObjectCache(IOObjectMap ioObjectCache) { + if (ioObjectCache != null) { + this.ioObjectCache = ioObjectCache; + } + } + + /** + * Returns the {@link IOObject} cache (to remember and recall {@link IOObject}s during a + * long-term scope), designed to be manipulated by operators in the process + * + * @return the IOObjectCache of the process + */ + public IOObjectMap getIOObjectCache() { + return ioObjectCache; + } + + // ------------------------- + // Data Tables (Logging) + // ------------------------- + + /** Adds the given logging listener. */ + public void addLoggingListener(final LoggingListener loggingListener) { + this.loggingListeners.add(loggingListener); + } + + /** Removes the given logging listener. */ + public void removeLoggingListener(final LoggingListener loggingListener) { + this.loggingListeners.remove(loggingListener); + } + + /** Returns true if a data table object with the given name exists. */ + public boolean dataTableExists(final String name) { + return dataTableMap.get(name) != null; + } + + /** + * Adds the given data table. + */ + public void addDataTable(final DataTable table) { + dataTableMap.put(table.getName(), table); + for (LoggingListener listener : loggingListeners) { + listener.addDataTable(table); + } + } + + /** Clears a single data table, i.e. removes all entries. */ + public void clearDataTable(final String name) { + DataTable table = getDataTable(name); + if (table != null) { + if (table instanceof SimpleDataTable) { + ((SimpleDataTable) table).clear(); + } + } + } + + /** Deletes a single data table. */ + public void deleteDataTable(final String name) { + if (dataTableExists(name)) { + DataTable table = dataTableMap.remove(name); + + for (LoggingListener listener : loggingListeners) { + listener.removeDataTable(table); + } + } + } + + /** + * Returns the data table associated with the given name. If the name was not used yet, an empty + * DataTable object is created with the given columnNames. + */ + public DataTable getDataTable(final String name) { + return dataTableMap.get(name); + } + + /** Returns all data tables. */ + public Collection getDataTables() { + return dataTableMap.values(); + } + + /** Removes all data tables before running a new process. */ + private void clearDataTables() { + dataTableMap.clear(); + } + + // ------------------------------ + // Report Streams + // ------------------------------ + + /** + * This method adds a new report stream with the given name + */ + public void addReportStream(final ReportStream stream) { + reportStreamMap.put(stream.getName(), stream); + } + + /** + * Returns the reportStream with given name + */ + public ReportStream getReportStream(final String name) { + if (name == null || name.length() == 0) { + if (reportStreamMap.size() == 1) { + return reportStreamMap.values().iterator().next(); + } else { + return null; + } + } else { + return reportStreamMap.get(name); + } + } + + /** + * Removes this reportStream from process. This report Stream will not be notified about new + * report items. + * + * @param name + * of the report stream given in the ReportGenerator operator + */ + public void removeReportStream(final String name) { + reportStreamMap.remove(name); + } + + public void clearReportStreams() { + reportStreamMap.clear(); + } + + // ---------------------- + // Operator Handling + // ---------------------- + + /** Sets the current root operator. This might lead to a new registering of operator names. */ + public void setRootOperator(final ProcessRootOperator root) { + if (this.rootOperator != null) { + this.rootOperator.removeObserver(delegatingOperatorObserver); + } + this.rootOperator = root; + this.rootOperator.addObserver(delegatingOperatorObserver, false); + this.operatorNameMap.clear(); + this.rootOperator.setProcess(this); + } + + /** Delivers the current root operator. */ + public ProcessRootOperator getRootOperator() { + return rootOperator; + } + + /** Returns the operator with the given name. */ + public Operator getOperator(final String name) { + return operatorNameMap.get(name); + } + + /** Returns the operator that is currently being executed. */ + public Operator getCurrentOperator() { + return currentOperator; + } + + /** Returns a Collection view of all operators. */ + public Collection getAllOperators() { + List result = rootOperator.getAllInnerOperators(); + result.add(0, rootOperator); + return result; + } + + /** Returns a Set view of all operator names (i.e. Strings). */ + public Collection getAllOperatorNames() { + Collection allNames = new LinkedList<>(); + for (Operator o : getAllOperators()) { + allNames.add(o.getName()); + } + return allNames; + } + + /** Sets the operator that is currently being executed. */ + public void setCurrentOperator(final Operator operator) { + this.currentOperator = operator; + } + + // ------------------------------------- + // start, stop, resume, breakpoints + // ------------------------------------- + + /** We synchronize on this object to wait and resume operation. */ + private final Object breakpointLock = new Object(); + + /** Pauses the process at a breakpoint. */ + public void pause(final Operator operator, final IOContainer iocontainer, final int breakpointType) { + setProcessState(PROCESS_STATE_PAUSED); + fireBreakpointEvent(operator, iocontainer, breakpointType); + while (getProcessState() == Process.PROCESS_STATE_PAUSED) { + synchronized (breakpointLock) { + try { + breakpointLock.wait(); + } catch (InterruptedException e) { + } + } + } + } + + /** Resumes the process after it has been paused. */ + public void resume() { + setProcessState(PROCESS_STATE_RUNNING); + synchronized (breakpointLock) { + breakpointLock.notifyAll(); + } + fireResumeEvent(); + } + + /** Stops the process as soon as possible. */ + public void stop() { + this.setProcessState(PROCESS_STATE_STOPPED); + synchronized (breakpointLock) { + breakpointLock.notifyAll(); + } + } + + /** Stops the process as soon as possible. */ + public void pause() { + this.setProcessState(PROCESS_STATE_PAUSED); + } + + /** Returns true iff the process should be stopped. */ + public boolean shouldStop() { + return getProcessState() == PROCESS_STATE_STOPPED; + } + + /** Returns true iff the process should be stopped. */ + public boolean shouldPause() { + return getProcessState() == PROCESS_STATE_PAUSED; + } + + // -------------------- + // Breakpoint Handling + // -------------------- + + /** Adds a breakpoint listener. */ + public void addBreakpointListener(final BreakpointListener listener) { + breakpointListeners.add(listener); + } + + /** Removes a breakpoint listener. */ + public void removeBreakpointListener(final BreakpointListener listener) { + breakpointListeners.remove(listener); + } + + /** Fires the event that the process was paused. */ + private void fireBreakpointEvent(final Operator operator, final IOContainer ioContainer, final int location) { + for (BreakpointListener l : breakpointListeners) { + l.breakpointReached(this, operator, ioContainer, location); + } + } + + /** Fires the event that the process was resumed. */ + public void fireResumeEvent() { + LinkedList l = new LinkedList<>(breakpointListeners); + for (BreakpointListener listener : l) { + listener.resume(); + } + } + + // ----------------- + // Checks + // ----------------- + + /** + * Delivers the information about unknown parameter types which occurred during process creation + * (from streams or files). + */ + public List getUnknownParameters() { + return this.unknownParameterInformation; + } + + /** + * Clears the information about unknown parameter types which occurred during process creation + * (from streams or files). + */ + public void clearUnknownParameters() { + this.unknownParameterInformation.clear(); + } + + /** + * Checks for correct number of inner operators, properties, and io. + * + * @deprecated Use {@link #checkProcess(IOContainer)} instead + */ + @Deprecated + public boolean checkExperiment(final IOContainer inputContainer) { + return checkProcess(inputContainer); + } + + /** Checks for correct number of inner operators, properties, and io. */ + public boolean checkProcess(final IOContainer inputContainer) { + rootOperator.checkAll(); + return true; + } + + // ------------------ + // Running + // ------------------ + + /** + * This method initializes the process, the operators, and the services and must be invoked at + * the beginning of run. It also resets all apply counts. + */ + private final void prepareRun(final int logVerbosity) throws OperatorException { + initLogging(logVerbosity); + + setProcessState(PROCESS_STATE_RUNNING); + getLogger().fine("Initialising process setup."); + + RandomGenerator.init(this); + ResultService.init(this); + + clearDataTables(); + clearReportStreams(); + clearMacros(); + clearStorage(); + if (getExecutionMode() != ExecutionMode.ONLY_DIRTY) { + getRootOperator().clear(Port.CLEAR_DATA); + } + AttributeFactory.resetNameCounters(); + + getLogger().fine("Process initialised."); + } + + /** + * Loads results from the repository if specified in the {@link ProcessContext}. + * + * @param firstPort + * Specifies the first port which is read from the ProcessContext. This enables the + * possibility to skip ports for which input is already specified via the input + * parameter of the run() method. + */ + protected void loadInitialData(final int firstPort) throws UserError { + ProcessContext context = getContext(); + if (context.getInputRepositoryLocations().isEmpty()) { + return; + } + getLogger() + .info("Loading initial data" + (firstPort > 0 ? " (starting at port " + (firstPort + 1) + ")" : "") + "."); + for (int i = firstPort; i < context.getInputRepositoryLocations().size(); i++) { + String location = context.getInputRepositoryLocations().get(i); + if (location == null || location.length() == 0) { + getLogger().fine("Input #" + (i + 1) + " not specified."); + } else { + if (i >= rootOperator.getSubprocess(0).getInnerSources().getNumberOfPorts()) { + getLogger().warning("No input port available for process input #" + (i + 1) + ": " + location); + } else { + OutputPort port = rootOperator.getSubprocess(0).getInnerSources().getPortByIndex(i); + RepositoryLocation loc; + try { + loc = resolveRepositoryLocation(location); + } catch (MalformedRepositoryLocationException e1) { + throw new PortUserError(port, 325, e1.getMessage()); + } catch (UserError e1) { + throw new PortUserError(port, 325, e1.getMessage()); + } + try { + Entry entry = loc.locateEntry(); + if (entry == null) { + throw new PortUserError(port, 312, loc, "Entry does not exist."); + } + if (entry instanceof IOObjectEntry) { + getLogger().info("Assigning " + loc + " to input port " + port.getSpec() + "."); + // only deliver the data if the port is really connected + if (port.isConnected()) { + port.deliver(((IOObjectEntry) entry).retrieveData(null)); + } + } else if (entry instanceof BlobEntry) { + getLogger().info("Assigning " + loc + " to input port " + port.getSpec() + "."); + // only deliver the data if the port is really connected + if (port.isConnected()) { + port.deliver(new RepositoryBlobObject(loc)); + } + } else { + getLogger().info( + "Cannot assigning " + loc + " to input port " + port.getSpec() + + ": Repository location does not reference an IOObject entry."); + throw new PortUserError(port, 312, loc, "Not an IOObject entry."); + } + } catch (RepositoryException e) { + throw new PortUserError(port, 312, loc, e.getMessage()); + } + } + } + } + } + + /** Stores the results in the repository if specified in the {@link ProcessContext}. */ + protected void saveResults() throws UserError { + ProcessContext context = getContext(); + if (context.getOutputRepositoryLocations().isEmpty()) { + return; + } + getLogger().info("Saving results."); + for (int i = 0; i < context.getOutputRepositoryLocations().size(); i++) { + String locationStr = context.getOutputRepositoryLocations().get(i); + if (locationStr == null || locationStr.length() == 0) { + getLogger().fine("Output #" + (i + 1) + " not specified."); + } else { + if (i >= rootOperator.getSubprocess(0).getInnerSinks().getNumberOfPorts()) { + getLogger().warning("No output port corresponding to process output #" + (i + 1) + ": " + locationStr); + } else { + InputPort port = rootOperator.getSubprocess(0).getInnerSinks().getPortByIndex(i); + RepositoryLocation location; + try { + location = rootOperator.getProcess().resolveRepositoryLocation(locationStr); + } catch (MalformedRepositoryLocationException e1) { + throw new PortUserError(port, 325, e1.getMessage()); + } catch (UserError e1) { + throw new PortUserError(port, 325, e1.getMessage()); + } + IOObject data = port.getDataOrNull(IOObject.class); + if (data == null) { + getLogger().warning( + "Nothing to store at " + location + ": No results produced at " + port.getSpec() + "."); + } else { + try { + RepositoryAccessor repositoryAccessor = getRepositoryAccessor(); + location.setAccessor(repositoryAccessor); + RepositoryManager.getInstance(repositoryAccessor).store(data, location, rootOperator); + + } catch (RepositoryException e) { + throw new PortUserError(port, 315, location, e.getMessage()); + } + } + } + } + } + } + + public void applyContextMacros() { + for (Pair macro : context.getMacros()) { + getLogger().fine("Defining context macro: " + macro.getFirst() + " = " + macro.getSecond() + "."); + getMacroHandler().addMacro(macro.getFirst(), macro.getSecond()); + } + } + + /** Starts the process with no input. */ + public final IOContainer run() throws OperatorException { + return run(new IOContainer()); + } + + /** Starts the process with the given log verbosity. */ + public final IOContainer run(final int logVerbosity) throws OperatorException { + return run(new IOContainer(), logVerbosity); + } + + /** Starts the process with the given input. */ + public final IOContainer run(final IOContainer input) throws OperatorException { + return run(input, LogService.UNKNOWN_LEVEL); + } + + /** Starts the process with the given input. The process uses the given log verbosity. */ + public final IOContainer run(final IOContainer input, final int logVerbosity) throws OperatorException { + return run(input, logVerbosity, null); + } + + /** + * Starts the process with the given input. The process uses a default log verbosity. The + * boolean flag indicates if some static initializations should be cleaned before the process is + * started. This should usually be true but it might be useful to set this to false if, for + * example, several process runs uses the same object visualizer which would have been cleaned + * otherwise. + */ + @Deprecated + public final IOContainer run(final IOContainer input, final boolean unused) throws OperatorException { + return run(input, LogService.UNKNOWN_LEVEL); + } + + /** + * Starts the process with the given input. The process uses the given log verbosity. The + * boolean flag indicates if some static initializations should be cleaned before the process is + * started. This should usually be true but it might be useful to set this to false if, for + * example, several process runs uses the same object visualizer which would have been cleaned + * otherwise. + */ + @Deprecated + public final IOContainer run(final IOContainer input, final int logVerbosity, final boolean cleanUp) + throws OperatorException { + return run(input, logVerbosity, null); + } + + /** + * Starts the process with the given input. The process uses the given log verbosity. The + * boolean flag indicates if some static initializations should be cleaned before the process is + * started. This should usually be true but it might be useful to set this to false if, for + * example, several process runs uses the same object visualizer which would have been cleaned + * otherwise. + * + * Since the macros are cleaned then as well it is not possible to set macros to a process but + * with the given macroMap of this method. + */ + @Deprecated + public final IOContainer run(final IOContainer input, final int logVerbosity, final boolean cleanUp, + final Map macroMap) throws OperatorException { + return run(input, logVerbosity, macroMap); + + } + + public final IOContainer run(final IOContainer input, final int logVerbosity, final Map macroMap) + throws OperatorException { + return run(input, logVerbosity, macroMap, true); + } + + /** + * Starts the process with the given input. The process uses the given log verbosity. + * + * If input is not null, it is delivered to the input ports of the process. If it is null or + * empty, the input is read instead from the locations specified in the {@link ProcessContext}. + * + * If input contains less IOObjects than are specified in the context, the remaining ones are + * read according to the context. + * + * @param storeOutput + * Specifies if the output of the process should be saved. This is useful, if you + * embed a process using the Execute Process operator, and do not want to store the + * output as specified by the process context. + */ + public final IOContainer run(final IOContainer input, int logVerbosity, final Map macroMap, + final boolean storeOutput) throws OperatorException { + // make sure licensing constraints are not violated + // iterate over all operators in the process + for (Operator op : rootOperator.getAllInnerOperators()) { + // we only care about enabled operators + if (op.isEnabled()) { + + // Check for annotations that constrain access to the current operator + List licenseViolations = ProductConstraintManager.INSTANCE.checkAnnotationViolations(op, + true); + if (!licenseViolations.isEmpty()) { + throw new LicenseViolationException(op, licenseViolations); + } + + // as a side effect mark all enabled operators as dirty + // so it is clear which ones have already been executed + op.makeDirty(); + } + } + // fetching process name for logging + String name = null; + if (getProcessLocation() != null) { + name = getProcessLocation().toString(); + } + + int myVerbosity = rootOperator.getParameterAsInt(ProcessRootOperator.PARAMETER_LOGVERBOSITY); + if (logVerbosity == LogService.UNKNOWN_LEVEL) { + logVerbosity = LogService.OFF; + } + logVerbosity = Math.min(logVerbosity, myVerbosity); + getLogger().setLevel(WrapperLoggingHandler.LEVELS[logVerbosity]); + String logFilename = rootOperator.getParameter(ProcessRootOperator.PARAMETER_LOGFILE); + Handler logHandler = null; + if (logFilename != null) { + try { + logHandler = new FileHandler(logFilename); + logHandler.setFormatter(new SimpleFormatter()); + logHandler.setLevel(Level.ALL); + getLogger().config("Logging process to file " + logFilename); + } catch (Exception e) { + getLogger().warning("Cannot create log file '" + logFilename + "': " + e); + } + } + if (logHandler != null) { + getLogger().addHandler(logHandler); + } + + setProcessState(PROCESS_STATE_RUNNING); + prepareRun(logVerbosity); + + long start = System.currentTimeMillis(); + + // load data as specified in process context + int firstInput = 0; + if (input != null) { + firstInput = input.getIOObjects().length; + } + loadInitialData(firstInput); + + // macros + applyContextMacros(); + if (macroMap != null) { + for (Map.Entry entry : macroMap.entrySet()) { + getMacroHandler().addMacro(entry.getKey(), entry.getValue()); + } + } + rootOperator.processStarts(); + + if (name != null) { + getLogger().info("Process " + name + " starts"); + } else { + getLogger().info("Process starts"); + } + getLogger().fine("Process:" + Tools.getLineSeparator() + getRootOperator().createProcessTree(3)); + + try { + ActionStatisticsCollector.getInstance().logExecution(this); + if (input != null) { + rootOperator.deliverInput(Arrays.asList(input.getIOObjects())); + } + rootOperator.execute(); + if (storeOutput) { + saveResults(); + } + IOContainer result = rootOperator.getResults(isOmittingNullResults()); + long end = System.currentTimeMillis(); + + getLogger().fine("Process:" + Tools.getLineSeparator() + getRootOperator().createProcessTree(3)); + if (name != null) { + getLogger().info("Process " + name + " finished successfully after " + Tools.formatDuration(end - start)); + } else { + getLogger().info("Process finished successfully after " + Tools.formatDuration(end - start)); + } + + return result; + } catch (OperatorException e) { + if (e instanceof ProcessStoppedException) { + Operator op = getOperator(((ProcessStoppedException) e).getOperatorName()); + ActionStatisticsCollector.getInstance().log(op, ActionStatisticsCollector.OPERATOR_EVENT_STOPPED); + } else { + ActionStatisticsCollector.getInstance().log(getCurrentOperator(), + ActionStatisticsCollector.OPERATOR_EVENT_FAILURE); + if (e instanceof UserError) { + ActionStatisticsCollector.getInstance().log(((UserError) e).getOperator(), + ActionStatisticsCollector.OPERATOR_EVENT_USER_ERROR); + } else { + ActionStatisticsCollector.getInstance().log(getCurrentOperator(), + ActionStatisticsCollector.OPERATOR_EVENT_OPERATOR_EXCEPTION); + } + } + throw e; + } finally { + stop(); + tearDown(); + if (logHandler != null) { + getLogger().removeHandler(logHandler); + logHandler.close(); + } + } + } + + /** This method is invoked after a process has finished. */ + private void tearDown() { + try { + rootOperator.processFinished(); + } catch (OperatorException e) { + getLogger().log(Level.WARNING, "Problem during finishing the process: " + e.getMessage(), e); + } + + // clean up + // clearMacros(); + clearReportStreams(); + clearStorage(); + clearUnknownParameters(); + ResultService.close(); + } + + // ---------------------- + // Process IO + // ---------------------- + + public static Charset getEncoding(String encoding) { + if (encoding == null) { + encoding = ParameterService.getParameterValue(RapidMiner.PROPERTY_RAPIDMINER_GENERAL_DEFAULT_ENCODING); + if (encoding == null || encoding.trim().length() == 0) { + encoding = RapidMiner.SYSTEM_ENCODING_NAME; + } + } + + Charset result = null; + if (RapidMiner.SYSTEM_ENCODING_NAME.equals(encoding)) { + result = Charset.defaultCharset(); + } else { + try { + result = Charset.forName(encoding); + } catch (IllegalCharsetNameException e) { + result = Charset.defaultCharset(); + } catch (UnsupportedCharsetException e) { + result = Charset.defaultCharset(); + } catch (IllegalArgumentException e) { + result = Charset.defaultCharset(); + } + } + return result; + } + + /** Saves the process to the process file. */ + public void save() throws IOException { + try { + Process.checkIfSavable(this); + } catch (Exception e) { + throw new IOException(e.getMessage()); + } + if (processLocation != null) { + this.isProcessConverted = false; + processLocation.store(this, null); + } else { + throw new IOException("No process location is specified."); + } + } + + /** Saves the process to the given process file. */ + public void save(final File file) throws IOException { + try { + Process.checkIfSavable(this); + } catch (Exception e) { + throw new IOException(e.getMessage()); + } + new FileProcessLocation(file).store(this, null); + } + + /** + * Resolves the given filename against the directory containing the process file. + */ + public File resolveFileName(final String name) { + File absolute = new File(name); + if (absolute.isAbsolute()) { + return absolute; + } + if (processLocation instanceof FileProcessLocation) { + File processFile = ((FileProcessLocation) processLocation).getFile(); + return Tools.getFile(processFile.getParentFile(), name); + } else { + String homeName; + String resolvedir = System.getProperty("rapidminer.test.resolvedir"); + if (resolvedir == null) { + homeName = System.getProperty("user.home"); + } else { + homeName = resolvedir; + } + if (homeName != null) { + File file = new File(new File(homeName), name); + getLogger().warning("Process not attached to a file. Resolving against user directory: '" + file + "'."); + return file; + } else { + getLogger().warning("Process not attached to a file. Trying abolute filename '" + name + "'."); + return new File(name); + } + } + } + + /** Reads the process setup from the given input stream. */ + public void readProcess(final Reader in) throws XMLException, IOException { + readProcess(in, null); + } + + public void readProcess(final Reader in, final ProgressListener progressListener) throws XMLException, IOException { + Map nameMapBackup = operatorNameMap; + operatorNameMap = new HashMap<>(); // no invocation of clear (see below) + + if (progressListener != null) { + progressListener.setTotal(120); + progressListener.setCompleted(0); + } + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(in)); + if (progressListener != null) { + progressListener.setCompleted(20); + } + unknownParameterInformation.clear(); + XMLImporter xmlImporter = new XMLImporter(progressListener); + xmlImporter.parse(document, this, unknownParameterInformation); + + nameMapBackup = operatorNameMap; + rootOperator.clear(Port.CLEAR_ALL); + } catch (javax.xml.parsers.ParserConfigurationException e) { + throw new XMLException(e.toString(), e); + } catch (SAXException e) { + throw new XMLException("Cannot parse document: " + e.getMessage(), e); + } finally { + operatorNameMap = nameMapBackup; // if everything went fine --> + // map = new map, if not --> + // map = old map (backup) + if (progressListener != null) { + progressListener.complete(); + } + } + } + + /** + * Returns a "name (i)" if name is already in use. This new name should then be used + * as operator name. + */ + public String registerName(final String name, final Operator operator) { + if (operatorNameMap.get(name) != null) { + String baseName = name; + int index = baseName.indexOf(" ("); + if (index >= 0) { + baseName = baseName.substring(0, index); + } + int i = 2; + while (operatorNameMap.get(baseName + " (" + i + ")") != null) { + i++; + } + String newName = baseName + " (" + i + ")"; + operatorNameMap.put(newName, operator); + return newName; + } else { + operatorNameMap.put(name, operator); + return name; + } + } + + /** This method is used for unregistering a name from the operator name map. */ + public void unregisterName(final String name) { + operatorNameMap.remove(name); + } + + public void notifyRenaming(final String oldName, final String newName) { + rootOperator.notifyRenaming(oldName, newName); + } + + @Override + public String toString() { + if (rootOperator == null) { + return "empty process"; + } else { + return "Process:" + Tools.getLineSeparator() + rootOperator.getXML(true); + } + } + + private final EventListenerList processSetupListeners = new EventListenerList(); + + /** Delegates any changes in the ProcessContext to the root operator. */ + private final Observer delegatingContextObserver = new Observer() { + + @Override + public void update(final Observable observable, final ProcessContext arg) { + fireUpdate(); + } + }; + private final Observer delegatingOperatorObserver = new Observer() { + + @Override + public void update(final Observable observable, final Operator arg) { + fireUpdate(); + } + }; + + public void addProcessSetupListener(final ProcessSetupListener listener) { + processSetupListeners.add(ProcessSetupListener.class, listener); + } + + public void removeProcessSetupListener(final ProcessSetupListener listener) { + processSetupListeners.remove(ProcessSetupListener.class, listener); + } + + public void fireOperatorAdded(final Operator operator) { + for (ProcessSetupListener l : processSetupListeners.getListeners(ProcessSetupListener.class)) { + l.operatorAdded(operator); + } + } + + public void fireOperatorChanged(final Operator operator) { + for (ProcessSetupListener l : processSetupListeners.getListeners(ProcessSetupListener.class)) { + l.operatorChanged(operator); + } + } + + public void fireOperatorRemoved(final Operator operator, final int oldIndex, final int oldIndexAmongEnabled) { + for (ProcessSetupListener l : processSetupListeners.getListeners(ProcessSetupListener.class)) { + l.operatorRemoved(operator, oldIndex, oldIndexAmongEnabled); + } + } + + public void fireExecutionOrderChanged(final ExecutionUnit unit) { + for (ProcessSetupListener l : processSetupListeners.getListeners(ProcessSetupListener.class)) { + l.executionOrderChanged(unit); + } + } + + public ExecutionMode getExecutionMode() { + return executionMode; + } + + public void setExecutionMode(final ExecutionMode mode) { + this.executionMode = mode; + } + + public DebugMode getDebugMode() { + return debugMode; + } + + public void setDebugMode(final DebugMode mode) { + this.debugMode = mode; + if (mode == DebugMode.DEBUG_OFF) { + getRootOperator().clear(Port.CLEAR_REAL_METADATA); + } + } + + /** Resolves a repository location relative to {@link #getRepositoryLocation()}. */ + public RepositoryLocation resolveRepositoryLocation(final String loc) throws UserError, + MalformedRepositoryLocationException { + if (RepositoryLocation.isAbsolute(loc)) { + RepositoryLocation repositoryLocation = new RepositoryLocation(loc); + repositoryLocation.setAccessor(getRepositoryAccessor()); + return repositoryLocation; + } + RepositoryLocation repositoryLocation = getRepositoryLocation(); + if (repositoryLocation != null) { + RepositoryLocation repositoryLocation2 = new RepositoryLocation(repositoryLocation.parent(), loc); + repositoryLocation2.setAccessor(getRepositoryAccessor()); + return repositoryLocation2; + } else { + throw new UserError(null, 317, loc); + } + } + + /** Turns loc into a repository location relative to {@link #getRepositoryLocation()}. */ + public String makeRelativeRepositoryLocation(final RepositoryLocation loc) { + RepositoryLocation repositoryLocation = getRepositoryLocation(); + if (repositoryLocation != null) { + return loc.makeRelative(repositoryLocation.parent()); + } else { + return loc.getAbsoluteLocation(); + } + } + + public void setContext(final ProcessContext context) { + if (this.context != null) { + this.context.removeObserver(delegatingContextObserver); + } + this.context = context; + this.context.addObserver(delegatingContextObserver, false); + fireUpdate(); + } + + public ProcessContext getContext() { + return context; + } + + public void setImportMessage(final String importMessage) { + this.importMessage = importMessage; + } + + /** + * This returns true if the process has been imported and ImportRules have been applied during + * importing. Since the backward compatibility is lost on save, one can warn by retrieving this + * value. + */ + public boolean isProcessConverted() { + return isProcessConverted; + } + + /** + * This sets whether the process is converted. + */ + public void setProcessConverted(final boolean isProcessConverted) { + this.isProcessConverted = isProcessConverted; + } + + /** + * Returns some user readable messages generated during import by {@link XMLImporter}. + */ + public String getImportMessage() { + return importMessage; + } + + // process location (file/repository) + + /** Returns true iff either a file or a repository location is defined. */ + public boolean hasSaveDestination() { + return processLocation != null; + } + + /** + * Returns the current process file. + * + * @deprecated Use {@link #getProcessFile()} instead + */ + @Deprecated + public File getExperimentFile() { + return getProcessFile(); + } + + /** + * Returns the current process file. + * + * @deprecated Use {@link #getProcessLocation()} + */ + @Deprecated + public File getProcessFile() { + if (processLocation instanceof FileProcessLocation) { + return ((FileProcessLocation) processLocation).getFile(); + } else { + return null; + } + } + + /** + * Sets the process file. This file might be used for resolving relative filenames. + * + * @deprecated Please use {@link #setProcessFile(File)} instead. + */ + @Deprecated + public void setExperimentFile(final File file) { + setProcessLocation(new FileProcessLocation(file)); + } + + /** Sets the process file. This file might be used for resolving relative filenames. */ + public void setProcessFile(final File file) { + setProcessLocation(new FileProcessLocation(file)); + } + + public void setProcessLocation(final ProcessLocation processLocation) { + // keep process file version if same file, otherwise overwrite + if (this.processLocation != null && !this.processLocation.equals(processLocation)) { + this.isProcessConverted = false; + getLogger().info( + "Decoupling process from location " + this.processLocation + ". Process is now associated with file " + + processLocation + "."); + } + this.processLocation = processLocation; + fireUpdate(); + } + + public ProcessLocation getProcessLocation() { + return this.processLocation; + } + + public RepositoryLocation getRepositoryLocation() { + if (processLocation instanceof RepositoryProcessLocation) { + return ((RepositoryProcessLocation) processLocation).getRepositoryLocation(); + } else { + return null; + } + } + + /** + * @return if false is returned, the {@link IOContainer} returned by {@link #run()} + * will contain null results instead of just omitting them. + */ + public boolean isOmittingNullResults() { + return omitNullResults; + } + + /** + * If set to false the {@link IOContainer} returned by {@link #run()} will contain + * null results instead of omitting them. By default this is true. + */ + public void setOmitNullResults(boolean omitNullResults) { + this.omitNullResults = omitNullResults; + } + + /** + * Can be called by GUI components if visual representation or any other state not known to the + * process itself has changed. + */ + public void updateNotify() { + fireUpdate(this); + } + + public RepositoryAccessor getRepositoryAccessor() { + return repositoryAccessor; + } + + public void setRepositoryAccessor(final RepositoryAccessor repositoryAccessor) { + this.repositoryAccessor = repositoryAccessor; + } + + public Annotations getAnnotations() { + return annotations; + } + + /** + * Indicates how deeply nested the current process is. The original process itself has a depth + * of {@code 0}. If that process spawns a new one via an Execute Process operator, the depth of + * the new one will be {@code 1}. If the new process also contains an Execute Process operator, + * the depth will be {@code 2} and so on. + * + * @return the nesting depth of the current process + */ + public int getDepth() { + return nestingDepth; + } + + /** + * Sets the nesting depth of this process. See {@link #getDepth()} for details. + * + * @param depth + * the new nesting depth + */ + public void setDepth(int depth) { + this.nestingDepth = depth; + } + + /** + * Checks weather the process can be saved as is. Throws an Exception if the Process should not + * be saved. + **/ + public static void checkIfSavable(final Process process) throws Exception { + for (Operator operator : process.getAllOperators()) { + if (operator instanceof DummyOperator) { + throw new Exception( + "The process contains dummy operators. Remove all dummy operators or install all missing extensions in order to save the process."); + } + } + } + +} diff --git a/src/main/java/com/rapidminer/ProcessContext.java b/src/main/java/com/rapidminer/ProcessContext.java new file mode 100644 index 000000000..273c7bbc0 --- /dev/null +++ b/src/main/java/com/rapidminer/ProcessContext.java @@ -0,0 +1,253 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.operator.OperatorCreationException; +import com.rapidminer.operator.libraries.OperatorLibrary; +import com.rapidminer.repository.RepositoryLocation; +import com.rapidminer.tools.AbstractObservable; +import com.rapidminer.tools.container.Pair; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + + +/** + *

+ * The process context holds some data controlling the execution of a {@link Process}. This includes + * connections of the input and output ports of the root operator to repository locations as well as + * the definition of macros. + *

+ *

+ * The fact that this data is defined outside the process itself is particularly useful if this + * process is offered as a service, so it can be adapted easily. Furthermore, this saves the process + * designer from defining data reading and storing operators at the beginning and at the end of the + * process. + *

+ *

+ * Note: A ProcessContext is not necessarily associate with a {@link Process}. E.g., if a process is + * run remotely, it does not necessarily exist on the machine that prepares the context. + *

+ *

+ * Since this class acts merely as a data container, it has public getter and setter methods which + * return references to the actual data (as opposed to immutable views). In order to trigger an + * update, call a setter method rather than adding to the lists, which is invisible to the process + * context. + *

+ *

+ * The data is saved as strings rather than, e.g. using {@link RepositoryLocation}s. + *

+ *

+ * Since this class is saved as a Lob with the ProcessExecutionParameters entity, serializability + * must be ensured. This is guaranteed by the fact that this class only contains {@link List}s of + * strings or {@link Pair}s of strings, where {@link Pair} is serializable. + *

+ * + * @author Simon Fischer + */ +public class ProcessContext extends AbstractObservable implements Serializable { + + private static final long serialVersionUID = 1L; + + private List inputRepositoryLocations = new ArrayList<>(); + + private List outputRepositoryLocations = new ArrayList<>(); + + private List> macros = new LinkedList<>(); + + private List> libraryLocations = new LinkedList<>(); + + public ProcessContext() {} + + public List getInputRepositoryLocations() { + return Collections.unmodifiableList(inputRepositoryLocations); + } + + public void setInputRepositoryLocations(List inputRepositoryLocations) { + if (inputRepositoryLocations.contains(null)) { + throw new NullPointerException("Null elements not allowed"); + } + this.inputRepositoryLocations = inputRepositoryLocations; + fireUpdate(this); + } + + public List getOutputRepositoryLocations() { + return Collections.unmodifiableList(outputRepositoryLocations); + } + + public void setOutputRepositoryLocations(List outputRepositoryLocations) { + if (outputRepositoryLocations.contains(null)) { + throw new NullPointerException("Null elements not allowed"); + } + this.outputRepositoryLocations = outputRepositoryLocations; + fireUpdate(this); + } + + public List> getMacros() { + return macros; + } + + /** + * Updates the given macro with the given value. Fires an update after applying the changes. + * + * @param macroIndex + * index of the macro in the {@link #getMacros()} list + * @param pairIndex + * 0 for first value; 1 for second value + * @param newValue + */ + public void updateMacroValue(int macroIndex, int pairIndex, String newValue) { + switch (pairIndex) { + case 0: + getMacros().get(macroIndex).setFirst(newValue); + fireUpdate(this); + break; + case 1: + getMacros().get(macroIndex).setSecond(newValue); + fireUpdate(this); + break; + default: + throw new IndexOutOfBoundsException(pairIndex + " > 1"); + } + } + + /** Adds a macro to the list or sets an existing one. */ + public void addMacro(Pair macro) { + for (Pair existingMacro : this.macros) { + if (existingMacro.getFirst().equals(macro.getFirst())) { + // overwrite existing + existingMacro.setSecond(macro.getSecond()); + return; + } + } + this.macros.add(macro); + fireUpdate(this); + } + + /** Removes a macro from the list */ + public void removeMacro(int index) { + this.macros.remove(index); + fireUpdate(this); + } + + public void setMacros(List> macros) { + this.macros = macros; + fireUpdate(this); + } + + public void setOutputRepositoryLocation(int index, String location) { + if (location == null) { + throw new NullPointerException("Null location not allowed"); + } + while (outputRepositoryLocations.size() <= index) { + outputRepositoryLocations.add(""); + } + outputRepositoryLocations.set(index, location); + fireUpdate(); + } + + public void setInputRepositoryLocation(int index, String location) { + if (location == null) { + throw new NullPointerException("Null location not allowed"); + } + while (inputRepositoryLocations.size() <= index) { + inputRepositoryLocations.add(""); + } + inputRepositoryLocations.set(index, location); + fireUpdate(); + } + + public void removeOutputLocation(int rowIndex) { + outputRepositoryLocations.remove(rowIndex); + } + + public void removeInputLocation(int rowIndex) { + inputRepositoryLocations.remove(rowIndex); + } + + public void addOutputLocation(String location) { + if (location == null) { + throw new NullPointerException("Location must not be null"); + } + outputRepositoryLocations.add(location); + } + + public void addInputLocation(String location) { + if (location == null) { + throw new NullPointerException("Location must not be null"); + } + inputRepositoryLocations.add(location); + } + + /** + * Merges the current context with the given one. Macros will be simply added, input and output + * locations override their respective counterparts if not null. This modifies this instance. + */ + public void superimpose(ProcessContext other) { + if (other == null) { + return; + } + for (Pair macro : other.macros) { + this.macros.add(macro); + } + + for (int i = 0; i < other.inputRepositoryLocations.size(); i++) { + String loc = other.inputRepositoryLocations.get(i); + if ((loc != null) && !loc.isEmpty()) { + this.setInputRepositoryLocation(i, loc); + } + } + + for (int i = 0; i < other.outputRepositoryLocations.size(); i++) { + String loc = other.outputRepositoryLocations.get(i); + if ((loc != null) && !loc.isEmpty()) { + this.setOutputRepositoryLocation(i, loc); + } + } + } + + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("Macros: ").append(getMacros()); + b.append("; Input: ").append(getInputRepositoryLocations()); + b.append("; Output: ").append(getOutputRepositoryLocations()); + return b.toString(); + } + + /** + * This returns all loaded OperatorLibries that should be used within this process. + */ + public List getOperatorLibraries() { + return Collections.emptyList(); + } + + public void addOperatorLibrary(OperatorLibrary library, String location) { + libraryLocations.add(new Pair<>(library, location)); + try { + library.registerOperators(); + } catch (OperatorCreationException e) { + e.printStackTrace(); + // TODO: This is unnecessary if operators aren't initialized during registration! + } + } +} diff --git a/src/main/java/com/rapidminer/ProcessListener.java b/src/main/java/com/rapidminer/ProcessListener.java new file mode 100644 index 000000000..7a38a386e --- /dev/null +++ b/src/main/java/com/rapidminer/ProcessListener.java @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.operator.Operator; + + +/** + * Listens to events during the run of an process. + * + * @author Ingo Mierswa Exp $ + */ +public interface ProcessListener { + + /** Will be invoked during process start. */ + public void processStarts(Process process); + + /** Will be invoked every time another operator is started in the process. */ + public void processStartedOperator(Process process, Operator op); + + /** Will be invoked every time an operator is finished */ + public void processFinishedOperator(Process process, Operator op); + + /** Will invoked when the process was successfully finished. */ + public void processEnded(Process process); + +} diff --git a/src/main/java/com/rapidminer/ProcessLocation.java b/src/main/java/com/rapidminer/ProcessLocation.java new file mode 100644 index 000000000..64b59050e --- /dev/null +++ b/src/main/java/com/rapidminer/ProcessLocation.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.tools.ProgressListener; +import com.rapidminer.tools.XMLException; + +import java.io.IOException; + + +/** + * A place where a process can be saved. Basically, this is either a file or a location in a + * repository. + * + * @author Simon Fischer + * */ +public interface ProcessLocation { + + /** Reads the process and returns it. */ + public Process load(ProgressListener listener) throws IOException, XMLException; + + /** Stores the process at the referenced location. */ + public void store(Process process, ProgressListener listener) throws IOException; + + /** The toString representation is used, e.g. in the welcome screen dialog, */ + @Override + public String toString(); + + /** + * Reads the contents of the referenced resource and returns the XML without parsing it. Used if + * process file is broken. + */ + public String getRawXML() throws IOException; + + /** Returns a string saved to the history file. */ + public String toHistoryFileString(); + + /** Returns a string as it is displayed in the recent files menu. */ + public String toMenuString(); + + /** Returns a short name, e.g. the last component of the path. */ + public String getShortName(); +} diff --git a/src/main/java/com/rapidminer/ProcessSetupListener.java b/src/main/java/com/rapidminer/ProcessSetupListener.java new file mode 100644 index 000000000..c4c1c8163 --- /dev/null +++ b/src/main/java/com/rapidminer/ProcessSetupListener.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.operator.ExecutionUnit; +import com.rapidminer.operator.Operator; + +import java.util.EventListener; + + +/** + * Listener for process setup, i.e. insertion, deletion and property changes of operators. + * + * @author Simon Fischer + * + */ +public interface ProcessSetupListener extends EventListener { + + /** Called if a new operator was added to the process. */ + public void operatorAdded(Operator operator); + + /** + * Called if an operator was removed from the process. + * + * @param oldIndex + * The former index of the operator within its {@link ExecutionUnit}. + * @param oldIndexAmongEnabled + * The former index of the operator within its {@link ExecutionUnit} enabled + * operators + */ + public void operatorRemoved(Operator operator, int oldIndex, int oldIndexAmongEnabled); + + /** Called if an operator changed in any way, e.g. if it was renamed. */ + public void operatorChanged(Operator operator); + + /** Called if the execution order within an ExecutionUnit changes. */ + public void executionOrderChanged(ExecutionUnit unit); + +} diff --git a/src/main/java/com/rapidminer/ProcessStateListener.java b/src/main/java/com/rapidminer/ProcessStateListener.java new file mode 100644 index 000000000..dfc9ff105 --- /dev/null +++ b/src/main/java/com/rapidminer/ProcessStateListener.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +/** + * This listener can be used to register for process state changes like start/pause/stop initiated + * by user. + * + * @author Christian Pels, Nils Woehler + * + */ +public interface ProcessStateListener { + + /** + * Fired if a process is started. + * + * @param process + * the process that has been started + */ + public void started(Process process); + + /** + * Fired if a process was paused. + * + * @param process + * the process that was paused + */ + public void paused(Process process); + + /** + * Fired if a process was resumed. + * + * @param process + * the process that was resumed + */ + public void resumed(Process process); + + /** + * Fired if a process was stopped. + * + * @param process + * the process that was stopped + */ + public void stopped(Process process); + +} diff --git a/src/main/java/com/rapidminer/ProcessStorageListener.java b/src/main/java/com/rapidminer/ProcessStorageListener.java new file mode 100644 index 000000000..b0584bc32 --- /dev/null +++ b/src/main/java/com/rapidminer/ProcessStorageListener.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +/** + * Notified when process is stored or opened. + * + * @author Philipp Kersting + */ +public interface ProcessStorageListener { + + /** + * Called when a process is stored in the GUI. + * + * @param process + */ + public void stored(Process process); + + /** + * Called when a process is opened in the GUI. + * + * @param process + */ + public void opened(Process process); +} diff --git a/src/main/java/com/rapidminer/RapidMiner.java b/src/main/java/com/rapidminer/RapidMiner.java new file mode 100644 index 000000000..cf8e1cd8d --- /dev/null +++ b/src/main/java/com/rapidminer/RapidMiner.java @@ -0,0 +1,1015 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import java.awt.Frame; +import java.awt.Image; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Scanner; +import java.util.Set; +import java.util.Vector; +import java.util.logging.Level; + +import com.rapidminer.core.license.ActionStatisticsLicenseManagerListener; +import com.rapidminer.core.license.ProductConstraintManager; +import com.rapidminer.gui.RapidMinerGUI; +import com.rapidminer.gui.properties.SettingsItems; +import com.rapidminer.gui.renderer.RendererService; +import com.rapidminer.gui.safemode.SafeMode; +import com.rapidminer.gui.tools.SplashScreen; +import com.rapidminer.gui.tools.VersionNumber; +import com.rapidminer.io.process.XMLImporter; +import com.rapidminer.license.AlreadyRegisteredException; +import com.rapidminer.license.InvalidProductException; +import com.rapidminer.license.License; +import com.rapidminer.license.location.LicenseLoadingException; +import com.rapidminer.license.location.LicenseLocation; +import com.rapidminer.license.product.Product; +import com.rapidminer.operator.IOObject; +import com.rapidminer.operator.IOObjectMap; +import com.rapidminer.operator.ProcessRootOperator; +import com.rapidminer.operator.learner.CapabilityProvider; +import com.rapidminer.parameter.ParameterType; +import com.rapidminer.parameter.ParameterTypeBoolean; +import com.rapidminer.parameter.ParameterTypeCategory; +import com.rapidminer.parameter.ParameterTypeDirectory; +import com.rapidminer.parameter.ParameterTypeInt; +import com.rapidminer.parameter.ParameterTypePassword; +import com.rapidminer.parameter.ParameterTypeString; +import com.rapidminer.repository.RepositoryManager; +import com.rapidminer.test.asserter.AsserterFactoryRapidMiner; +import com.rapidminer.test_utils.RapidAssert; +import com.rapidminer.tools.FileSystemService; +import com.rapidminer.tools.GlobalAuthenticator; +import com.rapidminer.tools.I18N; +import com.rapidminer.tools.I18N.SettingsType; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.OperatorService; +import com.rapidminer.tools.ParameterService; +import com.rapidminer.tools.PlatformUtilities; +import com.rapidminer.tools.ProgressListener; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.WebServiceTools; +import com.rapidminer.tools.XMLException; +import com.rapidminer.tools.XMLSerialization; +import com.rapidminer.tools.cipher.CipherTools; +import com.rapidminer.tools.cipher.KeyGenerationException; +import com.rapidminer.tools.cipher.KeyGeneratorTool; +import com.rapidminer.tools.config.ConfigurationManager; +import com.rapidminer.tools.plugin.Plugin; +import com.rapidminer.tools.usagestats.UsageStatistics; + + +/** + * Main program. Entry point for command line programm, GUI and wrappers. Please note that + * applications which use RapidMiner as a data mining library will have to invoke one of the init + * methods provided by this class before applying processes or operators. Several init methods exist + * and choosing the correct one with optimal parameters might drastically reduce runtime and / or + * initialization time. + * + * @author Ingo Mierswa, Adrian Wilke + */ +public class RapidMiner { + + public static final String SYSTEM_ENCODING_NAME = "SYSTEM"; + + /** URL prefix of URLs that can be opened with RapidMiner. */ + public static final String RAPIDMINER_URL_PREFIX = "rapidminer://"; + + public static enum ExitMode { + NORMAL, ERROR, RELAUNCH + } + + private static final int RELAUNCH_EXIT_CODE = 2; + + /** Indicates how RapidMiner is being executed. */ + public enum ExecutionMode { + /** It is unknown how RM was invoked. */ + UNKNOWN(true, false, false, true), + /** RM is executed using {@link RapidMinerCommandLine#main(String[])}. */ + COMMAND_LINE(true, true, false, true), + /** RM is executed using {@link RapidMinerGUI#main(String[])}. */ + UI(false, true, true, true), + /** RM is running inside an application server. */ + APPSERVER(true, false, false, false), + /** RM is running as an applet inside a browser. */ + APPLET(false, true, true, false), + /** RM is embedded into another program. */ + EMBEDDED_WITH_UI(false, true, false, false), + /** RM is embedded into another program. */ + EMBEDDED_WITHOUT_UI(true, true, false, false), + /** RM is embedded into an applet. */ + EMBEDDED_AS_APPLET(false, false, false, false), + /** RM is running within Java Web Start. */ + WEBSTART(false, true, true, true), + /** We are executing unit tests. */ + TEST(true, false, false, true); + + private final boolean isHeadless; + private final boolean canAccessFilesystem; + private final boolean hasMainFrame; + private final boolean loadManagedExtensions; + + private ExecutionMode(final boolean isHeadless, final boolean canAccessFilesystem, final boolean hasMainFrame, + final boolean loadManagedExtensions) { + this.isHeadless = isHeadless; + this.canAccessFilesystem = canAccessFilesystem; + this.hasMainFrame = hasMainFrame; + this.loadManagedExtensions = loadManagedExtensions; + } + + public boolean isHeadless() { + return isHeadless; + } + + public boolean canAccessFilesystem() { + return canAccessFilesystem; + } + + public boolean hasMainFrame() { + return hasMainFrame; + } + + public boolean isLoadingManagedExtensions() { + return loadManagedExtensions; + } + } + + private static ExecutionMode executionMode = ExecutionMode.UNKNOWN; + private static final VersionNumber VERSION = new RapidMinerVersion(); + private static boolean assertersInitialized = false; + + // --- GENERAL PROPERTIES --- + + /** The name of the property indicating the version of RapidMiner (read only). */ + public static final String PROPERTY_RAPIDMINER_VERSION = "rapidminer.version"; + + /** + * Enables special features for developers: Validate process action, operator doc editor, etc. + */ + public static final String PROPERTY_DEVELOPER_MODE = "rapidminer.developermode"; + + /** + * The name of the property indicating the path to a additional operator description XML + * file(s). If more than one, then the files have to be separated using the File.pathSeparator + * character. + */ + public static final String PROPERTY_RAPIDMINER_OPERATORS_ADDITIONAL = "rapidminer.operators.additional"; + + /** + * The name of the property indicating the path to additional ioobjects description XML file(s). + * If more than one, then the files have to be separated using the File.pathSeparator character. + */ + public static final String PROPERTY_RAPIDMINER_OBJECTS_ADDITIONAL = "rapidminer.objects.additional"; + + /** The name of the property indicating the path to an RC file (settings). */ + public static final String PROPERTY_RAPIDMINER_RC_FILE = "rapidminer.rcfile"; + + /** The name of the property indicating the path to the global logging file. */ + public static final String PROPERTY_RAPIDMINER_GLOBAL_LOG_FILE = "rapidminer.global.logging.file"; + + /** The name of the property indicating the path to the global logging file. */ + public static final String PROPERTY_RAPIDMINER_GLOBAL_LOG_VERBOSITY = "rapidminer.global.logging.verbosity"; + + // Webstart properties + public static final String PROPERTY_HOME_REPOSITORY_URL = "rapidminer.homerepository.url"; + public static final String PROPERTY_HOME_REPOSITORY_USER = "rapidminer.homerepository.user"; + public static final String PROPERTY_HOME_REPOSITORY_PASSWORD = "rapidminer.homerepository.password"; + + // --- INIT PROPERTIES --- + + /** A file path to an operator description XML file. */ + public static final String PROPERTY_RAPIDMINER_INIT_OPERATORS = "rapidminer.init.operators"; + + public static final String PROPERTY_RAPIDMINER_GENERAL_LOCALE_LANGUAGE = "rapidminer.general.locale.language"; + public static final String PROPERTY_RAPIDMINER_GENERAL_LOCALE_COUNTRY = "rapidminer.general.locale.country"; + public static final String PROPERTY_RAPIDMINER_GENERAL_LOCALE_VARIANT = "rapidminer.general.locale.variant"; + + /** Boolean parameter indicating if the plugins should be initialized at all. */ + public static final String PROPERTY_RAPIDMINER_INIT_PLUGINS = "rapidminer.init.plugins"; + + /** A file path to the directory containing the plugin Jar files. */ + public static final String PROPERTY_RAPIDMINER_INIT_PLUGINS_LOCATION = "rapidminer.init.plugins.location"; + + // --- OTHER PROPERTIES --- + + /** The property name for "The number of fraction digits of formatted numbers." */ + public static final String PROPERTY_RAPIDMINER_GENERAL_FRACTIONDIGITS_NUMBERS = "rapidminer.general.fractiondigits.numbers"; + + /** + * The property name for "The number of fraction digits of formatted percent values." + */ + public static final String PROPERTY_RAPIDMINER_GENERAL_FRACTIONDIGITS_PERCENT = "rapidminer.general.fractiondigits.percent"; + + /** + * The name of the property indicating the maximum number of attributes stored for shortened + * meta data transformation. + */ + public static final String PROPERTY_RAPIDMINER_GENERAL_MAX_META_DATA_ATTRIBUTES = "rapidminer.general.md_attributes_limit"; + + /** + * The name of the property indicating the maximum number of nominal values to store for meta + * data transformation. + */ + public static final String PROPERTY_RAPIDMINER_GENERAL_MAX_NOMINAL_VALUES = "rapidminer.general.md_nominal_values_limit"; + + /** + * The name of the property defining how many lines are read for guessing values types for input + * operations without defined value type. + */ + public static final String PROPERTY_RAPIDMINER_GENERAL_MAX_TEST_ROWS = "rapidminer.general.max_rows_used_for_guessing"; + + /** + * The maximum depth a nested "Execute Process" chain can have. If exceeded, the process is + * aborted. See {@link Process#getDepth()} for more details. + */ + public static final String PROPERTY_RAPIDMINER_GENERAL_MAX_PROCESS_NESTING_DEPTH = "rapidminer.general.max_process_execution_nesting_depth"; + + /** + * The property name for "Path to external Java editor. %f is replaced by filename and %l + * by the linenumber." + */ + public static final String PROPERTY_RAPIDMINER_TOOLS_EDITOR = "rapidminer.tools.editor"; + + /** The property specifying the method to send mails. Either SMTP or sendmail. */ + public static final String PROPERTY_RAPIDMINER_TOOLS_MAIL_METHOD = "rapidminer.tools.mail.method"; + public static final String[] PROPERTY_RAPIDMINER_TOOLS_MAIL_METHOD_VALUES = { "sendmail", "SMTP" }; + public static final int PROPERTY_RAPIDMINER_TOOLS_MAIL_METHOD_SENDMAIL = 0; + public static final int PROPERTY_RAPIDMINER_TOOLS_MAIL_METHOD_SMTP = 1; + + /** + * Property specifying the email address to which mails are sent if no email address is + * specified in the {@link ProcessRootOperator}. + */ + public static final String PROPERTY_RAPIDMINER_TOOLS_MAIL_DEFAULT_RECIPIENT = "rapidminer.tools.mail.default_recipient"; + + /** + * The default value of the minimum time a process must run such that it sends a notification + * mail upon completion. + */ + public static final String PROPERTY_RAPIDMINER_TOOLS_MAIL_DEFAULT_PROCESS_DURATION_FOR_MAIL = "rapidminer.tools.mail.process_duration_for_mail"; + + /** The property name for "Path to sendmail. Used for email notifications." */ + public static final String PROPERTY_RAPIDMINER_TOOLS_SENDMAIL_COMMAND = "rapidminer.tools.sendmail.command"; + + /** The property name for "The smtp host. Used for email notifications." */ + public static final String PROPERTY_RAPIDMINER_TOOLS_SMTP_HOST = "rapidminer.tools.smtp.host"; + + /** The property name for "The smtp port. Used for email notifications." */ + public static final String PROPERTY_RAPIDMINER_TOOLS_SMTP_PORT = "rapidminer.tools.smtp.port"; + + /** The property name for the "SMTP user. Used for email notifications." */ + public static final String PROPERTY_RAPIDMINER_TOOLS_SMTP_USER = "rapidminer.tools.smtp.user"; + + /** + * The property name for the "SMTP pssword (is necessary). Used for email + * notifications." + */ + public static final String PROPERTY_RAPIDMINER_TOOLS_SMTP_PASSWD = "rapidminer.tools.smtp.passwd"; + + /** + * If set to true, the query builders and database assistants and query_builders show only + * standard tables (no views and system tables). + */ + public static final String PROPERTY_RAPIDMINER_TOOLS_DB_ONLY_STANDARD_TABLES = "rapidminer.tools.db.assist.show_only_standard_tables"; + + /** + * The property name for "Use unix special characters for logfile highlighting (requires + * new RapidMiner instance)." + */ + public static final String PROPERTY_RAPIDMINER_GENERAL_LOGFILE_FORMAT = "rapidminer.general.logfile.format"; + + /** + * The property name for "Indicates if RapidMiner should be used in debug mode (print + * exception stacks and shows more technical error messages)" + */ + public static final String PROPERTY_RAPIDMINER_GENERAL_DEBUGMODE = "rapidminer.general.debugmode"; + + /** The name of the property indicating the default encoding for files. */ + public static final String PROPERTY_RAPIDMINER_GENERAL_DEFAULT_ENCODING = "rapidminer.general.encoding"; + + /** The name of the property indicating the preferred globally used time zone. */ + public static final String PROPERTY_RAPIDMINER_GENERAL_TIME_ZONE = "rapidminer.general.timezone"; + + /** The maximum number of working threads that should be used by processes. */ + public static final String PROPERTY_RAPIDMINER_GENERAL_NUMBER_OF_THREADS = "rapidminer.general.number_of_threads"; + + // --- INIT PROPERTIES --- + + /** + * this property can be used to limit the maximum amount of memory RM Studio will use (in MB) + */ + public static final String PROPERTY_RAPIDMINER_MAX_MEMORY = "maxMemory"; + + public static final String PROPERTY_RAPIDMINER_HTTP_PROXY_SET = "http.proxySet"; + public static final String PROPERTY_RAPIDMINER_HTTP_PROXY_HOST = "http.proxyHost"; + public static final String PROPERTY_RAPIDMINER_HTTP_PROXY_PORT = "http.proxyPort"; + public static final String PROPERTY_RAPIDMINER_HTTP_PROXY_NON_PROXY_HOSTS = "http.nonProxyHosts"; + public static final String PROPERTY_RAPIDMINER_HTTP_PROXY_USERNAME = "http.proxyUsername"; + public static final String PROPERTY_RAPIDMINER_HTTP_PROXY_PASSWORD = "http.proxyPassword"; + + public static final String PROPERTY_RAPIDMINER_HTTPS_PROXY_SET = "https.proxySet"; + public static final String PROPERTY_RAPIDMINER_HTTPS_PROXY_HOST = "https.proxyHost"; + public static final String PROPERTY_RAPIDMINER_HTTPS_PROXY_PORT = "https.proxyPort"; + public static final String PROPERTY_RAPIDMINER_HTTPS_PROXY_USERNAME = "https.proxyUsername"; + public static final String PROPERTY_RAPIDMINER_HTTPS_PROXY_PASSWORD = "https.proxyPassword"; + + public static final String PROPERTY_RAPIDMINER_FTP_PROXY_SET = "ftp.proxySet"; + public static final String PROPERTY_RAPIDMINER_FTP_PROXY_HOST = "ftp.proxyHost"; + public static final String PROPERTY_RAPIDMINER_FTP_PROXY_PORT = "ftp.proxyPort"; + public static final String PROPERTY_RAPIDMINER_FTP_PROXY_USERNAME = "ftp.proxyUsername"; + public static final String PROPERTY_RAPIDMINER_FTP_PROXY_PASSWORD = "ftp.proxyPassword"; + public static final String PROPERTY_RAPIDMINER_FTP_PROXY_NON_PROXY_HOSTS = "ftp.nonProxyHosts"; + + public static final String PROPERTY_RAPIDMINER_SOCKS_PROXY_HOST = "socksProxyHost"; + public static final String PROPERTY_RAPIDMINER_SOCKS_PROXY_PORT = "socksProxyPort"; + + public static final String PROCESS_FILE_EXTENSION = "rmp"; + + /** + * This map of {@link IOObject}s is used to remember {@link IOObject}s during the runtime of + * RapidMiner Studio (default state to remember {@link IOObject}s of {@link Process}es) + */ + private static IOObjectMap ioObjectCache; + + static { + System.setProperty(PROPERTY_RAPIDMINER_VERSION, RapidMiner.getLongVersion()); + ParameterService.setParameterValue(PROPERTY_RAPIDMINER_VERSION, RapidMiner.getLongVersion()); + + parameterTypesDescription = new HashSet<>(); + + // set default language to english + String[] default_language = new String[1]; + default_language[0] = "eng"; + + // scan language definitons. skip comments + Vector languages = new Vector<>(); + Scanner scanLanguageDefs = new Scanner( + RapidMiner.class.getResourceAsStream("/com/rapidminer/resources/i18n/language_definitions.txt")); + try { + while (scanLanguageDefs.hasNextLine()) { + String nextLine = scanLanguageDefs.nextLine(); + if (!nextLine.contains("#")) { + languages.add(nextLine); + } + } + } finally { + scanLanguageDefs.close(); + } + + // if there is less then one language, take default language + if (languages.size() < 1) { + registerParameter(new ParameterTypeCategory(PROPERTY_RAPIDMINER_GENERAL_LOCALE_LANGUAGE, "", default_language, 0)); + + } else { + // save vector as array + int idx = 0; + String[] languageArray = new String[languages.size()]; + for (String lang : languages) { + languageArray[idx] = lang; + ++idx; + } + registerParameter(new ParameterTypeCategory(PROPERTY_RAPIDMINER_GENERAL_LOCALE_LANGUAGE, "", languageArray, 0)); + } + + registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_GENERAL_FRACTIONDIGITS_NUMBERS, "", 0, Integer.MAX_VALUE, + 3)); + registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_GENERAL_FRACTIONDIGITS_PERCENT, "", 0, Integer.MAX_VALUE, + 2)); + registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_GENERAL_MAX_NOMINAL_VALUES, "", 0, Integer.MAX_VALUE, 100)); + registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_GENERAL_MAX_TEST_ROWS, "", 0, Integer.MAX_VALUE, 100)); + registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_GENERAL_MAX_PROCESS_NESTING_DEPTH, "", 0, + Integer.MAX_VALUE, 100)); + registerParameter(new ParameterTypeBoolean(PROPERTY_RAPIDMINER_GENERAL_LOGFILE_FORMAT, "", false)); + registerParameter(new ParameterTypeBoolean(PROPERTY_RAPIDMINER_GENERAL_DEBUGMODE, "", false)); + registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_GENERAL_DEFAULT_ENCODING, "", SYSTEM_ENCODING_NAME)); + registerParameter(new ParameterTypeCategory(PROPERTY_RAPIDMINER_GENERAL_TIME_ZONE, "", Tools.getAllTimeZones(), + Tools.SYSTEM_TIME_ZONE)); + registerParameter(new ParameterTypeBoolean(CapabilityProvider.PROPERTY_RAPIDMINER_GENERAL_CAPABILITIES_WARN, "", + false)); + registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_GENERAL_NUMBER_OF_THREADS, "", 0, Integer.MAX_VALUE, 0)); + registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_TOOLS_EDITOR, "", true)); + registerParameter(new ParameterTypeCategory(PROPERTY_RAPIDMINER_TOOLS_MAIL_METHOD, "", + PROPERTY_RAPIDMINER_TOOLS_MAIL_METHOD_VALUES, PROPERTY_RAPIDMINER_TOOLS_MAIL_METHOD_SMTP)); + registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_TOOLS_MAIL_DEFAULT_RECIPIENT, "", true)); + registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_TOOLS_MAIL_DEFAULT_PROCESS_DURATION_FOR_MAIL, "", 0, + Integer.MAX_VALUE, 30)); + + registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_TOOLS_SENDMAIL_COMMAND, "", true)); + registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_TOOLS_SMTP_HOST, "", true)); + registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_TOOLS_SMTP_PORT, "", true)); + registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_TOOLS_SMTP_USER, "", true)); + registerParameter(new ParameterTypePassword(PROPERTY_RAPIDMINER_TOOLS_SMTP_PASSWD, "")); + + registerParameter(new ParameterTypeBoolean(PROPERTY_RAPIDMINER_TOOLS_DB_ONLY_STANDARD_TABLES, "", true)); + + RapidMiner.registerParameter(new ParameterTypeBoolean(PROPERTY_RAPIDMINER_INIT_PLUGINS, "", true)); + RapidMiner.registerParameter(new ParameterTypeDirectory(PROPERTY_RAPIDMINER_INIT_PLUGINS_LOCATION, "", true)); + + // System parameter types + + RapidMiner.registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_MAX_MEMORY, "", 384, Integer.MAX_VALUE, true), + "system"); + RapidMiner.registerParameter(new ParameterTypeBoolean(PROPERTY_RAPIDMINER_HTTP_PROXY_SET, "", false), "system"); + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_HTTP_PROXY_HOST, "", true), "system"); + RapidMiner + .registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_HTTP_PROXY_PORT, "", 0, 65535, true), "system"); + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_HTTP_PROXY_USERNAME, "", true), "system"); + RapidMiner.registerParameter(new ParameterTypePassword(PROPERTY_RAPIDMINER_HTTP_PROXY_PASSWORD, ""), "system"); + + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_HTTP_PROXY_NON_PROXY_HOSTS, "", true), + "system"); + + RapidMiner.registerParameter(new ParameterTypeBoolean(PROPERTY_RAPIDMINER_HTTPS_PROXY_SET, "", false), "system"); + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_HTTPS_PROXY_HOST, "", true), "system"); + RapidMiner.registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_HTTPS_PROXY_PORT, "", 0, 65535, true), + "system"); + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_HTTPS_PROXY_USERNAME, "", true), "system"); + RapidMiner.registerParameter(new ParameterTypePassword(PROPERTY_RAPIDMINER_HTTPS_PROXY_PASSWORD, ""), "system"); + RapidMiner.registerParameter(new ParameterTypeBoolean(PROPERTY_RAPIDMINER_FTP_PROXY_SET, "", false), "system"); + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_FTP_PROXY_HOST, "", true), "system"); + RapidMiner.registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_FTP_PROXY_PORT, "", 0, 65535, true), "system"); + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_FTP_PROXY_NON_PROXY_HOSTS, "", true), + "system"); + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_FTP_PROXY_USERNAME, "", true), "system"); + RapidMiner.registerParameter(new ParameterTypePassword(PROPERTY_RAPIDMINER_FTP_PROXY_PASSWORD, ""), "system"); + + RapidMiner.registerParameter(new ParameterTypeString(PROPERTY_RAPIDMINER_SOCKS_PROXY_HOST, "", true), "system"); + RapidMiner.registerParameter(new ParameterTypeInt(PROPERTY_RAPIDMINER_SOCKS_PROXY_PORT, "", 0, 65535, true), + "system"); + RapidMiner.registerParameter(new ParameterTypeInt(WebServiceTools.WEB_SERVICE_TIMEOUT, "", 1, Integer.MAX_VALUE, + 20000), "system"); + + // initialize the state of IOObjects + ioObjectCache = new IOObjectMap(); + } + + private static InputHandler inputHandler = new ConsoleInputHandler(); + + private static SplashScreen splashScreen; + + private static final List shutdownHooks = new LinkedList<>(); + + private static final List startupHooks = new LinkedList<>(); + + private static boolean isInitiated = false; + + private static final Set parameterTypesDescription; + + private static boolean performedInitialSettings = false; + + public static String getShortVersion() { + return VERSION.getShortVersion(); + } + + public static String getLongVersion() { + return VERSION.getLongVersion(); + } + + public static VersionNumber getVersion() { + return VERSION; + } + + /** + * Returns the global IOObject cache which is used by operators to remember and recall IOObjects + * in simulated app sessions + * + * @return the global IOObject cache + */ + public static IOObjectMap getGlobalIOObjectCache() { + return ioObjectCache; + } + + /** + * @deprecated Use {@link #readProcessFile(File)} instead + */ + @Deprecated + public static Process readExperimentFile(final File experimentfile) throws XMLException, IOException, + InstantiationException, IllegalAccessException { + return readProcessFile(experimentfile); + } + + public static Process readProcessFile(final File processFile) throws XMLException, IOException, InstantiationException, + IllegalAccessException { + return readProcessFile(processFile, null); + } + + public static Process readProcessFile(final File processFile, final ProgressListener progressListener) + throws XMLException, IOException, InstantiationException, IllegalAccessException { + try { + LogService.getRoot().log(Level.FINE, "com.rapidminer.RapidMiner.reading_process_file", processFile); + if (!processFile.exists() || !processFile.canRead()) { + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.RapidMiner.reading_process_definition_file_error", + processFile); + } + return new Process(processFile, progressListener); + } catch (XMLException e) { + throw new XMLException(processFile.getName() + ":" + e.getMessage(), e); + } + } + + /** + * Initializes RapidMiner with the default {@link RMProduct} and default {@link LicenseLocation} + * pointing to the RapidMiner user-folder. During initialization, the following system + * properties are evaluated. All can be specified in one of the RapidMiner configuration files, + * by using {@link System#setProperty(String, String)}, or by passing a -Dkey=value + * to the Java executable. + * + *
    + *
  • rapidminer.init.operators (file path)
  • + *
  • rapidminer.init.plugins (true or false)
  • + *
  • rapidminer.init.plugins.location (directory path)
  • + *
  • rapidminer.init.weka (true or false)
  • + *
  • rapidminer.init.jdbc.lib (true or false)
  • + *
  • rapidminer.init.jdbc.lib.location (directory path)
  • + *
  • rapidminer.init.jdbc.classpath (true or false)
  • + *
+ */ + public static void init() { + init(null, null); + } + + /** + * Same as {@link #init()} but allows to specify a {@link Product} and a {@link LicenseLocation} + * . The provided {@link Product} needs to contain all constraints defined in + * {@link RMConstraint}.
+ *
+ * If product is null the default product from {@link ProductConstraintManager} + * will be used. If {@link LicenseLocation} is null the default + * {@link LicenseLocation} from {@link ProductConstraintManager} will be used. + */ + public static void init(final Product product, final LicenseLocation licenseLocation) { + + RapidMiner.splashMessage("init_i18n"); + I18N.getErrorBundle(); + + // ensure rapidminer.home is set + RapidMiner.splashMessage("rm_home"); + PlatformUtilities.ensureRapidMinerHomeSet(Level.INFO); + + RapidMiner.splashMessage("init_parameter_service"); + // check if this version is started for the first time + performInitialSettings(); + ParameterService.init(); + + // initializing networking tools + GlobalAuthenticator.init(); + + // do initial license check + RapidMiner.splashMessage("license_check"); + + // initialize product constraint manager + try { + if (!ProductConstraintManager.INSTANCE.isInitialized()) { + ProductConstraintManager.INSTANCE.initialize(licenseLocation, product); + } + } catch (IllegalAccessException | AlreadyRegisteredException | LicenseLoadingException | InvalidProductException e) { + // should never happen + throw new RuntimeException("Product constraint manager could not be initialized!", e); + } + + // show product name, version, edition and registered to + License activeLicense = ProductConstraintManager.INSTANCE.getActiveLicense(); + RapidMiner.splashLicense(activeLicense); + + // install action statistics license event listener + ProductConstraintManager.INSTANCE.registerLicenseManagerListener(ActionStatisticsLicenseManagerListener.INSTANCE); + + // init repositories + RapidMiner.splashMessage("init_repository"); + RepositoryManager.init(); + + // parse settings xml (before plugins are initialized) + SettingsItems.INSTANCE.parseStudioXml(); + + // registering operators + RapidMiner.splashMessage("register_plugins"); + Plugin.initAll(); + Plugin.initPluginSplashTexts(RapidMiner.splashScreen); + + RapidMiner.splashMessage("init_ops"); + OperatorService.init(); + + // init custom repositories after extension initialization + RepositoryManager.initCustomRepositories(); + + UsageStatistics.getInstance(); // initializes as a side effect + + RapidMiner.splashMessage("xml_transformer"); + XMLImporter.init(); + + // generate encryption key if necessary + if (!CipherTools.isKeyAvailable()) { + RapidMiner.splashMessage("gen_key"); + try { + KeyGeneratorTool.createAndStoreKey(); + } catch (KeyGenerationException e) { + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.RapidMiner.generating_encryption_key_error", e.getMessage()), e); + } + } + + RapidMiner.splashMessage("init_configurables"); + ConfigurationManager.getInstance().initialize(); + + // initialize renderers + RapidMiner.splashMessage("init_renderers"); + RendererService.init(); + + // initialize xml serialization + RapidMiner.splashMessage("xml_serialization"); + XMLSerialization.init(Plugin.getMajorClassLoader()); + + if (executionMode == ExecutionMode.TEST) { + initAsserters(); + } + + initSettingsDescriptions(); + + started(); + } + + /** + * Sets descriptions for settings-parameters registered in static initializers. Has to be called + * after all settings-parameters have been created. + * + * The methods {@link #registerParameter(ParameterType)} and + * {@link #registerParameter(ParameterType, String)} can be used to register settings-parameters + * and remember them to add the I18n description here. + * + * The I18n description has to be set after the registration of parameters, as the I18n would + * initialize the parameter service at a point of time where the I18n description of the + * parameter has not been set. + */ + public static void initSettingsDescriptions() { + for (ParameterType parameterType : RapidMiner.parameterTypesDescription) { + parameterType.setDescription(I18N.getSettingsMessage(parameterType.getKey(), SettingsType.DESCRIPTION)); + } + } + + /** + * This method initializes RapidMiner's and all installed Plugin Asserters that will be used by + * {@link RapidAssert}. CAUTION: This function has to be called AFTER {@link #init()}. + */ + public static void initAsserters() { + if (!assertersInitialized) { + LogService.getRoot().log(Level.INFO, "Initializing Asserters..."); + Plugin.initPluginTests(); + RapidAssert.ASSERTER_REGISTRY.registerAllAsserters(new AsserterFactoryRapidMiner()); + assertersInitialized = true; + } + } + + public static SplashScreen showSplash() { + return showSplash(null); + } + + public static SplashScreen showSplash(final Image productLogo) { + RapidMiner.splashScreen = new SplashScreen(getShortVersion(), productLogo); + RapidMiner.splashScreen.showSplashScreen(); + return RapidMiner.splashScreen; + } + + public static void hideSplash() { + RapidMiner.splashScreen.dispose(); + } + + /** Displays the message with 18n key gui.splash.messageKey. */ + public static void splashMessage(final String messageKey) { + performInitialSettings(); + if (RapidMiner.splashScreen != null) { + RapidMiner.splashScreen.setMessage(I18N.getMessage(I18N.getGUIBundle(), "gui.splash." + messageKey)); + } else { + LogService.getRoot().config(I18N.getMessage(I18N.getGUIBundle(), "gui.splash." + messageKey)); + } + } + + /** Displays the edition and registered to info. */ + public static void splashLicense(final License license) { + if (RapidMiner.splashScreen != null) { + RapidMiner.splashScreen.setLicense(license); + } + } + + /** Displays the formatted message with 18n key gui.splash.messageKey. */ + public static void splashMessage(final String messageKey, final Object... args) { + performInitialSettings(); + if (RapidMiner.splashScreen != null) { + RapidMiner.splashScreen.setMessage(I18N.getMessage(I18N.getGUIBundle(), "gui.splash." + messageKey, args)); + } + } + + private static void performInitialSettings() { + if (performedInitialSettings) { + return; + } + boolean firstStart = false; + boolean versionChanged = false; + VersionNumber lastVersionNumber = null; + VersionNumber currentVersionNumber = new VersionNumber(getLongVersion()); + + File lastVersionFile = new File(FileSystemService.getUserRapidMinerDir(), "lastversion"); + if (!lastVersionFile.exists()) { + firstStart = true; + } else { + String versionString = null; + BufferedReader in = null; + try { + in = new BufferedReader(new FileReader(lastVersionFile)); + versionString = in.readLine(); + } catch (IOException e) { + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.RapidMiner.reading_global_version_file_error"), e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.RapidMiner.closing_stream_error", lastVersionFile), e); + } + } + } + + if (versionString != null) { + lastVersionNumber = new VersionNumber(versionString); + if (currentVersionNumber.compareTo(lastVersionNumber) > 0) { + firstStart = true; + } + if (currentVersionNumber.compareTo(lastVersionNumber) != 0) { + versionChanged = true; + } + } else { + firstStart = true; + } + } + + // init this version (workspace etc.) + if (firstStart) { + performFirstInitialization(lastVersionNumber, currentVersionNumber); + } + + if (firstStart || versionChanged) { + // write version file + writeLastVersion(lastVersionFile); + } + + performedInitialSettings = true; + } + + private static void writeLastVersion(final File versionFile) { + PrintWriter out = null; + try { + out = new PrintWriter(new FileWriter(versionFile)); + out.println(getLongVersion()); + } catch (IOException e) { + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.RapidMiner.writing_current_version_error"), e); + } finally { + if (out != null) { + out.close(); + } + } + } + + private static void performFirstInitialization(final VersionNumber lastVersion, final VersionNumber currentVersion) { + if (currentVersion != null) { + LogService.getRoot().log(Level.INFO, "com.rapidminer.RapidMiner.performing_upgrade", + new Object[] { lastVersion != null ? " from version " + lastVersion : "", currentVersion }); + } + + } + + public static SplashScreen getSplashScreen() { + performInitialSettings(); + return RapidMiner.splashScreen; + } + + public static Frame getSplashScreenFrame() { + performInitialSettings(); + if (RapidMiner.splashScreen != null) { + return RapidMiner.splashScreen.getSplashScreenFrame(); + } else { + return null; + } + } + + public static void setInputHandler(final InputHandler inputHandler) { + RapidMiner.inputHandler = inputHandler; + } + + public static InputHandler getInputHandler() { + return inputHandler; + } + + public synchronized static void addShutdownHook(final Runnable runnable) { + shutdownHooks.add(runnable); + } + + /** + * Adds the given {@link Runnable} to the list of hooks which will be executed after initiation + * of RapidMiner. If RapidMiner is already initiated the given {@link Runnable} will be executed + * immediately. + */ + public synchronized static void addStartupHook(final Runnable runnable) { + if (isInitiated) { + runStartupHook(runnable); + } + startupHooks.add(runnable); + } + + private synchronized static void started() { + for (Runnable runnable : startupHooks) { + runStartupHook(runnable); + } + isInitiated = true; + } + + public static boolean isInitialized() { + return isInitiated; + } + + private static void runStartupHook(final Runnable runnable) { + try { + runnable.run(); + } catch (Exception e) { + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.RapidMiner.executing_startup_hook_error", e.getMessage()), e); + } + } + + public synchronized static void quit(final ExitMode exitMode) { + for (Runnable hook : shutdownHooks) { + try { + hook.run(); + } catch (Exception e) { + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.RapidMiner.executing_shotdown_hook_error", e.getMessage()), e); + } + } + try { + Runtime.getRuntime().runFinalization(); + } catch (Exception e) { + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.RapidMiner.error_during_finalization", e.getMessage()), e); + } + isInitiated = false; + switch (exitMode) { + case NORMAL: + launchComplete(); + System.exit(0); + break; + case RELAUNCH: + launchComplete(); + relaunch(); + break; + case ERROR: + default: // error + System.exit(1); + break; + } + } + + public static void relaunch() { + LogService.getRoot().info("RapidMiner will be restarted..."); + System.exit(RELAUNCH_EXIT_CODE); + } + + private static void launchComplete() { + SafeMode safeMode = RapidMinerGUI.getSafeMode(); + if (safeMode != null) { + safeMode.launchComplete(); + } + } + + /** + * Registers parameter type at {@link ParameterService} and puts it in + * {@link RapidMiner#parameterTypesDescription}. + * + * The descriptions will be set by {@link #initSettingsDescriptions()} later. + */ + public static void registerParameter(ParameterType parameterType) { + ParameterService.registerParameter(parameterType); + RapidMiner.parameterTypesDescription.add(parameterType); + } + + /** + * Registers parameter type at {@link ParameterService} and puts it in + * {@link RapidMiner#parameterTypesDescription}. + * + * The descriptions will be set by {@link #initSettingsDescriptions()} later. + */ + public static void registerParameter(ParameterType parameterType, String group) { + ParameterService.registerParameter(parameterType, group); + RapidMiner.parameterTypesDescription.add(parameterType); + } + + public static ExecutionMode getExecutionMode() { + return executionMode; + } + + public static void setExecutionMode(final ExecutionMode executionMode) { + RapidMiner.executionMode = executionMode; + } + + /** + * Returns a set of {@link ParameterType}s for the RapidMiner system properties. + * + * @deprecated Use {@link #getRapidMinerProperties()} instead + */ + @Deprecated + public static Set getYaleProperties() { + return getRapidMinerProperties(); + } + + /** + * Use {@link ParameterService#getDefinedParameterTypes()} instead. Returns a set of + * {@link ParameterType}s for the RapidMiner system properties. + */ + @Deprecated + public static Set getRapidMinerProperties() { + return ParameterService.getDefinedParameterTypes(); + } + + /** + * @deprecated Use {@link #ParameterService.registerParameter(ParameterType)} instead + */ + @Deprecated + public static void registerYaleProperty(final ParameterType type) { + ParameterService.registerParameter(type); + } + + /** + * Please use {@link ParameterService#registerParameter(ParameterType)} instead. + * + * This registers a property with the name of the given ParameterType. For convenience the + * property is of this type, for offering the user a reasonable interface. + */ + @Deprecated + public static void registerRapidMinerProperty(final ParameterType type) { + ParameterService.registerParameter(type); + } + + /** + * This method is deprecated and remains only for compatiblity reasons. Please refer to + * {@link ParameterService#getParameterValue(String)} instead. + * + * This method will return the value of an registered RapidMiner Property or null if no property + * is known with the given identifier. + * + * @param property + * The identifier of the property + * @return the String value of the property or null if property is unknown. + */ + @Deprecated + public static String getRapidMinerPropertyValue(final String property) { + return ParameterService.getParameterValue(property); + } + + /** + * This method will set the given property to the given value. Please use + * {@link ParameterService#setParameterValue(String, String)} instead of this method. + */ + @Deprecated + public static void setRapidMinerPropertyValue(final String property, final String value) { + ParameterService.setParameterValue(property, value); + } +} diff --git a/src/main/java/com/rapidminer/RapidMinerVersion.java b/src/main/java/com/rapidminer/RapidMinerVersion.java new file mode 100644 index 000000000..eb8cc3f6d --- /dev/null +++ b/src/main/java/com/rapidminer/RapidMinerVersion.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import com.rapidminer.gui.tools.VersionNumber; +import com.rapidminer.tools.PlatformUtilities; + +/** + * Retrieves the current version of RapidMiner by calling + * {@link PlatformUtilities#getReleaseVersion()}. + * + * @author Simon Fischer, Nils Woehler + */ +public class RapidMinerVersion extends VersionNumber { + + public RapidMinerVersion() { + super(PlatformUtilities.getReleaseVersion()); + } +} diff --git a/src/main/java/com/rapidminer/RepositoryProcessLocation.java b/src/main/java/com/rapidminer/RepositoryProcessLocation.java new file mode 100644 index 000000000..669fe0efe --- /dev/null +++ b/src/main/java/com/rapidminer/RepositoryProcessLocation.java @@ -0,0 +1,196 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer; + +import java.io.IOException; +import java.util.logging.Level; + +import com.rapidminer.gui.tools.SwingTools; +import com.rapidminer.operator.UserData; +import com.rapidminer.repository.Entry; +import com.rapidminer.repository.Folder; +import com.rapidminer.repository.ProcessEntry; +import com.rapidminer.repository.RepositoryException; +import com.rapidminer.repository.RepositoryLocation; +import com.rapidminer.repository.internal.remote.RemoteContentManager; +import com.rapidminer.repository.internal.remote.RemoteProcessEntry; +import com.rapidminer.repository.internal.remote.RemoteRepository; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.PasswordInputCanceledException; +import com.rapidminer.tools.ProgressListener; +import com.rapidminer.tools.XMLException; + + +/** + * @author Simon Fischer + */ +public class RepositoryProcessLocation implements ProcessLocation { + + /** key for custom user property */ + public static final String UPDATE_REVISION_ON_SAVE_KEY = "update_revision_on_save"; + + /** A simple {@link UserData} object to pass {@link Boolean} values */ + public static class SimpleBooleanUserData implements UserData { + + private boolean value; + + public SimpleBooleanUserData(boolean value) { + this.value = value; + } + + @Override + public UserData copyUserData(Object newParent) { + return this; + } + + public boolean isSet() { + return value; + } + + } + + private final RepositoryLocation repositoryLocation; + + public RepositoryProcessLocation(RepositoryLocation location) { + super(); + this.repositoryLocation = location; + } + + private ProcessEntry getEntry() throws IOException { + Entry entry; + try { + entry = repositoryLocation.locateEntry(); + } catch (RepositoryException e) { + throw new IOException("Cannot locate entry '" + repositoryLocation + "': " + e, e); + } + if (entry == null) { + throw new IOException("No such entry: " + repositoryLocation); + } else if (!(entry instanceof ProcessEntry)) { + throw new IOException("No process entry: " + repositoryLocation); + } else { + return (ProcessEntry) entry; + } + } + + @Override + public String getRawXML() throws IOException { + try { + return getEntry().retrieveXML(); + } catch (RepositoryException e) { + throw new IOException("Cannot access entry '" + repositoryLocation + "': " + e, e); + } + } + + @Override + public Process load(ProgressListener listener) throws IOException, XMLException { + if (listener != null) { + listener.setCompleted(60); + } + final String xml = getRawXML(); + Process process = new Process(xml); + process.setProcessLocation(this); + if (listener != null) { + listener.setCompleted(80); + } + return process; + } + + @Override + public String toHistoryFileString() { + return "repository " + repositoryLocation.toString(); + } + + @Override + public void store(Process process, ProgressListener listener) throws IOException { + try { + Entry entry = repositoryLocation.locateEntry(); + if (entry == null) { + Folder folder = repositoryLocation.parent().createFoldersRecursively(); + folder.createProcessEntry(repositoryLocation.getName(), process.getRootOperator().getXML(false)); + } else { + if (entry instanceof ProcessEntry) { + boolean isReadOnly = repositoryLocation.getRepository().isReadOnly(); + if (isReadOnly) { + SwingTools.showSimpleErrorMessage("save_to_read_only_repo", "", repositoryLocation.toString()); + } else { + UserData updateRevisionOnSave = process.getRootOperator().getUserData(UPDATE_REVISION_ON_SAVE_KEY); + if (updateRevisionOnSave != null && ((SimpleBooleanUserData) updateRevisionOnSave).isSet()) { + if (entry instanceof RemoteProcessEntry) { + RemoteRepository repo = ((RemoteProcessEntry) entry).getRepository(); + if (repo != null) { + try { + RemoteContentManager entryService = repo.getContentManager(); + entryService.startNewRevision(entry.getLocation().getPath()); + entry.getContainingFolder().refresh(); + Entry newRevisionEntry = repo.locate(entry.getLocation().getPath()); + ((ProcessEntry) newRevisionEntry).storeXML(process.getRootOperator().getXML(false)); + process.getRootOperator().setUserData(UPDATE_REVISION_ON_SAVE_KEY, null); + } catch (PasswordInputCanceledException e) { + // do nothing + } + } + } + } else { + ((ProcessEntry) entry).storeXML(process.getRootOperator().getXML(false)); + } + } + } else { + throw new RepositoryException("Entry " + repositoryLocation + " is not a process entry."); + } + } + LogService.getRoot().log(Level.INFO, "com.rapidminer.RepositoryProcessLocation.saved_process_definition", + repositoryLocation); + } catch (RepositoryException e) { + throw new IOException("Cannot store process at " + repositoryLocation + ": " + e.getMessage(), e); + } + } + + public RepositoryLocation getRepositoryLocation() { + return repositoryLocation; + } + + @Override + public String toMenuString() { + return repositoryLocation.toString(); + } + + @Override + public String toString() { + return toMenuString(); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof RepositoryProcessLocation)) { + return false; + } else { + return ((RepositoryProcessLocation) o).repositoryLocation.equals(this.repositoryLocation); + } + } + + @Override + public int hashCode() { + return repositoryLocation.hashCode(); + } + + @Override + public String getShortName() { + return repositoryLocation.getName(); + } +} diff --git a/src/main/java/com/rapidminer/core/license/ActionStatisticsLicenseManagerListener.java b/src/main/java/com/rapidminer/core/license/ActionStatisticsLicenseManagerListener.java new file mode 100644 index 000000000..d8baf172d --- /dev/null +++ b/src/main/java/com/rapidminer/core/license/ActionStatisticsLicenseManagerListener.java @@ -0,0 +1,124 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.core.license; + +import java.util.List; + +import com.rapidminer.license.License; +import com.rapidminer.license.LicenseEvent; +import com.rapidminer.license.LicenseManagerListener; +import com.rapidminer.license.LicenseEvent.LicenseEventType; +import com.rapidminer.license.annotation.LicenseLevel; +import com.rapidminer.license.violation.LicenseConstraintViolation; +import com.rapidminer.license.violation.LicenseLevelViolation; +import com.rapidminer.license.violation.LicenseViolation; +import com.rapidminer.license.violation.LicenseViolation.ViolationType; +import com.rapidminer.tools.usagestats.ActionStatisticsCollector; + + +/** + * The {@link LicenseManagerListener} that listens for {@link LicenseEvent} to collection action + * statistics. + * + * @author Nils Woehler + * + */ +public enum ActionStatisticsLicenseManagerListener implements LicenseManagerListener { + + INSTANCE; + + @Override + public void handleLicenseEvent(LicenseEvent event) { + LicenseEventType type = event.getType(); + switch (type) { + case LICENSE_VIOLATED: + licenseViolated(event.getLicenseViolations()); + break; + case LICENSE_EXPIRED: + break; + case ACTIVE_LICENSE_CHANGED: + break; + case LICENSE_STORED: + break; + default: + throw new RuntimeException("Unknown license event type: " + type); + } + } + + /** + * Logs violation statistics. + */ + private void licenseViolated(List licenseViolations) { + + // Only log license constraint violations in case of multiple violations + if (licenseViolations.size() > 1) { + for (LicenseViolation violation : licenseViolations) { + if (violation.getViolationType() == ViolationType.LICENSE_CONSTRAINT_VIOLATED) { + logConstraintViolation((LicenseConstraintViolation) violation); + } + } + } else { + + // At least one violation is present, otherwise the method wouldn't be called + LicenseViolation violation = licenseViolations.get(0); + switch (violation.getViolationType()) { + case LICENSE_CONSTRAINT_VIOLATED: + logConstraintViolation((LicenseConstraintViolation) violation); + break; + case LICENSE_LEVEL_VIOLATED: + logLicenseLevelViolation((LicenseLevelViolation) violation); + break; + default: + throw new RuntimeException("Unknown violation type " + violation.getViolationType()); + + } + } + + } + + /** + * Logs a license constraint violation. + * + * @param constraintViolation + * the {@link LicenseConstraintViolation} to log + */ + private void logConstraintViolation(LicenseConstraintViolation constraintViolation) { + + License license = constraintViolation.getLicense(); + + // only count violations for licenses that are not null + if (license != null) { + ActionStatisticsCollector.getInstance() + .log(ActionStatisticsCollector.TYPE_CONSTRAINT, constraintViolation.getConstraint().getKey(), + license.getProductId() + ":" + license.getProductEdition()); + } + } + + /** + * Logs a license level violation. + * + * @param violation + * the {@link LicenseLevelViolation} to log + */ + private void logLicenseLevelViolation(LicenseLevelViolation violation) { + LicenseLevel annotation = violation.getLicenseAnnotation(); + ActionStatisticsCollector.getInstance().log(ActionStatisticsCollector.TYPE_LICENSE_LEVEL, annotation.productId(), + annotation.comparison() + ":" + String.valueOf(annotation.precedence())); + } +} diff --git a/src/main/java/com/rapidminer/core/license/DatabaseConstraintViolationException.java b/src/main/java/com/rapidminer/core/license/DatabaseConstraintViolationException.java new file mode 100644 index 000000000..f184eecf2 --- /dev/null +++ b/src/main/java/com/rapidminer/core/license/DatabaseConstraintViolationException.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.core.license; + +import com.rapidminer.license.violation.LicenseConstraintViolation; +import com.rapidminer.operator.Operator; + + +/** + * The exception that is thrown in case the database license constraint is violated. + * + * @author Nils Woehler + * + */ +public class DatabaseConstraintViolationException extends LicenseViolationException { + + private static final long serialVersionUID = 1L; + + private final String databaseURL; + + /** + * @param op + * the operator which causes the constraint violation exception + * @param violation + * the database constraint violation + */ + public DatabaseConstraintViolationException(Operator op, String databaseURL, + @SuppressWarnings("rawtypes") LicenseConstraintViolation violation) { + super(op, violation); + this.databaseURL = databaseURL; + } + + /** + * @return the database URL + */ + public String getDatabaseURL() { + return databaseURL; + } + +} diff --git a/src/main/java/com/rapidminer/core/license/LicenseViolationException.java b/src/main/java/com/rapidminer/core/license/LicenseViolationException.java new file mode 100644 index 000000000..d86b9727b --- /dev/null +++ b/src/main/java/com/rapidminer/core/license/LicenseViolationException.java @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.core.license; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import com.rapidminer.license.violation.LicenseViolation; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorException; +import com.rapidminer.tools.I18N; + + +/** + * General exception that is thrown if an operator cannot be executed because of + * {@link LicenseViolation}s. + * + * @author Nils Woehler + */ +public class LicenseViolationException extends OperatorException { + + private static final long serialVersionUID = 1L; + + private final Operator op; + + private final List violations; + + /** + * @param op + * the causing operator + * @param violation + * the corresponding {@link LicenseViolation} + */ + public LicenseViolationException(Operator op, LicenseViolation violation) { + this(op, Arrays.asList(violation)); + } + + /** + * @param op + * the causing operator + * @param cause + * Corresponding list of {@link LicenseViolation}s. + */ + public LicenseViolationException(Operator op, List violations) { + super(null); + this.op = op; + this.violations = violations; + } + + /** + * @return the operator name or null if no operator was provided + */ + public String getOperatorName() { + return op == null ? null : op.getName(); + } + + /** + * @return the list of {@link LicenseViolation}s. + */ + public List getLicenseViolations() { + return new LinkedList<>(violations); + } + + @Override + public String toString() { + return I18N.getErrorMessage("process.error.operator_license_violation", getOperatorName()); + } +} diff --git a/src/main/java/com/rapidminer/core/license/OpenSourceLicense.java b/src/main/java/com/rapidminer/core/license/OpenSourceLicense.java new file mode 100644 index 000000000..fa844558b --- /dev/null +++ b/src/main/java/com/rapidminer/core/license/OpenSourceLicense.java @@ -0,0 +1,121 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.core.license; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import com.rapidminer.license.Constraints; +import com.rapidminer.license.DefaultConstraints; +import com.rapidminer.license.License; +import com.rapidminer.license.LicenseConstants; +import com.rapidminer.license.LicenseStatus; +import com.rapidminer.license.LicenseUser; +import com.rapidminer.license.StudioLicenseConstants; + + +/** + * The license returned by the {@link OpenSourceLicenseManager}. It is a valid Basic edition with a + * default user. + * + * @author Nils Woehler + * @since 6.5.0 + * + */ +public class OpenSourceLicense implements License { + + @Override + public int compareTo(License o) { + return 0; + } + + @Override + public int getPrecedence() { + return 0; + } + + @Override + public String getProductId() { + return StudioLicenseConstants.PRODUCT_ID; + } + + @Override + public String getProductEdition() { + return LicenseConstants.STARTER_EDITION; + } + + @Override + public LicenseUser getLicenseUser() { + return new OpenSourceUser(); + } + + @Override + public Constraints getConstraints() { + return new DefaultConstraints(); + } + + @Override + public Date getStartDate() { + return null; + } + + @Override + public Date getExpirationDate() { + return null; + } + + @Override + public LicenseStatus getStatus() { + return LicenseStatus.VALID; + } + + @Override + public LicenseStatus validate(Date now) { + return LicenseStatus.VALID; + } + + @Override + public boolean isStarterLicense() { + return true; + } + + @Override + public String getLicenseID() { + return "832c6f9a-7ed3-408f-8c6b-749900952766"; + } + + @Override + public License copy() { + return new OpenSourceLicense(); + } + + @Override + public Set getVersions() { + return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(StudioLicenseConstants.VERSION))); + } + + @Override + public String getAnnotations() { + return null; + } + +} diff --git a/src/main/java/com/rapidminer/core/license/OpenSourceLicenseManager.java b/src/main/java/com/rapidminer/core/license/OpenSourceLicenseManager.java new file mode 100644 index 000000000..5d99470a1 --- /dev/null +++ b/src/main/java/com/rapidminer/core/license/OpenSourceLicenseManager.java @@ -0,0 +1,166 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.core.license; + +import java.util.Collections; +import java.util.List; + +import com.rapidminer.license.AlreadyRegisteredException; +import com.rapidminer.license.ConstraintNotRestrictedException; +import com.rapidminer.license.InvalidProductException; +import com.rapidminer.license.License; +import com.rapidminer.license.LicenseManager; +import com.rapidminer.license.LicenseManagerListener; +import com.rapidminer.license.LicenseValidationException; +import com.rapidminer.license.StudioLicenseConstants; +import com.rapidminer.license.UnknownProductException; +import com.rapidminer.license.location.LicenseLoadingException; +import com.rapidminer.license.location.LicenseLocation; +import com.rapidminer.license.location.LicenseStoringException; +import com.rapidminer.license.product.Constraint; +import com.rapidminer.license.product.Product; +import com.rapidminer.license.utils.Pair; +import com.rapidminer.license.violation.LicenseConstraintViolation; +import com.rapidminer.license.violation.LicenseViolation; + + +/** + * The {@link LicenseManager} which is installed by the {@link ProductConstraintManager} in case no + * other LicenseManager is available on {@link ProductConstraintManager} initialization. It has a + * hard-coded basic edition license with a default user and cannot store any new licenses. + * + * @author Nils Woehler + * @since 6.5.0 + * + */ +public class OpenSourceLicenseManager implements LicenseManager { + + private final License license = new OpenSourceLicense(); + + @Override + public void registerProduct(Product newProduct) + throws AlreadyRegisteredException, LicenseLoadingException, InvalidProductException { + if (!StudioLicenseConstants.PRODUCT_ID.equals(newProduct.getProductId())) { + throw new InvalidProductException("LicenseManager does not allow to register products.", + newProduct.getProductId()); + } + } + + @Override + public List checkAnnotationViolations(Object obj, boolean informListeners) { + return Collections.emptyList(); + } + + @Override + public LicenseConstraintViolation checkConstraintViolation(Product product, Constraint constraint, + C checkedValue, boolean informListeners) { + return checkConstraintViolation(product, constraint, checkedValue, null, informListeners); + } + + @Override + public LicenseConstraintViolation checkConstraintViolation(Product product, Constraint constraint, + C checkedValue, String i18nKey, boolean informListeners) { + if (StudioLicenseConstants.PRODUCT_ID.equals(product.getProductId())) { + return null; // ignore + } else { + // all other products are not allowed to be used + try { + return new LicenseConstraintViolation(null, constraint, getConstraintValue(product, constraint), null, + i18nKey); + } catch (ConstraintNotRestrictedException e) { + // cannot happen + return null; + } + } + } + + @Override + public License getActiveLicense(Product product) { + if (StudioLicenseConstants.PRODUCT_ID.equals(product.getProductId())) { + return license; + } else { + // no license available for other products + return null; + } + } + + @Override + public S getConstraintValue(Product product, Constraint constraint) + throws ConstraintNotRestrictedException { + return constraint.getDefaultValue(); + } + + @Override + public List getLicenses(Product product) { + return Collections.singletonList(license); + } + + @Override + public License getUpcomingLicense(Product product) { + return null; + } + + @Override + public boolean isAllowed(Product product, Constraint constraint, C checkedValue) { + return true; + } + + @Override + public boolean isAllowedByAnnotations(Object obj) { + return true; + } + + @Override + public Pair validateLicense(Product product, String licenseText) + throws UnknownProductException, LicenseValidationException { + if (StudioLicenseConstants.PRODUCT_ID.equals(product.getProductId())) { + return new Pair(product, license); + } else { + // do not return licenses other than for Studio + throw new UnknownProductException(product.getProductId()); + } + } + + @Override + public License storeNewLicense(String licenseText) + throws LicenseStoringException, UnknownProductException, LicenseValidationException { + throw new LicenseValidationException("Storing of licenses not supported by this LicenseManager.", null); + } + + @Override + public void registerLicenseManagerListener(LicenseManagerListener l) { + // ignore + } + + @Override + public void removeLicenseManagerListener(LicenseManagerListener l) { + // ignore + } + + @Override + public void setLicenseLocation(LicenseLocation location) { + // ignore + } + + @Override + public List getAllActiveLicenses() { + return Collections.singletonList(license); + } + +} diff --git a/src/main/java/com/rapidminer/core/license/OpenSourceUser.java b/src/main/java/com/rapidminer/core/license/OpenSourceUser.java new file mode 100644 index 000000000..9d6885996 --- /dev/null +++ b/src/main/java/com/rapidminer/core/license/OpenSourceUser.java @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.core.license; + +import java.util.Collections; +import java.util.Map; + +import com.rapidminer.license.LicenseUser; + + +/** + * The default license user which is returned by the {@link OpenSourceLicense}. + * {@link OpenSourceLicense} is only active if the {@link OpenSourceLicense} has been installed by + * the {@link ProductConstraintManager}. + * + * @author Nils Woehler + * @since 6.5.0 + * + */ +public class OpenSourceUser implements LicenseUser { + + @Override + public LicenseUser putProperty(String key, String value) { + return this; + } + + @Override + public String getProperty(String key) { + return ""; + } + + @Override + public Map getProperties() { + return Collections.emptyMap(); + } + + @Override + public String getName() { + return ""; + } + + @Override + public String getEmail() { + return ""; + } + + @Override + public LicenseUser copy() { + return new OpenSourceUser(); + } +} diff --git a/src/main/java/com/rapidminer/core/license/ProductConstraintManager.java b/src/main/java/com/rapidminer/core/license/ProductConstraintManager.java new file mode 100644 index 000000000..36798ee57 --- /dev/null +++ b/src/main/java/com/rapidminer/core/license/ProductConstraintManager.java @@ -0,0 +1,393 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.core.license; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.rapidminer.license.AlreadyRegisteredException; +import com.rapidminer.license.InvalidProductException; +import com.rapidminer.license.License; +import com.rapidminer.license.LicenseConstants; +import com.rapidminer.license.LicenseManager; +import com.rapidminer.license.LicenseManagerListener; +import com.rapidminer.license.LicenseManagerRegistry; +import com.rapidminer.license.LicenseStatus; +import com.rapidminer.license.LicenseValidationException; +import com.rapidminer.license.StudioLicenseConstants; +import com.rapidminer.license.UnknownProductException; +import com.rapidminer.license.location.FileLicenseLocation; +import com.rapidminer.license.location.LicenseLoadingException; +import com.rapidminer.license.location.LicenseLocation; +import com.rapidminer.license.location.LicenseStoringException; +import com.rapidminer.license.product.Constraint; +import com.rapidminer.license.product.DefaultProduct; +import com.rapidminer.license.product.Product; +import com.rapidminer.license.product.StringCategoryConstraint; +import com.rapidminer.license.utils.Pair; +import com.rapidminer.license.violation.LicenseViolation; +import com.rapidminer.operator.Operator; +import com.rapidminer.tools.FileSystemService; +import com.rapidminer.tools.I18N; +import com.rapidminer.tools.LogService; + + +/** + * This class handles the interaction with the {@link LicenseManager} for RapidMiner. It installs + * the {@link Product} that will be used to retrieve licenses. Furthermore it has convenience + * methods to check RapidMiner constraints. + * + * @author Nils Woehler + * + */ +public enum ProductConstraintManager { + + INSTANCE; + + /** + * folder name for licenses + */ + private static final String LICENSES_FOLDER_NAME = "licenses"; + + /** + * the signature for the RapidMiner Studio product used for verification of our default product + */ + private static final String RAPIDMINER_STUDIO_PRODUCT_SIGNATURE = "hDrRULoLLXGHbY//kyrUvuRy5pYg4Lg1rYukLP0t0OA51SVOc61DkJx+MlhxnAotg8Ss8IvrBKZ19L19g46V9SFbMe3wNmzFqgXC/cCPyiLi+FvVVFXKq0MfqY4pVOX+nBzU0kc8Y8tYoZJgK/WtGGdF1LMcSjpg1CO/o7bpFhxLAYFsX2gKJG5E+ullWxu1Gyg2EkqW80Qw4R0zJKjN+MzFtCfktp0g6X+C5sml3vsIlfeu0GPRgI+FHeezWpUci2ZZeQrtK1gfqJTF2G0x5b6cbw1EAXFgmhfkAkB5jt57odCpkmVp7pRWpJFXbC3WVJO2OMvsUoL8UBUqIYldXQ=="; + + private static final Product DEFAULT_PRODUCT = new DefaultProduct(StudioLicenseConstants.PRODUCT_ID, + StudioLicenseConstants.VERSION, false, RAPIDMINER_STUDIO_PRODUCT_SIGNATURE, + LicenseConstants.CONNECTORS_CONSTRAINT, LicenseConstants.PRODUCTIVITY_CONSTRAINT, + LicenseConstants.SERVER_EDITION_CONSTRAINT); + + private static final Path MAIN_LICENSE_PATH = Paths + .get(new File(FileSystemService.getUserRapidMinerDir(), LICENSES_FOLDER_NAME).toURI()); + + /** The product that is used to retrieve RM licenses */ + private Product registeredProduct; + + private StringCategoryConstraint connectorsConstraint; + private StringCategoryConstraint productivityConstraint; + private StringCategoryConstraint serverEditionConstraint; + + private AtomicBoolean initialized = new AtomicBoolean(false); + + /** + * + * Initialized the {@link LicenseManager} with the provided {@link LicenseLocation}. Furthermore + * the provided product is registered. The provided product must contain all constraints defined + * in {@link RMConstraints}. + */ + public synchronized void initialize(LicenseLocation licenseLocation, Product product) + throws IllegalAccessException, AlreadyRegisteredException, LicenseLoadingException, InvalidProductException { + if (initialized.get()) { + throw new UnsupportedOperationException("Cannot initialize the ProductConstraintManager twice"); + } + + // Install open-source license manager in case no available + if (LicenseManagerRegistry.INSTANCE.get() == null) { + LicenseManagerRegistry.INSTANCE.set(new OpenSourceLicenseManager()); + } + + LogService.getRoot().info("com.rapidminer.license.ConstraintManager.initializing_constraint_manager"); + + if (licenseLocation == null) { + LogService.getRoot().info("com.rapidminer.license.ConstraintManager.using_default_license_location"); + Path installationLicenseFolder = null; + try { + installationLicenseFolder = FileSystemService.getRapidMinerHome().toPath().resolve(LICENSES_FOLDER_NAME); + } catch (IOException e) { + LogService.getRoot() + .info("com.rapidminer.license.ConstraintManager.cannot_use_installation_folder_licenses"); + } + // Files.isDirectory follows symbolic links + if (installationLicenseFolder != null && Files.isDirectory(installationLicenseFolder)) { + licenseLocation = new FileLicenseLocation(MAIN_LICENSE_PATH, installationLicenseFolder); + LogService.getRoot().info("com.rapidminer.license.ConstraintManager.found_installation_folder_licenses"); + } else { + licenseLocation = new FileLicenseLocation(MAIN_LICENSE_PATH); + } + } + LicenseManagerRegistry.INSTANCE.get().setLicenseLocation(licenseLocation); + + if (product == null) { + product = DEFAULT_PRODUCT; + LogService.getRoot().info("com.rapidminer.license.ConstraintManager.using_default_product"); + } + // make sure that extensions CANNOT be used to init the RM Studio product constraints + if (product.isExtension()) { + throw new InvalidProductException("Cannot init RapidMiner Studio with extension product!", + product.getProductId()); + } + + // make sure only core product ID is used + if (!product.getProductId().matches(Product.RM_REGEX)) { + throw new InvalidProductException( + "Cannot init RapidMiner Studio. Only core product IDs (matching " + Product.RM_REGEX + ") are allowed!", + product.getProductId()); + } + + // check if all default Studio constraint are defined for the product that should be + // installed + for (Constraint rmConstr : LicenseConstants.getDefaultConstraints()) { + + // get constraint from product + String constraintId = rmConstr.getKey(); + Constraint productConstraint = product.findConstraint(constraintId); + + // check if product contains constraint + if (productConstraint == null) { + throw new RuntimeException(I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.license.ConstraintManager.no_constraint_defined", rmConstr.getKey())); + } + + // also check if constraint is of correct type + if (!productConstraint.getClass().isAssignableFrom(rmConstr.getClass())) { + throw new RuntimeException("Constraint with constraintId " + rmConstr.getKey() + + " is of wrong type. Expected class: " + rmConstr.getClass()); + } + + // remember constraints in class variables + switch (constraintId) { + case LicenseConstants.PRODUCTIVITY_CONSTRAINT_ID: + productivityConstraint = (StringCategoryConstraint) productConstraint; + break; + case LicenseConstants.CONNECTORS_CONSTRAINT_ID: + connectorsConstraint = (StringCategoryConstraint) productConstraint; + break; + case LicenseConstants.SERVER_EDITION_CONSTRAINT_ID: + serverEditionConstraint = (StringCategoryConstraint) productConstraint; + break; + default: + throw new RuntimeException("Unknown constraint " + rmConstr.getKey()); + } + } + + // register product to license manager + LicenseManagerRegistry.INSTANCE.get().registerProduct(product); + + // remember registered product + registeredProduct = product; + + // set initialized + initialized.set(true); + } + + /** + * @return true if the {@link ProductConstraintManager} has been initialized + */ + public boolean isInitialized() { + return initialized.get(); + } + + /** + * @return the currently registered {@link Product} + */ + public Product getProduct() { + return registeredProduct; + } + + /** + * @return if a trial license is contained in the list of licenses true is + * returned. + */ + public boolean wasTrialActivated() { + List licenses = LicenseManagerRegistry.INSTANCE.get().getLicenses(getProduct()); + for (License lic : licenses) { + if (lic.getProductEdition().equals(StudioLicenseConstants.TRIAL_EDITION)) { + return true; + } + } + return false; + } + + /** + * Checks if there ever was a license activated which is better than a Free edition. Examples + * are either a trial edition or any other paid edition. + * + * @return true if at least one trial or any other editions except basic was + * activated; false otherwise + */ + public boolean wasHigherThanFreeActivated() { + List licenses = LicenseManagerRegistry.INSTANCE.get().getLicenses(getProduct()); + for (License lic : licenses) { + if (!lic.getProductEdition().equals(LicenseConstants.STARTER_EDITION)) { + return true; + } + } + return false; + } + + /** + * Checks if there ever was any license activated. + * + * @return true if at least one license was activated; false otherwise + */ + public boolean wasAnyLicenseActivated() { + return LicenseManagerRegistry.INSTANCE.get().getLicenses(getProduct()).size() > 0; + } + + /** + * @return returns true if it reasonable to offer trial to the user, based on + * locally available information. This method does not ask the server whether trial is + * still available. It checks if a trial license was installed and if trial is better + * than the currently active license. + */ + public boolean shouldTrialBeOffered() { + return !wasTrialActivated() && getActiveLicense().getPrecedence() < StudioLicenseConstants.TRIAL_LICENSE_PRECEDENCE; + } + + /** + * @return returns true if the current active license is a trial license + */ + public boolean isTrialLicense() { + return StudioLicenseConstants.TRIAL_EDITION + .equals(LicenseManagerRegistry.INSTANCE.get().getActiveLicense(getProduct()).getProductEdition()); + } + + /** + * @return the current active license for the {@link Product} installed to the + * {@link ProductConstraintManager}. + */ + public License getActiveLicense() { + return LicenseManagerRegistry.INSTANCE.get().getActiveLicense(getProduct()); + } + + /** + * Checks whether the provided license text is valid for the {@link Product} installed. + * + * @param licenseText + * the text of the license which should be validated + * @return true in case the license text is valid, false otherwise + */ + public boolean isLicenseValid(String licenseText) { + Pair validateLicense = null; + try { + validateLicense = LicenseManagerRegistry.INSTANCE.get().validateLicense(null, licenseText); + } catch (LicenseValidationException | UnknownProductException e) { + return false; + } + LicenseStatus status = validateLicense.getSecond().getStatus(); + return status == LicenseStatus.VALID || status == LicenseStatus.STARTS_IN_FUTURE; + } + + /** + * Install a new license to the {@link LicenseManager}. Should only be called if + * {@link #isLicenseValid(String)} returns true. + * + * @param licenseText + * the text if the license that should be installed + * + * @return the freshly installed license. + */ + public License installNewLicense(String licenseText) + throws LicenseStoringException, UnknownProductException, LicenseValidationException { + return LicenseManagerRegistry.INSTANCE.get().storeNewLicense(licenseText); + } + + /** + * @param l + * the license manager listener + */ + public void registerLicenseManagerListener(LicenseManagerListener l) { + LicenseManagerRegistry.INSTANCE.get().registerLicenseManagerListener(l); + } + + /** + * @param l + * removes the provided license manager listener from the license manager + */ + public void removeLicenseManagerListener(LicenseManagerListener l) { + LicenseManagerRegistry.INSTANCE.get().removeLicenseManagerListener(l); + } + + /** + * @return the upcoming license for the product installed to the + * {@link ProductConstraintManager} + */ + public License getUpcomingLicense() { + return LicenseManagerRegistry.INSTANCE.get().getUpcomingLicense(getProduct()); + } + + /** + * @param enteredLicenseKey + * the key that was entered and should be validated + * @return + * @throws UnknownProductException + * if the licenses belongs to an unknown product + * @throws LicenseValidationException + * if something goes wrong during validation this exception it thrown.
+ * CAUTION: the returned license can still have an invalid license status even + * though no exception was thrown. + */ + public Pair validateLicense(String enteredLicenseKey) + throws LicenseValidationException, UnknownProductException { + return LicenseManagerRegistry.INSTANCE.get().validateLicense(null, enteredLicenseKey); + } + + /** + * See {@link LicenseManager#checkAnnotationViolations(Object, boolean)} for more details. + */ + public List checkAnnotationViolations(Operator op, boolean informListeners) { + return LicenseManagerRegistry.INSTANCE.get().checkAnnotationViolations(op, informListeners); + } + + /** + * See {@link LicenseManager#isAllowedByAnnotations(Object)} for more details. + */ + public boolean isAllowedByAnnotations(Operator op) { + return LicenseManagerRegistry.INSTANCE.get().isAllowedByAnnotations(op); + } + + /** + * Checks if community license or a higher license is installed. + * + * @return {@code true} if at least a community license is installed + */ + public boolean isCommunityFeatureAllowed() { + return !LicenseManagerRegistry.INSTANCE.get().getActiveLicense(ProductConstraintManager.INSTANCE.getProduct()) + .isStarterLicense(); + } + + /** + * @return the productivity constraint object + */ + public StringCategoryConstraint getProductivityConstraint() { + return productivityConstraint; + } + + /** + * @return the server edition constraint object + */ + public StringCategoryConstraint getServerEditionConstraint() { + return serverEditionConstraint; + } + + /** + * @return the connector constraint object + */ + public StringCategoryConstraint getConnectorsConstraint() { + return connectorsConstraint; + } + +} diff --git a/src/main/java/com/rapidminer/datatable/AbstractDataTable.java b/src/main/java/com/rapidminer/datatable/AbstractDataTable.java new file mode 100644 index 000000000..d6f3827d7 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/AbstractDataTable.java @@ -0,0 +1,267 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.io.IOException; +import java.io.PrintWriter; +import java.lang.ref.WeakReference; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import org.jfree.data.Range; + +import com.rapidminer.gui.plotter.charts.AbstractChartPanel.Selection; +import com.rapidminer.report.Tableable; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.container.Pair; + + +/** + * This abstract data table implementation provides some default implementations for data tables + * like listener handling. The method {@link #fireEvent()} can be used to promote changes to all + * listeners. + * + * In addition, IO methods are also provided by this abstract implementation. + * + * @author Ingo Mierswa + */ +public abstract class AbstractDataTable implements DataTable, Tableable { + + /** The list of data table listeners. */ + private List> weakReferencedListeners = new LinkedList<>(); + private List listeners = new LinkedList<>(); + + /** The name of the table. */ + private String name; + + private HashSet deselectionSet = new HashSet<>(); + + private int deselectionCount; + + /** + * This is a constructor that will not set any name. It is used for serialization of subclasses. + */ + public AbstractDataTable() { + this(""); + } + + public AbstractDataTable(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + @Override + public String[] getColumnNames() { + String[] result = new String[getNumberOfColumns()]; + for (int i = 0; i < result.length; i++) { + result[i] = getColumnName(i); + } + return result; + } + + @Override + public void addDataTableListener(DataTableListener dataTableListener, boolean weakReference) { + if (weakReference) { + this.weakReferencedListeners.add(new WeakReference<>(dataTableListener)); + } else { + addDataTableListener(dataTableListener); + } + } + + @Override + public void addDataTableListener(DataTableListener dataTableListener) { + listeners.add(dataTableListener); + } + + @Override + public void removeDataTableListener(DataTableListener dataTableListener) { + Iterator> it = weakReferencedListeners.iterator(); + while (it.hasNext()) { + DataTableListener l = it.next().get(); + if (l == null || l == dataTableListener) { + it.remove(); + } + } + listeners.remove(dataTableListener); + } + + protected void fireEvent() { + // copy to avoid ConcurrentModification + List> clone = new LinkedList<>(weakReferencedListeners); + Iterator> i = clone.iterator(); + while (i.hasNext()) { + WeakReference reference = i.next(); + DataTableListener listener = reference.get(); + if (listener != null) { + listener.dataTableUpdated(this); + } else { + weakReferencedListeners.remove(reference); + } + } + + for (DataTableListener l : listeners) { + l.dataTableUpdated(this); + } + } + + @Override + public String getValueAsString(DataTableRow row, int column) { + final double value = row.getValue(column); + if (Double.isNaN(value)) { + return null; + } else if (isDate(column)) { + return Tools.formatDate(new Date((long) value)); + } else if (isDateTime(column)) { + return Tools.formatDateTime(new Date((long) value)); + } else if (isTime(column)) { + return Tools.formatTime(new Date((long) value)); + } else if (isNominal(column)) { + return mapIndex(column, (int) value); + } else { + return value + ""; + } + } + + @Override + public void write(PrintWriter out) throws IOException { + out.println("# Generated by " + getName() + "[" + getClass().getName() + "]"); + for (int j = 0; j < getNumberOfColumns(); j++) { + out.print((j != 0 ? "\t" : "# ") + getColumnName(j)); + } + out.println(); + + for (DataTableRow row : this) { + for (int j = 0; j < getNumberOfColumns(); j++) { + out.print((j != 0 ? "\t" : "") + getValueAsString(row, j)); + } + out.println(); + } + + out.flush(); + } + + @Override + public boolean containsMissingValues() { + Iterator i = iterator(); + while (i.hasNext()) { + DataTableRow row = i.next(); + for (int j = 0; j < getNumberOfColumns(); j++) { + if (Double.isNaN(row.getValue(j))) { + return true; + } + } + } + return false; + } + + @Override + public int getRowNumber() { + return getNumberOfRows(); + } + + @Override + public int getColumnNumber() { + return getNumberOfColumns(); + } + + @Override + public String getCell(int row, int column) { + double value = getRow(row).getValue(column); + if (isDate(column)) { + return Tools.formatDate(new Date((long) value)); + } else if (isDateTime(column)) { + return Tools.formatDateTime(new Date((long) value)); + } else if (isTime(column)) { + return Tools.formatTime(new Date((long) value)); + } else if (isNominal(column)) { + return mapIndex(column, (int) value); + } else { + return Tools.formatIntegerIfPossible(value); + } + } + + @Override + public void prepareReporting() {} + + @Override + public void finishReporting() {} + + @Override + public boolean isFirstLineHeader() { + return false; + } + + @Override + public boolean isFirstColumnHeader() { + return false; + } + + @Override + public boolean isDeselected(String id) { + return deselectionSet.contains(id); + } + + @Override + public void setSelection(Selection selection) { + deselectionCount = 0; + Collection> delimiters = selection.getDelimiters(); + Iterator i = iterator(); + deselectionSet.clear(); + while (i.hasNext()) { + DataTableRow row = i.next(); + boolean rowSelected = true; + for (Pair delimiter : delimiters) { + int col = getColumnIndex(delimiter.getFirst()); + if (col >= 0 && col < this.getNumberOfColumns()) { + double value = row.getValue(col); + if (Double.isNaN(value)) { + continue; + } + rowSelected &= delimiter.getSecond().contains(value); + } + } + if (!rowSelected) { + String id = row.getId(); + if (id != null) { + deselectionSet.add(id); + deselectionCount++; + } + } + } + fireEvent(); + } + + @Override + public int getSelectionCount() { + return getNumberOfRows() - deselectionCount; + } +} diff --git a/src/main/java/com/rapidminer/datatable/BidirectionalMappingProvider.java b/src/main/java/com/rapidminer/datatable/BidirectionalMappingProvider.java new file mode 100644 index 000000000..9f5abddad --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/BidirectionalMappingProvider.java @@ -0,0 +1,28 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +/** + * @author Marius Helf + * + */ +public interface BidirectionalMappingProvider extends DataTableMappingProvider { + + double mapToParentValue(double value); +} diff --git a/src/main/java/com/rapidminer/datatable/CorrelationMatrixRow2DataTableRowIterator.java b/src/main/java/com/rapidminer/datatable/CorrelationMatrixRow2DataTableRowIterator.java new file mode 100644 index 000000000..9edc6b022 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/CorrelationMatrixRow2DataTableRowIterator.java @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.operator.visualization.dependencies.NumericalMatrix; + +import java.util.Iterator; + + +/** + * This iterator iterates over all examples of an example set and creates + * {@link com.rapidminer.datatable.CorrelationMatrixRow2DataTableRowWrapper} objects. + * + * @author Ingo Mierswa + */ +public class CorrelationMatrixRow2DataTableRowIterator implements Iterator { + + private NumericalMatrix matrix; + + private int currentRow; + + /** + * Creates a new DataTable iterator backed up by examples. If the idAttribute is null the + * DataTableRows will not be able to deliver an Id. + */ + public CorrelationMatrixRow2DataTableRowIterator(NumericalMatrix matrix) { + this.matrix = matrix; + this.currentRow = 0; + } + + @Override + public boolean hasNext() { + return currentRow < matrix.getNumberOfRows(); + } + + @Override + public DataTableRow next() { + DataTableRow row = new CorrelationMatrixRow2DataTableRowWrapper(matrix, currentRow); + currentRow++; + return row; + } + + @Override + public void remove() { + throw new RuntimeException("CorrelationMatrixRow2DataTableRowIterator: removing rows is not supported!"); + } +} diff --git a/src/main/java/com/rapidminer/datatable/CorrelationMatrixRow2DataTableRowWrapper.java b/src/main/java/com/rapidminer/datatable/CorrelationMatrixRow2DataTableRowWrapper.java new file mode 100644 index 000000000..ddbb15b72 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/CorrelationMatrixRow2DataTableRowWrapper.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.operator.visualization.dependencies.NumericalMatrix; + + +/** + * This class allows to use the rows of a + * {@link com.rapidminer.operator.visualization.dependencies.NumericalMatrix} as basis for + * {@link com.rapidminer.datatable.DataTableRow}. + * + * @author Ingo Mierswa + */ +public class CorrelationMatrixRow2DataTableRowWrapper implements DataTableRow { + + private NumericalMatrix matrix; + + private int rowIndex; + + /** Creates a new wrapper. If the Id Attribute is null, the DataTableRow will not contain an Id. */ + public CorrelationMatrixRow2DataTableRowWrapper(NumericalMatrix matrix, int rowIndex) { + this.matrix = matrix; + this.rowIndex = rowIndex; + } + + @Override + public String getId() { + return null; + } + + @Override + public double getValue(int index) { + if (index == 0) { + return rowIndex; + } else { + return this.matrix.getValue(rowIndex, index - 1); + } + } + + @Override + public int getNumberOfValues() { + return matrix.getNumberOfColumns() + 1; + } +} diff --git a/src/main/java/com/rapidminer/datatable/DataTable.java b/src/main/java/com/rapidminer/datatable/DataTable.java new file mode 100644 index 000000000..2d74cafef --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTable.java @@ -0,0 +1,176 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.Process; +import com.rapidminer.gui.plotter.charts.AbstractChartPanel.Selection; +import com.rapidminer.report.Tableable; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; + + +/** + * A data table that contains Object arrays that record process results, data, etc. Instances of + * this class are automatically created by {@link Process#getDataTables()} and are used mainly by + * the {@link com.rapidminer.operator.visualization.ProcessLogOperator}. On the other hand, also + * {@link com.rapidminer.example.ExampleSet}s can also be used as an data table object. + * + * @author Ingo Mierswa + */ +public interface DataTable extends Iterable, Tableable { + + /** + * Indicates if the column with the given index is nominal. For numerical or date columns, the + * value false should be returned. + */ + public boolean isNominal(int index); + + /** + * Indicates if the column with the given index is nominal. For numerical or date columns, the + * value false should be returned. + */ + public boolean isTime(int index); + + /** + * Indicates if the column with the given index is nominal. For numerical or date columns, the + * value false should be returned. + */ + public boolean isDate(int index); + + /** + * Indicates if the column with the given index is nominal. For numerical or date columns, the + * value false should be returned. + */ + public boolean isDateTime(int index); + + /** + * Indicates if the column with the given index is nominal. For numerical or date columns, the + * value false should be returned. + */ + public boolean isNumerical(int index); + + /** + * If a column is nominal, the index value must be mapped to the nominal value by this method. + * If the given column is not nominal, this method might throw a {@link NullPointerException}. + */ + public String mapIndex(int column, int index); + + /** + * If a column is nominal, the nominal value must be mapped to a (new) index by this method. If + * the given column is not nominal, this method might throw a {@link NullPointerException}. + */ + public int mapString(int column, String value); + + /** Returns the name of the i-th column. */ + @Override + public String getColumnName(int i); + + /** Returns the column index of the column with the given name. */ + public int getColumnIndex(String name); + + /** Returns the weight of the column or Double.NaN if no weight is available. */ + public double getColumnWeight(int i); + + /** Returns true if this data table is supporting column weights. */ + public boolean isSupportingColumnWeights(); + + /** Returns the total number of columns. */ + public int getNumberOfColumns(); + + /** + * Returns the total number of special columns. Please note that these columns do not need to be + * in an ordered sequence. In order to make sure that a column is a special column the method + * {@link #isSpecial(int)} should be used. + */ + public int getNumberOfSpecialColumns(); + + /** + * Returns true if this column is a special column which might usually not be used for some + * plotters, for example weights or labels. + */ + public boolean isSpecial(int column); + + /** Returns an array of all column names. */ + public String[] getColumnNames(); + + /** Returns the name of this data table. */ + public String getName(); + + /** Sets the name of the data table. */ + public void setName(String name); + + /** Adds the given {@link DataTableRow} to the table. */ + public void add(DataTableRow row); + + /** Returns an iterator over all {@link DataTableRow}s. */ + @Override + public Iterator iterator(); + + /** + * Returns the data table row with the given index. Please note that this method is not + * guaranteed to be efficiently implemented. If you want to scan the complete data table you + * should use the iterator() method instead. + */ + public DataTableRow getRow(int index); + + /** Returns the total number of rows. */ + public int getNumberOfRows(); + + /** + * Returns the number of different values for the i-th column. Might return -1 or throw an + * exception if the specific column is not nominal. + */ + public int getNumberOfValues(int column); + + /** Must deliver the proper value as string, i.e. the mapped value for nominal columns. */ + public String getValueAsString(DataTableRow row, int column); + + /** Adds a table listener listening for data changes. */ + public void addDataTableListener(DataTableListener dataTableListener); + + /** + * Adds a table listener listening for data changes. + * + * @param weakReference + * if true, the listener is stored in a weak reference, so that the listener + * mechanism does not keep garbage collection from deleting the listener. + */ + public void addDataTableListener(DataTableListener dataTableListener, boolean weakReference); + + /** Removes the given listener from the list of data change listeners. */ + public void removeDataTableListener(DataTableListener dataTableListener); + + /** Writes the table into the given writer. */ + public void write(PrintWriter out) throws IOException; + + /** Performs a sampling of this data table. Following operations should only work on the sample. */ + public DataTable sample(int newSize); + + /** Returns true if this data table contains missing values. */ + public boolean containsMissingValues(); + + // public boolean isDeselected(int index); + public boolean isDeselected(String id); + + public void setSelection(Selection selection); + + public int getSelectionCount(); +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableExampleSetAdapter.java b/src/main/java/com/rapidminer/datatable/DataTableExampleSetAdapter.java new file mode 100644 index 000000000..fcf3bc1f3 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableExampleSetAdapter.java @@ -0,0 +1,332 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.rapidminer.ObjectVisualizer; +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.AttributeTypeException; +import com.rapidminer.example.AttributeWeights; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Tools; +import com.rapidminer.example.set.SplittedExampleSet; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.DoubleArrayDataRow; +import com.rapidminer.example.table.MemoryExampleTable; +import com.rapidminer.gui.RapidMinerGUI; +import com.rapidminer.operator.UserError; +import com.rapidminer.tools.ObjectVisualizerService; +import com.rapidminer.tools.Ontology; +import com.rapidminer.tools.ParameterService; + + +/** + * This class can be used to use an example set as data table. The data is directly read from the + * example set instead of building a copy. Please note that the method for adding new rows is not + * supported by this type of data tables. + * + * @author Ingo Mierswa + */ +public class DataTableExampleSetAdapter extends AbstractDataTable { + + private static final int DEFAULT_MAX_SIZE_FOR_SHUFFLED_SAMPLING = 100000; + + private ExampleSet exampleSet; + + private List allAttributes = new ArrayList(); + + private int numberOfRegularAttributes = 0; + + private AttributeWeights weights = null; + + private Attribute idAttribute; + + public DataTableExampleSetAdapter(ExampleSet exampleSet, AttributeWeights weights) { + this(exampleSet, weights, true); + } + + /** + * @param ignoreId + * If this variable is true, the id will not be visible in the data table. + */ + public DataTableExampleSetAdapter(ExampleSet exampleSet, AttributeWeights weights, boolean ignoreId) { + super("Data Table"); + this.exampleSet = exampleSet; + this.weights = weights; + + for (Attribute attribute : exampleSet.getAttributes()) { + allAttributes.add(attribute); + } + + this.idAttribute = exampleSet.getAttributes().getId(); + Iterator s = exampleSet.getAttributes().specialAttributes(); + while (s.hasNext()) { + Attribute specialAttribute = s.next().getAttribute(); + if (!ignoreId || idAttribute == null || !idAttribute.getName().equals(specialAttribute.getName())) { + allAttributes.add(specialAttribute); + } + } + + this.numberOfRegularAttributes = exampleSet.getAttributes().size(); + + // TODO: Find another solution for this hack + registerVisualizerForMe(exampleSet); + } + + public DataTableExampleSetAdapter(DataTableExampleSetAdapter dataTableExampleSetAdapter) { + super(dataTableExampleSetAdapter.getName()); + this.exampleSet = dataTableExampleSetAdapter.exampleSet; // shallow clone + this.allAttributes = dataTableExampleSetAdapter.allAttributes; // shallow clone + this.numberOfRegularAttributes = dataTableExampleSetAdapter.numberOfRegularAttributes; + this.weights = dataTableExampleSetAdapter.weights; // shallow clone + this.idAttribute = dataTableExampleSetAdapter.idAttribute; // shallow clone + + // TODO: Find another solution for this hack + registerVisualizerForMe(dataTableExampleSetAdapter); + } + + @Override + public int getNumberOfSpecialColumns() { + return allAttributes.size() - numberOfRegularAttributes; + } + + @Override + public boolean isSpecial(int index) { + return index >= numberOfRegularAttributes; + } + + @Override + public boolean isNominal(int index) { + return Ontology.ATTRIBUTE_VALUE_TYPE.isA(allAttributes.get(index).getValueType(), Ontology.NOMINAL); + } + + @Override + public boolean isDate(int index) { + return Ontology.ATTRIBUTE_VALUE_TYPE.isA(allAttributes.get(index).getValueType(), Ontology.DATE); + } + + @Override + public boolean isTime(int index) { + return Ontology.ATTRIBUTE_VALUE_TYPE.isA(allAttributes.get(index).getValueType(), Ontology.TIME); + } + + @Override + public boolean isDateTime(int index) { + return Ontology.ATTRIBUTE_VALUE_TYPE.isA(allAttributes.get(index).getValueType(), Ontology.DATE_TIME); + } + + @Override + public boolean isNumerical(int index) { + return Ontology.ATTRIBUTE_VALUE_TYPE.isA(allAttributes.get(index).getValueType(), Ontology.NUMERICAL); + } + + public String getLabelName() { + if (this.exampleSet.getAttributes().getLabel() != null) { + return this.exampleSet.getAttributes().getLabel().getName(); + } else { + return null; + } + } + + public String getClusterName() { + if (this.exampleSet.getAttributes().getCluster() != null) { + return this.exampleSet.getAttributes().getCluster().getName(); + } else { + return null; + } + } + + public boolean isLabelNominal() { + if (this.exampleSet.getAttributes().getLabel() != null) { + return this.exampleSet.getAttributes().getLabel().getValueType() == Ontology.NOMINAL; + } else { + return false; // if there is no label, it should not be nominal + } + } + + public boolean hasId() { + if (exampleSet.getAttributes().getId() == null) { + return false; + } else { + return true; + } + } + + @Override + public String mapIndex(int column, int value) { + try { + return allAttributes.get(column).getMapping().mapIndex(value); + } catch (AttributeTypeException e) { + // Can throw AttributeTypeException in case mapping is empty + return "?"; + } + } + + @Override + public int mapString(int column, String value) { + return allAttributes.get(column).getMapping().mapString(value); + } + + @Override + public int getNumberOfValues(int column) { + return allAttributes.get(column).getMapping().size(); + } + + @Override + public String getColumnName(int i) { + return allAttributes.get(i).getName(); + } + + @Override + public int getColumnIndex(String name) { + for (int i = 0; i < allAttributes.size(); i++) { + if (allAttributes.get(i).getName().equals(name)) { + return i; + } + } + return -1; + } + + @Override + public boolean isSupportingColumnWeights() { + return weights != null; + } + + @Override + public double getColumnWeight(int column) { + if (weights == null) { + return Double.NaN; + } else { + return weights.getWeight(getColumnName(column)); + } + } + + @Override + public int getNumberOfColumns() { + return this.allAttributes.size(); + } + + @Override + public void add(DataTableRow row) { + throw new RuntimeException("DataTableExampleSetAdapter: adding new rows is not supported!"); + } + + @Override + public DataTableRow getRow(int index) { + return new Example2DataTableRowWrapper(exampleSet.getExample(index), allAttributes, idAttribute); + } + + @Override + public Iterator iterator() { + return new Example2DataTableRowIterator(exampleSet.iterator(), allAttributes, idAttribute); + } + + @Override + public int getNumberOfRows() { + return this.exampleSet.size(); + } + + @Override + public DataTable sample(int newSize) { + DataTableExampleSetAdapter result = new DataTableExampleSetAdapter(this); + + double ratio = (double) newSize / (double) getNumberOfRows(); + + int maxNumberBeforeSampling = DEFAULT_MAX_SIZE_FOR_SHUFFLED_SAMPLING; + String maxString = ParameterService.getParameterValue(RapidMinerGUI.PROPERTY_RAPIDMINER_GUI_MAX_STATISTICS_ROWS); + if (maxString != null) { + try { + maxNumberBeforeSampling = Integer.parseInt(maxString); + } catch (NumberFormatException e) { + // do nothing + } + } + + ExampleSet exampleSet = null; + if (getNumberOfRows() < maxNumberBeforeSampling) { + try { + exampleSet = new SplittedExampleSet(this.exampleSet, ratio, SplittedExampleSet.SHUFFLED_SAMPLING, false, 0); + } catch (UserError e) { + // this exception is only thrown for Stratified Sampling + } + if (exampleSet == null) { + return null; // cannot happen + } + ((SplittedExampleSet) exampleSet).selectSingleSubset(0); + } else { + exampleSet = Tools.getLinearSubsetCopy(this.exampleSet, newSize, 0); + } + + result.exampleSet = exampleSet; + return result; + } + + public static ExampleSet createExampleSetFromDataTable(DataTable table) { + List attributes = new ArrayList(); + + for (int i = 0; i < table.getNumberOfColumns(); i++) { + if (table.isDate(i)) { + Attribute attribute = AttributeFactory.createAttribute(table.getColumnName(i), Ontology.DATE); + attributes.add(attribute); + } else if (table.isTime(i)) { + Attribute attribute = AttributeFactory.createAttribute(table.getColumnName(i), Ontology.TIME); + attributes.add(attribute); + } else if (table.isDateTime(i)) { + Attribute attribute = AttributeFactory.createAttribute(table.getColumnName(i), Ontology.DATE_TIME); + attributes.add(attribute); + } else if (table.isNominal(i)) { + Attribute attribute = AttributeFactory.createAttribute(table.getColumnName(i), Ontology.NOMINAL); + attributes.add(attribute); + } else { + Attribute attribute = AttributeFactory.createAttribute(table.getColumnName(i), Ontology.REAL); + attributes.add(attribute); + } + } + + MemoryExampleTable exampleTable = new MemoryExampleTable(attributes); + + for (int i = 0; i < table.getNumberOfRows(); i++) { + DataTableRow row = table.getRow(i); + double[] values = new double[attributes.size()]; + for (int a = 0; a < values.length; a++) { + Attribute attribute = attributes.get(a); + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(attribute.getValueType(), Ontology.DATE_TIME)) { + values[a] = row.getValue(a); + } else if (attribute.isNominal()) { + values[a] = attribute.getMapping().mapString(table.getValueAsString(row, a)); + } else { + values[a] = row.getValue(a); + } + } + exampleTable.addDataRow(new DoubleArrayDataRow(values)); + } + + return exampleTable.createExampleSet(); + } + + private void registerVisualizerForMe(Object father) { + ObjectVisualizer visualizer = ObjectVisualizerService.getVisualizerForObject(father); + ObjectVisualizerService.addObjectVisualizer(this, visualizer); + } + +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableFilterCondition.java b/src/main/java/com/rapidminer/datatable/DataTableFilterCondition.java new file mode 100644 index 000000000..9ea2e3e08 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableFilterCondition.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +/** + * This is the interface of conditions for FilteredDataTables. They might be stacked in order to + * decide which examples should be kept. + * + * @author Sebastian Land + * + */ +public interface DataTableFilterCondition { + + /** + * This method decides if the given data row is kept or filtered out. If return true, the row + * will be in the resulting filtered data set. If returns false, the row will be removed in the + * resulting set. + */ + public boolean keepRow(DataTableRow row); + +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableKernelModelAdapter.java b/src/main/java/com/rapidminer/datatable/DataTableKernelModelAdapter.java new file mode 100644 index 000000000..5703a4d9b --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableKernelModelAdapter.java @@ -0,0 +1,296 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import com.rapidminer.example.Attribute; +import com.rapidminer.operator.learner.functions.kernel.KernelModel; + + +/** + * This class can be used to use a kernel model as data table. The data is directly read from the + * kernel model instead of building a copy. Please note that the method for adding new rows is not + * supported by this type of data tables. + * + * @author Ingo Mierswa + */ +public class DataTableKernelModelAdapter extends AbstractDataTable { + + /** Helper class to iterated over the examples or support vectors of a {@link KernelModel}. */ + private static class KernelModelIterator implements Iterator { + + private int counter = 0; + + private DataTableKernelModelAdapter adapter; + + public KernelModelIterator(DataTableKernelModelAdapter adapter) { + this.adapter = adapter; + } + + @Override + public boolean hasNext() { + return counter < adapter.getNumberOfRows(); + } + + @Override + public DataTableRow next() { + DataTableRow row = adapter.getRow(counter); + counter++; + return row; + } + + @Override + public void remove() { + throw new RuntimeException("DataTable.KernelModelIterator: remove not supported!"); + } + } + + private KernelModel kernelModel; + + private String[] attributeNames; + + private static final String DEFAULT_REGULAR_ATTRIBUTE_PREFIX = "attribute"; + + private int[] sampleMapping = null; + + private Map index2LabelMap = new HashMap<>(); + private Map label2IndexMap = new HashMap<>(); + + public DataTableKernelModelAdapter(KernelModel kernelModel) { + super("Kernel Model Support Vectors"); + this.kernelModel = kernelModel; + int labelCounter = 0; + if (this.kernelModel.isClassificationModel()) { + for (int i = 0; i < this.kernelModel.getNumberOfSupportVectors(); i++) { + String label = this.kernelModel.getClassificationLabel(i); + if (label2IndexMap.get(label) == null) { + this.label2IndexMap.put(label, labelCounter); + this.index2LabelMap.put(labelCounter, label); + labelCounter++; + } + } + } + + // storing attribute names + attributeNames = new String[kernelModel.getTrainingHeader().getAttributes().size()]; + int i = 0; + for (Attribute attribute : kernelModel.getTrainingHeader().getAttributes()) { + attributeNames[i] = attribute.getName(); + i++; + } + } + + public DataTableKernelModelAdapter(DataTableKernelModelAdapter dataTableKernelModelAdapter) { + super(dataTableKernelModelAdapter.getName()); + this.kernelModel = dataTableKernelModelAdapter.kernelModel; // shallow clone + this.index2LabelMap = dataTableKernelModelAdapter.index2LabelMap; // shallow clone + this.label2IndexMap = dataTableKernelModelAdapter.label2IndexMap; // shallow clone + + this.sampleMapping = null; + } + + @Override + public int getNumberOfSpecialColumns() { + return KernelModelRow2DataTableRowWrapper.NUMBER_OF_SPECIAL_COLUMNS; + } + + @Override + public boolean isSpecial(int index) { + return index < KernelModelRow2DataTableRowWrapper.NUMBER_OF_SPECIAL_COLUMNS; + } + + @Override + public boolean isNominal(int index) { + if (index == KernelModelRow2DataTableRowWrapper.LABEL) { + return this.kernelModel.isClassificationModel(); + } else { + return index == KernelModelRow2DataTableRowWrapper.SUPPORT_VECTOR; + } + } + + @Override + public boolean isDate(int index) { + return false; + } + + @Override + public boolean isTime(int index) { + return false; + } + + @Override + public boolean isDateTime(int index) { + return false; + } + + @Override + public boolean isNumerical(int index) { + return !isNominal(index); + } + + @Override + public String mapIndex(int column, int value) { + if (column == KernelModelRow2DataTableRowWrapper.LABEL && this.kernelModel.isClassificationModel()) { + return index2LabelMap.get(value); + } else if (column == KernelModelRow2DataTableRowWrapper.SUPPORT_VECTOR) { + if (value == 0) { + return "no support vector"; + } else { + return "support vector"; + } + } else { + return null; + } + } + + @Override + public int mapString(int column, String value) { + if (column == KernelModelRow2DataTableRowWrapper.LABEL && this.kernelModel.isClassificationModel()) { + return label2IndexMap.get(value); + } else if (column == KernelModelRow2DataTableRowWrapper.SUPPORT_VECTOR) { + if ("no support vector".equals(value)) { + return 0; + } else { + return 1; + } + } else { + return -1; + } + } + + @Override + public int getNumberOfValues(int column) { + if (column == KernelModelRow2DataTableRowWrapper.LABEL && this.kernelModel.isClassificationModel()) { + return index2LabelMap.size(); + } else if (column == KernelModelRow2DataTableRowWrapper.SUPPORT_VECTOR) { + return 2; + } else { + return -1; + } + } + + @Override + public String getColumnName(int i) { + if (i < KernelModelRow2DataTableRowWrapper.NUMBER_OF_SPECIAL_COLUMNS) { + return KernelModelRow2DataTableRowWrapper.SPECIAL_COLUMN_NAMES[i]; + } else { + int attributeIndex = i - KernelModelRow2DataTableRowWrapper.NUMBER_OF_SPECIAL_COLUMNS; + if (attributeIndex >= 0 && attributeIndex <= attributeNames.length) { + return attributeNames[attributeIndex]; + } + return DEFAULT_REGULAR_ATTRIBUTE_PREFIX + (attributeIndex + 1); + } + } + + @Override + public int getColumnIndex(String name) { + for (int i = 0; i < KernelModelRow2DataTableRowWrapper.NUMBER_OF_SPECIAL_COLUMNS; i++) { + if (KernelModelRow2DataTableRowWrapper.SPECIAL_COLUMN_NAMES[i].equals(name)) { + return i; + } + } + for (int i = 0; i < attributeNames.length; i++) { + if (attributeNames[i].equals(name)) { + return i; + } + } + if (name.startsWith(DEFAULT_REGULAR_ATTRIBUTE_PREFIX)) { + return Integer.parseInt(name.substring(DEFAULT_REGULAR_ATTRIBUTE_PREFIX.length())) + + KernelModelRow2DataTableRowWrapper.NUMBER_OF_SPECIAL_COLUMNS - 1; + } + return -1; + } + + @Override + public boolean isSupportingColumnWeights() { + return false; + } + + @Override + public double getColumnWeight(int column) { + return Double.NaN; + } + + @Override + public int getNumberOfColumns() { + return kernelModel.getNumberOfAttributes() + KernelModelRow2DataTableRowWrapper.NUMBER_OF_SPECIAL_COLUMNS; + } + + @Override + public int getNumberOfRows() { + if (this.sampleMapping == null) { + return this.kernelModel.getNumberOfSupportVectors(); + } else { + return this.sampleMapping.length; + } + } + + @Override + public void add(DataTableRow row) { + throw new RuntimeException("DataTableKernelModelAdapter: adding new rows is not supported!"); + } + + @Override + public DataTableRow getRow(int index) { + if (this.sampleMapping == null) { + return new KernelModelRow2DataTableRowWrapper(this.kernelModel, this, index); + } else { + return new KernelModelRow2DataTableRowWrapper(this.kernelModel, this, this.sampleMapping[index]); + } + } + + @Override + public Iterator iterator() { + return new KernelModelIterator(this); + } + + @Override + public DataTable sample(int newSize) { + DataTableKernelModelAdapter result = new DataTableKernelModelAdapter(this); + + double ratio = (double) newSize / (double) getNumberOfRows(); + Random random = new Random(2001); + List usedRows = new LinkedList<>(); + for (int i = 0; i < getNumberOfRows(); i++) { + if (random.nextDouble() <= ratio) { + int index = i; + if (this.sampleMapping != null) { + index = this.sampleMapping[index]; + } + usedRows.add(index); + } + } + int[] sampleMapping = new int[usedRows.size()]; + int counter = 0; + Iterator i = usedRows.iterator(); + while (i.hasNext()) { + sampleMapping[counter++] = i.next(); + } + + result.sampleMapping = sampleMapping; + return result; + } + +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableListener.java b/src/main/java/com/rapidminer/datatable/DataTableListener.java new file mode 100644 index 000000000..db6f98774 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableListener.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +/** + * Listens to updates of a DataTable object. + * + * @author Simon Fischer, Ingo Mierswa + */ +public interface DataTableListener { + + public void dataTableUpdated(DataTable source); + +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableMappingProvider.java b/src/main/java/com/rapidminer/datatable/DataTableMappingProvider.java new file mode 100644 index 000000000..5a970984d --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableMappingProvider.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +/** + * Provides a value mapping for {@link DataTable}s. See {@link ValueMappingDataTableView}. + * + * @author Marius Helf + * + */ +public interface DataTableMappingProvider { + + /** + * Returns the mapped value for the originalValue. + */ + public double mapFromParentValue(double parentValue); +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableNaturalSortProvider.java b/src/main/java/com/rapidminer/datatable/DataTableNaturalSortProvider.java new file mode 100644 index 000000000..248a02eed --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableNaturalSortProvider.java @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.gui.new_plotter.utility.DataStructureUtils; +import com.rapidminer.tools.container.Pair; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + + +/** + * A sort provider which sorts the rows based on the values of one column. Nominal values are sorted + * by the string values, all other column types use the double values for sorting. + * + * @author Marius Helf + * + */ +public class DataTableNaturalSortProvider implements DataTableSortProvider { + + boolean ascending; + int columnIdx; + + public DataTableNaturalSortProvider(int columnIdx, boolean ascending) { + super(); + this.ascending = ascending; + this.columnIdx = columnIdx; + } + + @Override + public int[] getIndexMapping(DataTable dataTable) { + if (columnIdx >= 0 && columnIdx < dataTable.getColumnNumber()) { + + // get list of all values, either nominal or numeric + List> allValues = new LinkedList>(); + if (dataTable.isNominal(columnIdx)) { + double rowIdx = 0; + for (DataTableRow row : dataTable) { + allValues.add(new Pair(rowIdx, row.getValue(columnIdx))); + rowIdx += 1; + } + } else { + double rowIdx = 0; + for (DataTableRow row : dataTable) { + allValues.add(new Pair(rowIdx, row.getValue(columnIdx))); + rowIdx += 1; + } + } + + // sort list + Collections.sort(allValues, new DataStructureUtils.PairComparator(ascending)); + + // create mapping from idx and values + int[] indexMapping = new int[allValues.size()]; + int idx = 0; + for (Pair entry : allValues) { + indexMapping[idx] = entry.getFirst().intValue(); + ++idx; + } + return indexMapping; + } else { + int rowCount = dataTable.getRowNumber(); + int[] indexMapping = new int[rowCount]; + for (int i = 0; i < rowCount; ++i) { + indexMapping[i] = i; + } + return indexMapping; + } + } + + @Override + public DataTableNaturalSortProvider clone() { + DataTableNaturalSortProvider clone = new DataTableNaturalSortProvider(columnIdx, ascending); + return clone; + } +} diff --git a/src/main/java/com/rapidminer/datatable/DataTablePairwiseMatrixExtractionAdapter.java b/src/main/java/com/rapidminer/datatable/DataTablePairwiseMatrixExtractionAdapter.java new file mode 100644 index 000000000..3e9175021 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTablePairwiseMatrixExtractionAdapter.java @@ -0,0 +1,241 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.operator.visualization.dependencies.NumericalMatrix; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * This class can be used to use all pairs (entries) of a numerical matrix as data table. The data + * is directly read from the numerical matrix instead of building a copy. If the matrix is + * symmetrical, only pairs of the lower left triangle are returned. Please note that the method for + * adding new rows is not supported by this type of data tables. + * + * @author Ingo Mierswa, Sebastian Land + */ +public class DataTablePairwiseMatrixExtractionAdapter extends AbstractDataTable { + + private NumericalMatrix matrix; + + private String[] rowNames; + + private Map rowName2IndexMap = new HashMap(); + + private String[] columnNames; + + private Map columnName2IndexMap = new HashMap(); + + private String[] tableColumnNames; + + private boolean showSymetrical; + + public DataTablePairwiseMatrixExtractionAdapter(NumericalMatrix matrix, String[] rowNames, String[] columnNames, + String[] tableColumnNames, boolean showSymetrical) { + super("Pairwise Correlation Table"); + this.showSymetrical = showSymetrical; + this.matrix = matrix; + + this.rowNames = rowNames; + for (int i = 0; i < this.rowNames.length; i++) { + this.rowName2IndexMap.put(this.rowNames[i], i); + } + + this.columnNames = columnNames; + for (int i = 0; i < this.columnNames.length; i++) { + this.columnName2IndexMap.put(this.columnNames[i], i); + } + + this.tableColumnNames = tableColumnNames; + if ((this.tableColumnNames == null) || (this.tableColumnNames.length != 3)) { + throw new RuntimeException( + "Cannot create pairwise matrix extraction data table with other than 3 table column names."); + } + } + + /** + * Creates all pairs of one triangle of the given symetrical matrix. + */ + public DataTablePairwiseMatrixExtractionAdapter(NumericalMatrix matrix, String[] rowNames, String[] columnNames, + String[] tableColumnNames) { + this(matrix, rowNames, columnNames, tableColumnNames, true); + } + + @Override + public int getNumberOfSpecialColumns() { + return 0; + } + + @Override + public boolean isSpecial(int index) { + return false; + } + + @Override + public boolean isNominal(int index) { + return (index <= 1); + } + + @Override + public boolean isDate(int index) { + return false; + } + + @Override + public boolean isTime(int index) { + return false; + } + + @Override + public boolean isDateTime(int index) { + return false; + } + + @Override + public boolean isNumerical(int index) { + return (index > 1); + } + + @Override + public String mapIndex(int column, int value) { + if (column == 0) { + return rowNames[value]; + } else if (column == 1) { + return columnNames[value]; + } else { + return "?"; + } + } + + /** + * Please note that this method does not map new strings but is only able to deliver strings + * which where already known during construction. + */ + @Override + public int mapString(int column, String value) { + if (column == 0) { + Integer result = this.rowName2IndexMap.get(value); + if (result == null) { + return -1; + } else { + return result; + } + } else if (column == 1) { + Integer result = this.columnName2IndexMap.get(value); + if (result == null) { + return -1; + } else { + return result; + } + } else { + return -1; + } + } + + @Override + public int getNumberOfValues(int column) { + if (column == 0) { + return rowNames.length; + } else if (column == 1) { + return columnNames.length; + } else { + return -1; + } + } + + @Override + public String getColumnName(int i) { + return tableColumnNames[i]; + } + + @Override + public int getColumnIndex(String name) { + for (int i = 0; i < tableColumnNames.length; i++) { + if (tableColumnNames[i].equals(name)) { + return i; + } + } + return -1; + } + + @Override + public boolean isSupportingColumnWeights() { + return false; + } + + @Override + public double getColumnWeight(int column) { + return Double.NaN; + } + + @Override + public int getNumberOfColumns() { + return tableColumnNames.length; + } + + @Override + public void add(DataTableRow row) { + throw new RuntimeException("DataTablePairwiseCorrelationMatrixAdapter: adding new rows is not supported!"); + } + + @Override + public DataTableRow getRow(int rowIndex) { + if (matrix.isSymmetrical() && showSymetrical) { + int firstAttribute = 0; + int secondAttribute = 1; + for (int i = 0; i < rowIndex; i++) { + secondAttribute++; + if (secondAttribute >= matrix.getNumberOfColumns()) { + firstAttribute++; + secondAttribute = firstAttribute + 1; + } + } + return new PairwiseMatrix2DataTableRowWrapper(this.matrix, firstAttribute, secondAttribute); + } else { + return new PairwiseMatrix2DataTableRowWrapper(this.matrix, rowIndex / matrix.getNumberOfColumns(), rowIndex + % matrix.getNumberOfColumns()); + } + } + + @Override + public Iterator iterator() { + return new PairwiseMatrix2DataTableRowIterator(this.matrix, showSymetrical); + } + + @Override + public int getNumberOfRows() { + if (matrix.isSymmetrical() && showSymetrical) { + return ((rowNames.length * rowNames.length) - rowNames.length) / 2; + } else { + return (matrix.getNumberOfRows() * matrix.getNumberOfColumns()); + } + } + + /** + * Not implemented!!! Please use this class only for plotting purposes if you can ensure that + * the number of columns / rows is small. + */ + @Override + public DataTable sample(int newSize) { + return this; + } +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableRow.java b/src/main/java/com/rapidminer/datatable/DataTableRow.java new file mode 100644 index 000000000..13ce00d7d --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableRow.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +/** + * A data list that contains Object arrays that record process results or other data. Each row can + * consist of an id and an object array which represents the data. + * + * @author Ingo Mierswa + */ +public interface DataTableRow { + + /** Returns the Id of this table row. */ + public String getId(); + + /** Returns the i-th value. */ + public double getValue(int index); + + /** Returns the total number of values. */ + public int getNumberOfValues(); +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableSortProvider.java b/src/main/java/com/rapidminer/datatable/DataTableSortProvider.java new file mode 100644 index 000000000..1484461ac --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableSortProvider.java @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +/** + * + * @author Marius Helf + * + */ +public interface DataTableSortProvider extends Cloneable { + + public int[] getIndexMapping(DataTable dataTable); + + public DataTableSortProvider clone(); +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableSymmetricalMatrixAdapter.java b/src/main/java/com/rapidminer/datatable/DataTableSymmetricalMatrixAdapter.java new file mode 100644 index 000000000..a8c1f9c5b --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableSymmetricalMatrixAdapter.java @@ -0,0 +1,176 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.operator.visualization.dependencies.NumericalMatrix; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * This class can be used to use a symmetrical matrix as data table. The data is directly read from + * the symmetrical matrix (e.g. a correlation matrix) instead of building a copy. Please note that + * the method for adding new rows is not supported by this type of data tables. + * + * @author Ingo Mierswa + */ +public class DataTableSymmetricalMatrixAdapter extends AbstractDataTable { + + private NumericalMatrix matrix; + + private String[] index2NameMap; + + private Map name2IndexMap = new HashMap(); + + public DataTableSymmetricalMatrixAdapter(NumericalMatrix matrix, String name, String[] columnNames) { + super(name); + this.matrix = matrix; + this.index2NameMap = columnNames; + for (int i = 0; i < this.index2NameMap.length; i++) { + this.name2IndexMap.put(this.index2NameMap[i], i); + } + } + + @Override + public int getNumberOfSpecialColumns() { + return 0; + } + + @Override + public boolean isSpecial(int index) { + return false; + } + + @Override + public boolean isNominal(int index) { + return index == 0; + } + + @Override + public boolean isDate(int index) { + return false; + } + + @Override + public boolean isTime(int index) { + return false; + } + + @Override + public boolean isDateTime(int index) { + return false; + } + + @Override + public boolean isNumerical(int index) { + return index != 0; + } + + @Override + public String mapIndex(int column, int value) { + return this.index2NameMap[value]; + } + + /** + * Please note that this method does not map new strings but is only able to deliver strings + * which where already known during construction. + */ + @Override + public int mapString(int column, String value) { + Integer result = this.name2IndexMap.get(value); + if (result == null) { + return -1; + } else { + return result; + } + } + + @Override + public int getNumberOfValues(int column) { + if (column == 0) { + return this.index2NameMap.length; + } else { + return -1; + } + } + + @Override + public String getColumnName(int i) { + if (i == 0) { + return "Attributes"; + } else { + return this.index2NameMap[i - 1]; + } + } + + @Override + public int getColumnIndex(String name) { + if (name.equals("Attributes")) { + return 0; + } else { + return mapString(0, name) + 1; + } + } + + @Override + public boolean isSupportingColumnWeights() { + return false; + } + + @Override + public double getColumnWeight(int column) { + return Double.NaN; + } + + @Override + public int getNumberOfColumns() { + return this.index2NameMap.length + 1; + } + + @Override + public void add(DataTableRow row) { + throw new RuntimeException("DataTableCorrelationMatrixAdapter: adding new rows is not supported!"); + } + + @Override + public DataTableRow getRow(int index) { + return new CorrelationMatrixRow2DataTableRowWrapper(this.matrix, index); + } + + @Override + public Iterator iterator() { + return new CorrelationMatrixRow2DataTableRowIterator(this.matrix); + } + + @Override + public int getNumberOfRows() { + return this.index2NameMap.length; + } + + /** + * Not implemented!!! Please use this class only for plotting purposes if you can ensure that + * the number of columns / rows is small. + */ + @Override + public DataTable sample(int newSize) { + return this; + } +} diff --git a/src/main/java/com/rapidminer/datatable/DataTableView.java b/src/main/java/com/rapidminer/datatable/DataTableView.java new file mode 100644 index 000000000..2da06aa5f --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/DataTableView.java @@ -0,0 +1,248 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.util.Iterator; +import java.util.Random; +import java.util.Vector; + + +/** + * This class is a view on a DataTable which hides all examples not listed in an index list. + * + * Set the list of selected examples via {@link #setSelectedIndices(Vector)}. + * + * @author Marius Helf + * + */ +public class DataTableView extends AbstractDataTable implements DataTableListener { + + private final DataTable parentTable; + private Vector selectedIndices = null; + private int numberOfSelectedRows; + + public DataTableView(DataTable parentDataTable) { + super(parentDataTable.getName()); + + this.parentTable = parentDataTable; + + // building initial selected indices: All + numberOfSelectedRows = parentTable.getNumberOfRows(); + + parentTable.addDataTableListener(this, true); + + } + + public DataTable getParentTable() { + return parentTable; + } + + public void setSelectedIndices(Vector selectedIndices) { + this.selectedIndices = selectedIndices; + if (selectedIndices != null) { + numberOfSelectedRows = selectedIndices.size(); + } else { + numberOfSelectedRows = parentTable.getRowNumber(); + } + fireEvent(); + } + + @Override + public Iterator iterator() { + return new Iterator() { + + int nextRow = 0; + + @Override + public boolean hasNext() { + return nextRow < numberOfSelectedRows; + } + + @Override + public DataTableRow next() { + DataTableRow row = getRow(nextRow); + nextRow++; + return row; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove() not suppported by FilterDataTable"); + } + }; + } + + @Override + public int getNumberOfRows() { + return numberOfSelectedRows; + } + + @Override + public DataTableRow getRow(int index) { + if (index < numberOfSelectedRows) { + if (selectedIndices == null) { + return parentTable.getRow(index); + } else { + return parentTable.getRow(selectedIndices.get(index)); + } + } else { + throw new ArrayIndexOutOfBoundsException("Index exceeds filtered range: " + index); + } + } + + /* + * Delegating methods + */ + @Override + public void add(DataTableRow row) { + parentTable.add(row); + } + + @Override + public int getColumnIndex(String name) { + return parentTable.getColumnIndex(name); + } + + @Override + public String getColumnName(int i) { + return parentTable.getColumnName(i); + } + + @Override + public double getColumnWeight(int i) { + return parentTable.getColumnWeight(i); + } + + @Override + public int getNumberOfColumns() { + return parentTable.getNumberOfColumns(); + } + + @Override + public int getNumberOfSpecialColumns() { + return parentTable.getNumberOfSpecialColumns(); + } + + @Override + public int getNumberOfValues(int column) { + return parentTable.getNumberOfValues(column); + } + + @Override + public boolean isDate(int index) { + return parentTable.isDate(index); + } + + @Override + public boolean isDateTime(int index) { + return parentTable.isDateTime(index); + } + + @Override + public boolean isNominal(int index) { + return parentTable.isNominal(index); + } + + @Override + public boolean isNumerical(int index) { + return parentTable.isNumerical(index); + } + + @Override + public boolean isSpecial(int column) { + return parentTable.isSpecial(column); + } + + @Override + public boolean isSupportingColumnWeights() { + return parentTable.isSupportingColumnWeights(); + } + + @Override + public boolean isTime(int index) { + return parentTable.isTime(index); + } + + @Override + public String mapIndex(int column, int index) { + return parentTable.mapIndex(column, index); + } + + @Override + public int mapString(int column, String value) { + return parentTable.mapString(column, value); + } + + /** + * Performs a simple sampling without replacement. If newSize is greater than the size of this + * DataTableView, this DataTableView is returned. + * + * Creates a view onto this DataTableView (i.e. the this DataTableView won't get garbage + * collected as long as the sampled DataTableView is around.) + */ + @Override + public DataTable sample(int newSize) { + int rowCount = getRowNumber(); + if (rowCount <= newSize) { + return this; + } + + // initialize sampled indices + int[] sampledSelectedIndices = new int[rowCount]; + for (int i = 0; i < rowCount; ++i) { + sampledSelectedIndices[i] = i; + } + + // shuffle sampled indices + Random rng = new Random(0); + int swapIdx; + int tmpValue; + for (int i = 0; i < rowCount; ++i) { + swapIdx = rng.nextInt(rowCount); + tmpValue = sampledSelectedIndices[swapIdx]; + sampledSelectedIndices[swapIdx] = sampledSelectedIndices[i]; + sampledSelectedIndices[i] = tmpValue; + } + + // convert prefix of sampled indices to vector and set as selected indices for sampled data + // table view + DataTableView sampledDataTable = new DataTableView(this); + Vector sampledSelectedIndicesVector = new Vector(newSize); + for (int i = 0; i < newSize; ++i) { + sampledSelectedIndicesVector.add(sampledSelectedIndices[i]); + } + sampledDataTable.setSelectedIndices(sampledSelectedIndicesVector); + + return sampledDataTable; + } + + /** + * Resets the selected indices and then contains all rows. Anything else is not possible since + * there does not exist any rule how to update the view. + * + * Subclasses like {@link FilteredDataTable} should implement a smarter version of this + * function. + */ + @Override + public void dataTableUpdated(DataTable source) { + selectedIndices = null; + numberOfSelectedRows = source.getRowNumber(); + fireEvent(); + } +} diff --git a/src/main/java/com/rapidminer/datatable/Example2DataTableRowIterator.java b/src/main/java/com/rapidminer/datatable/Example2DataTableRowIterator.java new file mode 100644 index 000000000..ecb9d5ad8 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/Example2DataTableRowIterator.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; + +import java.util.Iterator; +import java.util.List; + + +/** + * This iterator iterates over all examples of an example set and creates + * {@link com.rapidminer.datatable.Example2DataTableRowWrapper} objects. + * + * @author Ingo Mierswa + */ +public class Example2DataTableRowIterator implements Iterator { + + private Iterator reader; + + private List allAttributes; + + private Attribute idAttribute; + + /** + * Creates a new DataTable iterator backed up by examples. If the idAttribute is null the + * DataTableRows will not be able to deliver an Id. + */ + public Example2DataTableRowIterator(Iterator reader, List allAttributes, Attribute idAttribute) { + this.reader = reader; + this.allAttributes = allAttributes; + this.idAttribute = idAttribute; + } + + @Override + public boolean hasNext() { + return reader.hasNext(); + } + + @Override + public DataTableRow next() { + return new Example2DataTableRowWrapper(reader.next(), allAttributes, idAttribute); + } + + @Override + public void remove() { + reader.remove(); + } +} diff --git a/src/main/java/com/rapidminer/datatable/Example2DataTableRowWrapper.java b/src/main/java/com/rapidminer/datatable/Example2DataTableRowWrapper.java new file mode 100644 index 000000000..41792a5ab --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/Example2DataTableRowWrapper.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; + +import java.util.List; + + +/** + * This class allows to use {@link com.rapidminer.example.Example}s as basis for + * {@link com.rapidminer.datatable.DataTableRow}. + * + * @author Ingo Mierswa + */ +public class Example2DataTableRowWrapper implements DataTableRow { + + private Example example; + + private List allAttributes; + + private Attribute idAttribute; + + /** Creates a new wrapper. If the Id Attribute is null, the DataTableRow will not contain an Id. */ + public Example2DataTableRowWrapper(Example example, List allAttributes, Attribute idAttribute) { + this.example = example; + this.allAttributes = allAttributes; + this.idAttribute = idAttribute; + } + + @Override + public String getId() { + if (idAttribute == null) { + return null; + } else { + return this.example.getValueAsString(idAttribute); + } + } + + @Override + public double getValue(int index) { + return this.example.getValue(allAttributes.get(index)); + } + + @Override + public int getNumberOfValues() { + return allAttributes.size(); + } +} diff --git a/src/main/java/com/rapidminer/datatable/FilteredDataTable.java b/src/main/java/com/rapidminer/datatable/FilteredDataTable.java new file mode 100644 index 000000000..2513b738f --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/FilteredDataTable.java @@ -0,0 +1,195 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; + + +/** + * This DataTable filters the contained rows using a stack of FilterConditions. Each time the stack + * is modified, it informs it's DataTableFilteredListener that they need to update the table. + * + * @author Sebastian Land, Marius Helf + */ +public class FilteredDataTable extends DataTableView { + + public static enum ConditionCombination { + AND, // all conditions must match + OR // at least one condition must match + } + + public static interface DataTableFilteredListener { + + /** + * This method is called by a datatable, if its content is changed. + */ + public void informDataTableChange(DataTable dataTable); + } + + private List listeners = new LinkedList(); + + private ArrayList conditionStack = new ArrayList(); + + private final ConditionCombination conditionCombination; + + public FilteredDataTable(DataTable parentDataTable) { + super(parentDataTable); + this.conditionCombination = ConditionCombination.AND; + } + + public FilteredDataTable(DataTable parentDataTable, ConditionCombination conditionCombination) { + super(parentDataTable); + this.conditionCombination = conditionCombination; + } + + /** + * Adds a new condition. null arguments will be ignored. + * + * @param condition + */ + public void addCondition(DataTableFilterCondition condition) { + if (condition == null) { + return; + } + conditionStack.add(condition); + setSelectedIndices(updateSelection()); + informDataTableFilteredListener(); + } + + /** + * Adds a batch of conditions. The listeners will be only informed after all of the conditions + * have been added. Null conditions will be ignored. + * + * @param conditions + * The collection of the conditions to be added. Must not be null. + */ + public void addConditions(Iterable conditions) { + boolean changed = false; + for (DataTableFilterCondition condition : conditions) { + if (condition != null) { + conditionStack.add(condition); + changed = true; + } + } + if (changed) { + setSelectedIndices(updateSelection()); + informDataTableFilteredListener(); + } + } + + public void removeCondition() { + if (conditionStack.size() > 0) { + conditionStack.remove(conditionStack.size() - 1); + setSelectedIndices(updateSelection()); + informDataTableFilteredListener(); + } + } + + public void removeAllConditions() { + if (conditionStack.size() > 0) { + conditionStack.clear(); + setSelectedIndices(updateSelection()); + informDataTableFilteredListener(); + } + } + + /** + * Replaces all conditions. See addConditions for parameter description. + */ + public void replaceConditions(Iterable newConditions) { + int oldSize = conditionStack.size(); + conditionStack.clear(); + if (!newConditions.iterator().hasNext() && oldSize > 0) { + setSelectedIndices(updateSelection()); + informDataTableFilteredListener(); + return; + } + addConditions(newConditions); + } + + /** + * @return a vector which contains the indices of all rows in the parent table that match the + * condition stack. + */ + private Vector updateSelection() { + if (conditionStack.isEmpty()) { + return null; + } + + int parentRowIndex = 0; + Vector selectedIndices = new Vector(); + for (DataTableRow row : getParentTable()) { + // heuristic: if we have accesses to the row, cache the row in a SimpleDataTableRow + if (conditionStack.size() / 2 > row.getNumberOfValues() && !(row instanceof SimpleDataTableRow)) { + row = new SimpleDataTableRow(row); + } + + switch (conditionCombination) { + case AND: + boolean keep = true; + + for (int conditionIndex = conditionStack.size() - 1; conditionIndex >= 0 && keep; conditionIndex--) { + keep &= conditionStack.get(conditionIndex).keepRow(row); + if (!keep) { + break; + } + } + if (keep) { + selectedIndices.add(parentRowIndex); + } + break; + case OR: + for (int conditionIndex = conditionStack.size() - 1; conditionIndex >= 0; conditionIndex--) { + if (conditionStack.get(conditionIndex).keepRow(row)) { + selectedIndices.add(parentRowIndex); + break; + } + } + break; + } + parentRowIndex++; + } + return selectedIndices; + } + + /* + * Listener Methods + */ + public void addDataTableFilteredListener(DataTableFilteredListener listener) { + this.listeners.add(listener); + } + + public void removeDataTableFilteredListewner(DataTableFilteredListener listener) { + this.listeners.remove(listener); + } + + private void informDataTableFilteredListener() { + for (DataTableFilteredListener listener : listeners) { + listener.informDataTableChange(this); + } + } + + @Override + public void dataTableUpdated(DataTable source) { + setSelectedIndices(updateSelection()); + } +} diff --git a/src/main/java/com/rapidminer/datatable/GnuPlotDataTableHandler.java b/src/main/java/com/rapidminer/datatable/GnuPlotDataTableHandler.java new file mode 100644 index 000000000..5615077b7 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/GnuPlotDataTableHandler.java @@ -0,0 +1,145 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.io.PrintStream; +import java.text.DateFormat; +import java.util.Collection; +import java.util.Comparator; +import java.util.Date; +import java.util.Iterator; +import java.util.TreeSet; + + +/** + * This class can be used to create GnuPlot files from data tables. + * + * @author Ingo Mierswa + */ +public class GnuPlotDataTableHandler implements DataTableListener { + + private static final Comparator ROW_COMPARATOR = new Comparator() { + + @Override + public int compare(double[] row1, double[] row2) { + for (int i = 0; i < row1.length; i++) { + if (row1[i] < row2[i]) { + return -1; + } else if (row1[i] > row2[i]) { + return +1; + } + } + return 0; + }; + }; + + private DataTable table; + + public GnuPlotDataTableHandler(DataTable table) { + this.table = table; + this.table.addDataTableListener(this); + } + + @Override + public void dataTableUpdated(DataTable table) { + this.table = table; + } + + public void writeGNUPlot(PrintStream out, int x, int y, int[] z, String linetype, String additionalCommands, + String terminal) { + writeGNUPlotHeader(out, table.getColumnName(x), (y != -1 ? table.getColumnName(y) : table.getColumnName(z[0])), + table.getColumnName(z[0]), additionalCommands, terminal); + if (y != -1) { + out.print("splot "); + } else { + out.print("plot "); + } + for (int i = 0; i < z.length; i++) { + if (i > 0) { + out.print(", "); + } + out.print("'-' title \"" + table.getColumnName(z[i]) + "\" with " + linetype);// linespoints"); + } + out.println(); + for (int i = 0; i < z.length; i++) { + if (y != -1) { + write3DGNUPlotData(out, x, y, z[i]); + } else { + write2DGNUPlotData(out, x, z[i]); + } + out.println("e"); + } + } + + private void writeGNUPlotHeader(PrintStream out, String xAxis, String yAxis, String zAxis, String additionalCommands, + String terminal) { + out.println("#!gnuplot"); + out.println("# Generated by " + getClass() + " on " + DateFormat.getDateTimeInstance().format(new Date())); + if (xAxis != null) { + out.println("set xlabel \"" + xAxis + "\""); + } + if (yAxis != null) { + out.println("set ylabel \"" + yAxis + "\""); + } + if (zAxis != null) { + out.println("set zlabel \"" + zAxis + "\""); + } + if (additionalCommands != null) { + out.println(additionalCommands); + } + if (terminal != null) { + out.println("set terminal " + terminal); + } + } + + private void write2DGNUPlotData(PrintStream out, int x, int y) { + Collection plot = new TreeSet(ROW_COMPARATOR); + Iterator i = table.iterator(); + while (i.hasNext()) { + DataTableRow row = i.next(); + plot.add(new double[] { row.getValue(x), row.getValue(y) }); + } + + Iterator j = plot.iterator(); + while (j.hasNext()) { + double[] row = j.next(); + out.println(row[0] + "\t" + row[1]); + } + } + + private void write3DGNUPlotData(PrintStream out, int x, int y, int z) { + Collection plot = new TreeSet(ROW_COMPARATOR); + Iterator i = table.iterator(); + while (i.hasNext()) { + DataTableRow row = i.next(); + plot.add(new double[] { row.getValue(x), row.getValue(y), row.getValue(z) }); + } + + double oldX = Double.NaN; + Iterator j = plot.iterator(); + while (j.hasNext()) { + double[] row = j.next(); + if ((!Double.isNaN(oldX)) && (row[0] != oldX)) { + out.println(); + } + out.println(row[0] + "\t" + row[1] + "\t" + row[2]); + oldX = row[0]; + } + } +} diff --git a/src/main/java/com/rapidminer/datatable/KernelModelRow2DataTableRowWrapper.java b/src/main/java/com/rapidminer/datatable/KernelModelRow2DataTableRowWrapper.java new file mode 100644 index 000000000..fe379740a --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/KernelModelRow2DataTableRowWrapper.java @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.operator.learner.functions.kernel.KernelModel; + + +/** + * This class wraps the data row of a kernel model. + * + * @author Ingo Mierswa + */ +public class KernelModelRow2DataTableRowWrapper implements DataTableRow { + + static final String[] SPECIAL_COLUMN_NAMES = { "counter", "label", "function value", "alpha", "abs(alpha)", + "support vector" }; + + public static final int COUNTER = 0; + public static final int LABEL = 1; + public static final int FUNCTION_VALUE = 2; + public static final int ALPHA = 3; + public static final int ABS_ALPHA = 4; + public static final int SUPPORT_VECTOR = 5; + + public static final int NUMBER_OF_SPECIAL_COLUMNS = 6; + + private KernelModel kernelModel; + private DataTableKernelModelAdapter adapter; + private int index; + + public KernelModelRow2DataTableRowWrapper(KernelModel kernelModel, DataTableKernelModelAdapter adapter, int index) { + this.kernelModel = kernelModel; + this.adapter = adapter; + this.index = index; + } + + @Override + public String getId() { + return this.kernelModel.getId(index); + } + + @Override + public int getNumberOfValues() { + return kernelModel.getNumberOfAttributes() + NUMBER_OF_SPECIAL_COLUMNS; + } + + @Override + public double getValue(int column) { + switch (column) { + case COUNTER: + return index; + case LABEL: + if (this.kernelModel.isClassificationModel()) { + String label = this.kernelModel.getClassificationLabel(index); + return adapter.mapString(LABEL, label); + } else { + return this.kernelModel.getRegressionLabel(index); + } + case FUNCTION_VALUE: + return this.kernelModel.getFunctionValue(index); + case ALPHA: + return this.kernelModel.getAlpha(index); + case ABS_ALPHA: + return Math.abs(this.kernelModel.getAlpha(index)); + case SUPPORT_VECTOR: + return Math.abs(this.kernelModel.getAlpha(index)) != 0.0d ? 1 : 0; + default: + return this.kernelModel.getAttributeValue(index, column - NUMBER_OF_SPECIAL_COLUMNS); + } + } +} diff --git a/src/main/java/com/rapidminer/datatable/NominalSortingDataTableMapping.java b/src/main/java/com/rapidminer/datatable/NominalSortingDataTableMapping.java new file mode 100644 index 000000000..dd0d85637 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/NominalSortingDataTableMapping.java @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.gui.new_plotter.utility.DataStructureUtils; +import com.rapidminer.tools.container.Pair; + +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + + +/** + * A view on a dataTable which changes the mapping of nominal values such that nominal values or + * ordered lexically ascending or descending with increasing index values. + * + * Uses lazy initialization, i.e. the mapping is only created on first access. + * + * @author Marius Helf + * + */ +public class NominalSortingDataTableMapping implements BidirectionalMappingProvider, DataTableListener { + + /** + * Maps values from the parent table to the new values. + */ + Map parentToChildMapping = null; + Map childToParentMapping = null; + private boolean ascending; + private int columnIdx; + private final DataTable originalDataTable; + + public NominalSortingDataTableMapping(ValueMappingDataTableView dataTable, int columnIdx, boolean ascending) { + if (!dataTable.isNominal(columnIdx)) { + throw new IllegalArgumentException("NominalSortingDataTableMapping can only work on nominal columns."); + } + this.ascending = ascending; + this.columnIdx = columnIdx; + this.originalDataTable = dataTable.getParent(); + originalDataTable.addDataTableListener(this, true); + } + + private void updateMapping(DataTable dataTable, int columnIdx, boolean ascending) { + List distinctValues = DataStructureUtils.getDistinctDataTableValues(dataTable, columnIdx); + List> valueStrings = new LinkedList>(); + for (double value : distinctValues) { + valueStrings.add(new Pair(value, dataTable.mapIndex(columnIdx, (int) value))); + } + + Collections.sort(valueStrings, new DataStructureUtils.PairComparator(ascending)); + + parentToChildMapping = new HashMap(); + childToParentMapping = new HashMap(); + double idx = 0.0; + for (Pair entry : valueStrings) { + parentToChildMapping.put(entry.getFirst(), idx); + childToParentMapping.put(idx, entry.getFirst()); + idx += 1; + } + } + + @Override + public double mapFromParentValue(double originalValue) { + if (parentToChildMapping == null) { + updateMapping(originalDataTable, columnIdx, ascending); + } + return parentToChildMapping.get(originalValue); + } + + @Override + public void dataTableUpdated(DataTable source) { + // invalidate mapping (will be recalculated on next access) + parentToChildMapping = null; + childToParentMapping = null; + } + + @Override + public double mapToParentValue(double value) { + if (childToParentMapping == null) { + updateMapping(originalDataTable, columnIdx, ascending); + } + return childToParentMapping.get(value); + } +} diff --git a/src/main/java/com/rapidminer/datatable/PairwiseMatrix2DataTableRowIterator.java b/src/main/java/com/rapidminer/datatable/PairwiseMatrix2DataTableRowIterator.java new file mode 100644 index 000000000..17669de65 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/PairwiseMatrix2DataTableRowIterator.java @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.operator.visualization.dependencies.NumericalMatrix; + +import java.util.Iterator; + + +/** + * This iterator iterates over examples of a numerical matrix and creates + * {@link com.rapidminer.datatable.CorrelationMatrixRow2DataTableRowWrapper} objects. If matrix is + * symetrical, it will iterate only over the pairs of the lower left triangle of the matrix, sparing + * the diagonal. Otherwise it will return all pairs. + * + * @author Ingo Mierswa, Sebastian Land + */ +public class PairwiseMatrix2DataTableRowIterator implements Iterator { + + private NumericalMatrix matrix; + + private int firstAttribute; + + private int secondAttribute; + + private boolean showSymetrically; + + /** + * Creates a new DataTable iterator for the given numerical matrix. If the idAttribute is null + * the DataTableRows will not be able to deliver an Id. + */ + public PairwiseMatrix2DataTableRowIterator(NumericalMatrix matrix) { + this(matrix, true); + } + + /** + * Creates a new iterator that will show the matrix symetrically only if matrix is symetrically + * and parameter showSymetrically is true. + */ + public PairwiseMatrix2DataTableRowIterator(NumericalMatrix matrix, boolean showSymetrically) { + this.showSymetrically = showSymetrically; + this.matrix = matrix; + this.firstAttribute = 0; + if (matrix.isSymmetrical()) { + this.secondAttribute = 1; + } else { + this.secondAttribute = 0; + } + } + + @Override + public boolean hasNext() { + return (firstAttribute < matrix.getNumberOfRows()) && (secondAttribute < matrix.getNumberOfColumns()); + } + + @Override + public DataTableRow next() { + DataTableRow row = new PairwiseMatrix2DataTableRowWrapper(matrix, firstAttribute, secondAttribute); + if (matrix.isSymmetrical() && showSymetrically) { + secondAttribute++; + if (secondAttribute >= matrix.getNumberOfColumns()) { + firstAttribute++; + secondAttribute = firstAttribute + 1; + } + } else { + secondAttribute++; + if (secondAttribute >= matrix.getNumberOfColumns()) { + secondAttribute = 0; + firstAttribute++; + } + } + return row; + } + + @Override + public void remove() { + throw new RuntimeException("PairwiseCorrelation2DataTableRowIterator: removing rows is not supported!"); + } +} diff --git a/src/main/java/com/rapidminer/datatable/PairwiseMatrix2DataTableRowWrapper.java b/src/main/java/com/rapidminer/datatable/PairwiseMatrix2DataTableRowWrapper.java new file mode 100644 index 000000000..883eafc19 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/PairwiseMatrix2DataTableRowWrapper.java @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.operator.visualization.dependencies.NumericalMatrix; + + +/** + * This class allows to use the entries of a + * {@link com.rapidminer.operator.visualization.dependencies.NumericalMatrix} as basis for + * {@link com.rapidminer.datatable.DataTableRow}. + * + * @author Ingo Mierswa + */ +public class PairwiseMatrix2DataTableRowWrapper implements DataTableRow { + + private NumericalMatrix matrix; + + private int firstIndex; + + private int secondIndex; + + /** Creates a new wrapper. */ + public PairwiseMatrix2DataTableRowWrapper(NumericalMatrix matrix, int firstIndex, int secondIndex) { + this.matrix = matrix; + this.firstIndex = firstIndex; + this.secondIndex = secondIndex; + } + + @Override + public String getId() { + return "value(" + this.matrix.getColumnName(firstIndex) + ", " + this.matrix.getColumnName(secondIndex) + ") = " + + this.matrix.getValue(firstIndex, secondIndex); + } + + @Override + public double getValue(int index) { + if (index == 0) { + return firstIndex; + } else if (index == 1) { + return secondIndex; + } else { + return this.matrix.getValue(firstIndex, secondIndex); + } + } + + @Override + public int getNumberOfValues() { + return 3; + } +} diff --git a/src/main/java/com/rapidminer/datatable/RangeFilterCondition.java b/src/main/java/com/rapidminer/datatable/RangeFilterCondition.java new file mode 100644 index 000000000..8bda68736 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/RangeFilterCondition.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.tools.math.container.Range; + + +/** + * This condition filters out row, if their value of the specified dimension does not lie in given + * value range. + * + * @author Sebastian Land + * + */ +public class RangeFilterCondition implements DataTableFilterCondition { + + private Range range; + private int dimensionIndex; + + public RangeFilterCondition(Range range, int dimensionIndex) { + this.range = range; + this.dimensionIndex = dimensionIndex; + } + + @Override + public boolean keepRow(DataTableRow row) { + double value = row.getValue(dimensionIndex); + return (range.contains(value)); + } + +} diff --git a/src/main/java/com/rapidminer/datatable/RegionFilterCondition.java b/src/main/java/com/rapidminer/datatable/RegionFilterCondition.java new file mode 100644 index 000000000..189f058ab --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/RegionFilterCondition.java @@ -0,0 +1,102 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import com.rapidminer.tools.math.container.Range; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + + +/** + * This FilterCondition is a multidimensional equivalent to the RangeFilterCondition. + * + * @author Sebastian Land + */ +public class RegionFilterCondition implements DataTableFilterCondition { + + public static final class Region { + + Map delimiters = new LinkedHashMap(); + + /** + * This method will return true if this region is restricted by adding the given range in + * the given dimension. If it remains unchanged, because the range covers this region + * completely, this method will return false; + */ + public boolean addRestrictingRange(int dimension, Range range) { + Range existing = delimiters.get(dimension); + if (existing == null) { + delimiters.put(dimension, range); + return true; + } else { + if (existing.contains(range) && !existing.equals(range)) { + delimiters.put(dimension, range); + return true; + } + } + return false; + } + + public boolean containsRow(DataTableRow row) { + for (Entry pair : delimiters.entrySet()) { + if (!pair.getValue().contains(row.getValue(pair.getKey()))) { + return false; + } + } + return true; + } + + @Override + public boolean equals(Object arg) { + if (arg instanceof Region) { + Region region = ((Region) arg); + boolean equal = region.delimiters.size() == delimiters.size(); + for (Integer key : delimiters.keySet()) { + equal &= delimiters.get(key).equals(region.delimiters.get(key)); + if (!equal) { + break; + } + } + return equal; + } + return false; + } + } + + private Region region; + + public RegionFilterCondition(Region region) { + this.region = region; + } + + @Override + public boolean keepRow(DataTableRow row) { + return region.containsRow(row); + } + + /** + * This returns a region object, which stores all ranged in all dimensions. They might be + * successively added by calling the addRange method. + */ + public static final Region createRegion() { + return new Region(); + } +} diff --git a/src/main/java/com/rapidminer/datatable/SimpleDataTable.java b/src/main/java/com/rapidminer/datatable/SimpleDataTable.java new file mode 100644 index 000000000..53df2ab84 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/SimpleDataTable.java @@ -0,0 +1,369 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; + +import com.rapidminer.tools.Tools; + + +/** + * A simple data table implementation which stores the data itself. + * + * @author Ingo Mierswa, Simon Fischer + */ +public class SimpleDataTable extends AbstractDataTable implements Serializable { + + private static final long serialVersionUID = 4459570725439894361L; + + private List data = new ArrayList<>(); + + private String[] columns; + + private double[] weights; + + private boolean[] specialColumns; + + private Map> index2StringMap = new HashMap<>(); + private Map> string2IndexMap = new HashMap<>(); + + private int[] currentIndices; + + public SimpleDataTable(String name, String[] columns) { + this(name, columns, null); + } + + public SimpleDataTable(String name, String[] columns, double[] weights) { + super(name); + this.columns = columns; + this.weights = weights; + this.specialColumns = new boolean[columns.length]; + for (int i = 0; i < this.specialColumns.length; i++) { + this.specialColumns[i] = false; + } + this.currentIndices = new int[columns.length]; + for (int i = 0; i < currentIndices.length; i++) { + currentIndices[i] = 0; + } + } + + private SimpleDataTable(SimpleDataTable simpleDataTable) { + super(simpleDataTable.getName()); + + this.columns = null; + if (simpleDataTable.columns != null) { + this.columns = new String[simpleDataTable.columns.length]; + for (int i = 0; i < simpleDataTable.columns.length; i++) { + this.columns[i] = simpleDataTable.columns[i]; + } + } + + this.weights = null; + if (simpleDataTable.weights != null) { + this.weights = new double[simpleDataTable.weights.length]; + for (int i = 0; i < simpleDataTable.weights.length; i++) { + this.weights[i] = simpleDataTable.weights[i]; + } + } + + this.specialColumns = null; + if (simpleDataTable.specialColumns != null) { + this.specialColumns = new boolean[simpleDataTable.specialColumns.length]; + for (int i = 0; i < simpleDataTable.specialColumns.length; i++) { + this.specialColumns[i] = simpleDataTable.specialColumns[i]; + } + } + + this.currentIndices = new int[simpleDataTable.currentIndices.length]; + for (int i = 0; i < this.currentIndices.length; i++) { + this.currentIndices[i] = simpleDataTable.currentIndices[i]; + } + + this.index2StringMap = new HashMap<>(); + for (Map.Entry> entry : simpleDataTable.index2StringMap.entrySet()) { + Integer key = entry.getKey(); + Map indexMap = entry.getValue(); + Map newIndexMap = new HashMap<>(); + for (Map.Entry innerEntry : indexMap.entrySet()) { + newIndexMap.put(innerEntry.getKey(), innerEntry.getValue()); + } + this.index2StringMap.put(key, newIndexMap); + } + + this.string2IndexMap = new HashMap<>(); + for (Map.Entry> entry : simpleDataTable.string2IndexMap.entrySet()) { + Integer key = entry.getKey(); + Map indexMap = entry.getValue(); + Map newIndexMap = new HashMap<>(); + for (Map.Entry innerEntry : indexMap.entrySet()) { + newIndexMap.put(innerEntry.getKey(), innerEntry.getValue()); + } + this.string2IndexMap.put(key, newIndexMap); + } + } + + @Override + public int getNumberOfSpecialColumns() { + int counter = 0; + for (boolean b : specialColumns) { + if (b) { + counter++; + } + } + return counter; + } + + @Override + public boolean isSpecial(int index) { + return specialColumns[index]; + } + + public void setSpecial(int index, boolean special) { + this.specialColumns[index] = special; + } + + @Override + public boolean isNominal(int column) { + return index2StringMap.get(column) != null; + } + + @Override + public boolean isDate(int index) { + return false; + } + + @Override + public boolean isTime(int index) { + return false; + } + + @Override + public boolean isDateTime(int index) { + return false; + } + + @Override + public boolean isNumerical(int index) { + return !isNominal(index); + } + + @Override + public String mapIndex(int column, int index) { + Map columnIndexMap = index2StringMap.get(column); + return columnIndexMap.get(index); + } + + @Override + public int mapString(int column, String value) { + Map columnValueMap = string2IndexMap.get(column); + if (columnValueMap == null) { + columnValueMap = new HashMap<>(); + columnValueMap.put(value, currentIndices[column]); + string2IndexMap.put(column, columnValueMap); + Map columnIndexMap = new HashMap<>(); + columnIndexMap.put(currentIndices[column], value); + index2StringMap.put(column, columnIndexMap); + int returnValue = currentIndices[column]; + currentIndices[column]++; + return returnValue; + } else { + Integer result = columnValueMap.get(value); + if (result != null) { + return result.intValue(); + } else { + int newIndex = currentIndices[column]; + columnValueMap.put(value, newIndex); + Map columnIndexMap = index2StringMap.get(column); + columnIndexMap.put(newIndex, value); + currentIndices[column]++; + return newIndex; + } + } + } + + @Override + public int getNumberOfValues(int column) { + return index2StringMap.get(column).size(); + } + + public void cleanMappingTables() { + Map> allValues = new HashMap<>(); + for (Map.Entry> entry : this.string2IndexMap.entrySet()) { + Integer key = entry.getKey(); + Set columnValues = new HashSet<>(); + for (String current : entry.getValue().keySet()) { + columnValues.add(current); + } + allValues.put(key, columnValues); + } + + for (DataTableRow row : this) { + for (int i = 0; i < getNumberOfColumns(); i++) { + if (isNominal(i)) { + String currentValue = getValueAsString(row, i); + allValues.get(i).remove(currentValue); + } + } + } + + for (int i = 0; i < getNumberOfColumns(); i++) { + Set toDelete = allValues.get(i); + if (toDelete != null) { + Map string2Index = this.string2IndexMap.get(i); + Map index2String = this.index2StringMap.get(i); + for (String current : toDelete) { + int oldIndex = string2Index.get(current); + index2String.remove(oldIndex); + string2Index.remove(current); + } + } + } + } + + @Override + public boolean isSupportingColumnWeights() { + return weights != null; + } + + @Override + public double getColumnWeight(int column) { + if (weights == null) { + return Double.NaN; + } else { + return weights[column]; + } + } + + @Override + public String getColumnName(int i) { + return columns[i]; + } + + @Override + public int getColumnIndex(String name) { + for (int i = 0; i < columns.length; i++) { + if (columns[i].equals(name)) { + return i; + } + } + return -1; + } + + @Override + public int getNumberOfColumns() { + return columns.length; + } + + @Override + public String[] getColumnNames() { + return columns; + } + + @Override + public synchronized void add(DataTableRow row) { + synchronized (data) { + data.add(row); + fireEvent(); + } + } + + public synchronized void remove(DataTableRow row) { + synchronized (data) { + data.remove(row); + fireEvent(); + } + } + + @Override + public DataTableRow getRow(int index) { + return data.get(index); + } + + @Override + public synchronized Iterator iterator() { + Iterator i = null; + synchronized (data) { + i = data.iterator(); + } + return i; + } + + @Override + public int getNumberOfRows() { + int result = 0; + synchronized (data) { + result = data.size(); + } + return result; + } + + public void clear() { + data.clear(); + fireEvent(); + } + + @Override + public synchronized DataTable sample(int newSize) { + if (getNumberOfRows() <= newSize) { + return this; + } else { + SimpleDataTable result = new SimpleDataTable(this); + + // must be a usual random since otherwise plotting would change the rest of + // the process during a breakpoint result viewing + Random random = new Random(); + + List indices = new ArrayList<>(getNumberOfRows()); + for (int i = 0; i < getNumberOfRows(); i++) { + indices.add(i); + } + + while (result.getNumberOfRows() < newSize) { + int index = random.nextInt(indices.size()); + result.add(data.get(indices.remove(index))); + } + + return result; + } + } + + /** Dumps the complete table into a string (complete data!). */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (DataTableRow row : this) { + for (int i = 0; i < getNumberOfColumns(); i++) { + if (i != 0) { + result.append(", "); + } + result.append(row.getValue(i)); + } + result.append(Tools.getLineSeparator()); + } + return result.toString(); + } +} diff --git a/src/main/java/com/rapidminer/datatable/SimpleDataTableRow.java b/src/main/java/com/rapidminer/datatable/SimpleDataTableRow.java new file mode 100644 index 000000000..3fc41a4b4 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/SimpleDataTableRow.java @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.io.Serializable; + + +/** + * A data list that contains Object arrays that record process results or other data. Each row can + * consist of an id and an object array which represents the data. + * + * @author Ingo Mierswa, Marius Helf + */ +public class SimpleDataTableRow implements DataTableRow, Serializable { + + private static final long serialVersionUID = 1L; + + private double[] row; + + private String id; + + /** + * Creates a SimpleDataTableRow with the same values as other. + */ + public SimpleDataTableRow(DataTableRow other) { + copyValuesFromOtherRow(other); + } + + public SimpleDataTableRow(double[] row) { + this(row, null); + } + + public SimpleDataTableRow(double[] row, String id) { + this.row = row; + this.id = id; + } + + @Override + public String getId() { + return id; + } + + @Override + public double getValue(int index) { + return row[index]; + } + + @Override + public int getNumberOfValues() { + return row.length; + } + + public void copyValuesFromOtherRow(DataTableRow other) { + int numberOfValues = other.getNumberOfValues(); + row = new double[numberOfValues]; + for (int i = 0; i < numberOfValues; ++i) { + row[i] = other.getValue(i); + } + } +} diff --git a/src/main/java/com/rapidminer/datatable/SortedDataTableView.java b/src/main/java/com/rapidminer/datatable/SortedDataTableView.java new file mode 100644 index 000000000..68e70c2b2 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/SortedDataTableView.java @@ -0,0 +1,245 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.util.Iterator; +import java.util.Random; +import java.util.Vector; + + +/** + * A view on a parent DataTable which maps the row indices such that the view is sorted. The sort + * order is defined by a DataTableSortProvider. + * + * @author Marius Helf, Nils Woehler + */ +public class SortedDataTableView extends AbstractDataTable implements DataTableListener { + + private DataTable parentTable; + private DataTableSortProvider sortProvider; + private int[] indexMappingCache = null; + + public SortedDataTableView(DataTable parentDataTable, DataTableSortProvider sortProvider) { + super(parentDataTable.getName()); + this.parentTable = parentDataTable; + this.sortProvider = sortProvider; + parentTable.addDataTableListener(this); + } + + @Override + public Iterator iterator() { + return new Iterator() { + + int nextRow = 0; + + @Override + public boolean hasNext() { + return nextRow < getNumberOfRows(); + } + + @Override + public DataTableRow next() { + DataTableRow row = getRow(nextRow); + nextRow++; + return row; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove() not suppported by SortedDataTableView"); + } + }; + } + + @Override + public DataTableRow getRow(int index) { + if (indexMappingCache == null) { + updateIndexMapping(); + } + return parentTable.getRow(indexMappingCache[index]); + } + + private void updateIndexMapping() { + if (sortProvider != null) { + indexMappingCache = sortProvider.getIndexMapping(parentTable); + } else { + int rowCount = getRowNumber(); + indexMappingCache = new int[rowCount]; + for (int i = 0; i < rowCount; ++i) { + indexMappingCache[i] = i; + } + } + } + + public DataTableSortProvider getSortProvider() { + return sortProvider; + } + + /** + * Sets the new sort provider, invalidates cache and informs all listeners. + */ + public void setSortProvider(DataTableSortProvider sortProvider) { + if (this.sortProvider != sortProvider) { + invalidateIndexMapping(); + this.sortProvider = sortProvider; + fireEvent(); + } + } + + private void invalidateIndexMapping() { + indexMappingCache = null; + } + + /* + * Delegating methods + */ + @Override + public int getNumberOfRows() { + return parentTable.getNumberOfRows(); + } + + @Override + public void add(DataTableRow row) { + parentTable.add(row); + } + + @Override + public int getColumnIndex(String name) { + return parentTable.getColumnIndex(name); + } + + @Override + public String getColumnName(int i) { + return parentTable.getColumnName(i); + } + + @Override + public double getColumnWeight(int i) { + return parentTable.getColumnWeight(i); + } + + @Override + public int getNumberOfColumns() { + return parentTable.getNumberOfColumns(); + } + + @Override + public int getNumberOfSpecialColumns() { + return parentTable.getNumberOfSpecialColumns(); + } + + @Override + public int getNumberOfValues(int column) { + return parentTable.getNumberOfValues(column); + } + + @Override + public boolean isDate(int index) { + return parentTable.isDate(index); + } + + @Override + public boolean isDateTime(int index) { + return parentTable.isDateTime(index); + } + + @Override + public boolean isNominal(int index) { + return parentTable.isNominal(index); + } + + @Override + public boolean isNumerical(int index) { + return parentTable.isNumerical(index); + } + + @Override + public boolean isSpecial(int column) { + return parentTable.isSpecial(column); + } + + @Override + public boolean isSupportingColumnWeights() { + return parentTable.isSupportingColumnWeights(); + } + + @Override + public boolean isTime(int index) { + return parentTable.isTime(index); + } + + @Override + public String mapIndex(int column, int index) { + return parentTable.mapIndex(column, index); + } + + @Override + public int mapString(int column, String value) { + return parentTable.mapString(column, value); + } + + /** + * Performs a simple sampling without replacement. If newSize is greater than the size of this + * DataTableView, this DataTableView is returned. + * + * Creates a view onto this SortedDataTableView (i.e. this SortedDataTableView won't get garbage + * collected as long as the sampled DataTableView is around.) + */ + @Override + public DataTable sample(int newSize) { + int rowCount = getRowNumber(); + if (rowCount <= newSize) { + return this; + } + + // initialize sampled indices + int[] sampledSelectedIndices = new int[rowCount]; + for (int i = 0; i < rowCount; ++i) { + sampledSelectedIndices[i] = i; + } + + // shuffle sampled indices + Random rng = new Random(0); + int swapIdx; + int tmpValue; + for (int i = 0; i < rowCount; ++i) { + swapIdx = rng.nextInt(rowCount); + tmpValue = sampledSelectedIndices[swapIdx]; + sampledSelectedIndices[swapIdx] = sampledSelectedIndices[i]; + sampledSelectedIndices[i] = tmpValue; + } + + // convert prefix of sampled indices to vector and set as selected indices for sampled data + // table view + DataTableView sampledDataTable = new DataTableView(this); + Vector sampledSelectedIndicesVector = new Vector(newSize); + for (int i = 0; i < newSize; ++i) { + sampledSelectedIndicesVector.add(sampledSelectedIndices[i]); + } + sampledDataTable.setSelectedIndices(sampledSelectedIndicesVector); + + return new SortedDataTableView(sampledDataTable, sortProvider); + } + + @Override + public void dataTableUpdated(DataTable source) { + invalidateIndexMapping(); // invalidate cache + fireEvent(); + } +} diff --git a/src/main/java/com/rapidminer/datatable/ValueMappingDataTableRow.java b/src/main/java/com/rapidminer/datatable/ValueMappingDataTableRow.java new file mode 100644 index 000000000..f7326cba7 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/ValueMappingDataTableRow.java @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +/** + * @author Marius Helf + */ +public class ValueMappingDataTableRow implements DataTableRow { + + private ValueMappingDataTableView dataTable; + private DataTableRow row; + + public ValueMappingDataTableRow(DataTableRow row, ValueMappingDataTableView valueMappingDataTable) { + this.dataTable = valueMappingDataTable; + this.row = row; + } + + @Override + public String getId() { + return row.getId(); + } + + @Override + public double getValue(int index) { + double value = row.getValue(index); + return dataTable.mapValue(value, index); + } + + @Override + public int getNumberOfValues() { + return row.getNumberOfValues(); + } + +} diff --git a/src/main/java/com/rapidminer/datatable/ValueMappingDataTableView.java b/src/main/java/com/rapidminer/datatable/ValueMappingDataTableView.java new file mode 100644 index 000000000..c4d3f9390 --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/ValueMappingDataTableView.java @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.datatable; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; + + +/** + * A view on a parent DataTable which maps values from the parent table to other values. Can e.g. be + * used to change the mapping of nominal values. + * + * @author Marius Helf + */ +public class ValueMappingDataTableView extends AbstractDataTable implements DataTableListener { + + public static interface MappedDataTableListener { + + /** + * This method is called by a datatable, if its content is changed. + */ + public void informDataTableChange(DataTable dataTable); + } + + private List listeners = new LinkedList(); + + private DataTable parentTable; + private Vector mappings; + + public ValueMappingDataTableView(DataTable parentDataTable) { + super(parentDataTable.getName()); + this.parentTable = parentDataTable; + + // init mappings with nulls + int columnCount = parentTable.getColumnNumber(); + mappings = new Vector(columnCount); + for (int i = 0; i < columnCount; ++i) { + mappings.add(null); + } + + parentTable.addDataTableListener(this); + } + + double mapValue(double originalValue, int columnIdx) { + double mappedValue = originalValue; + + if (mappings.elementAt(columnIdx) != null) { + mappedValue = mappings.elementAt(columnIdx).mapFromParentValue(originalValue); + } + + return mappedValue; + } + + @Override + public Iterator iterator() { + return new Iterator() { + + int nextRow = 0; + + @Override + public boolean hasNext() { + return nextRow < getNumberOfRows(); + } + + @Override + public DataTableRow next() { + DataTableRow row = getRow(nextRow); + nextRow++; + return row; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("remove() not suppported by FilterDataTable"); + } + }; + } + + @Override + public DataTableRow getRow(int index) { + return new ValueMappingDataTableRow(parentTable.getRow(index), this); + } + + @Override + public int getNumberOfRows() { + return parentTable.getNumberOfRows(); + } + + public void setMappingProvider(int columnIdx, DataTableMappingProvider mapping) { + if (mapping != mappings.elementAt(columnIdx)) { + mappings.set(columnIdx, mapping); + informMappedDataTableListeners(); + fireEvent(); + } + } + + /* + * Listener Methods + */ + public void addMappedDataTableListener(MappedDataTableListener listener) { + this.listeners.add(listener); + } + + public void removeMappedDataTableListewner(MappedDataTableListener listener) { + this.listeners.remove(listener); + } + + private void informMappedDataTableListeners() { + for (MappedDataTableListener listener : listeners) { + listener.informDataTableChange(this); + } + } + + /* + * Delegating methods + */ + + @Override + public void add(DataTableRow row) { + parentTable.add(row); + } + + @Override + public int getColumnIndex(String name) { + return parentTable.getColumnIndex(name); + } + + @Override + public String getColumnName(int i) { + return parentTable.getColumnName(i); + } + + @Override + public double getColumnWeight(int i) { + return parentTable.getColumnWeight(i); + } + + @Override + public int getNumberOfColumns() { + return parentTable.getNumberOfColumns(); + } + + @Override + public int getNumberOfSpecialColumns() { + return parentTable.getNumberOfSpecialColumns(); + } + + @Override + public int getNumberOfValues(int column) { + return parentTable.getNumberOfValues(column); + } + + @Override + public boolean isDate(int index) { + return parentTable.isDate(index); + } + + @Override + public boolean isDateTime(int index) { + return parentTable.isDateTime(index); + } + + @Override + public boolean isNominal(int index) { + return parentTable.isNominal(index); + } + + @Override + public boolean isNumerical(int index) { + return parentTable.isNumerical(index); + } + + @Override + public boolean isSpecial(int column) { + return parentTable.isSpecial(column); + } + + @Override + public boolean isSupportingColumnWeights() { + return parentTable.isSupportingColumnWeights(); + } + + @Override + public boolean isTime(int index) { + return parentTable.isTime(index); + } + + @Override + public String mapIndex(int column, int index) { + int parentIdx = index; + DataTableMappingProvider mapping = mappings.elementAt(column); + if (mapping != null) { + if (mapping instanceof BidirectionalMappingProvider) { + BidirectionalMappingProvider bidiMapping = (BidirectionalMappingProvider) mapping; + parentIdx = (int) bidiMapping.mapToParentValue(index); + } else { + return null; + } + } + return parentTable.mapIndex(column, parentIdx); + } + + @Override + public int mapString(int column, String value) { + int index = parentTable.mapString(column, value); + + return (int) mapValue(index, column); + } + + @Override + public DataTable sample(int newSize) { + // return parentTable.sample(newSize); + return this; + } + + @Override + public void dataTableUpdated(DataTable source) { + fireEvent(); + } + + public DataTable getParent() { + return parentTable; + } +} diff --git a/src/main/java/com/rapidminer/datatable/package.html b/src/main/java/com/rapidminer/datatable/package.html new file mode 100644 index 000000000..73fd7110f --- /dev/null +++ b/src/main/java/com/rapidminer/datatable/package.html @@ -0,0 +1,14 @@ + + + + + + + + +DataTables are the most important data container interface for RapidMiner which +are used for all statistics and plotting purposes. This package also contains +wrappers for ExampleSets, KernelModels, and other data table types. + + + diff --git a/src/main/java/com/rapidminer/example/AbstractAttributes.java b/src/main/java/com/rapidminer/example/AbstractAttributes.java new file mode 100644 index 000000000..9169b84f1 --- /dev/null +++ b/src/main/java/com/rapidminer/example/AbstractAttributes.java @@ -0,0 +1,341 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.LogService; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; + + +/** + * This is the abstract superclass for all attribute set implementations. It is sufficient for + * subclasses to overwrite the method {@link Attributes#allAttributeRoles()} and the corresponding + * add and remove methods. + * + * @author Ingo Mierswa + */ +public abstract class AbstractAttributes implements Attributes { + + private static final long serialVersionUID = -3419958538074776957L; + + @Override + public abstract Object clone(); + + @Override + public Iterator iterator() { + return new AttributeIterator(allAttributeRoles(), REGULAR); + } + + @Override + public Iterator allAttributes() { + return new AttributeIterator(allAttributeRoles(), ALL); + } + + @Override + public Iterator specialAttributes() { + return new AttributeRoleIterator(allAttributeRoles(), SPECIAL); + } + + @Override + public Iterator regularAttributes() { + return new AttributeRoleIterator(allAttributeRoles(), REGULAR); + } + + @Override + public boolean contains(Attribute attribute) { + return findAttributeRole(attribute.getName()) != null; + } + + @Override + public int allSize() { + return calculateSize(allAttributes()); + } + + @Override + public int size() { + return calculateSize(iterator()); + } + + @Override + public int specialSize() { + return calculateSize(specialAttributes()); + } + + private int calculateSize(Iterator i) { + int counter = 0; + while (i.hasNext()) { + i.next(); + counter++; + } + return counter; + } + + @Override + public void addRegular(Attribute attribute) { + add(new AttributeRole(attribute)); + } + + @Override + public boolean remove(Attribute attribute) { + AttributeRole role = getRole(attribute); + if (role != null) { + return remove(role); + } else { + return false; + } + } + + @Override + public void clearRegular() { + List toRemove = new LinkedList(); + Iterator i = allAttributeRoles(); + while (i.hasNext()) { + AttributeRole role = i.next(); + if (!role.isSpecial()) { + toRemove.add(role); + } + } + + for (AttributeRole role : toRemove) { + remove(role); + } + } + + @Override + public void clearSpecial() { + List toRemove = new LinkedList(); + Iterator i = allAttributeRoles(); + while (i.hasNext()) { + AttributeRole role = i.next(); + if (role.isSpecial()) { + toRemove.add(role); + } + } + + for (AttributeRole role : toRemove) { + remove(role); + } + } + + @Override + public Attribute replace(Attribute first, Attribute second) { + AttributeRole role = getRole(first); + if (role != null) { + role.setAttribute(second); + } else { + throw new java.util.NoSuchElementException("Attribute " + first + " cannot be replaced by attribute " + second + + ": " + first + " is not part of the example set!"); + } + return second; + } + + @Override + public Attribute get(String name) { + return get(name, true); + } + + @Override + public Attribute get(String name, boolean caseSensitive) { + AttributeRole result = findRoleByName(name, caseSensitive); + if (result == null) { + result = findRoleBySpecialName(name, caseSensitive); + } + if (result != null) { + return result.getAttribute(); + } else { + return null; + } + } + + @Override + public AttributeRole findRoleByName(String name) { + return findRoleByName(name, true); + } + + @Override + public AttributeRole findRoleBySpecialName(String specialName) { + return findRoleBySpecialName(specialName, true); + } + + @Override + public Attribute getRegular(String name) { + AttributeRole role = findRoleByName(name); + if (role != null) { + if (!role.isSpecial()) { + return role.getAttribute(); + } else { + // LogService.getGlobal().logWarning("No regular attribute with name '"+name+"' found, however, there is a special attribute with the same name."); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.AbstractAttributes.no_regular_attribute_found", name); + return null; + } + } else { + return null; + } + // return findAttribute(name, iterator()); + } + + @Override + public Attribute getSpecial(String name) { + AttributeRole role = findRoleBySpecialName(name); + if (role == null) { + return null; + } else { + return role.getAttribute(); + } + } + + @Override + public AttributeRole getRole(Attribute attribute) { + return getRole(attribute.getName()); + } + + @Override + public AttributeRole getRole(String name) { + return findAttributeRole(name); + } + + @Override + public Attribute getLabel() { + return getSpecial(LABEL_NAME); + } + + @Override + public void setLabel(Attribute label) { + setSpecialAttribute(label, LABEL_NAME); + } + + @Override + public Attribute getPredictedLabel() { + return getSpecial(PREDICTION_NAME); + } + + @Override + public Attribute getConfidence(String classLabel) { + return getSpecial(CONFIDENCE_NAME + "_" + classLabel); + } + + @Override + public void setPredictedLabel(Attribute predictedLabel) { + setSpecialAttribute(predictedLabel, PREDICTION_NAME); + } + + @Override + public Attribute getId() { + return getSpecial(ID_NAME); + } + + @Override + public void setId(Attribute id) { + setSpecialAttribute(id, ID_NAME); + } + + @Override + public Attribute getWeight() { + return getSpecial(WEIGHT_NAME); + } + + @Override + public void setWeight(Attribute weight) { + setSpecialAttribute(weight, WEIGHT_NAME); + } + + @Override + public Attribute getCluster() { + return getSpecial(CLUSTER_NAME); + } + + @Override + public void setCluster(Attribute cluster) { + setSpecialAttribute(cluster, CLUSTER_NAME); + } + + @Override + public Attribute getOutlier() { + return getSpecial(OUTLIER_NAME); + } + + @Override + public void setOutlier(Attribute outlier) { + setSpecialAttribute(outlier, OUTLIER_NAME); + } + + @Override + public Attribute getCost() { + return getSpecial(CLASSIFICATION_COST); + } + + @Override + public void setCost(Attribute cost) { + setSpecialAttribute(cost, CLASSIFICATION_COST); + } + + @Override + public void setSpecialAttribute(Attribute attribute, String specialName) { + AttributeRole oldRole = findRoleBySpecialName(specialName); + if (oldRole != null) { + remove(oldRole); + } + if (attribute != null) { + remove(attribute); + AttributeRole role = new AttributeRole(attribute); + role.setSpecial(specialName); + ; + add(role); + } + } + + @Override + public Attribute[] createRegularAttributeArray() { + int index = 0; + Attribute[] result = new Attribute[size()]; + for (Attribute attribute : this) { + result[index++] = attribute; + } + return result; + } + + /** Returns a string representation of this attribute set. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(getClass().getSimpleName() + ": "); + Iterator r = allAttributeRoles(); + boolean first = true; + while (r.hasNext()) { + if (!first) { + result.append(", "); + } + result.append(r.next()); + first = false; + } + return result.toString(); + } + + private AttributeRole findAttributeRole(String name) { + AttributeRole role = findRoleByName(name); + if (role != null) { + return role; + } else { + return findRoleBySpecialName(name); + } + } +} diff --git a/src/main/java/com/rapidminer/example/Attribute.java b/src/main/java/com/rapidminer/example/Attribute.java new file mode 100644 index 000000000..49568cc0d --- /dev/null +++ b/src/main/java/com/rapidminer/example/Attribute.java @@ -0,0 +1,207 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.NominalMapping; +import com.rapidminer.operator.Annotations; + +import java.io.Serializable; +import java.util.Iterator; + + +/** + * Attributes should hold all information about a single attribute. + *
    + *
  • the name
  • + *
  • the value type (nominal, numerical, ...)
  • + *
  • the block type (single value, time series...)
  • + *
  • a link to attribute statistics
  • + *
  • a link to a nominal value mapping (if applicable)
  • + *
  • a link to the information about how the attribute was generated
  • + *
+ * + * @author Ingo Mierswa + */ +public interface Attribute extends Cloneable, Serializable { + + /** Used to identify that this attribute is not part of any example table. */ + public static final int UNDEFINED_ATTRIBUTE_INDEX = -1; + + /** Used to identify view attributes */ + public static final int VIEW_ATTRIBUTE_INDEX = -2; + + /** + * Indicates a missing value for nominal values. For the internal values and numerical values, + * Double.NaN is used which can be checked via {@link Double#isNaN(double)}. + */ + public static final String MISSING_NOMINAL_VALUE = "?"; + + /** + * Returns true if the given object is an attribute with the same name and table index. + */ + @Override + public boolean equals(Object o); + + /** + * Returns the hash code. Please note that equal attributes must return the same hash code. + */ + @Override + public int hashCode(); + + /** Clones this attribute. */ + public Object clone(); + + // ---------------------------------------------------------------------- + + /** Returns the name of the attribute. */ + public String getName(); + + /** Sets the name of the attribute. */ + public void setName(String name); + + /** Returns the index in the example table. */ + public int getTableIndex(); + + /** Sets the index in the example table. */ + public void setTableIndex(int index); + + // ---------------------------------------------------------------------- + + /** + * Sets the Attributes instance to which this attribute belongs. This instance will be notified + * when the attribute renames itself. This method must not be called except by the + * {@link Attributes} to which this AttributeRole is added. + */ + public void addOwner(Attributes attributes); + + public void removeOwner(Attributes attributes); + + // ---------------------------------------------------------------------- + + /** Returns the value for the column this attribute corresponds to in the given data row. */ + public double getValue(DataRow row); + + /** Sets the value for the column this attribute corresponds to in the given data row. */ + public void setValue(DataRow row, double value); + + public void addTransformation(AttributeTransformation transformation); + + public AttributeTransformation getLastTransformation(); + + /** Clear all transformations. */ + public void clearTransformations(); + + // ---------------------------------------------------------------------- + + /** + * Returns an iterator over all statistics objects available for this type of attribute. + * Additional statistics can be registered via {@link #registerStatistics(Statistics)}. + */ + public Iterator getAllStatistics(); + + /** Registers the attribute statistics. */ + public void registerStatistics(Statistics statistics); + + /** + * Returns the attribute statistics. + * + * @deprecated Please use the method {@link ExampleSet#getStatistics(Attribute, String)} + * instead. + */ + @Deprecated + public double getStatistics(String statisticsName); + + /** + * Returns the attribute statistics with the given parameter. + * + * @deprecated Please use the method {@link ExampleSet#getStatistics(Attribute, String, String)} + * instead. + */ + @Deprecated + public double getStatistics(String statisticsName, String parameter); + + /** Returns the construction description. */ + public String getConstruction(); + + /** Sets the construction description. */ + public void setConstruction(String description); + + /** + * Returns the nominal mapping between nominal values and internal double representations. + * Please note that invoking this method might result in an + * {@link UnsupportedOperationException} for non-nominal attributes. + */ + public NominalMapping getMapping(); + + /** + * Returns the nominal mapping between nominal values and internal double representations. + * Please note that invoking this method might result in an exception for non-nominal + * attributes. + */ + public void setMapping(NominalMapping nominalMapping); + + // ---------------------------------------------------------------------- + + /** + * Returns the block type of this attribute. + * + * @see com.rapidminer.tools.Ontology#ATTRIBUTE_BLOCK_TYPE + */ + public int getBlockType(); + + /** + * Sets the block type of this attribute. + * + * @see com.rapidminer.tools.Ontology#ATTRIBUTE_BLOCK_TYPE + */ + public void setBlockType(int b); + + /** + * Returns the value type of this attribute. + * + * @see com.rapidminer.tools.Ontology#ATTRIBUTE_VALUE_TYPE + */ + public int getValueType(); + + /** Returns a human readable string that describes this attribute. */ + @Override + public String toString(); + + /** Sets the default value for this attribute. */ + public void setDefault(double value); + + /** Returns the default value for this attribute. */ + public double getDefault(); + + /** Returns true if the attribute is nominal. */ + public boolean isNominal(); + + /** Returns true if the attribute is numerical. */ + public boolean isNumerical(); + + /** Returns true if the attribute is date_time. */ + public boolean isDateTime(); + + /** Returns a formatted string of the given value according to the attribute type. */ + public String getAsString(double value, int digits, boolean quoteNominal); + + /** Returns a set of annotations for this attribute. */ + public Annotations getAnnotations(); +} diff --git a/src/main/java/com/rapidminer/example/AttributeDescription.java b/src/main/java/com/rapidminer/example/AttributeDescription.java new file mode 100644 index 000000000..6684fe46f --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeDescription.java @@ -0,0 +1,137 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.Ontology; + +import java.io.Serializable; + + +/** + * This class holds all basic information about an attribute. This is useful since a cloned + * attribute can simply use the same reference to a description object wihtout the need of cloning + * all information. This reduces the amount of used memory due to attribute clones. + * + * @author Ingo Mierswa + */ +public class AttributeDescription implements Serializable { + + private static final long serialVersionUID = 8641898727515830321L; + + /** The name of the attribute. */ + private String name; + + /** + * An int indicating the value type in terms of the Ontology.ATTRIBUTE_VALUE_TYPE. + */ + private int valueType = Ontology.ATTRIBUTE_VALUE; + + /** + * An int indicating the block type in terms of the Ontology.ATTRIBUTE_BLOCK_TYPE. + */ + private int blockType = Ontology.ATTRIBUTE_BLOCK; + + /** The default value for this Attribute. */ + private double defaultValue = 0.0; + + /** Index of this attribute in its ExampleTable. */ + private int index = Attribute.UNDEFINED_ATTRIBUTE_INDEX; + + public AttributeDescription(Attribute attribute, String name, int valueType, int blockType, double defaultValue, + int tableIndex) { + this.name = name; + this.valueType = valueType; + this.blockType = blockType; + this.defaultValue = defaultValue; + this.index = tableIndex; + + } + + private AttributeDescription(AttributeDescription other) { + this.name = other.name; + this.valueType = other.valueType; + this.blockType = other.blockType; + this.defaultValue = other.defaultValue; + this.index = other.index; + } + + @Override + public Object clone() { + return new AttributeDescription(this); + } + + public String getName() { + return this.name; + } + + public void setName(String newName) { + this.name = newName; + } + + public int getValueType() { + return this.valueType; + } + + public int getBlockType() { + return this.blockType; + } + + public void setBlockType(int b) { + this.blockType = b; + } + + public double getDefault() { + return this.defaultValue; + } + + public void setDefault(double defaultValue) { + this.defaultValue = defaultValue; + } + + public int getTableIndex() { + return this.index; + } + + public void setTableIndex(int i) { + this.index = i; + } + + /** + * Returns true if the given attribute has the same name and the same table index. + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof AttributeDescription)) { + return false; + } + AttributeDescription a = (AttributeDescription) o; + if (!this.name.equals(a.getName())) { + return false; + } + if (this.index != a.getTableIndex()) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return name.hashCode() ^ Integer.valueOf(this.index).hashCode(); + } +} diff --git a/src/main/java/com/rapidminer/example/AttributeIterator.java b/src/main/java/com/rapidminer/example/AttributeIterator.java new file mode 100644 index 000000000..46ec43489 --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeIterator.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.Iterator; + + +/** + * Iterates over either only the regular attribute, only the special attributes, or over all all + * attributes. + * + * @author Ingo Mierswa + */ +public class AttributeIterator implements Iterator { + + private Iterator parent; + + private int type = Attributes.REGULAR; + + private Attribute current = null; + + private boolean hasNextInvoked = false; + + private AttributeRole currentRole = null; + + public AttributeIterator(Iterator parent, int type) { + this.parent = parent; + this.type = type; + } + + @Override + public boolean hasNext() { + this.hasNextInvoked = true; + if (!parent.hasNext() && currentRole == null) { + current = null; + return false; + } else { + AttributeRole role; + if (currentRole == null) { + role = parent.next(); + } else { + role = currentRole; + } + switch (type) { + case Attributes.REGULAR: + if (!role.isSpecial()) { + current = role.getAttribute(); + currentRole = role; + return true; + } else { + return hasNext(); + } + case Attributes.SPECIAL: + if (role.isSpecial()) { + current = role.getAttribute(); + currentRole = role; + return true; + } else { + return hasNext(); + } + case Attributes.ALL: + current = role.getAttribute(); + currentRole = role; + return true; + default: + current = null; + return false; + } + } + } + + @Override + public Attribute next() { + if (!this.hasNextInvoked) { + hasNext(); + } + this.hasNextInvoked = false; + this.currentRole = null; + return current; + } + + @Override + public void remove() { + parent.remove(); + this.currentRole = null; + this.hasNextInvoked = false; + } +} diff --git a/src/main/java/com/rapidminer/example/AttributeRole.java b/src/main/java/com/rapidminer/example/AttributeRole.java new file mode 100644 index 000000000..2d254599f --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeRole.java @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; + + +/** + * This class holds the example set relevant information about a table attribute, i.e. its role + * (either regular or special). If the described attribute is a special attribute, this class also + * contains the corresponding special attribute name. + * + * @author Ingo Mierswa + */ +public class AttributeRole implements Serializable { + + private static final long serialVersionUID = -4855352048163007173L; + + private boolean special = false; + + private String specialName = null; + + private Attribute attribute; + + private transient List owners = new LinkedList(); + + public AttributeRole(Attribute attribute) { + this.attribute = attribute; + } + + /** Clone constructor. */ + private AttributeRole(AttributeRole other) { + this.attribute = (Attribute) other.attribute.clone(); + this.special = other.special; + this.specialName = other.specialName; + } + + public Object readResolve() { + if (owners == null) { + owners = new LinkedList(); + } + return this; + } + + /** Performs a deep clone of the special fields but only a shallow clone of the attribute. */ + @Override + public Object clone() { + return new AttributeRole(this); + } + + /** + * This method must not be called except by the {@link Attributes} to which this AttributeRole + * is added. + */ + protected void addOwner(Attributes attributes) { + this.owners.add(attributes); + } + + /** + * This method must not be called except by the {@link Attributes} to which this AttributeRole + * is added. + */ + protected void removeOwner(Attributes attributes) { + this.owners.remove(attributes); + } + + public Attribute getAttribute() { + return attribute; + } + + public void setAttribute(Attribute attribute) { + this.attribute = attribute; + } + + public boolean isSpecial() { + return special; + } + + public String getSpecialName() { + return specialName; + } + + public void setSpecial(String specialName) { + for (Attributes attributes : owners) { + attributes.rename(this, specialName); + } + this.specialName = specialName; + if (specialName != null) { + this.special = true; + } else { + this.special = false; + } + } + + public void changeToRegular() { + setSpecial(null); + } + + @Override + public String toString() { + if (isSpecial()) { + return specialName + " := " + attribute.getName(); + } else { + return attribute.getName(); + } + } +} diff --git a/src/main/java/com/rapidminer/example/AttributeRoleIterator.java b/src/main/java/com/rapidminer/example/AttributeRoleIterator.java new file mode 100644 index 000000000..951d362fb --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeRoleIterator.java @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.Iterator; + + +/** + * An iterator for attribute roles which is able to iterate over all attributes or skip either + * regular or special attributes. + * + * @author Ingo Mierswa + */ +public class AttributeRoleIterator implements Iterator { + + private Iterator parent; + + private int type = Attributes.REGULAR; + + private AttributeRole current = null; + + public AttributeRoleIterator(Iterator parent, int type) { + this.parent = parent; + this.type = type; + } + + @Override + public boolean hasNext() { + while ((current == null) && (parent.hasNext())) { + AttributeRole candidate = parent.next(); + switch (type) { + case Attributes.REGULAR: + if (!candidate.isSpecial()) { + current = candidate; + } + break; + case Attributes.SPECIAL: + if (candidate.isSpecial()) { + current = candidate; + } + break; + case Attributes.ALL: + current = candidate; + break; + default: + break; + } + } + return current != null; + } + + @Override + public AttributeRole next() { + hasNext(); + AttributeRole returnValue = current; + current = null; + return returnValue; + } + + @Override + public void remove() { + parent.remove(); + this.current = null; + } +} diff --git a/src/main/java/com/rapidminer/example/AttributeTransformation.java b/src/main/java/com/rapidminer/example/AttributeTransformation.java new file mode 100644 index 000000000..0e34515b4 --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeTransformation.java @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.io.Serializable; + + +/** + * This interface is used to define on-the-fly transformations in data views. + * + * @author Ingo Mierswa + */ +public interface AttributeTransformation extends Serializable { + + public Object clone(); + + public double transform(Attribute attribute, double value); + + public double inverseTransform(Attribute attribute, double value); + + public boolean isReversable(); + +} diff --git a/src/main/java/com/rapidminer/example/AttributeTypeException.java b/src/main/java/com/rapidminer/example/AttributeTypeException.java new file mode 100644 index 000000000..6c38c50b7 --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeTypeException.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +/** + * This exception will be thrown if operators use properties of attributes which are not supported + * by this attribute, for example, if a nominal mapping of the third value is retrieved from a + * binominal attribute. + * + * @author Ingo Mierswa + */ +public class AttributeTypeException extends RuntimeException { + + private static final long serialVersionUID = -990113662782113571L; + + public AttributeTypeException(String message) { + super(message); + } +} diff --git a/src/main/java/com/rapidminer/example/AttributeWeight.java b/src/main/java/com/rapidminer/example/AttributeWeight.java new file mode 100644 index 000000000..5eba05a7d --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeWeight.java @@ -0,0 +1,134 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.math.Averagable; + + +/** + * Helper class containing the name of an attribute and the corresponding weight. + * + * @author Ingo Mierswa + */ +public class AttributeWeight extends Averagable implements Comparable { + + private static final long serialVersionUID = 4459877599722270416L; + + /** The name of the attribute. */ + private String name; + + /** The weight of the attribute. */ + private double weight; + + /** A counter for building averages. */ + private int counter = 1; + + /** The parent attribute weights. */ + private AttributeWeights weights; + + /** Creates a new attribute weight object. */ + public AttributeWeight(AttributeWeights weights, String name, double weight) { + this.weights = weights; + this.name = name; + this.weight = weight; + } + + /** + * Clone constructor. The name and the weight are deep cloned, the reference to the + * AttributeWeights object is only a shallow copy. + */ + public AttributeWeight(AttributeWeight attWeight) { + super(attWeight); + this.weights = attWeight.weights; + this.name = attWeight.name; + this.weight = attWeight.weight; + } + + /** Returns the name of the attribute. */ + @Override + public String getName() { + return name; + } + + /** Returns the weight of the attribute. */ + public double getWeight() { + return weight / counter; + } + + /** Sets the weight of the attribute. */ + public void setWeight(double weight) { + this.weight = weight; + } + + /** + * Returns the MakroVariance since no other micro variance can be calculated. + */ + @Override + public double getMikroVariance() { + return getMakroVariance(); + } + + /** Returns the current weight. */ + @Override + public double getMikroAverage() { + return getWeight() / counter; + } + + /** + * Compares the weight of this object with the weight of another AttributeWeight object. May + * also use the absolute weight. + */ + @Override + public int compareTo(AttributeWeight o) { + double w1 = weight; + double w2 = o.weight; + + assert (weights == o.weights); + if (weights.getWeightType() == AttributeWeights.ABSOLUTE_WEIGHTS) { + w1 = Math.abs(w1); + w2 = Math.abs(w2); + } + + return Double.compare(w1, w2) * weights.getSortingType(); + } + + /** Returns true if both objects have the same name and the same weight. */ + @Override + public boolean equals(Object o) { + if (!(o instanceof AttributeWeight)) { + return false; + } + AttributeWeight w = (AttributeWeight) o; + return this.name.equals(w.name) && (this.weight == w.weight); + } + + @Override + public int hashCode() { + long bits = Double.doubleToLongBits(this.weight); + return this.name.hashCode() ^ ((int) (bits ^ bits >>> 32)); + } + + /** Builds the sum of weights and counters. */ + @Override + public void buildSingleAverage(Averagable avg) { + AttributeWeight other = (AttributeWeight) avg; + this.weight += other.weight; + this.counter += other.counter; + } +} diff --git a/src/main/java/com/rapidminer/example/AttributeWeights.java b/src/main/java/com/rapidminer/example/AttributeWeights.java new file mode 100644 index 000000000..e09eeed13 --- /dev/null +++ b/src/main/java/com/rapidminer/example/AttributeWeights.java @@ -0,0 +1,396 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.RapidMiner; +import com.rapidminer.datatable.DataTable; +import com.rapidminer.datatable.SimpleDataTable; +import com.rapidminer.datatable.SimpleDataTableRow; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.math.AverageVector; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + + +/** + * AttributeWeights holds the information about the weights of attributes of an example set. It is + * delivered by several feature weighting algorithms or learning schemes. The use of a linked hash + * map ensures that the added features are stored in the same sequence they were added. + * + * @author Ingo Mierswa + */ +public class AttributeWeights extends AverageVector { + + private static final long serialVersionUID = 7000978931118131854L; + + /** Indicates that the weights should not be sorted at all. */ + public static final int NO_SORTING = 0; + + /** Indicates that the weights should be sorted in descending order. */ + public static final int DECREASING = -1; + + /** Indicates that the weights should be sorted in ascending order. */ + public static final int INCREASING = 1; + + /** Indicates that the the actual weights should be used for sorting. */ + public static final int ORIGINAL_WEIGHTS = 0; + + /** Indicates that the the absolute weights should be used for sorting. */ + public static final int ABSOLUTE_WEIGHTS = 1; + + /** This comparator sorts the names of attributes according to their weights. */ + private class WeightComparator implements Comparator { + + /** Indicates if absolute weights should be used for sorting. */ + private final int comparatorWeightType; + + /** Indicates the sorting direction. */ + private final int direction; + + /** Creates a new weight comparator. */ + public WeightComparator(int direction, int comparatorWeightType) { + this.comparatorWeightType = comparatorWeightType; + this.direction = direction; + } + + /** Creates two attribute weights. */ + @Override + public int compare(String o1, String o2) { + double w1 = weightMap.get(o1).getWeight(); + double w2 = weightMap.get(o2).getWeight(); + + if (comparatorWeightType == ABSOLUTE_WEIGHTS) { + w1 = Math.abs(w1); + w2 = Math.abs(w2); + } + + return Double.compare(w1, w2) * direction; + } + } + + // ================================================================================ + + /** Indicates the type of sorting. */ + private int sortType = NO_SORTING; + + /** Indicates if absolute or actual weights should be used for sorting. */ + private int weightType = ORIGINAL_WEIGHTS; + + /** Maps the name of an attribute to the corresponding attribute weight. */ + private Map weightMap = new LinkedHashMap<>(); + + /** Creates a new empty attribute weights object. */ + public AttributeWeights() {} + + /** + * Creates a new attribute weights object containing a weight of 1 for each of the given input + * attributes. + */ + public AttributeWeights(ExampleSet exampleSet) { + for (Attribute attribute : exampleSet.getAttributes()) { + setWeight(attribute.getName(), 1.0d); + } + } + + /** Clone constructor. */ + private AttributeWeights(AttributeWeights weights) { + super(); + Iterator i = weights.getAttributeNames().iterator(); + while (i.hasNext()) { + String name = (String) i.next(); + this.setWeight(name, weights.getWeight(name)); + } + cloneAnnotationsFrom(weights); + } + + /** Returns the name of this AverageVector. */ + @Override + public String getName() { + return "AttributeWeights"; + } + + /** Sets the weight for the attribute with the given name. */ + public void setWeight(String name, double weight) { + AttributeWeight oldWeight = weightMap.get(name); + if (Double.isNaN(weight)) { + weightMap.remove(name); + super.removeAveragable(oldWeight); + } else if (oldWeight == null) { + AttributeWeight attWeight = new AttributeWeight(this, name, weight); + super.addAveragable(attWeight); + weightMap.put(name, attWeight); + } else { + oldWeight.setWeight(weight); + } + } + + /** + * Returns the weight for the attribute with the given name. Returns Double.NaN if the weight + * for the queried attribute is not known. + */ + public double getWeight(String name) { + AttributeWeight weight = weightMap.get(name); + if (weight == null) { + return Double.NaN; + } else { + return weight.getWeight(); + } + } + + /** Returns the currently used weight type. */ + public int getWeightType() { + return weightType; + } + + /** Returns the currently used weight type. */ + public void setWeightType(int weightType) { + this.weightType = weightType; + } + + /** Returns the currently used sorting type. */ + public int getSortingType() { + return sortType; + } + + /** Sets the currently used sorting type. */ + public void setSortingType(int sortingType) { + this.sortType = sortingType; + } + + /** Returns the number of features in this map. */ + @Override + public int size() { + return weightMap.size(); + } + + /** + * This method removes the given attribute weight from this object. + */ + public void removeAttributeWeight(String attributeName) { + this.weightMap.remove(attributeName); + } + + /** + * Returns an set of attribute names in this map ordered by their insertion time. + */ + public Set getAttributeNames() { + return weightMap.keySet(); + } + + /** + * Since this average vector cannot be compared this method always returns 0. + */ + @Override + public int compareTo(Object o) { + return 0; + } + + /** Returns true if both objects have the same weight map. */ + @Override + public boolean equals(Object o) { + if (!(o instanceof AttributeWeights)) { + return false; + } else { + AttributeWeights other = (AttributeWeights) o; + return this.weightMap.equals(other.weightMap); + } + } + + /** Returns the hash code of the weight map. */ + @Override + public int hashCode() { + return this.weightMap.hashCode(); + } + + /** + * Sorts the given array of attribute names according to their weight, the sorting direction + * (ascending or descending), and with respect to the fact if original or absolute weights + * should be used. Ascending means that the attributes with the smallest weights come first. + * + * @param direction + * INCREASING or DECREASING + * @param comparatorType + * WEIGHT or WEIGHT_ABSOLUTE. + */ + public void sortByWeight(String[] attributeNames, int direction, int comparatorType) { + Arrays.sort(attributeNames, new WeightComparator(direction, comparatorType)); + } + + /** + * This will sort the weights either ascending if the boolean flag is true or descending. * @param + * direction ASCENDING or DESCENDING + * + * @param comparatorType + * WEIGHT or WEIGHT_ABSOLUTE. + */ + public void sort(int direction, int comparatorType) { + Map newWeightMap = new LinkedHashMap<>(); + ArrayList attributes = new ArrayList<>(weightMap.keySet()); + Collections.sort(attributes, new WeightComparator(direction, comparatorType)); + for (String attributeName : attributes) { + newWeightMap.put(attributeName, weightMap.get(attributeName)); + } + weightMap = newWeightMap; + } + + /** Saves the attribute weights into an XML file. */ + public void save(File file) throws IOException { + writeAttributeWeights(file, Tools.getDefaultEncoding()); + } + + public void writeAttributeWeights(File file, Charset encoding) throws IOException { + PrintWriter out = null; + try { + out = new PrintWriter(new FileWriter(file)); + out.println(""); + out.println(""); + Iterator i = weightMap.keySet().iterator(); + while (i.hasNext()) { + String key = (String) i.next(); + double weight = weightMap.get(key).getWeight(); + out.println(" "); + } + out.println(""); + } catch (IOException e) { + throw e; + } finally { + if (out != null) { + out.close(); + } + } + } + + /** Loads a new AttributeWeights object from the given XML file. */ + public static AttributeWeights load(File file) throws IOException { + AttributeWeights result = new AttributeWeights(); + Document document = null; + try { + document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file); + } catch (SAXException e1) { + throw new IOException(e1.getMessage()); + } catch (ParserConfigurationException e1) { + throw new IOException(e1.getMessage()); + } + + Element attributeWeightsElement = document.getDocumentElement(); + if (!attributeWeightsElement.getTagName().equals("attributeweights")) { + throw new IOException("Outer tag of attribute weights file must be "); + } + + NodeList weights = attributeWeightsElement.getChildNodes(); + for (int i = 0; i < weights.getLength(); i++) { + Node node = weights.item(i); + if (node instanceof Element) { + Element weightTag = (Element) node; + String tagName = weightTag.getTagName(); + if (!tagName.equals("weight")) { + throw new IOException("Only tags are allowed, was " + tagName); + } + String name = weightTag.getAttribute("name"); + String value = weightTag.getAttribute("value"); + double weight = 1.0d; + try { + weight = Double.parseDouble(value); + } catch (NumberFormatException e) { + throw new IOException("Only numerical weights are allowed for the 'value' attribute."); + } + result.setWeight(name, weight); + } + } + return result; + } + + public String getExtension() { + return "wgt"; + } + + public String getFileDescription() { + return "attribute weights file"; + } + + /** Returns a string representation of this object. */ + @Override + public String toString() { + return "AttributeWeights (containing weights for " + weightMap.size() + " attributes)"; + } + + /** + * Returns a deep clone of the attribute weights which provides the same sequence of attribute + * names. + */ + @Override + public Object clone() { + return new AttributeWeights(this); + } + + /** This method normalizes all weights to the range 0 to 1. */ + public void normalize() { + double weightMin = Double.POSITIVE_INFINITY; + double weightMax = Double.NEGATIVE_INFINITY; + for (String name : getAttributeNames()) { + double weight = Math.abs(getWeight(name)); + weightMin = Math.min(weightMin, weight); + weightMax = Math.max(weightMax, weight); + } + Iterator w = weightMap.values().iterator(); + double diff = weightMax - weightMin; + while (w.hasNext()) { + AttributeWeight attributeWeight = w.next(); + double newWeight = 1.0d; + if (diff != 0.0d) { + newWeight = (Math.abs(attributeWeight.getWeight()) - weightMin) / diff; + } + attributeWeight.setWeight(newWeight); + } + } + + public DataTable createDataTable() { + DataTable dataTable = new SimpleDataTable("Attribute Weights", new String[] { "attribute", "weight" }); + for (Map.Entry entry : weightMap.entrySet()) { + String attName = entry.getKey(); + AttributeWeight attWeight = entry.getValue(); + double index = dataTable.mapString(0, attName); + double weightValue = attWeight.getWeight(); + double[] data = new double[] { index, weightValue }; + dataTable.add(new SimpleDataTableRow(data, attName)); + } + return dataTable; + } +} diff --git a/src/main/java/com/rapidminer/example/Attributes.java b/src/main/java/com/rapidminer/example/Attributes.java new file mode 100644 index 000000000..edd7c5843 --- /dev/null +++ b/src/main/java/com/rapidminer/example/Attributes.java @@ -0,0 +1,300 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.io.Serializable; +import java.util.Iterator; + + +/** + * This container holds all information about the example set attributes. Implementors might want to + * override {@link com.rapidminer.example.AbstractAttributes} for which only one of the iterating + * methods must be overridden. + * + * @author Ingo Mierswa + */ +public interface Attributes extends Iterable, Cloneable, Serializable { + + /** Indicates regular attributes. */ + public static final int REGULAR = 0; + + /** Indicates special attributes. */ + public static final int SPECIAL = 1; + + /** Indicates all attributes. */ + public static final int ALL = 2; + + /** The name of the confidence special attributes. */ + public static final String CONFIDENCE_NAME = "confidence"; + + /** The name of regular attributes. */ + public static final String ATTRIBUTE_NAME = "attribute"; + + /** The name of the special attribute id. */ + public static final String ID_NAME = "id"; + + /** The name of the special attribute label. */ + public static final String LABEL_NAME = "label"; + + /** The name of the special attribute prediction. */ + public static final String PREDICTION_NAME = "prediction"; + + /** The name of the special attribute cluster. */ + public static final String CLUSTER_NAME = "cluster"; + + /** The name of the special attribute weight (example weights). */ + public static final String WEIGHT_NAME = "weight"; + + /** The name of the special attribute batch. */ + public static final String BATCH_NAME = "batch"; + + /** The name of the special attribute outlier. */ + public static final String OUTLIER_NAME = "outlier"; + + /** The name of the classification cost special attribute. */ + public static final String CLASSIFICATION_COST = "cost"; + + /** The name of the classification cost special attribute. */ + public static final String BASE_VALUE = "base_value"; + + /** All known names of regular and special attribute types as an array. */ + public static final String[] KNOWN_ATTRIBUTE_TYPES = new String[] { ATTRIBUTE_NAME, LABEL_NAME, ID_NAME, WEIGHT_NAME, + BATCH_NAME, CLUSTER_NAME, PREDICTION_NAME, OUTLIER_NAME, CLASSIFICATION_COST, BASE_VALUE }; + + /** Indicates a regular attribute type. */ + public static final int TYPE_ATTRIBUTE = 0; + + /** Indicates the special attribute type label. */ + public static final int TYPE_LABEL = 1; + + /** Indicates the special attribute type id. */ + public static final int TYPE_ID = 2; + + /** Indicates the special attribute type weight (example weights). */ + public static final int TYPE_WEIGHT = 3; + + /** Indicates the special attribute type batch (example batches). */ + public static final int TYPE_BATCH = 4; + + /** Indicates the special attribute type cluster. */ + public static final int TYPE_CLUSTER = 5; + + /** Indicates the special attribute type prediction. */ + public static final int TYPE_PREDICTION = 6; + + /** Indicates the special attribute type outlier. */ + public static final int TYPE_OUTLIER = 7; + + /** Indicates the special attribute type cost. */ + public static final int TYPE_COST = 8; + + /** Indicates the special attribute type base_value. */ + public static final int TYPE_BASE_VALUE = 9; + + /** Returns a clone of this attribute set. */ + public Object clone(); + + /** Returns true if the given object is equal to this attribute set. */ + @Override + public boolean equals(Object o); + + /** Returns the hash code of this attribute set. */ + @Override + public int hashCode(); + + /** Iterates over all regular attributes. */ + @Override + public Iterator iterator(); + + /** Returns an iterator over all attributes, including the special attributes. */ + public Iterator allAttributes(); + + /** Returns an iterator over all attribute roles, including the special attribute roles. */ + public Iterator allAttributeRoles(); + + /** Returns an iterator over the attribute roles of the special attributes. */ + public Iterator specialAttributes(); + + /** Returns an iterator over the attribute roles of the regular attributes. */ + public Iterator regularAttributes(); + + /** Returns true if this attribute set contains the given attribute. */ + public boolean contains(Attribute attribute); + + /** Returns the number of regular attributes. */ + public int size(); + + /** Returns the number of special attributes. */ + public int specialSize(); + + /** Returns the number of all attributes, i.e. of the regular and the special attributes. */ + public int allSize(); + + /** Adds a new attribute role. */ + public void add(AttributeRole attributeRole); + + /** Adds the given attribute as regular attribute. */ + public void addRegular(Attribute attribute); + + /** Removes the given attribute role. */ + public boolean remove(AttributeRole attributeRole); + + /** Removes the given attribute. */ + public boolean remove(Attribute attribute); + + /** Removes all regular attributes. */ + public void clearRegular(); + + /** Removes all special attributes. */ + public void clearSpecial(); + + /** Replaces the first attribute by the second. Returns the second attribute. */ + public Attribute replace(Attribute first, Attribute second); + + /** Returns the attribute for the given name. The search is case sensitive. */ + public Attribute get(String name); + + /** + * Returns the attribute for the given name. If the search is performed case sensitive depends + * on the boolean parameter. Please keep in mind that case insensitive search is not optimized + * and will take linear time to number of attributes. + * */ + public Attribute get(String name, boolean caseSensitive); + + /** Returns the regular attribute for the given name. */ + public Attribute getRegular(String name); + + /** Returns the special attribute for the given special name. */ + public Attribute getSpecial(String name); + + /** Returns the attribute role for the given attribute. */ + public AttributeRole getRole(Attribute attribute); + + /** Returns the attribute role for the given name. */ + public AttributeRole getRole(String name); + + /** Returns the label attribute or null if no label attribute is defined. */ + public Attribute getLabel(); + + /** Sets the label attribute. If the given attribute is null, no label attribute will be used. */ + public void setLabel(Attribute label); + + /** Returns the predicted label attribute or null if no label attribute is defined. */ + public Attribute getPredictedLabel(); + + /** + * This method will return the confidence attribute of the given class or null if no confidence + * attribute exists for this class + */ + public Attribute getConfidence(String classLabel); + + /** + * Sets the predicted label attribute. If the given attribute is null, no predicted label + * attribute will be used. + */ + public void setPredictedLabel(Attribute predictedLabel); + + /** Returns the id attribute or null if no label attribute is defined. */ + public Attribute getId(); + + /** Sets the id attribute. If the given attribute is null, no id attribute will be used. */ + public void setId(Attribute id); + + /** Returns the weight attribute or null if no label attribute is defined. */ + public Attribute getWeight(); + + /** Sets the weight attribute. If the given attribute is null, no weight attribute will be used. */ + public void setWeight(Attribute weight); + + /** Returns the cluster attribute or null if no label attribute is defined. */ + public Attribute getCluster(); + + /** + * Sets the cluster attribute. If the given attribute is null, no cluster attribute will be + * used. + */ + public void setCluster(Attribute cluster); + + /** Returns the outlier attribute or null if no label attribute is defined. */ + public Attribute getOutlier(); + + /** + * Sets the outlier attribute. If the given attribute is null, no outlier attribute will be + * used. + */ + public void setOutlier(Attribute outlier); + + /** Returns the cost attribute or null if no label attribute is defined. */ + public Attribute getCost(); + + /** Sets the cost attribute. If the given attribute is null, no cost attribute will be used. */ + public void setCost(Attribute cost); + + /** + * Sets the special attribute for the given name. If the given attribute is null, no special + * attribute with this name will be used. + */ + public void setSpecialAttribute(Attribute attribute, String specialName); + + /** + * This method creates an attribute array from all regular attributes. ATTENTION: This method + * should only be used if it is ensured that the attribute roles and number of attributes cannot + * be changed, otherwise the delivered array will not be synchronized with the attribute roles + * object. Therefore, the iterator methods of this class should be preferred. + */ + public Attribute[] createRegularAttributeArray(); + + /** Returns a string representation of this attribute set. */ + @Override + public String toString(); + + /** + * Finds the {@link AttributeRole} belonging to the attribute with the given name (both regular + * and special). Search is performed case sensitive. + */ + public AttributeRole findRoleByName(String name); + + /** + * Finds the {@link AttributeRole} belonging to the attribute with the given name (both regular + * and special). If the search is performed case sensitive depends on the boolean parameter. + * Attention: Case insensitive search is not optimized and takes linear time with number of + * attributes. + */ + public AttributeRole findRoleByName(String name, boolean caseSensitive); + + /** Finds the {@link AttributeRole} with the given special name (both regular and special). */ + public AttributeRole findRoleBySpecialName(String specialName); + + /** + * Finds the {@link AttributeRole} with the given special name (both regular and special). If + * the search is performed case sensitive depends on the boolean parameter. Attention: Case + * insensitive search is not optimized and takes linear time with number of attributes. + */ + public AttributeRole findRoleBySpecialName(String specialName, boolean caseSensitive); + + /** @see #rename(Attribute, String) */ + public void rename(AttributeRole attributeRole, String newSpecialName); + + /** + * Notifies the Attributes that this attribute will rename itself to the given name immediately + * after this method returns. + */ + public void rename(Attribute attribute, String newName); + +} diff --git a/src/main/java/com/rapidminer/example/DelegateAttributes.java b/src/main/java/com/rapidminer/example/DelegateAttributes.java new file mode 100644 index 000000000..9b688c301 --- /dev/null +++ b/src/main/java/com/rapidminer/example/DelegateAttributes.java @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.Iterator; + + +/** + * This class delegates all method calls to the delegate object. Subclasses might want to override + * only some of the methods. + * + * @author Ingo Mierswa + * @deprecated Please extend {@link AbstractAttributes} instead since using this class might lead to + * stack overflow errors in cases where a large amount of iterations is performed + */ +@Deprecated +public class DelegateAttributes extends AbstractAttributes { + + private static final long serialVersionUID = 8476188336349012916L; + + protected Attributes delegate; + + public DelegateAttributes(Attributes delegate) { + this.delegate = delegate; + } + + private DelegateAttributes(DelegateAttributes roles) { + this.delegate = (Attributes) roles.delegate.clone(); + } + + @Override + public void add(AttributeRole attributeRole) { + this.delegate.add(attributeRole); + } + + @Override + public boolean remove(AttributeRole attributeRole) { + return this.delegate.remove(attributeRole); + } + + /** This method is usually overridden by subclasses. */ + @Override + public Iterator allAttributeRoles() { + return this.delegate.allAttributeRoles(); + } + + @Override + public Object clone() { + return new DelegateAttributes(this); + } + + @Override + public AttributeRole findRoleByName(String name, boolean caseSensitive) { + return delegate.findRoleByName(name, caseSensitive); + } + + @Override + public AttributeRole findRoleBySpecialName(String specialName, boolean caseSensitive) { + return delegate.findRoleBySpecialName(specialName, caseSensitive); + } + + @Override + public void rename(AttributeRole attributeRole, String newName) { + delegate.rename(attributeRole, newName); + } + + @Override + public void rename(Attribute attribute, String newName) { + delegate.rename(attribute, newName); + } +} diff --git a/src/main/java/com/rapidminer/example/Example.java b/src/main/java/com/rapidminer/example/Example.java new file mode 100644 index 000000000..bfdb41c40 --- /dev/null +++ b/src/main/java/com/rapidminer/example/Example.java @@ -0,0 +1,477 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.example.table.NumericalAttribute; +import com.rapidminer.example.table.SparseFormatDataRowReader; +import com.rapidminer.tools.Ontology; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + + +/** + * An example consists of a DataRow and some convenience methods to access the data. Hence, all + * values are actually doubles, symbolic values are mapped to integers stored in doubles.
+ * Since {@link ExampleSet}s are only a view on {@link ExampleTable}s, Examples are generated on the + * fly by {@link ExampleReader}s. Since they only contain the currently selected attributes + * operators need not to consider attribute selections or example subsets (samplings). + * + * @author Ingo Mierswa + */ +public class Example implements Serializable, Map { + + private static final long serialVersionUID = 7761687908683290928L; + + /** Separator used in the getAttributesAsString() method (tab). */ + public static final String SEPARATOR = " "; + + /** Separates indices from values in sparse format (colon). */ + public static final String SPARSE_SEPARATOR = ":"; + + /** The data for this example. */ + private DataRow data; + + /** The parent example set holding all attribute information for this data row. */ + private ExampleSet parentExampleSet; + + /** + * Creates a new Example that uses the data stored in a DataRow. The attributes correspond to + * the regular and special attributes. + */ + public Example(DataRow data, ExampleSet parentExampleSet) { + this.data = data; + this.parentExampleSet = parentExampleSet; + } + + /** Returns the data row which backs up the example in the example table. */ + public DataRow getDataRow() { + return this.data; + } + + /** Delivers the attributes. */ + public Attributes getAttributes() { + return this.parentExampleSet.getAttributes(); + } + + // -------------------------------------------------------------------------------- + + /** + * Returns the value of attribute a. In the case of nominal attributes, the delivered double + * value corresponds to an internal index + */ + public double getValue(Attribute a) { + return data.get(a); + } + + /** + * Returns the nominal value for the given attribute. + * + * @throws AttributeTypeException + * if the given attribute has the wrong value type + */ + public String getNominalValue(Attribute a) { + if (!a.isNominal()) { + throw new AttributeTypeException("Extraction of nominal example value for non-nominal attribute '" + a.getName() + + "' is not possible."); + } + double value = getValue(a); + if (Double.isNaN(value)) { + return Attribute.MISSING_NOMINAL_VALUE; + } else { + return a.getMapping().mapIndex((int) value); + } + } + + /** + * Returns the numerical value for the given attribute. + * + * @throws AttributeTypeException + * if the given attribute has the wrong value type + */ + public double getNumericalValue(Attribute a) { + if (!a.isNumerical()) { + throw new AttributeTypeException("Extraction of numerical example value for non-numerical attribute '" + + a.getName() + "' is not possible."); + } + return getValue(a); + } + + /** + * Returns the date value for the given attribute. + * + * @throws AttributeTypeException + * if the given attribute has the wrong value type + */ + public Date getDateValue(Attribute a) { + if (!Ontology.ATTRIBUTE_VALUE_TYPE.isA(a.getValueType(), Ontology.DATE_TIME)) { + throw new AttributeTypeException("Extraction of date example value for non-date attribute '" + a.getName() + + "' is not possible."); + } + return new Date((long) getValue(a)); + } + + /** + * Sets the value of attribute a. The attribute a need not necessarily be part of the example + * set the example is taken from, although this is no good style. + */ + public void setValue(Attribute a, double value) { + data.set(a, value); + } + + /** + * Sets the value of attribute a which must be a nominal attribute. The attribute a need not + * necessarily be part of the example set the example is taken from, although this is no good + * style. Missing values might be given by passing null as second argument. + */ + public void setValue(Attribute a, String str) { + if (!a.isNominal()) { + throw new AttributeTypeException("setValue(Attribute, String) only supported for nominal values!"); + } + if (str != null) { + setValue(a, a.getMapping().mapString(str)); + } else { + setValue(a, Double.NaN); + } + } + + /** + * Returns true if both nominal values are the same (if both attributes are nominal) or if both + * real values are the same (if both attributes are real values) or false otherwise. + */ + public boolean equalValue(Attribute first, Attribute second) { + if (first.isNominal() && second.isNominal()) { + return getValueAsString(first).equals(getValueAsString(second)); + } else if ((!first.isNominal()) && (!second.isNominal())) { + return com.rapidminer.tools.Tools.isEqual(getValue(first), getValue(second)); + } else { + return false; + } + } + + // --------------------------------------------------------------------------------- + + public double getLabel() { + return getValue(getAttributes().getLabel()); + } + + public void setLabel(double value) { + setValue(getAttributes().getLabel(), value); + } + + public double getPredictedLabel() { + return getValue(getAttributes().getPredictedLabel()); + } + + public void setPredictedLabel(double value) { + setValue(getAttributes().getPredictedLabel(), value); + } + + public double getId() { + return getValue(getAttributes().getId()); + } + + public void setId(double value) { + setValue(getAttributes().getId(), value); + } + + public double getWeight() { + return getValue(getAttributes().getWeight()); + } + + public void setWeight(double value) { + setValue(getAttributes().getWeight(), value); + } + + public double getConfidence(String classValue) { + return getValue(getAttributes().getConfidence(classValue)); + } + + public void setConfidence(String classValue, double confidence) { + setValue(getAttributes().getSpecial(Attributes.CONFIDENCE_NAME + "_" + classValue), confidence); + } + + // -------------------------------------------------------------------------------- + + /** + *

+ * Returns the value of this attribute as string representation, i.e. the number as string for + * numerical attributes and the correctly mapped categorical value for nominal values. The used + * number of fraction digits is unlimited (see + * {@link NumericalAttribute#DEFAULT_NUMBER_OF_DIGITS} ). Nominal values containing whitespaces + * will not be quoted. + *

+ * + *

+ * Please note that this method should not be used in order to get the nominal values, please + * use {@link #getNominalValue(Attribute)} instead. + *

+ */ + public String getValueAsString(Attribute attribute) { + return getValueAsString(attribute, NumericalAttribute.UNLIMITED_NUMBER_OF_DIGITS, false); + } + + /** + *

+ * Returns the value of this attribute as string representation, i.e. the number as string for + * numerical attributes and the correctly mapped categorical value for nominal values. If the + * value is numerical the given number of fraction digits is used. If the value is numerical, + * the given number of fraction digits is used. This value must be either one out of + * {@link NumericalAttribute#DEFAULT_NUMBER_OF_DIGITS} or + * {@link NumericalAttribute#UNLIMITED_NUMBER_OF_DIGITS} or a number greater or equal to 0. The + * boolean flag indicates if nominal values containing whitespaces should be quoted with double + * quotes. + *

+ * + *

+ * Please note that this method should not be used in order to get the nominal values, please + * use {@link #getNominalValue(Attribute)} instead. + *

+ */ + public String getValueAsString(Attribute attribute, int fractionDigits, boolean quoteNominal) { + double value = getValue(attribute); + return attribute.getAsString(value, fractionDigits, quoteNominal); + } + + /** + * Returns a dense string representation with all possible fraction digits. Nominal values will + * be quoted with double quotes. + */ + @Override + public String toString() { + return toDenseString(NumericalAttribute.UNLIMITED_NUMBER_OF_DIGITS, true); + } + + /** + * This method returns a dense string representation of the example. It first returns the values + * of all special attributes and then the values of all regular attributes. + */ + public String toDenseString(int fractionDigits, boolean quoteNominal) { + StringBuffer result = new StringBuffer(); + Iterator a = getAttributes().allAttributes(); + boolean first = true; + while (a.hasNext()) { + if (first) { + first = false; + } else { + result.append(SEPARATOR); + } + result.append(getValueAsString(a.next(), fractionDigits, quoteNominal)); + } + return result.toString(); + } + + /** + * Returns regular and some special attributes (label, id, and example weight) in sparse format. + * + * @param format + * one of the formats specified in {@link SparseFormatDataRowReader} + */ + public String toSparseString(int format, int fractionDigits, boolean quoteNominal) { + StringBuffer str = new StringBuffer(); + // label + Attribute labelAttribute = getAttributes().getSpecial(Attributes.LABEL_NAME); + if ((format == SparseFormatDataRowReader.FORMAT_YX) && (labelAttribute != null)) { + str.append(getValueAsString(labelAttribute, fractionDigits, quoteNominal) + " "); + } + + // id + Attribute idAttribute = getAttributes().getSpecial(Attributes.ID_NAME); + if (idAttribute != null) { + str.append("id:" + getValueAsString(idAttribute, fractionDigits, quoteNominal) + " "); + } + + // weight + Attribute weightAttribute = getAttributes().getSpecial(Attributes.WEIGHT_NAME); + if (weightAttribute != null) { + str.append("w:" + getValueAsString(weightAttribute, fractionDigits, quoteNominal) + " "); + } + + // batch + Attribute batchAttribute = getAttributes().getSpecial(Attributes.BATCH_NAME); + if (batchAttribute != null) { + str.append("b:" + getValueAsString(batchAttribute, fractionDigits, quoteNominal) + " "); + } + + // attributes + str.append(getAttributesAsSparseString(SEPARATOR, SPARSE_SEPARATOR, fractionDigits, quoteNominal) + " "); + + // label (format xy & prefix) + if ((format == SparseFormatDataRowReader.FORMAT_PREFIX) && (labelAttribute != null)) { + str.append("l:" + getValueAsString(labelAttribute, fractionDigits, quoteNominal)); + } + if ((format == SparseFormatDataRowReader.FORMAT_XY) && (labelAttribute != null)) { + str.append(getValueAsString(labelAttribute, fractionDigits, quoteNominal)); + } + return str.toString(); + } + + /** + * Returns the attribute values in the format
+ *
index:value index:value

+ * Index starts with 1. + * + * @param separator + * separates attributes + * @param indexValueSeparator + * separates index and value. + * @param fractionDigits + * the number of fraction digits used, if -1 all possible digits are used + */ + /* pp */String getAttributesAsSparseString(String separator, String indexValueSeparator, int fractionDigits, + boolean quoteNominal) { + StringBuffer str = new StringBuffer(); + boolean first = true; + int counter = 1; + for (Attribute attribute : getAttributes()) { + double value = getValue(attribute); + if (!Tools.isDefault(attribute.getDefault(), value)) { + if (!first) { + str.append(separator); + } + first = false; + str.append(counter + indexValueSeparator + getValueAsString(attribute, fractionDigits, quoteNominal)); + } + counter++; + } + return str.toString(); + } + + // =================================== + // The following methods implement + // the map interface for easy + // access of values in scripts + // =================================== + + @Override + public Object get(Object key) { + Attribute attribute = null; + if (key instanceof String) { + attribute = parentExampleSet.getAttributes().get((String) key); + } + double value = getValue(attribute); + if (Double.isNaN(value)) { + return "?"; + } + if (attribute == null) { + return null; + } else if (attribute.isNominal()) { + return getValueAsString(attribute); + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(attribute.getValueType(), Ontology.INTEGER)) { + return (int) getValue(attribute); + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(attribute.getValueType(), Ontology.DATE_TIME)) { + return new Date((long) getValue(attribute)); + } else { + return getValue(attribute); + } + } + + @Override + public Object put(String attributeName, Object value) { + Attribute attribute = parentExampleSet.getAttributes().get(attributeName); + if (attribute == null) { + throw new IllegalArgumentException("Unknown attribute name: '" + attributeName + "'"); + } else if (attribute.isNumerical()) { + if (value == null) { + setValue(attribute, Double.NaN); + } else { + try { + double doubleValue = Double.parseDouble(value.toString()); + setValue(attribute, doubleValue); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Only numerical values are allowed for numerical attribute: '" + + attributeName + "', was '" + value + "'"); + } + } + } else { + if (value == null) { + setValue(attribute, Double.NaN); + } else { + setValue(attribute, attribute.getMapping().mapString(value.toString())); + } + } + return value; + } + + @Override + public void clear() { + throw new UnsupportedOperationException("Clear is not supported by Example."); + } + + @Override + public boolean containsKey(Object key) { + Attribute attribute = null; + if (key instanceof String) { + attribute = parentExampleSet.getAttributes().get((String) key); + } + return attribute != null; + } + + @Override + public boolean containsValue(Object value) { + throw new UnsupportedOperationException("ContainsValue is not supported by Example."); + } + + @Override + public Set> entrySet() { + throw new UnsupportedOperationException("EntrySet is not supported by Example."); + } + + @Override + public boolean isEmpty() { + return parentExampleSet.getAttributes().allSize() == 0; + } + + @Override + public Set keySet() { + Set allKeys = new HashSet(); + Iterator a = parentExampleSet.getAttributes().allAttributes(); + while (a.hasNext()) { + allKeys.add(a.next().getName()); + } + return allKeys; + } + + @Override + public void putAll(Map m) { + throw new UnsupportedOperationException("PutAll is not supported by Example."); + } + + @Override + public String remove(Object key) { + throw new UnsupportedOperationException("Remove is not supported by Example."); + } + + @Override + public int size() { + return parentExampleSet.getAttributes().allSize(); + } + + @Override + public Collection values() { + throw new UnsupportedOperationException("Values is not supported by Example."); + } +} diff --git a/src/main/java/com/rapidminer/example/ExampleFormatter.java b/src/main/java/com/rapidminer/example/ExampleFormatter.java new file mode 100644 index 000000000..0294c0458 --- /dev/null +++ b/src/main/java/com/rapidminer/example/ExampleFormatter.java @@ -0,0 +1,383 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.Tools; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + + +/** + * Formats an example as specified by the format string. The dollar sign '$' is an escape character. + * Squared brackets '[' and ']' have a special meaning. The following escape sequences are + * interpreted: + *
+ *
$a:
+ *
All attributes separated by the default separator
+ *
$a[separator]:
+ *
All attributes separated by separator
+ *
$s[separator][indexSeparator]:
+ *
Sparse format. For all non 0 attributes the following strings are concatenated: the column + * index, the value of indexSeparator, the attribute value. Attributes are separated by separator.
+ *
$v[name]:
+ *
The value of the attribute with the given name (both regular and special attributes)
+ *
$k[index]:
+ *
The value of the attribute with the given index in the example set
+ *
$l:
+ *
The label
+ *
$p:
+ *
The predicted label
+ *
$d:
+ *
All prediction confidences for all classes in the form conf(class)=value
+ *
$d[class]:
+ *
The prediction confidence for the defined class as a simple number
+ *
$i:
+ *
The id
+ *
$w:
+ *
The weight
+ *
$c:
+ *
The cluster
+ *
$b:
+ *
The batch
+ *
$n:
+ *
The newline character
+ *
$t:
+ *
The tabulator character
+ *
$$:
+ *
The dollar sign
+ *
$[:
+ *
The '[' character
+ *
$]:
+ *
The ']' character
+ *
+ * + * @author Simon Fischer, Ingo Mierswa Exp $ + */ +public class ExampleFormatter { + + /** Represents one piece of formatting. */ + public static interface FormatCommand { + + public String format(Example example); + } + + /** + * Implements some simple format commands like 'a' for all attributes or 'l' for the label. + */ + public static class SimpleCommand implements FormatCommand { + + private char command; + + private String[] arguments; + + private int fractionDigits = -1; + + private boolean quoteNominal; + + private SimpleCommand(ExampleSet exampleSet, char command, String[] arguments, int fractionDigits, + boolean quoteNominal) throws FormatterException { + this.command = command; + this.fractionDigits = fractionDigits; + this.quoteNominal = quoteNominal; + if ((command != 'a') && (command != 's') && (command != 'l') && (command != 'p') && (command != 'd') + && (command != 'i') && (command != 'w') && (command != 'c') && (command != 'b')) { + throw new FormatterException("Unknown command: '" + command + "'"); + } + switch (command) { + case 'a': + if (arguments.length == 0) { + arguments = new String[] { Example.SEPARATOR }; + } + break; + case 's': + if (arguments.length == 0) { + arguments = new String[] { Example.SEPARATOR, Example.SPARSE_SEPARATOR }; + } + if (arguments.length == 1) { + arguments = new String[] { arguments[0], Example.SPARSE_SEPARATOR }; + } + if (arguments.length == 2) { + arguments = new String[] { arguments[0], arguments[1] }; + } + if (arguments.length > 2) { + throw new FormatterException( + "For command 's' only up to two arguments (separator and sparse separator) are allowed."); + } + break; + case 'l': + if (exampleSet.getAttributes().getLabel() == null) { + throw new FormatterException("Example set does not provide 'label' attribute, $l will not work."); + } + break; + case 'p': + if (exampleSet.getAttributes().getPredictedLabel() == null) { + throw new FormatterException( + "Example set does not provide 'predicted label' attribute, $p will not work."); + } + break; + case 'i': + if (exampleSet.getAttributes().getId() == null) { + throw new FormatterException("Example set does not provide 'id' attribute, $i will not work."); + } + break; + case 'w': + if (exampleSet.getAttributes().getWeight() == null) { + throw new FormatterException("Example set does not provide 'weight' attribute, $w will not work."); + } + break; + case 'c': + if (exampleSet.getAttributes().getCluster() == null) { + throw new FormatterException("Example set does not provide 'cluster' attribute, $c will not work."); + } + break; + case 'b': + if (exampleSet.getAttributes().getSpecial(Attributes.BATCH_NAME) == null) { + throw new FormatterException("Example set does not provide 'batch' attribute, $b will not work."); + } + break; + case 'd': + if (exampleSet.getAttributes().getPredictedLabel() == null) { + throw new FormatterException( + "Example set does not provide 'confidence' attributes, $d will not work."); + } + break; + default: + break; + } + this.arguments = arguments; + } + + @Override + public String format(Example example) { + switch (command) { + case 'a': + StringBuffer str = new StringBuffer(); + boolean first = true; + for (Attribute attribute : example.getAttributes()) { + if (!first) { + str.append(arguments[0]); + } + str.append(example.getValueAsString(attribute, fractionDigits, quoteNominal)); + first = false; + } + return str.toString(); + case 's': + return example.getAttributesAsSparseString(arguments[0], arguments[1], fractionDigits, quoteNominal); + case 'l': + return example.getValueAsString(example.getAttributes().getLabel(), fractionDigits, quoteNominal); + case 'p': + return example.getValueAsString(example.getAttributes().getPredictedLabel(), fractionDigits, + quoteNominal); + case 'i': + return example.getValueAsString(example.getAttributes().getId(), fractionDigits, quoteNominal); + case 'w': + return example.getValueAsString(example.getAttributes().getWeight(), fractionDigits, quoteNominal); + case 'c': + return example.getValueAsString(example.getAttributes().getCluster(), fractionDigits, quoteNominal); + case 'b': + return example.getValueAsString(example.getAttributes().getSpecial(Attributes.BATCH_NAME), + fractionDigits, quoteNominal); + case 'd': + if (arguments.length == 0) { + Iterator i = example.getAttributes().getPredictedLabel().getMapping().getValues().iterator(); + StringBuffer result = new StringBuffer(); + int index = 0; + while (i.hasNext()) { + String value = (String) i.next(); + if (index != 0) { + result.append(Example.SEPARATOR); + } + result.append("conf(" + value + ")=" + + Tools.formatNumber(example.getConfidence(value), fractionDigits)); + index++; + } + return result.toString(); + } else { + return Tools.formatNumber(example.getConfidence(arguments[0]), fractionDigits); + } + default: + return command + ""; + } + } + } + + /** Returns the value of an argument which must be an attribute's name. */ + public static class ValueCommand implements FormatCommand { + + private Attribute attribute; + + private int fractionDigits = -1; + + private boolean quoteWhitespace = false; + + public ValueCommand(char command, String[] arguments, ExampleSet exampleSet, int fractionDigits, + boolean quoteWhitespace) throws FormatterException { + this.fractionDigits = fractionDigits; + this.quoteWhitespace = quoteWhitespace; + if (arguments.length < 1) { + throw new FormatterException("Command 'v' needs argument!"); + } + switch (command) { + case 'v': + attribute = exampleSet.getAttributes().get(arguments[0]); + if (attribute == null) { + throw new FormatterException("Unknown attribute: '" + arguments[0] + "'!"); + } + break; + case 'k': + int column = -1; + try { + column = Integer.parseInt(arguments[0]); + } catch (NumberFormatException e) { + throw new FormatterException("Argument for 'k' must be an integer!"); + } + if ((column < 0) || (column >= exampleSet.getAttributes().size())) { + throw new FormatterException("Illegal column: '" + arguments[0] + "'!"); + } + + int counter = 0; + for (Attribute attribute : exampleSet.getAttributes()) { + if (counter >= column) { + this.attribute = attribute; + break; + } + counter++; + } + if (attribute == null) { + throw new FormatterException("Attribute #" + column + " not found."); + } + break; + default: + throw new FormatterException("Illegal command for ValueCommand: '" + command + "'"); + } + } + + @Override + public String format(Example example) { + return example.getValueAsString(attribute, fractionDigits, quoteWhitespace); + } + } + + /** Returns simply the given text. */ + public static class TextCommand implements FormatCommand { + + private String text; + + private TextCommand(String text) { + this.text = text; + } + + @Override + public String format(Example example) { + return text; + } + } + + /** The commands used subsequently to format the example. */ + private FormatCommand[] formatCommands; + + /** + * Constructs a new ExampleFormatter that executes the given array of formatting commands. The + * preferred way of creating an instance of ExampleFormatter is to + * {@link ExampleFormatter#compile(String, ExampleSet, int, boolean)} a format string. + */ + public ExampleFormatter(FormatCommand[] formatCommands) { + this.formatCommands = formatCommands; + } + + /** + * Factory method that compiles a format string and creates an instance of ExampleFormatter. + */ + public static ExampleFormatter compile(String formatString, ExampleSet exampleSet, int fractionDigits, + boolean quoteWhitespace) throws FormatterException { + List commandList = new LinkedList(); + compile(formatString, exampleSet, commandList, fractionDigits, quoteWhitespace); + FormatCommand[] commands = new FormatCommand[commandList.size()]; + commandList.toArray(commands); + return new ExampleFormatter(commands); + } + + /** Adds all commands to the commandList. */ + private static void compile(String formatString, ExampleSet exampleSet, List commandList, + int fractionDigits, boolean quoteWhitespace) throws FormatterException { + int start = 0; + while (true) { + int tagStart = formatString.indexOf("$", start); + if (tagStart == -1) { + commandList.add(new TextCommand(formatString.substring(start))); + break; + } + + if (tagStart == formatString.length() - 1) { + throw new FormatterException("Format string ends in '$'."); + } + + commandList.add(new TextCommand(formatString.substring(start, tagStart))); + + char command = formatString.charAt(tagStart + 1); + if ((command == '$') || (command == '[') || (command == ']')) { + commandList.add(new TextCommand("" + command)); + start = tagStart + 2; + continue; + } else if (command == 'n') { + commandList.add(new TextCommand(Tools.getLineSeparator())); + start = tagStart + 2; + continue; + } else if (command == 't') { + commandList.add(new TextCommand("\t")); + start = tagStart + 2; + continue; + } + + start = tagStart + 2; + List argumentList = new LinkedList(); + while ((start < formatString.length()) && (formatString.charAt(start) == '[')) { + int end = formatString.indexOf(']', start); + if (end == -1) { + throw new FormatterException("Unclosed '['!"); + } + argumentList.add(formatString.substring(start + 1, end)); + start = end + 1; + } + + String[] arguments = new String[argumentList.size()]; + argumentList.toArray(arguments); + switch (command) { + case 'v': + case 'k': + commandList.add(new ValueCommand(command, arguments, exampleSet, fractionDigits, quoteWhitespace)); + break; + default: + commandList.add(new SimpleCommand(exampleSet, command, arguments, fractionDigits, quoteWhitespace)); + break; + } + } + } + + /** Formats a single example. */ + public String format(Example example) { + StringBuffer str = new StringBuffer(); + for (int i = 0; i < formatCommands.length; i++) { + str.append(formatCommands[i].format(example)); + } + return str.toString(); + } +} diff --git a/src/main/java/com/rapidminer/example/ExampleReader.java b/src/main/java/com/rapidminer/example/ExampleReader.java new file mode 100644 index 000000000..99bd9d949 --- /dev/null +++ b/src/main/java/com/rapidminer/example/ExampleReader.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.Iterator; + + +/** + * An ExampleReader iterates over a sequence of examples. Please note, that although this interface + * extends Iterator, the method remove() is usually not supported. Invocing remove will + * lead to an {@link java.lang.UnsupportedOperationException} in most cases. + * + * @author Simon Fischer, Ingo Mierswa + */ +public interface ExampleReader extends Iterator { + +} diff --git a/src/main/java/com/rapidminer/example/ExampleSet.java b/src/main/java/com/rapidminer/example/ExampleSet.java new file mode 100644 index 000000000..2f45562d4 --- /dev/null +++ b/src/main/java/com/rapidminer/example/ExampleSet.java @@ -0,0 +1,160 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.ResultObject; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; + + +/** + * Interface definition for all example sets. Usually, example sets do not contain any data but are + * only views on an example table (for example for sampling or feature selection purposes). It + * should be possible to create a layered view on the data, hence the name multi-layered data view. + * ExampleSet implementation should support this view concept. + * + * @author Ingo Mierswa + */ +public interface ExampleSet extends ResultObject, Cloneable, Iterable { + + // ------------- Misc ----------------------------- + + /** Clones the example set. */ + public Object clone(); + + /** True if all attributes are equal. */ + @Override + public boolean equals(Object o); + + /** + * Returns the hash code. Two example sets must deliver the same hash code if they are equal. + */ + @Override + public int hashCode(); + + // -------------------- attributes -------------------- + + /** + * Returns the data structure holding all attributes. NOTE! if you intend to iterate over all + * Attributes of this ExampleSet then you need to create an Iterator by calling + * {@link ExampleSet#getAttributes()#getAttributes()} and use it instead. + */ + public Attributes getAttributes(); + + // -------------------- Examples -------------------- + + /** + * Returns the number of examples in this example set. This number should not be used to create + * for-loops to iterate through all examples. + */ + public int size(); + + /** + * Returns the underlying example table. Most operators should operate on the example set and + * manipulate example to change table data instead of using the table directly. + */ + public ExampleTable getExampleTable(); + + /** + * Returns the example with the given id value. If the example set does not contain an id + * attribute this method should return null. Call {@link #remapIds()} before using this method. + */ + public Example getExampleFromId(double value); + + /** + * Returns all examples which have the given id. Should return null in the case that there are + * no examples matching that id. + */ + public int[] getExampleIndicesFromId(double value); + + /** + * Returns the i-th example. It is not guaranteed that asking for an example by using the index + * in the example table is efficiently implemented. Therefore for-loops for iterations are not + * an option and an {@link ExampleReader} should be used. + */ + public Example getExample(int index); + + /** + * Remaps all ids. This method should be invoked before the method + * {@link #getExampleFromId(double)} is used. + */ + public void remapIds(); + + // -------------------- File Writing -------------------- + + /** Writes the data and the attribute description to a file. */ + public void writeDataFile(File dataFile, int fractionDigits, boolean quoteNominal, boolean zipped, boolean append, + Charset encoding) throws IOException; + + /** + * Writes the attribute meta descriptions into a file. The data file is used in order to + * determine the relative file positions and is not allowed to be null. + */ + public void writeAttributeFile(File attFile, File dataFile, Charset encoding) throws IOException; + + /** + * Writes the data and the attribute description to a sparse data file. + * + * @param dataFile + * the file to write the data to + * @param format + * specified by {@link com.rapidminer.operator.io.SparseFormatExampleSource} + * @param fractionDigits + * the number of fraction digits (-1 for all possible digits) + */ + public void writeSparseDataFile(File dataFile, int format, int fractionDigits, boolean quoteNominal, boolean zipped, + boolean append, Charset encoding) throws IOException; + + /** + * Writes the attribute meta descriptions for a sparse data file into a file. The data file is + * used in order to determine the relative file positions and is not allowed to be null. + * + * @param format + * specified by {@link com.rapidminer.operator.io.SparseFormatExampleSource} + */ + public void writeSparseAttributeFile(File attFile, File dataFile, int format, Charset encoding) throws IOException; + + // ------------------- Statistics --------------- + + /** Recalculate all attribute statistics. */ + public void recalculateAllAttributeStatistics(); + + /** Recalculate the attribute statistics of the given attribute. */ + public void recalculateAttributeStatistics(Attribute attribute); + + /** + * Returns the desired statistic for the given attribute. This method should be preferred over + * the deprecated method Attribute#getStatistics(String) since it correctly calculates and keep + * the statistics for the current example set and does not overwrite the statistics in the + * attribute. + */ + public double getStatistics(Attribute attribute, String statisticsName); + + /** + * Returns the desired statistic for the given attribute. This method should be preferred over + * the deprecated method Attribute#getStatistics(String) since it correctly calculates and keep + * the statistics for the current example set and does not overwrite the statistics in the + * attribute. + */ + public double getStatistics(Attribute attribute, String statisticsName, String statisticsParameter); + +} diff --git a/src/main/java/com/rapidminer/example/ExampleSetFactory.java b/src/main/java/com/rapidminer/example/ExampleSetFactory.java new file mode 100644 index 000000000..35de2bb84 --- /dev/null +++ b/src/main/java/com/rapidminer/example/ExampleSetFactory.java @@ -0,0 +1,316 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.DoubleArrayDataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.example.table.MemoryExampleTable; +import com.rapidminer.tools.Ontology; + + +/** + *

+ * This class can be used to easily create @link ExampleSet}s and the underlying + * {@link ExampleTable} with simple method calls. Please note that it is often better to explicitly + * fill the data table yourself, or, if possible, to extend {@link ExampleTable} or {@link DataRow} + * to provide the necessary data to RapidMiner. For memory usage reasons, it is also often not + * recommended to create the data matrix from your existing data in an extra step and then use one + * of the factory methods. In these cases, it is better to directly fill an {@link ExampleTable} + * from your data source. + *

+ * + *

+ * However, in some cases it might be more convenient to use this class in order to create example + * sets from data matrices in a fast and simple way. The resulting example set will be backed up by + * a {@link MemoryExampleTable}. If the data set at hand is completely numerical, one can simply use + * one of the double matrix methods provided by this class. This will lead to an {@link ExampleSet} + * containing only numerical attributes. Otherwise, one have to use the Object matrix methods. + * Please note that only String objects and Number objects (Double, Integer) are allowed in this + * case. Otherwise an Exception will be thrown. In case of the Object matrix methods the method + * tries to identify the type itself and initialized the example set with the correct attribute + * types (nominal or numerical). + *

+ * + *

+ * Please note that the internal representation of the nominal attribute values depend on the order + * they appear in the data set. If this is not allowed (e.g. for the label attribute of different + * training and testing sets, where the internal representation should be the same in order to + * prevent label flips) one should definitely use the usual ExampleTable - ExampleSet construction + * where the nominal attribute value mapping can and should be performed beforehand. In these cases + * the usage of this class is definitely not recommended. + *

+ * + * @author Ingo Mierswa + */ +public class ExampleSetFactory { + + /** + * Create a numerical example set from the given data matrix. The resulting example set will not + * contain a label and consists of numerical attributes only. + */ + public static ExampleSet createExampleSet(double[][] data) { + return createExampleSet(data, null); + } + + /** + * Create a numerical example set from the given data matrix. The label of the resulting example + * set be build from the column with the given index. The example set consists of numerical + * attributes only. + */ + public static ExampleSet createExampleSet(double[][] data, int classColumn) { + if (data.length == 0) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(double[][], int): data matrix is not allowed to be empty."); + } + double[][] dataWithoutLabel = new double[data.length][data[0].length - 1]; + double[] labels = new double[data.length]; + + for (int e = 0; e < data.length; e++) { + int counter = 0; + for (int a = 0; a < data[e].length; a++) { + if (a == classColumn) { + labels[e] = data[e][a]; + } else { + dataWithoutLabel[e][counter++] = data[e][a]; + } + } + } + + return createExampleSet(dataWithoutLabel, labels); + } + + /** + * Create a numerical example set from the given data matrix. The label of the resulting example + * set be build from the given double array. The example set consists of numerical attributes + * only. + */ + public static ExampleSet createExampleSet(double[][] data, double[] labels) { + if (data.length == 0) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(double[][], double[]): data matrix is not allowed to be empty."); + } + + // create attributes + int numberOfAttributes = data[0].length; + List attributeList = new ArrayList(numberOfAttributes + (labels != null ? 1 : 0)); + for (int a = 0; a < numberOfAttributes; a++) { + attributeList.add(AttributeFactory.createAttribute("att" + (a + 1), Ontology.NUMERICAL)); + } + Attribute labelAttribute = null; + if (labels != null) { + labelAttribute = AttributeFactory.createAttribute("label", Ontology.NUMERICAL); + attributeList.add(labelAttribute); + } + + // create table + MemoryExampleTable table = new MemoryExampleTable(attributeList); + for (int e = 0; e < data.length; e++) { + double[] dataRow = data[e]; + if (labelAttribute != null) { + dataRow = new double[numberOfAttributes + 1]; + System.arraycopy(data[e], 0, dataRow, 0, data[e].length); + dataRow[dataRow.length - 1] = labels[e]; + } + table.addDataRow(new DoubleArrayDataRow(dataRow)); + } + + return table.createExampleSet(labelAttribute); + } + + /** + * Create a mixed-type example set from the given data matrix. The resulting example set will + * not contain a label and might consist of numerical, nominal or date attributes. + */ + public static ExampleSet createExampleSet(Object[][] data) { + return createExampleSet(data, null); + } + + /** + * Create a numerical example set from the given data matrix. The label of the resulting example + * set be build from the column with the given index. The example set might consist of + * numerical, nominal or date attributes. + */ + public static ExampleSet createExampleSet(Object[][] data, int classColumn) { + if (data.length == 0) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], int): data matrix is not allowed to be empty."); + } + Object[][] dataWithoutLabel = new Object[data.length][data[0].length - 1]; + Object[] labels = new Object[data.length]; + + for (int e = 0; e < data.length; e++) { + int counter = 0; + for (int a = 0; a < data[e].length; a++) { + if (a == classColumn) { + labels[e] = data[e][a]; + } else { + dataWithoutLabel[e][counter++] = data[e][a]; + } + } + } + + return createExampleSet(dataWithoutLabel, labels); + } + + /** + * Create a numerical example set from the given data matrix. The label of the resulting example + * set be build from the given double array. The example set might consist of numerical, nominal + * or date attributes. + */ + public static ExampleSet createExampleSet(Object[][] data, Object[] labels) { + if (data.length == 0) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): data matrix is not allowed to be empty."); + } + + // create attributes + int numberOfAttributes = data[0].length; + int totalNumber = numberOfAttributes + (labels != null ? 1 : 0); + boolean[] nominal = new boolean[totalNumber]; + List attributeList = new ArrayList(totalNumber); + for (int a = 0; a < numberOfAttributes; a++) { + Object current = getFirstNonNull(data, a); + + if (current instanceof Number) { + attributeList.add(AttributeFactory.createAttribute("att" + (a + 1), Ontology.NUMERICAL)); + nominal[a] = false; + } else if (current instanceof String) { + attributeList.add(AttributeFactory.createAttribute("att" + (a + 1), Ontology.NOMINAL)); + nominal[a] = true; + } else if (current instanceof Date) { + attributeList.add(AttributeFactory.createAttribute("att" + (a + 1), Ontology.DATE_TIME)); + nominal[a] = false; + } else { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): only objects of type String or Number (Double, Integer) are allowed for the object data matrix."); + } + } + Attribute labelAttribute = null; + if (labels != null) { + Object current = labels[0]; + if (current instanceof Number) { + labelAttribute = AttributeFactory.createAttribute("label", Ontology.NUMERICAL); + nominal[nominal.length - 1] = false; + } else if (current instanceof String) { + labelAttribute = AttributeFactory.createAttribute("label", Ontology.NOMINAL); + nominal[nominal.length - 1] = true; + } else if (current instanceof Date) { + labelAttribute = AttributeFactory.createAttribute("label", Ontology.DATE_TIME); + nominal[nominal.length - 1] = false; + } else { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): only objects of type String or Number (Double, Integer) are allowed for the object data matrix."); + } + attributeList.add(labelAttribute); + } + + // create table + MemoryExampleTable table = new MemoryExampleTable(attributeList); + for (int e = 0; e < data.length; e++) { + double[] dataRow = new double[totalNumber]; + for (int a = 0; a < numberOfAttributes; a++) { + Object current = data[e][a]; + if (current == null) { + dataRow[a] = Double.NaN; + } else if (current instanceof Number) { + if (nominal[a]) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): type of objects did change in column. Only the same type of objects is allowed for complete columns."); + } + dataRow[a] = ((Number) current).doubleValue(); + } else if (current instanceof String) { + if (!nominal[a]) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): type of objects did change in column. Only the same type of objects is allowed for complete columns."); + } + dataRow[a] = attributeList.get(a).getMapping().mapString((String) current); + } else if (current instanceof Date) { + if (nominal[a]) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): type of objects did change in column. Only the same type of objects is allowed for complete columns."); + } + dataRow[a] = ((Date) current).getTime(); + } else { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): only objects of type String or Number (Double, Integer) are allowed for the object data matrix."); + } + } + if (labelAttribute != null) { + Object current = labels[e]; + if (current == null) { + dataRow[dataRow.length - 1] = Double.NaN; + } else if (current instanceof Number) { + if (nominal[nominal.length - 1]) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): type of objects did change in column. Only the same type of objects is allowed for complete columns."); + } + dataRow[dataRow.length - 1] = ((Number) current).doubleValue(); + } else if (current instanceof String) { + if (!nominal[nominal.length - 1]) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): type of objects did change in column. Only the same type of objects is allowed for complete columns."); + } + dataRow[dataRow.length - 1] = attributeList.get(attributeList.size() - 1).getMapping() + .mapString((String) current); + } else if (current instanceof Date) { + if (nominal[nominal.length - 1]) { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): type of objects did change in column. Only the same type of objects is allowed for complete columns."); + } + dataRow[dataRow.length - 1] = ((Date) current).getTime(); + } else { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): only objects of type String or Number (Double, Integer) are allowed for the object data matrix."); + } + } + table.addDataRow(new DoubleArrayDataRow(dataRow)); + } + + return table.createExampleSet(labelAttribute); + } + + /** + * @param data + * the data array object + * @param a + * the current attribute index + * @return the first non-null object + */ + private static Object getFirstNonNull(Object[][] data, int a) { + int tryCounter = 0; + Object current = data[tryCounter][a]; + while (current == null) { + tryCounter++; + if (tryCounter < data.length) { + current = data[tryCounter][a]; + } else { + throw new RuntimeException( + "ExampleSetFactory.createExampleSet(Object[][], Object[]): provided attribute at column " + a + + " does only contain null values."); + } + } + return current; + } +} diff --git a/src/main/java/com/rapidminer/example/FastExample2SparseTransform.java b/src/main/java/com/rapidminer/example/FastExample2SparseTransform.java new file mode 100644 index 000000000..a63c23f3d --- /dev/null +++ b/src/main/java/com/rapidminer/example/FastExample2SparseTransform.java @@ -0,0 +1,150 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.SparseDataRow; +import com.rapidminer.operator.UserError; + +import java.util.Arrays; + + +/** + * This class can be used for the efficient generation of sparse example formats. The constructor + * creates a mapping between example set and example table attribute indices which only need to be + * performed once. The sparse data can then be queried efficiently by using the methods + * {@link #getNonDefaultAttributeIndices(Example)} and + * {@link #getNonDefaultAttributeValues(Example)}. Please note that this filter should be + * reinstatiated for new example sets. Furthermore, a gain in performance is only achieved for + * examples with underlying {@link SparseDataRow}s. + * + * @author Julien Nioche, Ingo Mierswa ingomierswa Exp $ + */ +public class FastExample2SparseTransform { + + /** + * The mapping between the attribute indices in the data row / example table on the attribute + * indices of the given example set. This mapping is only necessary for examples backed up by + * {@link SparseDataRow}s. + */ + private int[] mapping; + + /** + * This attribute array is necessary since in example sets only iterators are provided for + * attributes. + */ + private Attribute[] attributes; + + /** + * The complete array of all attribute indices which can be used for data rows which do not + * implement {@link SparseDataRow}. + */ + private int[] allIndices; + + /** + * Returns for a table giving the equivalence between the positions of the Attributes in the + * ExampleTable and the number of the regular Attributes in the ExampleSet. A value of -1 + * indicates that the Attribute is not regular or has been deleted (is null). This is used in + * order to optimize the access to sparse DataRows (e.g. SVM implementations or for Weka), which + * is important when the number of Attributes is large. + * + * @throws UserError + */ + public FastExample2SparseTransform(ExampleSet es) throws UserError { + // init + this.mapping = new int[es.getExampleTable().getNumberOfAttributes()]; + for (int i = 0; i < mapping.length; i++) { + mapping[i] = -1; + } + + // create mappings + int pos = 0; + this.attributes = new Attribute[es.getAttributes().size()]; + this.allIndices = new int[es.getAttributes().size()]; + for (Attribute attribute : es.getAttributes()) { + int tableIndex = attribute.getTableIndex(); + if (tableIndex != Attribute.VIEW_ATTRIBUTE_INDEX) { + this.mapping[attribute.getTableIndex()] = pos; + this.attributes[pos] = attribute; + this.allIndices[pos] = pos; + pos++; + } else { + throw new UserError(null, 140); + } + } + + // trim is necessary in order to allow fast mapping! + for (Example e : es) { + e.getDataRow().trim(); + } + } + + /** + * Returns a list with the indices of the regular Attributes with non-default values. This can + * be used for a faster construction of sparse dataset representations when the number of + * Attributes is large. The positions of attributes are sorted by ascending number. + */ + public int[] getNonDefaultAttributeIndices(Example example) { + int numberNonDefaultAttributes = 0; + DataRow data = example.getDataRow(); + if (data instanceof SparseDataRow) { + int[] nonDefaultInd = ((SparseDataRow) (data)).getNonDefaultIndices(); + int[] tempArray = new int[nonDefaultInd.length]; + // map between the positive indices in the table + // and the corresponding attribute positions + for (int i = 0; i < nonDefaultInd.length; i++) { + int nextPos = mapping[nonDefaultInd[i]]; + if (nextPos != -1) { + tempArray[numberNonDefaultAttributes++] = nextPos; + } + } + // trim the table and sort it + int[] finalArray = new int[numberNonDefaultAttributes]; + System.arraycopy(tempArray, 0, finalArray, 0, numberNonDefaultAttributes); + // the positions have to be sorted for the sparse data + Arrays.sort(finalArray); + return finalArray; + } else { + // default behaviour for other DataRows + return allIndices; + } + } + + /** + * Returns an array of non-default values of the given example. These are only the values of + * regular attributes. Simply invokes {@link #getNonDefaultAttributeValues(Example, int[])} with + * the array of non-default indices for the given example. + */ + public double[] getNonDefaultAttributeValues(Example example) { + return getNonDefaultAttributeValues(example, getNonDefaultAttributeIndices(example)); + } + + /** + * Returns an array of non-default values of the given example. These are only the values of + * regular attributes. The size of the returned array is the same as the size of the given + * indices array. + */ + public double[] getNonDefaultAttributeValues(Example example, int[] nonDefaultIndices) { + double[] result = new double[nonDefaultIndices.length]; + for (int i = 0; i < result.length; i++) { + result[i] = example.getValue(this.attributes[nonDefaultIndices[i]]); + } + return result; + } +} diff --git a/src/main/java/com/rapidminer/example/FormatterException.java b/src/main/java/com/rapidminer/example/FormatterException.java new file mode 100644 index 000000000..63ded2495 --- /dev/null +++ b/src/main/java/com/rapidminer/example/FormatterException.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +/** + * This exception is thrown by the ExampleFormatter if the user specified format is not applicable + * to an example set. + * + * @author Ingo Mierswa + * + */ +public class FormatterException extends Exception { + + private static final long serialVersionUID = -2759316022177605234L; + + public FormatterException(String message) { + super(message); + } +} diff --git a/src/main/java/com/rapidminer/example/MinMaxStatistics.java b/src/main/java/com/rapidminer/example/MinMaxStatistics.java new file mode 100644 index 000000000..a3e36a0a9 --- /dev/null +++ b/src/main/java/com/rapidminer/example/MinMaxStatistics.java @@ -0,0 +1,89 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * Attribute statistics object for (pseudo-)numerical attributes like real numerical attributes or + * date attributes. + * + * @author Ingo Mierswa + */ +public class MinMaxStatistics implements Statistics { + + private static final long serialVersionUID = 1027895282018510951L; + + private double minimum = Double.POSITIVE_INFINITY; + + private double maximum = Double.NEGATIVE_INFINITY; + + public MinMaxStatistics() {} + + /** Clone constructor. */ + private MinMaxStatistics(MinMaxStatistics other) { + this.minimum = other.minimum; + this.maximum = other.maximum; + } + + @Override + public Object clone() { + return new MinMaxStatistics(this); + } + + @Override + public void count(double value, double weight) { + if (!Double.isNaN(value)) { + if (minimum > value) { + minimum = value; + } + if (maximum < value) { + maximum = value; + } + } + } + + @Override + public double getStatistics(Attribute attribute, String name, String parameter) { + if (MINIMUM.equals(name)) { + return this.minimum; + } else if (MAXIMUM.equals(name)) { + return this.maximum; + } else { + // LogService.getRoot().warning("Cannot calculate statistics, unknown type: " + name); + LogService.getRoot().log(Level.WARNING, "com.rapidminer.example.MinMaxStatistics.calculating_statistics_error", + name); + return Double.NaN; + } + } + + @Override + public boolean handleStatistics(String name) { + return MINIMUM.equals(name) || MAXIMUM.equals(name); + } + + @Override + public void startCounting(Attribute attribute) { + this.minimum = Double.POSITIVE_INFINITY; + this.maximum = Double.NEGATIVE_INFINITY; + } +} diff --git a/src/main/java/com/rapidminer/example/NominalStatistics.java b/src/main/java/com/rapidminer/example/NominalStatistics.java new file mode 100644 index 000000000..42b2a7c33 --- /dev/null +++ b/src/main/java/com/rapidminer/example/NominalStatistics.java @@ -0,0 +1,146 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.LogService; + +import java.util.Arrays; +import java.util.logging.Level; + + +/** + * Attribute statistics object for nominal attributes. + * + * @author Ingo Mierswa + */ +public class NominalStatistics implements Statistics { + + private static final long serialVersionUID = -7644523717916796701L; + + private long mode = -1; + + private long maxCounter = 0; + + private long[] scores; + + public NominalStatistics() {} + + /** Clone constructor. */ + private NominalStatistics(NominalStatistics other) { + this.mode = other.mode; + this.maxCounter = other.maxCounter; + if (other.scores != null) { + this.scores = new long[other.scores.length]; + for (int i = 0; i < this.scores.length; i++) { + this.scores[i] = other.scores[i]; + } + } + } + + /** Returns a clone of this statistics object. The attribute is only cloned by reference. */ + @Override + public Object clone() { + return new NominalStatistics(this); + } + + @Override + public void startCounting(Attribute attribute) { + this.scores = new long[attribute.getMapping().size()]; + this.mode = -1; + this.maxCounter = 0; + } + + @Override + public void count(double doubleIndex, double weight) { + if (!Double.isNaN(doubleIndex)) { + int index = (int) doubleIndex; + if (index >= 0) { + // more values than before? Increase Array size... + if (index >= scores.length) { + long[] newScores = new long[index + 1]; + System.arraycopy(scores, 0, newScores, 0, scores.length); + scores = newScores; + } + scores[index]++; + if (scores[index] > maxCounter) { + maxCounter = scores[index]; + mode = index; + } + } + } + } + + @Override + public boolean handleStatistics(String name) { + return MODE.equals(name) || COUNT.equals(name) || LEAST.equals(name); + } + + @Override + public double getStatistics(Attribute attribute, String name, String parameter) { + if (MODE.equals(name)) { + return this.mode; + } else if (COUNT.equals(name)) { + if (parameter != null) { + return getValueCount(attribute, parameter); + } else { + // LogService.getGlobal().log("Cannot calculate statistics COUNT for attribute "+attribute.getName()+": no value given...", + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.NominalStatistics.calculating_statistics_count_for_attribute_error", + attribute.getName()); + return Double.NaN; + } + } + if (LEAST.equals(name)) { + long minCounter = Integer.MAX_VALUE; + long least = 0; + for (int i = 0; i < scores.length; i++) { + if (scores[i] < minCounter) { + minCounter = scores[i]; + least = i; + } + } + return least; + } else { + // LogService.getGlobal().log("Cannot calculate statistics, unknown type: " + name, + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.NominalStatistics.calculating_statistics_unknown_type_error", name); + return Double.NaN; + } + } + + private long getValueCount(Attribute attribute, String value) { + if ((attribute != null) && (attribute.getMapping() != null)) { + int index = attribute.getMapping().getIndex(value); + if (index < 0) { + return -1; + } else { + return scores[index]; + } + } else { + return -1; + } + } + + @Override + public String toString() { + return "Counts: " + Arrays.toString(scores); + } +} diff --git a/src/main/java/com/rapidminer/example/NumericalStatistics.java b/src/main/java/com/rapidminer/example/NumericalStatistics.java new file mode 100644 index 000000000..74d75493a --- /dev/null +++ b/src/main/java/com/rapidminer/example/NumericalStatistics.java @@ -0,0 +1,100 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.logging.Level; + +import com.rapidminer.tools.LogService; + + +/** + * Attribute statistics object for numerical attributes. + * + * @author Ingo Mierswa + */ +public class NumericalStatistics implements Statistics { + + private static final long serialVersionUID = -6283236022093847887L; + + private double sum = 0.0d; + + private double squaredSum = 0.0d; + + private int valueCounter = 0; + + public NumericalStatistics() {} + + /** Clone constructor. */ + private NumericalStatistics(NumericalStatistics other) { + this.sum = other.sum; + this.squaredSum = other.squaredSum; + this.valueCounter = other.valueCounter; + } + + @Override + public Object clone() { + return new NumericalStatistics(this); + } + + @Override + public void startCounting(Attribute attribute) { + this.sum = 0.0d; + this.squaredSum = 0.0d; + this.valueCounter = 0; + } + + @Override + public void count(double value, double weight) { + if (!Double.isNaN(value)) { + sum += value; + squaredSum += value * value; + valueCounter++; + } + } + + @Override + public boolean handleStatistics(String name) { + return AVERAGE.equals(name) || VARIANCE.equals(name) || SUM.equals(name); + } + + @Override + public double getStatistics(Attribute attribute, String name, String parameter) { + if (AVERAGE.equals(name)) { + return this.sum / this.valueCounter; + } else if (VARIANCE.equals(name)) { + if (valueCounter <= 1) { + return 0; + } + double variance = (squaredSum - sum * sum / valueCounter) / (valueCounter - 1); + if (variance < 0) { + return 0; + } + return variance; + } else if (SUM.equals(name)) { + return this.sum; + } else { + + // LogService.getGlobal().log("Cannot calculate statistics, unknown type: " + name, + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.NumericalStatistics.calculating_statistics_unknown_type_error", name); + return Double.NaN; + } + } +} diff --git a/src/main/java/com/rapidminer/example/SimpleAttributes.java b/src/main/java/com/rapidminer/example/SimpleAttributes.java new file mode 100644 index 000000000..eaf61c548 --- /dev/null +++ b/src/main/java/com/rapidminer/example/SimpleAttributes.java @@ -0,0 +1,251 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.NoSuchElementException; + + +/** + * A very basic and simple implementation of the {@link com.rapidminer.example.Attributes} interface + * based on a linked list of {@link com.rapidminer.example.AttributeRole}s and simply delivers the + * same {@link com.rapidminer.example.AttributeRoleIterator} which might skip either regular or + * special attributes. + * + * @author Ingo Mierswa, Sebastian Land + */ +public class SimpleAttributes extends AbstractAttributes { + + private static final long serialVersionUID = 6388263725741578818L; + + private List attributes = new LinkedList<>(); + + private transient Map nameToAttributeRoleMap = new HashMap<>(); + private transient Map specialNameToAttributeRoleMap = new HashMap<>(); + + public SimpleAttributes() {} + + private SimpleAttributes(SimpleAttributes attributes) { + for (AttributeRole role : attributes.attributes) { + register((AttributeRole) role.clone(), false); + } + } + + public Object readResolve() { + if (nameToAttributeRoleMap == null) { + // in earlier versions we didn't have this map, so set it up here. anyway, the maps are + // transient. + nameToAttributeRoleMap = new HashMap<>(); + specialNameToAttributeRoleMap = new HashMap<>(); + } + for (AttributeRole attributeRole : attributes) { + register(attributeRole, true); + } + return this; + } + + @Override + public Object clone() { + return new SimpleAttributes(this); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof SimpleAttributes)) { + return false; + } + SimpleAttributes other = (SimpleAttributes) o; + return attributes.equals(other.attributes); + } + + @Override + public int hashCode() { + return attributes.hashCode(); + } + + @Override + public Iterator allAttributeRoles() { + final Iterator i = attributes.iterator(); + return new Iterator() { + + private AttributeRole current; + + @Override + public boolean hasNext() { + return i.hasNext(); + } + + @Override + public AttributeRole next() { + current = i.next(); + return current; + } + + @Override + public void remove() { + i.remove(); + unregister(current, true); + } + }; + } + + /** + * @param onlyMaps + * add only to maps, not to list. Useful for {@link #readResolve} + */ + private void register(AttributeRole attributeRole, boolean onlyMaps) { + String name = attributeRole.getAttribute().getName(); + if (nameToAttributeRoleMap.containsKey(name)) { + throw new IllegalArgumentException("Duplicate attribute name: " + name); + } + String specialName = attributeRole.getSpecialName(); + if (specialName != null) { + if (specialNameToAttributeRoleMap.containsKey(specialName)) { + throw new IllegalArgumentException("Duplicate attribute role: " + specialName); + } + } + this.nameToAttributeRoleMap.put(name, attributeRole); + if (specialName != null) { + this.specialNameToAttributeRoleMap.put(specialName, attributeRole); + } + if (!onlyMaps) { + this.attributes.add(attributeRole); + } + attributeRole.addOwner(this); + attributeRole.getAttribute().addOwner(this); + } + + /** + * + * @param onlyMap + * if true, removes the attribute only from the maps, but not from the list. this is + * useful for the iterator, which has already removed the attribute from the list. + */ + private boolean unregister(AttributeRole attributeRole, boolean onlyMap) { + if (!nameToAttributeRoleMap.containsKey(attributeRole.getAttribute().getName())) { + return false; + } + this.nameToAttributeRoleMap.remove(attributeRole.getAttribute().getName()); + if (attributeRole.getSpecialName() != null) { + this.specialNameToAttributeRoleMap.remove(attributeRole.getSpecialName()); + } + if (!onlyMap) { + this.attributes.remove(attributeRole); + } + attributeRole.removeOwner(this); + attributeRole.getAttribute().removeOwner(this); + return true; + } + + @Override + public void rename(AttributeRole attributeRole, String newSpecialName) { + if (attributeRole.getSpecialName() != null) { + AttributeRole role = specialNameToAttributeRoleMap.get(attributeRole.getSpecialName()); + if (role == null) { + throw new NoSuchElementException("Cannot rename attribute role. No such attribute role: " + + attributeRole.getSpecialName()); + } + if (role != attributeRole) { + throw new RuntimeException("Broken attribute role map."); + } + } + specialNameToAttributeRoleMap.remove(attributeRole.getSpecialName()); + if (newSpecialName != null) { + specialNameToAttributeRoleMap.put(newSpecialName, attributeRole); + } + + } + + @Override + public void rename(Attribute attribute, String newName) { + if (nameToAttributeRoleMap.containsKey(newName)) { + throw new IllegalArgumentException("Cannot rename attribute. Duplicate name: " + newName); + } + AttributeRole role = nameToAttributeRoleMap.get(attribute.getName()); + if (role == null) { + throw new NoSuchElementException("Cannot rename attribute. No such attribute: " + attribute.getName()); + } + if (role.getAttribute() != attribute) { + // this cannot happen + throw new RuntimeException("Broken attribute map."); + } + nameToAttributeRoleMap.remove(role.getAttribute().getName()); + nameToAttributeRoleMap.put(newName, role); + } + + @Override + public void add(AttributeRole attributeRole) { + register(attributeRole, false); + } + + @Override + public boolean remove(AttributeRole attributeRole) { + return unregister(attributeRole, false); + } + + @Override + public AttributeRole findRoleByName(String name, boolean caseSensitive) { + if (caseSensitive) { + return nameToAttributeRoleMap.get(name); + } else { + String lowerSearchTerm = name.toLowerCase(); + for (Entry entry : nameToAttributeRoleMap.entrySet()) { + if (lowerSearchTerm.equals(entry.getKey().toLowerCase())) { + return entry.getValue(); + } + } + return null; + } + } + + @Override + public AttributeRole findRoleBySpecialName(String specialName, boolean caseSensitive) { + if (caseSensitive) { + return specialNameToAttributeRoleMap.get(specialName); + } else { + String lowerSearchTerm = specialName.toLowerCase(); + for (Entry entry : specialNameToAttributeRoleMap.entrySet()) { + if (lowerSearchTerm.equals(entry.getKey().toLowerCase())) { + return entry.getValue(); + } + } + return null; + } + } + + @Override + public int size() { + return nameToAttributeRoleMap.size() - specialNameToAttributeRoleMap.size(); + } + + @Override + public int allSize() { + return nameToAttributeRoleMap.size(); + } + + @Override + public int specialSize() { + return specialNameToAttributeRoleMap.size(); + } +} diff --git a/src/main/java/com/rapidminer/example/Statistics.java b/src/main/java/com/rapidminer/example/Statistics.java new file mode 100644 index 000000000..1548988be --- /dev/null +++ b/src/main/java/com/rapidminer/example/Statistics.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.io.Serializable; + + +/** + * The superclass for all attribute statistics objects. + * + * @author Ingo Mierswa + */ +public interface Statistics extends Serializable { + + public static final String UNKNOWN = "unknown"; + public static final String AVERAGE = "average"; + public static final String AVERAGE_WEIGHTED = "average_weighted"; + public static final String VARIANCE = "variance"; + public static final String VARIANCE_WEIGHTED = "variance_weighted"; + public static final String MINIMUM = "minimum"; + public static final String MAXIMUM = "maximum"; + public static final String MODE = "mode"; + public static final String LEAST = "least"; + public static final String COUNT = "count"; + public static final String SUM = "sum"; + public static final String SUM_WEIGHTED = "sum_weighted"; + + public Object clone(); + + public void startCounting(Attribute attribute); + + public void count(double value, double weight); + + public boolean handleStatistics(String statisticsName); + + public double getStatistics(Attribute attribute, String statisticsName, String parameter); + +} diff --git a/src/main/java/com/rapidminer/example/Tools.java b/src/main/java/com/rapidminer/example/Tools.java new file mode 100644 index 000000000..2a521217e --- /dev/null +++ b/src/main/java/com/rapidminer/example/Tools.java @@ -0,0 +1,669 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import com.rapidminer.example.set.AttributeWeightedExampleSet; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.DoubleArrayDataRow; +import com.rapidminer.example.table.MemoryExampleTable; +import com.rapidminer.example.table.NominalMapping; +import com.rapidminer.generator.FeatureGenerator; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorCreationException; +import com.rapidminer.operator.OperatorException; +import com.rapidminer.operator.UserError; +import com.rapidminer.operator.ports.metadata.AttributeMetaData; +import com.rapidminer.operator.ports.metadata.ExampleSetMetaData; +import com.rapidminer.operator.preprocessing.IdTagging; +import com.rapidminer.tools.Ontology; +import com.rapidminer.tools.OperatorService; +import com.rapidminer.tools.RandomGenerator; +import com.rapidminer.tools.math.sampling.OrderedSamplingWithoutReplacement; + + +/** + * Provides some tools for calculation of certain measures and feature generation. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class Tools { + + // ================================================================================ + // -------------------- Tools -------------------- + // ================================================================================ + + public static String[] getAllAttributeNames(ExampleSet exampleSet) { + String[] attributeNames = new String[exampleSet.getAttributes().allSize()]; + int counter = 0; + Iterator a = exampleSet.getAttributes().allAttributes(); + while (a.hasNext()) { + Attribute attribute = a.next(); + attributeNames[counter++] = attribute.getName(); + } + return attributeNames; + } + + public static String[] getRegularAttributeNames(ExampleSet exampleSet) { + String[] attributeNames = new String[exampleSet.getAttributes().size()]; + int counter = 0; + for (Attribute attribute : exampleSet.getAttributes()) { + attributeNames[counter++] = attribute.getName(); + } + return attributeNames; + } + + public static String[] getRegularAttributeConstructions(ExampleSet exampleSet) { + String[] attributeNames = new String[exampleSet.getAttributes().size()]; + int counter = 0; + for (Attribute attribute : exampleSet.getAttributes()) { + // is generated + if (!attribute.getConstruction().equals(attribute.getName()) && !attribute.getConstruction().startsWith("gens")) { + attributeNames[counter++] = attribute.getConstruction(); + } else { + attributeNames[counter++] = attribute.getName(); + } + } + return attributeNames; + } + + // ================================================================================ + // -------------------- GENERATION -------------------- + // ================================================================================ + + public static Attribute[] createRegularAttributeArray(ExampleSet exampleSet) { + Attribute[] attributes = new Attribute[exampleSet.getAttributes().size()]; + int counter = 0; + for (Attribute attribute : exampleSet.getAttributes()) { + attributes[counter++] = attribute; + } + return attributes; + } + + public static Attribute[] getRandomCompatibleAttributes(ExampleSet exampleSet, FeatureGenerator generator, + String[] functions, Random random) { + List inputAttributes = generator.getInputCandidates(exampleSet, functions); + if (inputAttributes.size() > 0) { + return inputAttributes.get(random.nextInt(inputAttributes.size())); + } else { + return null; + } + } + + public static Attribute[] getWeightedCompatibleAttributes(AttributeWeightedExampleSet exampleSet, + FeatureGenerator generator, String[] functions, RandomGenerator random) { + List inputAttributes = generator.getInputCandidates(exampleSet, functions); + double[] probs = new double[inputAttributes.size()]; + double probSum = 0.0d; + Iterator i = inputAttributes.iterator(); + int k = 0; + while (i.hasNext()) { + Attribute[] candidate = i.next(); + for (int j = 0; j < candidate.length; j++) { + double weight = exampleSet.getWeight(candidate[j]); + probSum += weight; + probs[k] = weight; + } + } + for (int j = 0; j < probs.length; j++) { + probs[j] /= probSum; + } + return inputAttributes.get(random.randomIndex(probs)); + } + + /** + * Creates and adds the new attributes to the given example set + */ + public static Attribute createSpecialAttribute(ExampleSet exampleSet, String name, int valueType) { + Attribute attribute = AttributeFactory.createAttribute(name, valueType); + exampleSet.getExampleTable().addAttribute(attribute); + exampleSet.getAttributes().setSpecialAttribute(attribute, name); + return attribute; + } + + public static AttributeMetaData createWeightAttributeMetaData(ExampleSetMetaData emd) { + return new AttributeMetaData(Attributes.WEIGHT_NAME, Ontology.REAL, Attributes.WEIGHT_NAME); + } + + /** + * This method adds a new Weight Attribute initialized with 1.0d for each example to the example + * table as well as to the given ExampleSet. + */ + public static Attribute createWeightAttribute(ExampleSet exampleSet) { + Attribute weight = exampleSet.getAttributes().getWeight(); + if (weight != null) { + exampleSet.getLog().logWarning("ExampleSet.createWeightAttribute(): Overwriting old weight attribute!"); + } + + weight = AttributeFactory.createAttribute(Attributes.WEIGHT_NAME, Ontology.REAL); + exampleSet.getExampleTable().addAttribute(weight); + exampleSet.getAttributes().setWeight(weight); + + for (Example example : exampleSet) { + example.setValue(weight, 1d); + } + return weight; + } + + public static boolean containsValueType(ExampleSet exampleSet, int valueType) { + for (Attribute attribute : exampleSet.getAttributes()) { + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(attribute.getValueType(), valueType)) { + return true; + } + } + return false; + } + + /** + * Replaces the given real value by the new one. Please note that this method will only work for + * nominal attributes. + */ + public static void replaceValue(Attribute attribute, String oldValue, String newValue) { + if (!attribute.isNominal()) { + throw new RuntimeException("Example-Tools: replaceValue is only supported for nominal attributes."); + } + NominalMapping mapping = attribute.getMapping(); + int oldIndex = mapping.getIndex(oldValue); + if (oldIndex < 0) { + throw new RuntimeException( + "Example-Tools: replaceValue cannot be performed since old value was not defined in the attribute."); + } + mapping.setMapping(newValue, oldIndex); + } + + /** + * Replaces the given value by the new one. This method will only work for nominal attributes. + */ + public static void replaceValue(ExampleSet exampleSet, Attribute attribute, String oldValue, String newValue) { + if (!attribute.isNominal()) { + throw new RuntimeException("Example-Tools: replaceValue is only supported for nominal attributes."); + } + NominalMapping mapping = attribute.getMapping(); + if (oldValue.equals("?")) { + for (Example example : exampleSet) { + if (Double.isNaN(example.getValue(attribute))) { + example.setValue(attribute, mapping.mapString(newValue)); + } + } + } else { + int oldIndex = mapping.getIndex(oldValue); + if (oldIndex < 0) { + throw new RuntimeException( + "Example-Tools: replaceValue cannot be performed since old value was not defined in the attribute."); + } + if (newValue.equals("?")) { + for (Example example : exampleSet) { + int index = mapping.getIndex(example.getValueAsString(attribute)); + if (index == oldIndex) { + example.setValue(attribute, Double.NaN); + } + } + return; + } + int newIndex = mapping.getIndex(newValue); + if (newIndex >= 0) { + for (Example example : exampleSet) { + int index = mapping.getIndex(example.getValueAsString(attribute)); + if (index == oldIndex) { + example.setValue(attribute, newIndex); + } + } + } else { + mapping.setMapping(newValue, oldIndex); + } + } + } + + /** + * Replaces the given real value by the new one. Please note that this method will only properly + * work for numerical attributes since for nominal attributes no remapping is performed. Please + * note also that this method performs a data scan. + */ + public static void replaceValue(ExampleSet exampleSet, Attribute attribute, double oldValue, double newValue) { + for (Example example : exampleSet) { + double value = example.getValue(attribute); + if (Double.isNaN(oldValue) && Double.isNaN(value)) { + example.setValue(attribute, newValue); + continue; + } + if (com.rapidminer.tools.Tools.isEqual(value, oldValue)) { + example.setValue(attribute, newValue); + } + } + } + + /** + * Returns true if value and block types of the first attribute are subtypes of value and block + * type of the second. + */ + public static boolean compatible(Attribute first, Attribute second) { + return Ontology.ATTRIBUTE_VALUE_TYPE.isA(first.getValueType(), second.getValueType()) + && Ontology.ATTRIBUTE_BLOCK_TYPE.isA(first.getBlockType(), second.getBlockType()); + } + + // ================================================================================ + // P r o b a b i l t i e s + // ================================================================================ + + public static double getAverageWeight(AttributeWeightedExampleSet exampleSet) { + int counter = 0; + double weightSum = 0.0d; + for (Attribute attribute : exampleSet.getAttributes()) { + double weight = exampleSet.getWeight(attribute); + if (!Double.isNaN(weight)) { + weightSum += Math.abs(weight); + counter++; + } + } + return weightSum / counter; + } + + public static double[] getProbabilitiesFromWeights(Attribute[] attributes, AttributeWeightedExampleSet exampleSet) { + return getProbabilitiesFromWeights(attributes, exampleSet, false); + } + + public static double[] getInverseProbabilitiesFromWeights(Attribute[] attributes, AttributeWeightedExampleSet exampleSet) { + return getProbabilitiesFromWeights(attributes, exampleSet, true); + } + + /** + * Calculates probabilities for attribute selection purposes based on the given weight. + * Attributes whose weight is not defined in the weight vector get a probability corresponding + * to the average weight. Inverse probabilities can be calculated for cases where attributes + * with a high weight should be selected with small probability. + */ + public static double[] getProbabilitiesFromWeights(Attribute[] attributes, AttributeWeightedExampleSet exampleSet, + boolean inverse) { + double weightSum = 0.0d; + int counter = 0; + for (int i = 0; i < attributes.length; i++) { + double weight = exampleSet.getWeight(attributes[i]); + if (!Double.isNaN(weight)) { + weightSum += Math.abs(weight); + counter++; + } + } + double weightAverage = weightSum / counter; + weightSum += (attributes.length - counter) * weightAverage; + + double[] probs = new double[attributes.length]; + for (int i = 0; i < probs.length; i++) { + double weight = exampleSet.getWeight(attributes[i]); + if (Double.isNaN(weight)) { + probs[i] = weightAverage / weightSum; + } else { + probs[i] = inverse ? (2 * weightAverage - Math.abs(weight)) / weightSum : Math.abs(weight) / weightSum; + } + } + return probs; + } + + public static Attribute selectAttribute(Attribute[] attributes, double[] probs, Random random) { + double r = random.nextDouble(); + double sum = 0.0d; + for (int i = 0; i < attributes.length; i++) { + sum += probs[i]; + if (r < sum) { + return attributes[i]; + } + } + return attributes[attributes.length - 1]; + } + + public static boolean isDefault(double defaultValue, double value) { + if (Double.isNaN(defaultValue)) { + return Double.isNaN(value); + } + /* + * Don't use infinity. if (Double.isInfinite(defaultValue)) return Double.isInfinite(value); + */ + return defaultValue == value; + } + + /** + * The data set is not allowed to contain missing values. If it does, a {@link UserError} is + * thrown. + * + * @param exampleSet + * the {@link ExampleSet} to check + * @param task + * will be shown as the origin of the error + **/ + @Deprecated + public static void onlyNonMissingValues(ExampleSet exampleSet, String task) throws OperatorException { + onlyNonMissingValues(exampleSet, task, null, new String[] {}); + } + + /** + * The data set is not allowed to contain missing values. If it does, a {@link UserError} is + * thrown. + * + * @param exampleSet + * the {@link ExampleSet} to check + * @param task + * will be shown as the origin of the error + * @param operator + * the offending operator. Can be null + **/ + public static void onlyNonMissingValues(ExampleSet exampleSet, String task, Operator operator) throws OperatorException { + List specialAttList = new LinkedList<>(); + Iterator specialAttributes = exampleSet.getAttributes().specialAttributes(); + while (specialAttributes.hasNext()) { + specialAttList.add(specialAttributes.next().getSpecialName()); + } + onlyNonMissingValues(exampleSet, task, operator, specialAttList.toArray(new String[specialAttList.size()])); + } + + /** + * The data set is not allowed to contain missing values. If it does, a {@link UserError} is + * thrown. Special attributes will be ignored, except they are explicitly listed at + * specialAttributes. Furthermore, if a specified special attribute does not exist a + * {@link UserError} is also thrown! + * + * @param exampleSet + * the {@link ExampleSet} to check + * @param task + * will be shown as the origin of the error + * @param operator + * the offending operator. Can be null + * @param specialAttributes + * contains the special attributes which have to be checked. If a listed attribute + * does not exist or contains missing values, a {@link UserError} is thrown + **/ + public static void onlyNonMissingValues(ExampleSet exampleSet, String task, Operator operator, + String... specialAttributes) throws OperatorException { + HashSet specialToCheck = new HashSet<>(); + + for (int i = 0; i < specialAttributes.length; i++) { + Attribute att = exampleSet.getAttributes().getSpecial(specialAttributes[i]); + if (att != null) { + specialToCheck.add(att); + } else { + throw new UserError(operator, "113", specialAttributes[i]); + } + } + + for (Example example : exampleSet) { + if (operator != null) { + operator.checkForStop(); + } + Iterator allAttributes = example.getAttributes().allAttributeRoles(); + while (allAttributes.hasNext()) { + AttributeRole att = allAttributes.next(); + if (!att.isSpecial() || specialToCheck.contains(att.getAttribute())) { + if (Double.isNaN(example.getValue(att.getAttribute()))) { + throw new UserError(operator, 139, task); + } + } + } + } + } + + /** + * The attributes all have to be numerical. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void onlyNumericalAttributes(ExampleSet es, String task) throws OperatorException { + onlyNumericalAttributes(es.getAttributes(), task); + } + + /** + * The attributes all have to be numerical. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void onlyNumericalAttributes(Attributes attributes, String task) throws OperatorException { + for (Attribute attribute : attributes) { + if (!Ontology.ATTRIBUTE_VALUE_TYPE.isA(attribute.getValueType(), Ontology.NUMERICAL)) { + throw new UserError(null, 104, task, attribute.getName()); + } + } + } + + /** + * The attributes all have to be nominal or binary. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void onlyNominalAttributes(ExampleSet es, String task) throws OperatorException { + onlyNominalAttributes(es.getAttributes(), task); + } + + /** + * The attributes all have to be nominal or binary. + * + * @throws OperatorException + */ + public static void onlyNominalAttributes(Attributes attributes, String task) throws OperatorException { + for (Attribute attribute : attributes) { + if (!Ontology.ATTRIBUTE_VALUE_TYPE.isA(attribute.getValueType(), Ontology.NOMINAL)) { + throw new UserError(null, 103, task, attribute.getName()); + } + } + } + + /** + * The attributes all have to be nominal and have a maximum of two values or binominal. + * + * @param exampleSet + * the example set + * @throws OperatorException + * + */ + public static void maximumTwoNominalAttributes(ExampleSet exampleSet, String task) throws OperatorException { + for (Attribute attribute : exampleSet.getAttributes()) { + int valueType = attribute.getValueType(); + boolean throwError = false; + if (!Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL)) { + throwError = true; + } + if (valueType == Ontology.NOMINAL) { + if (attribute.getMapping().size() > 2) { + throwError = true; + } + } + if (throwError) { + throw new UserError(null, 114, task, attribute.getName()); + } + } + } + + /** + * The example set has to contain labels. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void isLabelled(ExampleSet es) throws OperatorException { + if (es.getAttributes().getLabel() == null) { + throw new UserError(null, 105); + } + } + + /** + * The example set has to be tagged with ids. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void isIdTagged(ExampleSet es) throws OperatorException { + if (es.getAttributes().getId() == null) { + throw new UserError(null, 129); + } + } + + /** + * The example set has to have ids. If no id attribute is available, it will be automatically + * created with help of the IDTagging operator. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void checkAndCreateIds(ExampleSet es) throws OperatorException { + if (es.getAttributes().getId() == null) { + try { + // create ids (and visualization) + IdTagging idTagging = OperatorService.createOperator(IdTagging.class); + idTagging.apply(es); + } catch (OperatorCreationException e) { + throw new UserError(null, 129); + } + } + } + + public static void checkIds(ExampleSet exampleSet) throws UserError { + if (exampleSet.getAttributes().getId() == null) { + throw new UserError(null, 129); + } + } + + /** + * The example set has to have nominal labels. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void hasNominalLabels(ExampleSet es) throws OperatorException { + isLabelled(es); + Attribute a = es.getAttributes().getLabel(); + if (!Ontology.ATTRIBUTE_VALUE_TYPE.isA(a.getValueType(), Ontology.NOMINAL)) { + throw new UserError(null, 101, "clustering", a.getName()); + } + } + + /** + * The example set has to contain at least one example. + * + * @param es + * the example set + * @throws OperatorException + */ + public static void isNonEmpty(ExampleSet es) throws OperatorException { + if (es.size() == 0) { + throw new UserError(null, 117); + } + } + + /** + * Returns a new example set based on a fresh memory example table sampled from the given set. + */ + public static ExampleSet getLinearSubsetCopy(ExampleSet exampleSet, int size, int offset) { + Map specialMap = new HashMap<>(); + List attributes = new LinkedList<>(); + Iterator a = exampleSet.getAttributes().allAttributeRoles(); + while (a.hasNext()) { + AttributeRole role = a.next(); + Attribute clone = (Attribute) role.getAttribute().clone(); + attributes.add(clone); + if (role.isSpecial()) { + specialMap.put(clone, role.getSpecialName()); + } + } + + MemoryExampleTable table = new MemoryExampleTable(attributes); + int maxSize = exampleSet.size(); + for (int i = offset; i < offset + size && i < maxSize; i++) { + Example example = exampleSet.getExample(i); + Iterator allI = exampleSet.getAttributes().allAttributes(); + int counter = 0; + double[] dataRow = new double[attributes.size()]; + while (allI.hasNext()) { + dataRow[counter++] = example.getValue(allI.next()); + } + table.addDataRow(new DoubleArrayDataRow(dataRow)); + } + + return table.createExampleSet(specialMap); + } + + /** + * Returns a new example set based on a fresh memory example table sampled from the given set. + */ + public static ExampleSet getShuffledSubsetCopy(ExampleSet exampleSet, int size, RandomGenerator randomGenerator) { + int[] selectedIndices = OrderedSamplingWithoutReplacement + .getSampledIndices(randomGenerator, exampleSet.size(), size); + Map specialMap = new HashMap<>(); + List attributes = new LinkedList<>(); + Iterator a = exampleSet.getAttributes().allAttributeRoles(); + while (a.hasNext()) { + AttributeRole role = a.next(); + Attribute clone = (Attribute) role.getAttribute().clone(); + attributes.add(clone); + if (role.isSpecial()) { + specialMap.put(clone, role.getSpecialName()); + } + } + + MemoryExampleTable table = new MemoryExampleTable(attributes); + + for (int i = 0; i < selectedIndices.length; i++) { + Example example = exampleSet.getExample(selectedIndices[i]); + Iterator allI = exampleSet.getAttributes().allAttributes(); + int counter = 0; + double[] dataRow = new double[attributes.size()]; + while (allI.hasNext()) { + dataRow[counter++] = example.getValue(allI.next()); + } + table.addDataRow(new DoubleArrayDataRow(dataRow)); + } + + return table.createExampleSet(specialMap); + } + + /** + * Check if the childMapping is a subset of the superMapping or equal to it. + * + * @param childMapping + * the potential subset you want to check + * @param superMapping + * the {@link NominalMapping} you want to check against + * @return will return true if the {@link NominalMapping} is a subset or equal else false will + * be returned + */ + public static boolean isNominalMappingSubsetOrEqualTo(NominalMapping childMapping, NominalMapping superMapping) { + if (childMapping.size() > superMapping.size()) { + return false; + } + List superList = superMapping.getValues(); + for (String value : childMapping.getValues()) { + if (!superList.contains(value)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/rapidminer/example/UnknownStatistics.java b/src/main/java/com/rapidminer/example/UnknownStatistics.java new file mode 100644 index 000000000..3d57d071c --- /dev/null +++ b/src/main/java/com/rapidminer/example/UnknownStatistics.java @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * The superclass for all attribute statistics objects. + * + * @author Ingo Mierswa + */ +public class UnknownStatistics implements Statistics { + + private static final long serialVersionUID = 217609774484151520L; + + private int unknownCounter = 0; + + public UnknownStatistics() {} + + /** Clone constructor. */ + private UnknownStatistics(UnknownStatistics other) { + this.unknownCounter = other.unknownCounter; + } + + @Override + public Object clone() { + return new UnknownStatistics(this); + } + + @Override + public void startCounting(Attribute attribute) { + this.unknownCounter = 0; + } + + @Override + public void count(double value, double weight) { + if (Double.isNaN(value)) { + unknownCounter++; + } + } + + @Override + public double getStatistics(Attribute attribute, String statisticsName, String parameter) { + if (UNKNOWN.equals(statisticsName)) { + return unknownCounter; + } else { + // LogService.getGlobal().log("Cannot calculate statistics, unknown type: " + + // statisticsName, LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.UnknownStatistics.calculating_statistics_unknown_type_error", statisticsName); + return Double.NaN; + } + } + + @Override + public boolean handleStatistics(String statisticsName) { + return UNKNOWN.equals(statisticsName); + } + + @Override + public String toString() { + return "unknown: " + this.unknownCounter; + } +} diff --git a/src/main/java/com/rapidminer/example/WeightedNumericalStatistics.java b/src/main/java/com/rapidminer/example/WeightedNumericalStatistics.java new file mode 100644 index 000000000..8b379727d --- /dev/null +++ b/src/main/java/com/rapidminer/example/WeightedNumericalStatistics.java @@ -0,0 +1,103 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * Attribute statistics object for weighted numerical attributes. + * + * @author Ingo Mierswa, Tobias Malbrecht + */ +public class WeightedNumericalStatistics implements Statistics { + + private static final long serialVersionUID = -6283236022093847887L; + + private double sum = 0.0d; + + private double squaredSum = 0.0d; + + private double totalWeight = 0.0d; + + private double count = 0.0d; + + public WeightedNumericalStatistics() {} + + /** Clone constructor. */ + private WeightedNumericalStatistics(WeightedNumericalStatistics other) { + this.sum = other.sum; + this.squaredSum = other.squaredSum; + this.totalWeight = other.totalWeight; + this.count = other.count; + } + + @Override + public Object clone() { + return new WeightedNumericalStatistics(this); + } + + @Override + public void startCounting(Attribute attribute) { + this.sum = 0.0d; + this.squaredSum = 0.0d; + this.totalWeight = 0; + this.count = 0; + } + + @Override + public void count(double value, double weight) { + if (Double.isNaN(weight)) { + weight = 1.0d; + } + if (!Double.isNaN(value)) { + sum += (weight * value); + squaredSum += weight * value * value; + totalWeight += weight; + count++; + } + } + + @Override + public boolean handleStatistics(String name) { + return AVERAGE_WEIGHTED.equals(name) || VARIANCE_WEIGHTED.equals(name) || SUM_WEIGHTED.equals(name); + } + + @Override + public double getStatistics(Attribute attribute, String name, String parameter) { + if (AVERAGE_WEIGHTED.equals(name)) { + return this.sum / this.totalWeight; + } else if (VARIANCE_WEIGHTED.equals(name)) { + if (count <= 1) { + return 0; + } + return (squaredSum - (sum * sum) / totalWeight) / (((count - 1) / count) * totalWeight); + } else if (SUM_WEIGHTED.equals(name)) { + return this.sum; + } else { + // LogService.getGlobal().log("Cannot calculate statistics, unknown type: " + name, + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.WeightedNumericalStatistics.calculating_statistics_unknown_type_error", name); + return Double.NaN; + } + } +} diff --git a/src/main/java/com/rapidminer/example/package.html b/src/main/java/com/rapidminer/example/package.html new file mode 100644 index 000000000..7bdc65aea --- /dev/null +++ b/src/main/java/com/rapidminer/example/package.html @@ -0,0 +1,15 @@ + + + + + + + + +The data core classes of RapidMiner. These perform both data and attribute handling. The +basic idea is that of a small database management system: the data itself is stored in an +example table (please note that this interface can stand for all types of data sources, +memory, databases, and files) and views on this table (example sets) are provided. + + + diff --git a/src/main/java/com/rapidminer/example/set/AbstractExampleReader.java b/src/main/java/com/rapidminer/example/set/AbstractExampleReader.java new file mode 100644 index 000000000..9bfad2ab7 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AbstractExampleReader.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.ExampleReader; + + +/** + * Abstract implementation which implements the method remove by throwing a + * {@link java.lang.UnsupportedOperationException}. + * + * @author Ingo Mierswa + */ +public abstract class AbstractExampleReader implements ExampleReader { + + @Override + public void remove() { + throw new UnsupportedOperationException("The 'remove' operation is not supported by ExampleReaders!"); + } +} diff --git a/src/main/java/com/rapidminer/example/set/AbstractExampleSet.java b/src/main/java/com/rapidminer/example/set/AbstractExampleSet.java new file mode 100644 index 000000000..082dceb16 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AbstractExampleSet.java @@ -0,0 +1,547 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.datatable.DataTable; +import com.rapidminer.datatable.DataTableExampleSetAdapter; +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.AttributeWeights; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Statistics; +import com.rapidminer.example.table.SparseFormatDataRowReader; +import com.rapidminer.io.process.XMLTools; +import com.rapidminer.operator.IOContainer; +import com.rapidminer.operator.IOObject; +import com.rapidminer.operator.MissingIOObjectException; +import com.rapidminer.operator.ResultObjectAdapter; +import com.rapidminer.tools.Ontology; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.XMLException; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.zip.GZIPOutputStream; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + + +/** + * Implements wrapper methods of abstract example set. Implements all ResultObject methods.
+ * + * Apart from the interface methods the implementing classes must have a public single argument + * clone constructor. This constructor is invoked by reflection from the clone method. Do not forget + * to call the superclass method. + * + * @author Ingo Mierswa, Simon Fischer + */ +public abstract class AbstractExampleSet extends ResultObjectAdapter implements ExampleSet { + + private static final long serialVersionUID = 8596141056047402798L; + + /** Maps attribute names to list of statistics objects. */ + private final Map> statisticsMap = new HashMap>(); + + /** Maps the id values on the line index in the example table. */ + private Map idMap = new HashMap(); + + /** This method overrides the implementation of ResultObjectAdapter and returns "ExampleSet". */ + @Override + public String getName() { + return "ExampleSet"; + } + + @Override + public Example getExampleFromId(double id) { + int[] indices = idMap.get(id); + if (indices != null && indices.length > 0) { + return getExample(indices[0]); + } else { + return null; + } + } + + @Override + public int[] getExampleIndicesFromId(double id) { + return idMap.get(id); + } + + // --- Visualisation and toString() methods --- + + @Override + public String toString() { + StringBuffer str = new StringBuffer(this.getClass().getSimpleName() + ":" + Tools.getLineSeparator()); + str.append(size() + " examples," + Tools.getLineSeparator()); + str.append(getAttributes().size() + " regular attributes," + Tools.getLineSeparator()); + + boolean first = true; + Iterator s = getAttributes().specialAttributes(); + while (s.hasNext()) { + if (first) { + str.append("special attributes = {" + Tools.getLineSeparator()); + first = false; + } + AttributeRole special = s.next(); + str.append(" " + special.getSpecialName() + " = " + special.getAttribute() + Tools.getLineSeparator()); + } + + if (!first) { + str.append("}"); + } else { + str.append("no special attributes" + Tools.getLineSeparator()); + } + + return str.toString(); + } + + /** + * This method is used to create a {@link DataTable} from this example set. The default + * implementation returns an instance of {@link DataTableExampleSetAdapter}. The given + * IOContainer is used to check if there are compatible attribute weights which would used as + * column weights of the returned table. Subclasses might want to override this method in order + * to allow for other data tables. + */ + public DataTable createDataTable(IOContainer container) { + AttributeWeights weights = null; + if (container != null) { + try { + weights = container.get(AttributeWeights.class); + for (Attribute attribute : getAttributes()) { + double weight = weights.getWeight(attribute.getName()); + if (Double.isNaN(weight)) { // not compatible + weights = null; + break; + } + } + } catch (MissingIOObjectException e) { + } + } + return new DataTableExampleSetAdapter(this, weights); + } + + // -------------------- File Writing -------------------- + + @Override + public void writeDataFile(File dataFile, int fractionDigits, boolean quoteNominal, boolean zipped, boolean append, + Charset encoding) throws IOException { + PrintWriter out = null; + OutputStream outStream = null; + try { + if (zipped) { + outStream = new GZIPOutputStream(new FileOutputStream(dataFile, append)); + } else { + outStream = new FileOutputStream(dataFile, append); + } + out = new PrintWriter(new OutputStreamWriter(outStream, encoding)); + Iterator reader = iterator(); + while (reader.hasNext()) { + out.println(reader.next().toDenseString(fractionDigits, quoteNominal)); + } + } catch (IOException e) { + throw e; + } finally { + if (out != null) { + out.close(); + } + if (outStream != null) { + outStream.close(); + } + } + } + + /** Writes the data into a sparse file format. */ + @Override + public void writeSparseDataFile(File dataFile, int format, int fractionDigits, boolean quoteNominal, boolean zipped, + boolean append, Charset encoding) throws IOException { + PrintWriter out = null; + OutputStream outStream = null; + try { + if (zipped) { + outStream = new GZIPOutputStream(new FileOutputStream(dataFile, append)); + } else { + outStream = new FileOutputStream(dataFile, append); + } + out = new PrintWriter(new OutputStreamWriter(outStream, encoding)); + Iterator reader = iterator(); + while (reader.hasNext()) { + out.println(reader.next().toSparseString(format, fractionDigits, quoteNominal)); + } + } catch (IOException e) { + throw e; + } finally { + if (out != null) { + out.close(); + } + if (outStream != null) { + outStream.close(); + } + } + } + + /** + * Writes the attribute descriptions for all examples. Writes first all regular attributes and + * then the special attributes (just like the data write format of {@link Example#toString()}. + * Please note that the given data file will only be used to determine the relative position. + */ + @Override + public void writeAttributeFile(File attFile, File dataFile, Charset encoding) throws IOException { + // determine relative path + if (dataFile == null) { + throw new IOException("ExampleSet writing: cannot determine path to data file: data file was not given!"); + } + String relativePath = Tools.getRelativePath(dataFile, attFile); + + try { + // building DOM + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + + Element root = document.createElement("attributeset"); + root.setAttribute("default_source", relativePath); + root.setAttribute("encoding", encoding.name()); + document.appendChild(root); + + int sourcecol = 1; + Iterator i = getAttributes().allAttributeRoles(); + while (i.hasNext()) { + root.appendChild(writeAttributeMetaData(i.next(), sourcecol, document, false)); + sourcecol++; + } + + // writing XML from DOM + PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(attFile), encoding)); + writer.print(XMLTools.toString(document, encoding)); + writer.close(); + } catch (ParserConfigurationException e) { + throw new IOException("Cannot create XML document builder: " + e, e); + } catch (XMLException e) { + throw new IOException("Could not format XML document:" + e, e); + } + } + + /** + * Writes the attribute descriptions for all examples. Writes only the special attributes which + * are supported by the sparse format of the method + * {@link Example#toSparseString(int, int, boolean)}. Please note that the given data file is + * only be used to determine the relative position. + */ + @Override + public void writeSparseAttributeFile(File attFile, File dataFile, int format, Charset encoding) throws IOException { + if (dataFile == null) { + throw new IOException("ExampleSet sparse writing: cannot determine path to data file: data file was not given!"); + } + + String relativePath = Tools.getRelativePath(dataFile, attFile); + + try { + // building DOM + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + + Element root = document.createElement("attributeset"); + root.setAttribute("default_source", relativePath); + root.setAttribute("encoding", encoding.name()); + document.appendChild(root); + + // special attributes + AttributeRole labelRole = getAttributes().getRole(Attributes.LABEL_NAME); + if ((labelRole != null) && (format != SparseFormatDataRowReader.FORMAT_NO_LABEL)) { + root.appendChild(writeAttributeMetaData(labelRole, 0, document, true)); + } + AttributeRole idRole = getAttributes().getRole(Attributes.ID_NAME); + if (idRole != null) { + root.appendChild(writeAttributeMetaData(idRole, 0, document, true)); + } + AttributeRole weightRole = getAttributes().getRole(Attributes.WEIGHT_NAME); + if (weightRole != null) { + root.appendChild(writeAttributeMetaData(weightRole, 0, document, true)); + } + + // regular attributes + int sourcecol = 1; + for (Attribute attribute : getAttributes()) { + root.appendChild(writeAttributeMetaData("attribute", attribute, sourcecol, document, false)); + sourcecol++; + } + + // writing XML from DOM + PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(attFile), encoding)); + writer.print(XMLTools.toString(document, encoding)); + writer.close(); + } catch (ParserConfigurationException e) { + throw new IOException("Cannot create XML document builder: " + e, e); + } catch (XMLException e) { + throw new IOException("Could not format XML document:" + e, e); + } + } + + /** Writes the data of this attribute in the given stream. */ + private Element writeAttributeMetaData(AttributeRole attributeRole, int sourcecol, Document document, boolean sparse) { + String tag = "attribute"; + if (attributeRole.isSpecial()) { + tag = attributeRole.getSpecialName(); + } + Attribute attribute = attributeRole.getAttribute(); + return writeAttributeMetaData(tag, attribute, sourcecol, document, sparse); + } + + /** Writes the data of this attribute in the given stream. */ + private Element writeAttributeMetaData(String tag, Attribute attribute, int sourcecol, Document document, boolean sparse) { + Element attributeElement = document.createElement(tag); + attributeElement.setAttribute("name", attribute.getName()); + if (!sparse || tag.equals("attribute")) { + attributeElement.setAttribute("sourcecol", sourcecol + ""); + } + attributeElement.setAttribute("valuetype", Ontology.ATTRIBUTE_VALUE_TYPE.mapIndex(attribute.getValueType())); + if (!Ontology.ATTRIBUTE_BLOCK_TYPE.isA(attribute.getBlockType(), Ontology.SINGLE_VALUE)) { + attributeElement.setAttribute("blocktype", Ontology.ATTRIBUTE_BLOCK_TYPE.mapIndex(attribute.getBlockType())); + } + + // nominal values + if ((Ontology.ATTRIBUTE_VALUE_TYPE.isA(attribute.getValueType(), Ontology.NOMINAL)) + && (!tag.equals(Attributes.KNOWN_ATTRIBUTE_TYPES[Attributes.TYPE_ID]))) { + for (String nominalValue : attribute.getMapping().getValues()) { + Element valueElement = document.createElement("value"); + valueElement.setTextContent(nominalValue); + attributeElement.appendChild(valueElement); + } + } + return attributeElement; + } + + public String getExtension() { + return "aml"; + } + + public String getFileDescription() { + return "attribute description file"; + } + + /** + * Returns true, if all attributes including labels and other special attributes are equal. + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof ExampleSet)) { + return false; + } + ExampleSet es = (ExampleSet) o; + return getAttributes().equals(es.getAttributes()); + } + + /** Returns the hash code of all attributes. */ + @Override + public int hashCode() { + return getAttributes().hashCode(); + } + + @Override + public IOObject copy() { + return clone(); + } + + /** + * Clones the example set by invoking a single argument clone constructor. Please note that a + * cloned example set has no information about the attribute statistics. That means, that + * attribute statistics must be (re-)calculated after the clone was created. + */ + @Override + public ExampleSet clone() { + try { + Class clazz = getClass(); + java.lang.reflect.Constructor cloneConstructor = clazz.getConstructor(new Class[] { clazz }); + AbstractExampleSet result = (AbstractExampleSet) cloneConstructor.newInstance(new Object[] { this }); + result.idMap = this.idMap; + return result; + } catch (IllegalAccessException e) { + throw new RuntimeException("Cannot clone ExampleSet: " + e.getMessage()); + } catch (NoSuchMethodException e) { + throw new RuntimeException("'" + getClass().getName() + "' does not implement clone constructor!"); + } catch (java.lang.reflect.InvocationTargetException e) { + throw new RuntimeException("Cannot clone " + getClass().getName() + ": " + e + ". Target: " + + e.getTargetException() + ". Cause: " + e.getCause() + "."); + } catch (InstantiationException e) { + throw new RuntimeException("Cannot clone " + getClass().getName() + ": " + e); + } + } + + // ============================================================================= + + @Override + public void remapIds() { + idMap = new HashMap(size()); + Attribute idAttribute = getAttributes().getSpecial(Attributes.ID_NAME); + if (idAttribute != null) { + int index = 0; + for (Example example : this) { + double value = example.getValue(idAttribute); + if (!Double.isNaN(value)) { + if (idMap.containsKey(value)) { + int[] indices = idMap.get(value); + int[] newIndices = new int[indices.length + 1]; + for (int i = 0; i < indices.length; i++) { + newIndices[i] = indices[i]; + } + newIndices[newIndices.length - 1] = index; + idMap.put(value, newIndices); + } else { + idMap.put(value, new int[] { index }); + } + } + index++; + } + } + } + + // ============================================================================= + + /** + * Recalculates the attribute statistics for all attributes. They are average value, variance, + * minimum, and maximum. For nominal attributes the occurences for all values are counted. This + * method collects all attributes (regular and special) in a list and invokes + * recalculateAttributeStatistics(List attributes) and performs only one data scan. + */ + @Override + public void recalculateAllAttributeStatistics() { + List allAttributes = new ArrayList(); + Iterator a = getAttributes().allAttributes(); + while (a.hasNext()) { + allAttributes.add(a.next()); + } + recalculateAttributeStatistics(allAttributes); + } + + /** Recalculate the attribute statistics of the given attribute. */ + @Override + public void recalculateAttributeStatistics(Attribute attribute) { + List allAttributes = new ArrayList(); + allAttributes.add(attribute); + recalculateAttributeStatistics(allAttributes); + } + + /** + * Here the Example Set is parsed only once, all the information is retained for each example + * set. + */ + private void recalculateAttributeStatistics(List attributeList) { + // do nothing if not desired + if (attributeList.size() == 0) { + return; + } else { + // init statistics + for (Attribute attribute : attributeList) { + Iterator stats = attribute.getAllStatistics(); + while (stats.hasNext()) { + Statistics statistics = stats.next(); + statistics.startCounting(attribute); + } + } + + // calculate statistics + Attribute weightAttribute = getAttributes().getWeight(); + if ((weightAttribute != null) && (!weightAttribute.isNumerical())) { + weightAttribute = null; + } + for (Example example : this) { + for (Attribute attribute : attributeList) { + double value = example.getValue(attribute); + double weight = 1.0d; + if (weightAttribute != null) { + weight = example.getValue(weightAttribute); + } + Iterator stats = attribute.getAllStatistics(); + while (stats.hasNext()) { + Statistics statistics = stats.next(); + statistics.count(value, weight); + } + } + } + + // store cloned statistics + for (Attribute attribute : attributeList) { + List statisticsList = statisticsMap.get(attribute.getName()); + // no stats known for this attribute at all --> new list + if (statisticsList == null) { + statisticsList = new LinkedList(); + statisticsMap.put(attribute.getName(), statisticsList); + } + + // in all cases: clear the list before adding new stats (clone of the calculations) + statisticsList.clear(); + + Iterator stats = attribute.getAllStatistics(); + while (stats.hasNext()) { + Statistics statistics = (Statistics) stats.next().clone(); + statisticsList.add(statistics); + } + } + } + } + + /** + * Returns the desired statistic for the given attribute. This method should be preferred over + * the deprecated method Attribute#getStatistics(String) since it correctly calculates and keep + * the statistics for the current example set and does not overwrite the statistics in the + * attribute. Invokes the method {@link #getStatistics(Attribute, String, String)} with a null + * statistics parameter. + */ + @Override + public double getStatistics(Attribute attribute, String statisticsName) { + return getStatistics(attribute, statisticsName, null); + } + + /** + * Returns the desired statistic for the given attribute. This method should be preferred over + * the deprecated method Attribute#getStatistics(String) since it correctly calculates and keep + * the statistics for the current example set and does not overwrite the statistics in the + * attribute. If the statistics were not calculated before (via one of the recalculate methods) + * this method will return NaN. If no statistics is available for the given name, also NaN is + * returned. + */ + @Override + public double getStatistics(Attribute attribute, String statisticsName, String statisticsParameter) { + List statisticsList = statisticsMap.get(attribute.getName()); + if (statisticsList == null) { + return Double.NaN; + } + + for (Statistics statistics : statisticsList) { + if (statistics.handleStatistics(statisticsName)) { + return statistics.getStatistics(attribute, statisticsName, statisticsParameter); + } + } + + return Double.NaN; + } +} diff --git a/src/main/java/com/rapidminer/example/set/AcceptAllCondition.java b/src/main/java/com/rapidminer/example/set/AcceptAllCondition.java new file mode 100644 index 000000000..5948eda8a --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AcceptAllCondition.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This subclass of {@link Condition} serves to accept all examples. + * + * @author Ingo Mierswa Exp $ + */ +public class AcceptAllCondition implements Condition { + + private static final long serialVersionUID = 9217842736819037165L; + + /** Creates a new condition. */ + public AcceptAllCondition() {} + + /** + * Throws an exception since this condition does not support parameter string. + */ + public AcceptAllCondition(ExampleSet exampleSet, String parameterString) {} + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + /** Returns true. */ + @Override + public boolean conditionOk(Example example) { + return true; + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributeSelectionExampleSet.java b/src/main/java/com/rapidminer/example/set/AttributeSelectionExampleSet.java new file mode 100644 index 000000000..c1c3243ce --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributeSelectionExampleSet.java @@ -0,0 +1,119 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; + +import java.util.Iterator; + + +/** + * An implementation of ExampleSet that is only a fixed view on a selection of attributes of the + * parent example set. + * + * @author Ingo Mierswa + */ +public class AttributeSelectionExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = 7946137859300860625L; + + private ExampleSet parent; + + /** + * Constructs a new AttributeSelectionExampleSet. Only those attributes with a true value in the + * selection mask will be used. If the given mask is null, all regular attributes of the parent + * example set will be used. + */ + public AttributeSelectionExampleSet(ExampleSet exampleSet, boolean[] selectionMask) { + this.parent = (ExampleSet) exampleSet.clone(); + if (selectionMask != null) { + if (selectionMask.length != exampleSet.getAttributes().size()) { + throw new IllegalArgumentException( + "Length of the selection mask must be equal to the parent's number of attributes."); + } + + int counter = 0; + Iterator i = this.parent.getAttributes().iterator(); + while (i.hasNext()) { + i.next(); + if (!selectionMask[counter]) { + i.remove(); + } + counter++; + } + } + } + + /** Clone constructor. */ + public AttributeSelectionExampleSet(AttributeSelectionExampleSet exampleSet) { + cloneAnnotationsFrom(exampleSet); + this.parent = (ExampleSet) exampleSet.parent.clone(); + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof AttributeSelectionExampleSet)) { + return false; + } + return this.parent.equals((o)); + } + + @Override + public int hashCode() { + return super.hashCode() ^ this.parent.hashCode(); + } + + // -------------------- overridden methods -------------------- + + /** Returns the attribute container. */ + @Override + public Attributes getAttributes() { + return this.parent.getAttributes(); + } + + /** + * Creates a new example set reader. + */ + @Override + public Iterator iterator() { + return new AttributesExampleReader(parent.iterator(), this); + } + + @Override + public Example getExample(int index) { + return this.parent.getExample(index); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + @Override + public int size() { + return parent.size(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributeTransformationRemapping.java b/src/main/java/com/rapidminer/example/set/AttributeTransformationRemapping.java new file mode 100644 index 000000000..688681e28 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributeTransformationRemapping.java @@ -0,0 +1,108 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeTransformation; +import com.rapidminer.example.AttributeTypeException; +import com.rapidminer.example.table.NominalMapping; + + +/** + * This transformation returns the remapped value. + * + * @author Ingo Mierswa + */ +public class AttributeTransformationRemapping implements AttributeTransformation { + + private static final long serialVersionUID = 1L; + + private NominalMapping overlayedMapping; + + public AttributeTransformationRemapping(NominalMapping overlayedMapping) { + this.overlayedMapping = overlayedMapping; + } + + public AttributeTransformationRemapping(AttributeTransformationRemapping other) { + this.overlayedMapping = (NominalMapping) other.overlayedMapping.clone(); + } + + @Override + public Object clone() { + return new AttributeTransformationRemapping(this); + } + + public void setNominalMapping(NominalMapping mapping) { + this.overlayedMapping = mapping; + } + + @Override + public double transform(Attribute attribute, double value) { + if (Double.isNaN(value)) { + return value; + } + if (attribute.isNominal()) { + try { + String nominalValue = attribute.getMapping().mapIndex((int) value); + int index = overlayedMapping.getIndex(nominalValue); + if (index < 0) { + return Double.NaN; + // return value; + } else { + return index; + } + } catch (AttributeTypeException e) { + return Double.NaN; + // throw new AttributeTypeException("Attribute '" + attribute.getName() + "': " + + // e.getMessage()); + } + } else { + return value; + } + } + + @Override + public double inverseTransform(Attribute attribute, double value) { + if (Double.isNaN(value)) { + return value; + } + if (attribute.isNominal()) { + try { + String nominalValue = overlayedMapping.mapIndex((int) value); + int newValue = attribute.getMapping().getIndex(nominalValue); + if (newValue < 0) { + return value; + } else { + return newValue; + } + } catch (AttributeTypeException e) { + return value; + // throw new AttributeTypeException("Attribute '" + attribute.getName() + "': " + + // e.getMessage()); + } + } else { + return value; + } + } + + @Override + public boolean isReversable() { + return true; + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributeTransformationReplaceMissing.java b/src/main/java/com/rapidminer/example/set/AttributeTransformationReplaceMissing.java new file mode 100644 index 000000000..d677e65c7 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributeTransformationReplaceMissing.java @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeTransformation; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * This transformation simply returns the same value. + * + * @author Ingo Mierswa + */ +public class AttributeTransformationReplaceMissing implements AttributeTransformation { + + private static final long serialVersionUID = 1L; + + private Map replacementMap; + + public AttributeTransformationReplaceMissing(Map replacementMap) { + this.replacementMap = replacementMap; + } + + public AttributeTransformationReplaceMissing(AttributeTransformationReplaceMissing other) { + this.replacementMap = new HashMap(); + Iterator> i = other.replacementMap.entrySet().iterator(); + while (i.hasNext()) { + Map.Entry entry = i.next(); + this.replacementMap.put(entry.getKey(), Double.valueOf(entry.getValue())); + } + } + + @Override + public Object clone() { + return new AttributeTransformationReplaceMissing(this); + } + + public void setReplacementMap(Map replacementMap) { + this.replacementMap = replacementMap; + } + + @Override + public double inverseTransform(Attribute attribute, double value) { + return value; + } + + @Override + public boolean isReversable() { + return false; + } + + @Override + public double transform(Attribute attribute, double value) { + if (Double.isNaN(value)) { + Double replacement = replacementMap.get(attribute.getName()); + if (replacement != null) { + return replacement; + } else { + return value; + } + } else { + return value; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributeTransformationWeighting.java b/src/main/java/com/rapidminer/example/set/AttributeTransformationWeighting.java new file mode 100644 index 000000000..dced21812 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributeTransformationWeighting.java @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeTransformation; +import com.rapidminer.example.AttributeWeights; + + +/** + * This transformation simply returns the weight-scaled value. It must only be used by + * {@link AttributeWeightedExampleSet} since this class takes care of reassigning + * {@link #attributeWeights} after clone. + * + * Usage of this Transformation for nominal attributes is forbidden, since the indices may not be + * altered! + * + * @author Ingo Mierswa + */ +public class AttributeTransformationWeighting implements AttributeTransformation { + + private static final long serialVersionUID = 1L; + + private AttributeWeights attributeWeights; + + public AttributeTransformationWeighting(AttributeWeights attributeWeights) { + setAttributeWeights(attributeWeights); + } + + /** Clone constructor. */ + public AttributeTransformationWeighting(AttributeTransformationWeighting other) { + // We don't clone here. Weights are re-assigned by AttributeWeightedExampleSet.clone(); + this.attributeWeights = other.attributeWeights; + } + + @Override + public Object clone() { + return new AttributeTransformationWeighting(this); + } + + public void setAttributeWeights(AttributeWeights weights) { + this.attributeWeights = weights; + } + + @Override + public double inverseTransform(Attribute attribute, double value) { + double weight = attributeWeights.getWeight(attribute.getName()); + if (!Double.isNaN(weight)) { + return value / weight; + } else { + return value; + } + } + + @Override + public boolean isReversable() { + return true; + } + + @Override + public double transform(Attribute attribute, double value) { + double weight = attributeWeights.getWeight(attribute.getName()); + if (!Double.isNaN(weight)) { + return value * weight; + } else { + return value; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributeValueFilter.java b/src/main/java/com/rapidminer/example/set/AttributeValueFilter.java new file mode 100644 index 000000000..ed2befd3a --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributeValueFilter.java @@ -0,0 +1,139 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + + +/** + * The condition is fulfilled if an attribute has a value equal to, not equal to, less than, ... a + * given value. This filter can be constructed from several conditions of the class + * {@link AttributeValueFilterSingleCondition} which must all be fulfilled. + * + * @author Ingo Mierswa + */ +public class AttributeValueFilter implements Condition { + + private static final long serialVersionUID = 6977275837081172924L; + + private static final int AND = 0; + private static final int OR = 1; + + /** The list of all single conditions. */ + private List conditions = new LinkedList(); + + private int combinationMode = AND; + + /** + * Creates a new AttributeValueFilter. If attribute is not nominal, value must be a number. + */ + public AttributeValueFilter(Attribute attribute, int comparisonType, String value) { + addCondition(attribute, comparisonType, value); + } + + /** + * Constructs an AttributeValueFilter for a given {@link ExampleSet} from a parameter string + * + * @param parameterString + * Must be of the form attribute1 R1 value1 RR attribute2 R2 value2 RR ..., where Ri + * is one out of =, != or <>, <, >, <=, and >= and all RR must be + * either || for OR or && for AND. + */ + public AttributeValueFilter(ExampleSet exampleSet, String parameterString) { + if ((parameterString == null) || (parameterString.length() == 0)) { + throw new IllegalArgumentException("Parameter string must not be empty!"); + } + + String[] splitted = parameterString.split("\\|\\|"); + if (splitted.length > 1) { + for (String condition : splitted) { + condition = condition.trim(); + addCondition(new AttributeValueFilterSingleCondition(exampleSet, condition)); + } + this.combinationMode = OR; + } else { + splitted = parameterString.split("\\&\\&"); + if (splitted.length > 1) { + for (String condition : splitted) { + condition = condition.trim(); + addCondition(new AttributeValueFilterSingleCondition(exampleSet, condition)); + } + this.combinationMode = AND; + } else { + addCondition(new AttributeValueFilterSingleCondition(exampleSet, parameterString)); + this.combinationMode = AND; + } + } + } + + private void addCondition(Attribute attribute, int comparisonType, String value) { + addCondition(new AttributeValueFilterSingleCondition(attribute, comparisonType, value)); + } + + private void addCondition(AttributeValueFilterSingleCondition condition) { + conditions.add(condition); + } + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + @Override + public String toString() { + return conditions.toString(); + } + + /** Returns true if all conditions are fulfilled for the given example. */ + @Override + public boolean conditionOk(Example e) { + Iterator i = conditions.iterator(); + while (i.hasNext()) { + AttributeValueFilterSingleCondition condition = i.next(); + if (combinationMode == AND) { + if (!condition.conditionOk(e)) { + return false; + } + } else { + if (condition.conditionOk(e)) { + return true; + } + } + } + if (combinationMode == AND) { + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributeValueFilterSingleCondition.java b/src/main/java/com/rapidminer/example/set/AttributeValueFilterSingleCondition.java new file mode 100644 index 000000000..fb86d42f3 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributeValueFilterSingleCondition.java @@ -0,0 +1,259 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.tools.Tools; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashSet; +import java.util.regex.PatternSyntaxException; + + +/** + * The condition is fulfilled if an attribute has a value equal to, not equal to, less than, ... a + * given value. + * + * @author Ingo Mierswa, Nils Woehler + */ +public class AttributeValueFilterSingleCondition implements Condition { + + private static final long serialVersionUID = 1537763901048986863L; + + private static final String[] COMPARISON_TYPES = { "<=", ">=", "!=", "<>", "=", "<", ">" }; + + private static final String MISSING_ENCODING = "\\?"; + + public static final int LEQ = 0; + + public static final int GEQ = 1; + + public static final int NEQ1 = 2; + + public static final int NEQ2 = 3; + + public static final int EQUALS = 4; + + public static final int LESS = 5; + + public static final int GREATER = 6; + + public static String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss Z"; + + private int comparisonType = EQUALS; + + private Attribute attribute; + + private double numericalValue; + + private String nominalValue; + + private Date dateValue; + + private HashSet allowedNominalValueIndices; + private boolean isMissingAllowed = false; + + /** + * Creates a new AttributeValueFilter. If attribute is not nominal, value must be either a + * number or a date string. + */ + public AttributeValueFilterSingleCondition(Attribute attribute, int comparisonType, String value) { + this.attribute = attribute; + this.comparisonType = comparisonType; + setValue(value); + } + + /** + * Constructs an AttributeValueFilter for a given {@link ExampleSet} from a parameter string + * + * @param parameterString + * Must be of the form attribute R value, where R is one out of =, !=, <&, >, + * <=, and >=. + */ + public AttributeValueFilterSingleCondition(ExampleSet exampleSet, String parameterString) { + if ((parameterString == null) || (parameterString.length() == 0)) { + throw new IllegalArgumentException("Parameter string must not be empty!"); + } + + int compIndex = -1; + for (comparisonType = 0; comparisonType < COMPARISON_TYPES.length; comparisonType++) { + compIndex = parameterString.indexOf(COMPARISON_TYPES[comparisonType]); + if (compIndex != -1) { + break; + } + } + if (compIndex == -1) { + throw new IllegalArgumentException("Parameter string must have the form 'attribute {=|<|>|<=|>=|!=} value'"); + } + String attName = parameterString.substring(0, compIndex).trim(); + String valueStr = parameterString.substring(compIndex + COMPARISON_TYPES[comparisonType].length()).trim(); + if ((attName.length() == 0) || (valueStr.length() == 0)) { + throw new IllegalArgumentException("Parameter string must have the form 'attribute {=|<|>|<=|>=|!=} value'"); + } + + this.attribute = exampleSet.getAttributes().get(attName); + + if (this.attribute == null) { + throw new IllegalArgumentException("Unknown attribute: '" + attName + "'"); + } + setValue(valueStr); + } + + private void setValue(String value) { + if (attribute.isNominal()) { + if ((comparisonType != EQUALS) && (comparisonType != NEQ1 && comparisonType != NEQ2)) { + throw new IllegalArgumentException("For nominal attributes only '=' and '!=' or '<>' is allowed!"); + } + this.nominalValue = value; + // Check if this string is equal to missing + this.isMissingAllowed = nominalValue.equals(MISSING_ENCODING); + + this.allowedNominalValueIndices = new HashSet(attribute.getMapping().size()); + for (String attributeValue : attribute.getMapping().getValues()) { + try { + if (attributeValue.equals(nominalValue) || attributeValue.matches(nominalValue)) { + allowedNominalValueIndices.add(attribute.getMapping().mapString(attributeValue)); + } + } catch (PatternSyntaxException e) { + } + } + } else if (attribute.isNumerical()) { + if (value.equals("?")) { + this.numericalValue = Double.NaN; + } else { + try { + this.numericalValue = Double.parseDouble(value); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Value for attribute '" + attribute.getName() + + "' must be numerical, but was '" + value + "'!"); + } + } + } else { // date + SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_PATTERN); + try { + if (value.equals("?")) { + this.dateValue = null; + } else { + this.dateValue = dateFormat.parse(value); + } + } catch (ParseException e) { + throw new IllegalArgumentException("Could not parse value '" + value + "' with date pattern " + DATE_PATTERN); + } + } + } + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + @Override + public String toString() { + return attribute.getName() + " " + COMPARISON_TYPES[comparisonType] + " " + + (attribute.isNominal() ? nominalValue : "" + numericalValue); + } + + /** + * Returns true if the condition is fulfilled for the given example. Comparisons with NaN and + * null return false. + */ + @Override + public boolean conditionOk(Example e) { + if (attribute.isNominal()) { + double doubleValue = e.getValue(attribute); + if (Double.isNaN(doubleValue)) { + switch (comparisonType) { + case NEQ1: + case NEQ2: + return !isMissingAllowed; + case EQUALS: + return isMissingAllowed; + default: + return false; + } + } else { + int value = (int) doubleValue; + switch (comparisonType) { + case NEQ1: + case NEQ2: + return !allowedNominalValueIndices.contains(value); + case EQUALS: + return allowedNominalValueIndices.contains(value); + default: + return false; + } + } + } else if (attribute.isNumerical()) { + switch (comparisonType) { + case LEQ: + return Tools.isLessEqual(e.getNumericalValue(attribute), numericalValue); + case GEQ: + return Tools.isGreaterEqual(e.getNumericalValue(attribute), numericalValue); + case NEQ1: + case NEQ2: + return Tools.isNotEqual(e.getNumericalValue(attribute), numericalValue); + case EQUALS: + return Tools.isEqual(e.getNumericalValue(attribute), numericalValue); + case LESS: + return Tools.isLess(e.getNumericalValue(attribute), numericalValue); + case GREATER: + return Tools.isGreater(e.getNumericalValue(attribute), numericalValue); + default: + return false; + } + } else { // date + Date currentDateValue; + if (Double.isNaN(e.getValue(attribute))) { + currentDateValue = null; + } else { + currentDateValue = e.getDateValue(attribute); + } + switch (comparisonType) { + case LEQ: + return Tools.isLessEqual(currentDateValue, dateValue); + case GEQ: + return Tools.isGreaterEqual(currentDateValue, dateValue); + case NEQ1: + case NEQ2: + return Tools.isNotEqual(currentDateValue, dateValue); + case EQUALS: + return Tools.isEqual(currentDateValue, dateValue); + case LESS: + return Tools.isLess(currentDateValue, dateValue); + case GREATER: + return Tools.isGreater(currentDateValue, dateValue); + default: + return false; + + } + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributeWeightedExampleSet.java b/src/main/java/com/rapidminer/example/set/AttributeWeightedExampleSet.java new file mode 100644 index 000000000..dcdd6387a --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributeWeightedExampleSet.java @@ -0,0 +1,303 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.datatable.DataTable; +import com.rapidminer.datatable.DataTableExampleSetAdapter; +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeTransformation; +import com.rapidminer.example.AttributeWeights; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; +import com.rapidminer.operator.IOContainer; +import com.rapidminer.tools.Tools; + +import java.util.Iterator; +import java.util.Random; + + +/** + * An implementation of ExampleSet that allows the weighting of the attributes. Weights can be + * queried by the method {@link #getWeight(Attribute)}. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class AttributeWeightedExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = -5662936146589379273L; + + /** The parent example set. */ + private final ExampleSet parent; + + private AttributeWeights attributeWeights = new AttributeWeights(); + + /** + * Constructs a new AttributeWeightedExampleSet. Initially all attributes are weighted with 1.0. + */ + protected AttributeWeightedExampleSet(ExampleSet exampleSet) { + this(exampleSet, null); + } + + /** + * Constructs a new AttributeWeightedExampleSet. The attributes are weighted with the given + * weights. Attributes which are not stored in the map are weighted with 1.0. + */ + public AttributeWeightedExampleSet(ExampleSet exampleSet, AttributeWeights weights) { + this(exampleSet, weights, 1.0d); + } + + /** + * Constructs a new AttributeWeightedExampleSet. The attributes are weighted with the given + * weights. Attributes which are not stored in the map are weighted with the given default + * weight. + */ + public AttributeWeightedExampleSet(ExampleSet exampleSet, AttributeWeights weights, double defaultWeight) { + this.parent = (ExampleSet) exampleSet.clone(); + this.attributeWeights = weights; + if (weights == null) { + this.attributeWeights = new AttributeWeights(); + for (Attribute attribute : this.parent.getAttributes()) { + setWeight(attribute, defaultWeight); + } + } + + AttributeTransformationWeighting transformation = new AttributeTransformationWeighting(this.attributeWeights); + for (Attribute attribute : this.parent.getAttributes()) { + // We have to check if the attribute is numerical at all, since otherwise weighting by + // multiplying with weight does not make sense + if (attribute.isNumerical()) { + attribute.addTransformation(transformation); + } + } + } + + /** Clone constructor. */ + public AttributeWeightedExampleSet(AttributeWeightedExampleSet exampleSet) { + cloneAnnotationsFrom(exampleSet); + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.attributeWeights = (AttributeWeights) exampleSet.attributeWeights.clone(); + + for (Attribute attribute : this.parent.getAttributes()) { + AttributeTransformation transformation = attribute.getLastTransformation(); + if (transformation != null) { + if (transformation instanceof AttributeTransformationWeighting) { + ((AttributeTransformationWeighting) transformation).setAttributeWeights(this.attributeWeights); + } + } + } + } + + public AttributeWeights getAttributeWeights() { + return this.attributeWeights; + } + + /** Returns a clone where the zero weighted attributes are not delivered. */ + public AttributeWeightedExampleSet createCleanClone() { + AttributeWeightedExampleSet clone = (AttributeWeightedExampleSet) clone(); + Iterator a = clone.getAttributes().iterator(); + while (a.hasNext()) { + Attribute attribute = a.next(); + double weight = this.attributeWeights.getWeight(attribute.getName()); + if (Tools.isZero(weight)) { + a.remove(); + } + } + return clone; + } + + @Override + public Attributes getAttributes() { + return this.parent.getAttributes(); + } + + /** Returns the weight of the attribute. */ + public double getWeight(Attribute attribute) { + if (this.attributeWeights == null) { + return 1.0d; + } else { + return this.attributeWeights.getWeight(attribute.getName()); + } + } + + /** + * Sets the weight of the attribute. + */ + public void setWeight(Attribute attribute, double weightValue) { + this.attributeWeights.setWeight(attribute.getName(), weightValue); + } + + /** Returns the number of selected attributes. */ + public int getNumberOfUsedAttributes() { + int counter = 0; + for (Attribute attribute : getAttributes()) { + if (!Tools.isEqual(getWeight(attribute), 0.0d)) { + counter++; + } + } + return counter; + } + + // -------------------- wrapper methods -------------------- + + /** Sets the weights of all attributes to 1.0. */ + public void selectAll() { + setAll(1.0d); + } + + /** Sets the weights of all attributes to 0.0. */ + public void deselectAll() { + setAll(0.0d); + } + + /** Sets all flags to the given value. */ + private void setAll(double weight) { + for (Attribute attribute : getAttributes()) { + setWeight(attribute, weight); + } + } + + // -------------------- selection methods -------------------- + + /** Returns the selection state of the attribute. */ + public boolean isAttributeUsed(Attribute attribute) { + return getWeight(attribute) != 0.0d; + } + + /** Sets the selection state of the attribute. */ + public void setAttributeUsed(Attribute attribute, boolean selected) { + setWeight(attribute, (selected ? 1.0d : 0.0d)); + } + + /** + * Flips the selection state of the attribute with the given index. (Convenience method for + * evolutionary algorithms). If a block starts with this attribute the whole block will be + * switched. Returns the index of the attribute which is the last one in the block or the index + * of the given attribute itself if it is not the start attribute of a block. + */ + public void flipAttributeUsed(Attribute attribute) { + setWeight(attribute, isAttributeUsed(attribute) ? 0.0d : 1.0d); + } + + /** + * Randomly selects approximately the given number of attributes. Will not throw an exception if + * the given number exceeds the current number of features. If no attributes would be selected a + * single attribute will be selected. + */ + public void selectRandomSubset(int n, Random random) { + double ratio = (double) n / (double) getAttributes().size(); + for (Attribute attribute : getAttributes()) { + if (random.nextDouble() < ratio) { + setWeight(attribute, 1.0d); + } else { + setWeight(attribute, 0.0d); + } + } + + if (getNumberOfUsedAttributes() == 0) { + double probDelta = 1.0d / getAttributes().size(); + double prob = random.nextDouble(); + double currentMax = probDelta; + for (Attribute attribute : getAttributes()) { + if (prob < currentMax) { + setWeight(attribute, 1.0d); + break; + } + currentMax += probDelta; + } + } + } + + // -------------------- overridden methods -------------------- + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof AttributeWeightedExampleSet)) { + return false; + } + return super.equals(o) && this.attributeWeights.equals(((AttributeWeightedExampleSet) o).attributeWeights); + } + + @Override + public int hashCode() { + return super.hashCode() ^ attributeWeights.hashCode(); + } + + @Override + public String toString() { + StringBuffer buffer = new StringBuffer(super.toString()); + buffer.append(Tools.getLineSeparator() + "Weights: "); + int i = 0; + for (Attribute attribute : getAttributes()) { + if (i != 0) { + buffer.append(", "); + } + if (i > 50) { + buffer.append("..."); + break; + } + buffer.append(attribute.getName() + ":" + getWeight(attribute)); + i++; + } + return buffer.toString(); + } + + @Override + public DataTable createDataTable(IOContainer container) { + return new DataTableExampleSetAdapter(this, getAttributeWeights()); + } + + /** + * Creates a new example set reader. + */ + @Override + public Iterator iterator() { + return new AttributesExampleReader(parent.iterator(), this); + } + + @Override + public Example getExample(int index) { + return this.parent.getExample(index); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + @Override + public int size() { + return parent.size(); + } + + /* + * (non-Javadoc) + * + * @see com.rapidminer.operator.ResultObjectAdapter#getAnnotations() + */ + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/AttributesExampleReader.java b/src/main/java/com/rapidminer/example/set/AttributesExampleReader.java new file mode 100644 index 000000000..7bef0da29 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/AttributesExampleReader.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + +import java.util.Iterator; + + +/** + * This reader simply uses all examples from the parent and all available attributes. + * + * @author Ingo Mierswa + */ +public class AttributesExampleReader extends AbstractExampleReader { + + /** The parent example reader. */ + private Iterator parent; + + /** The used attributes are described in this example set. */ + private ExampleSet exampleSet; + + /** Creates a simple example reader. */ + public AttributesExampleReader(Iterator parent, ExampleSet exampleSet) { + this.parent = parent; + this.exampleSet = exampleSet; + } + + /** Returns true if there are more data rows. */ + @Override + public boolean hasNext() { + return this.parent.hasNext(); + } + + /** Returns a new example based on the current data row. */ + @Override + public Example next() { + if (!hasNext()) { + return null; + } + Example example = this.parent.next(); + if (example == null) { + return null; + } + return new Example(example.getDataRow(), exampleSet); + } +} diff --git a/src/main/java/com/rapidminer/example/set/Condition.java b/src/main/java/com/rapidminer/example/set/Condition.java new file mode 100644 index 000000000..3413aa46c --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/Condition.java @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.operator.tools.ExpressionEvaluationException; + +import java.io.Serializable; + + +/** + * Objects implementing this interface are used by + * {@link com.rapidminer.example.set.ConditionedExampleSet}s, a special sub class of + * {@link com.rapidminer.example.ExampleSet} that skips all examples that do not fulfill this + * condition. In order for the + * {@link com.rapidminer.example.set.ConditionedExampleSet#createCondition(String, ExampleSet, String)} + * factory method to be able to create instances of an implementation of Condition, it must + * implement a two argument constructor taking an {@link ExampleSet} and a parameter String. The + * meaning of the parameter string is dependent on the implementation and may even be ignored, + * although it would be nice to print a warning. + * + * @author Ingo Mierswa, Simon Fischer + */ +public interface Condition extends Serializable { + + /** + * Should return true if the given example does fulfill this condition. + * + * @param example + * @return + * @throws ExpressionEvaluationException + * if the condition cannot be evaluated + */ + public boolean conditionOk(Example example) throws ExpressionEvaluationException; + + /** + * Returns a duplicate of this condition. Subclasses which cannot dynamically changed can also + * return the same object. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Deprecated + public Condition duplicate(); + +} diff --git a/src/main/java/com/rapidminer/example/set/ConditionCreationException.java b/src/main/java/com/rapidminer/example/set/ConditionCreationException.java new file mode 100644 index 000000000..051d2ab66 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/ConditionCreationException.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +/** + * Exception class whose instances are thrown during the creation of conditions. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class ConditionCreationException extends Exception { + + private static final long serialVersionUID = -7648754234739697969L; + + public ConditionCreationException(String message) { + super(message); + } + + public ConditionCreationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/rapidminer/example/set/ConditionedExampleSet.java b/src/main/java/com/rapidminer/example/set/ConditionedExampleSet.java new file mode 100644 index 000000000..13b1e88bd --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/ConditionedExampleSet.java @@ -0,0 +1,255 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; +import com.rapidminer.operator.OperatorProgress; +import com.rapidminer.operator.ProcessStoppedException; +import com.rapidminer.operator.tools.ExpressionEvaluationException; + + +/** + * Hides {@link Example}s that do not fulfill a given {@link Condition}. + * + * @author Ingo Mierswa + */ +public class ConditionedExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = 877488093216198777L; + + /** Array of short names for the known conditions. */ + public static final String[] KNOWN_CONDITION_NAMES = { "all", "correct_predictions", "wrong_predictions", + "no_missing_attributes", "missing_attributes", "no_missing_labels", "missing_labels", "attribute_value_filter", + "expression", "custom_filters" }; + + public static final int CONDITION_ALL = 0; + public static final int CONDITION_CORRECT_PREDICTIONS = 1; + public static final int CONDITION_WRONG_PREDICTIONS = 2; + public static final int CONDITION_NO_MISSING_ATTRIBUTES = 3; + public static final int CONDITION_MISSING_ATTRIBUTES = 4; + public static final int CONDITION_NO_MISSING_LABELS = 5; + public static final int CONDITION_MISSING_LABELS = 6; + public static final int CONDITION_ATTRIBUTE_VALUE_FILTER = 7; + public static final int CONDITION_EXPRESSION = 8; + public static final int CONDITION_CUSTOM_FILTER = 9; + + /** + * Array of fully qualified classnames of implementations of {@link Condition} that are useful + * independently of special applications. All conditions given here must provide a construtor + * with arguments (ExampleSet data, String parameters). + */ + private static final String[] KNOWN_CONDITION_IMPLEMENTATIONS = { AcceptAllCondition.class.getName(), + CorrectPredictionCondition.class.getName(), WrongPredictionCondition.class.getName(), + NoMissingAttributesCondition.class.getName(), MissingAttributesCondition.class.getName(), + NoMissingLabelsCondition.class.getName(), MissingLabelsCondition.class.getName(), + AttributeValueFilter.class.getName(), ExpressionFilter.class.getName(), CustomFilter.class.getName() }; + + private ExampleSet parent; + + private int[] mapping; + + /** + * Creates a new example which used only examples fulfilling the given condition. + * + * @throws ExpressionEvaluationException + */ + public ConditionedExampleSet(ExampleSet parent, Condition condition) throws ExpressionEvaluationException { + this(parent, condition, false); + } + + /** + * Creates a new example which used only examples fulfilling the given condition. + * + * @throws ExpressionEvaluationException + */ + public ConditionedExampleSet(ExampleSet parent, Condition condition, boolean inverted) + throws ExpressionEvaluationException { + this.parent = (ExampleSet) parent.clone(); + try { + this.mapping = calculateMapping(condition, inverted, null); + } catch (ProcessStoppedException e) { + // Cannot happen because progress is null + } + } + + /** + * Creates a new example which used only examples fulfilling the given condition. + * + * @param progress + * the {@link OperatorProgress} to report the progress to + * @throws ExpressionEvaluationException + * @throws ProcessStoppedException + * if the process was stopped, can only happen if progress not {@code null} + */ + public ConditionedExampleSet(ExampleSet parent, Condition condition, boolean inverted, OperatorProgress progress) + throws ExpressionEvaluationException, ProcessStoppedException { + this.parent = (ExampleSet) parent.clone(); + this.mapping = calculateMapping(condition, inverted, progress); + } + + /** Clone constructor. */ + public ConditionedExampleSet(ConditionedExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.mapping = new int[exampleSet.mapping.length]; + System.arraycopy(exampleSet.mapping, 0, this.mapping, 0, exampleSet.mapping.length); + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof ConditionedExampleSet)) { + return false; + } + ConditionedExampleSet other = (ConditionedExampleSet) o; + if (this.mapping.length != other.mapping.length) { + return false; + } + for (int i = 0; i < this.mapping.length; i++) { + if (this.mapping[i] != other.mapping[i]) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.mapping); + } + + private int[] calculateMapping(Condition condition, boolean inverted, OperatorProgress progress) + throws ExpressionEvaluationException, ProcessStoppedException { + if (progress != null) { + // +1 since a little is happening afterwards + progress.setTotal(parent.size() + 1); + } + List indices = new LinkedList(); + + // create mapping + int exampleCounter = 0; + for (Example example : parent) { + if (!inverted) { + if (condition.conditionOk(example)) { + indices.add(exampleCounter); + } + } else { + if (!condition.conditionOk(example)) { + indices.add(exampleCounter); + } + } + exampleCounter++; + if (progress != null && exampleCounter % 1000 == 0) { + progress.setCompleted(exampleCounter); + } + } + + int[] mapping = new int[indices.size()]; + int m = 0; + for (int index : indices) { + mapping[m++] = index; + } + return mapping; + } + + /** Returns a {@link MappedExampleReader}. */ + @Override + public Iterator iterator() { + return new MappedExampleReader(parent.iterator(), this.mapping); + } + + /** Returns the i-th example fulfilling the condition. */ + @Override + public Example getExample(int index) { + if ((index < 0) || (index >= this.mapping.length)) { + throw new RuntimeException("Given index '" + index + "' does not fit the filtered ExampleSet!"); + } else { + return parent.getExample(this.mapping[index]); + } + } + + /** Counts the number of examples which fulfills the condition. */ + @Override + public int size() { + return mapping.length; + } + + @Override + public Attributes getAttributes() { + return parent.getAttributes(); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + /** + * Checks if the given name is the short name of a known condition and creates it. If the name + * is not known, this method creates a new instance of className which must be an implementation + * of {@link Condition} by calling its two argument constructor passing it the example set and + * the parameter string + */ + public static Condition createCondition(String name, ExampleSet exampleSet, String parameterString) + throws ConditionCreationException { + String className = name; + for (int i = 0; i < KNOWN_CONDITION_NAMES.length; i++) { + if (KNOWN_CONDITION_NAMES[i].equals(name)) { + className = KNOWN_CONDITION_IMPLEMENTATIONS[i]; + break; + } + } + try { + Class clazz = com.rapidminer.tools.Tools.classForName(className); + if (!Condition.class.isAssignableFrom(clazz)) { + throw new ConditionCreationException("'" + className + "' does not implement Condition!"); + } + java.lang.reflect.Constructor constructor = clazz.getConstructor(new Class[] { ExampleSet.class, String.class }); + return (Condition) constructor.newInstance(new Object[] { exampleSet, parameterString }); + } catch (ClassNotFoundException e) { + throw new ConditionCreationException("Cannot find class '" + className + "'. Check your classpath.", e); + } catch (NoSuchMethodException e) { + throw new ConditionCreationException("'" + className + "' must implement two argument constructor " + className + + "(ExampleSet, String)!", e); + } catch (IllegalAccessException e) { + throw new ConditionCreationException("'" + className + "' cannot access two argument constructor " + className + + "(ExampleSet, String)!", e); + } catch (InstantiationException e) { + throw new ConditionCreationException(className + ": cannot create condition (" + e.getMessage() + ").", e); + } catch (Throwable e) { + throw new ConditionCreationException(className + ": cannot invoke condition (" + + (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()) + ").", e); + } + } + + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/CorrectPredictionCondition.java b/src/main/java/com/rapidminer/example/set/CorrectPredictionCondition.java new file mode 100644 index 000000000..af1923115 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/CorrectPredictionCondition.java @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This subclass of {@link Condition} serves to accept all examples which are correctly predicted. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class CorrectPredictionCondition implements Condition { + + private static final long serialVersionUID = -2971139314612252926L; + + /** Creates a new condition. */ + public CorrectPredictionCondition() {} + + /** + * Throws an exception since this condition does not support parameter string. + */ + public CorrectPredictionCondition(ExampleSet exampleSet, String parameterString) { + if (exampleSet.getAttributes().getLabel() == null) { + throw new IllegalArgumentException("CorrectPredictionCondition needs an example set with label attribute!"); + } + if (exampleSet.getAttributes().getPredictedLabel() == null) { + throw new IllegalArgumentException( + "CorrectPredictionCondition needs an example set with predicted label attribute!"); + } + } + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + /** Returns true if the example is correctly predicted. */ + @Override + public boolean conditionOk(Example example) { + return example.equalValue(example.getAttributes().getLabel(), example.getAttributes().getPredictedLabel()); + } +} diff --git a/src/main/java/com/rapidminer/example/set/CustomFilter.java b/src/main/java/com/rapidminer/example/set/CustomFilter.java new file mode 100644 index 000000000..1ee287f52 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/CustomFilter.java @@ -0,0 +1,1138 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; + +import com.rapidminer.MacroHandler; +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeTypeException; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.operator.nio.model.DataResultSet.ValueType; +import com.rapidminer.parameter.ParameterTypeTupel; +import com.rapidminer.tools.I18N; +import com.rapidminer.tools.Ontology; +import com.rapidminer.tools.Tools; + + +/** + * The condition is fulfilled if the individual filters are fulfilled. This filter can be + * constructed from several conditions of the type {@link CustomFilters} which either must all be + * fulfilled (AND) or only one must be fulfilled (OR). + * + * @author Marco Boeck + */ +public class CustomFilter implements Condition { + + /** + * Enum for custom filters. + */ + public static enum CustomFilters { + + EQUALS_NUMERICAL("gui.comparator.numerical.equals", "eq", Ontology.NUMERICAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + // special case to handle missing values + if (Double.isNaN(filter)) { + return Double.isNaN(input); + } + return input == filter; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + NOT_EQUALS_NUMERICAL("gui.comparator.numerical.not_equals", "ne", Ontology.NUMERICAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + // special case to handle missing values + if (Double.isNaN(input)) { + return !Double.isNaN(filter); + } + return input != filter; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + LESS("gui.comparator.numerical.less", "lt", Ontology.NUMERICAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return input < filter; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + LESS_EQUALS("gui.comparator.numerical.less_equals", "le", Ontology.NUMERICAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return input <= filter; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + GREATER_EQUALS("gui.comparator.numerical.greater_equals", "ge", Ontology.NUMERICAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return input >= filter; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + GREATER("gui.comparator.numerical.greater", "gt", Ontology.NUMERICAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return input > filter; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + + EQUALS_NOMINAL("gui.comparator.nominal.equals", "equals", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return input.equals(filter); + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + NOT_EQUALS_NOMINAL("gui.comparator.nominal.not_equals", "does_not_equal", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return !input.equals(filter); + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + IS_IN_NOMINAL("gui.comparator.nominal.is_in", "is_in", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + List filterList = Tools.unescape(filter, ESCAPE_CHAR, new char[] { SEPERATOR_CHAR }, SEPERATOR_CHAR); + for (String filterString : filterList) { + if (input.equals(filterString)) { + return true; + } + } + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + IS_NOT_IN_NOMINAL("gui.comparator.nominal.is_not_in", "is_not_in", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + List filterList = Tools.unescape(filter, ESCAPE_CHAR, new char[] { SEPERATOR_CHAR }, SEPERATOR_CHAR); + for (String filterString : filterList) { + if (input.equals(filterString)) { + return false; + } + } + return true; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + CONTAINS("gui.comparator.nominal.contains", "contains", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return input.contains(filter); + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + NOT_CONTAINS("gui.comparator.nominal.not_contains", "does_not_contain", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return !input.contains(filter); + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + STARTS_WITH("gui.comparator.nominal.starts_with", "starts_with", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return input.startsWith(filter); + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + ENDS_WITH("gui.comparator.nominal.ends_with", "ends_with", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return input.endsWith(filter); + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + REGEX("gui.comparator.nominal.regex", "matches", Ontology.NOMINAL) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return input.matches(filter); + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return false; + } + }, + MISSING("gui.comparator.special.is_missing", "is_missing", -1) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return Double.isNaN(input); + } + }, + NOT_MISSING("gui.comparator.special.is_not_missing", "is_not_missing", -1) { + + @Override + public boolean isNumericalConditionFulfilled(final double input, final double filter) { + return false; + } + + @Override + public boolean isNominalConditionFulfilled(final String input, final String filter) { + return false; + } + + @Override + public boolean isSpecialConditionFulfilled(final double input) { + return !Double.isNaN(input); + } + }; + + /** the symbol to seperate strings for IS_IN and IS_NOT_IN input */ + public static final char SEPERATOR_CHAR = ';'; + + /** the symbol to escape seperator symbols in IS_IN and IS_NOT_IN input */ + public static final char ESCAPE_CHAR = '\\'; + + /** the format string for date_time */ + public static final String DATE_TIME_FORMAT_STRING = "MM/dd/yyyy h:mm:ss a"; + + /** the old (bugged) format string for date_time */ + public static final String DATE_TIME_FORMAT_STRING_OLD = "MM/dd/yy h:mm:ss a"; + + /** the format string for date */ + public static final String DATE_FORMAT_STRING = "MM/dd/yyyy"; + + /** the old (bugged) format string for date */ + public static final String DATE_FORMAT_STRING_OLD = "MM/dd/yy"; + + /** the format string for time */ + public static final String TIME_FORMAT_STRING = "h:mm:ss a"; + + // ThreadLocal because DateFormat is NOT threadsafe and creating a new DateFormat is + // EXTREMELY expensive + /** the format for date_time */ + private static final ThreadLocal FORMAT_DATE_TIME = new ThreadLocal() { + + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat(DATE_TIME_FORMAT_STRING, Locale.ENGLISH); + } + }; + + /** the old format for date_time */ + private static final ThreadLocal FORMAT_DATE_TIME_OLD = new ThreadLocal() { + + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat(DATE_TIME_FORMAT_STRING_OLD, Locale.ENGLISH); + } + }; + + // ThreadLocal because DateFormat is NOT threadsafe and creating a new DateFormat is + // EXTREMELY expensive + /** the format for date */ + private static final ThreadLocal FORMAT_DATE = new ThreadLocal() { + + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat(DATE_FORMAT_STRING, Locale.ENGLISH); + } + }; + + /** the old format for date */ + private static final ThreadLocal FORMAT_DATE_OLD = new ThreadLocal() { + + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat(DATE_FORMAT_STRING_OLD, Locale.ENGLISH); + } + }; + + // ThreadLocal because DateFormat is NOT threadsafe and creating a new DateFormat is + // EXTREMELY expensive + /** the format for time */ + private static final ThreadLocal FORMAT_TIME = new ThreadLocal() { + + @Override + protected DateFormat initialValue() { + return new SimpleDateFormat(TIME_FORMAT_STRING, Locale.ENGLISH); + } + }; + + /** the label for this filter */ + private String label; + + /** the string representation for this filter */ + private String symbol; + + /** the help text for this filter */ + private String helptext; + + /** the valueType for this filter */ + private int valueType; + + /** + * Creates a new {@link CustomFilters} instance which is represented by the specified symbol + * and accepts the given {@link ValueType}. + * + * @param key + * @param symbol + * @param valueType + * the applicable {@link Ontology#ATTRIBUTE_VALUE_TYPE}. If set to -1, denotes a + * special filter which is not restricted to any value type + */ + private CustomFilters(final String key, final String symbol, final int valueType) { + this.symbol = symbol; + this.label = I18N.getMessage(I18N.getGUIBundle(), key + ".label"); + this.helptext = I18N.getMessage(I18N.getGUIBundle(), key + ".tip"); + this.valueType = valueType; + } + + /** + * Returns the {@link String} label for this comparator. + * + * @return + */ + public String getLabel() { + return label; + } + + /** + * Returns the {@link String} representation for this comparator. + * + * @return + */ + public String getSymbol() { + return symbol; + } + + /** + * Returns the helptext for this comparator. + * + * @return + */ + public String getHelptext() { + return helptext; + } + + /** + * Returns true if this filter is applicable for numerical values; + * false otherwise. + * + * @return + */ + public boolean isNumericalFilter() { + if (isSpecialFilter()) { + return false; + } + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NUMERICAL)) { + return true; + } + return false; + } + + /** + * Returns true if this filter is applicable for nominal values; + * false otherwise. + * + * @return + */ + public boolean isNominalFilter() { + if (isSpecialFilter()) { + return false; + } + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL)) { + return true; + } + return false; + } + + /** + * Returns true if this filter is a special filter (e.g. missing value filter); + * false otherwise.
+ * These filters are applicable for all attribute types. + * + * @return + */ + public boolean isSpecialFilter() { + if (valueType == -1) { + return true; + } + return false; + } + + /** + * Returns true if the numerical condition for this filter is fulfilled for the + * given value. Returns always false if the condition is for nominal values + * only. + * + * @param input + * @param filterValue + * @return + */ + public abstract boolean isNumericalConditionFulfilled(double input, double filterValue); + + /** + * Returns true if the nominal condition for this filter is fulfilled for the + * given value. Returns always false if the condition is for numerical values + * only. + * + * @param input + * @param filterValue + * @return + */ + public abstract boolean isNominalConditionFulfilled(String input, String filterValue); + + /** + * Returns true if the special condition for this filter is fulfilled for the + * given value. + * + * @param input + * @return + */ + public abstract boolean isSpecialConditionFulfilled(double input); + + /** + * Returns the {@link CustomFilters} matching the given label {@link String}. If none can be + * found, returns null. + * + * @param label + * @return + */ + public static CustomFilters getByLabel(final String label) { + for (CustomFilters filter : values()) { + if (filter.getLabel().equals(label)) { + return filter; + } + } + return null; + } + + /** + * Returns the {@link CustomFilters} matching the given symbol {@link String}. If none can + * be found, returns null. + * + * @param symbol + * @return + */ + public static CustomFilters getBySymbol(final String symbol) { + for (CustomFilters filter : values()) { + if (filter.getSymbol().equals(symbol)) { + return filter; + } + } + return null; + } + + /** + * Returns a list of {@link CustomFilters}s for the given {@link ValueType}. Returns an + * empty list if no filter was found. + * + * @param valueType + * @return + */ + public static List getFiltersForValueType(final int valueType) { + List list = new LinkedList<>(); + for (CustomFilters filter : values()) { + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL)) { + // only nominal filters + if (filter.isSpecialFilter() || filter.isNominalFilter()) { + list.add(filter); + } + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NUMERICAL)) { + // only numerical filters + if (filter.isSpecialFilter() || filter.isNumericalFilter()) { + list.add(filter); + } + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.DATE_TIME)) { + // only numerical filters + if (filter.isSpecialFilter() || filter.isNumericalFilter()) { + list.add(filter); + } + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.ATTRIBUTE_VALUE)) { + // unknown value type right now, allow all filters + list.add(filter); + } else { + // filter only defined for numerical or nominal or unknown + } + } + + return list; + } + + /** + * Returns a {@link Date} parsed via the date {@link String} or null if the + * given string could not be parsed. Uses {@link Locale#ENGLISH}. + *

+ * Not static because {@link DateFormat} is NOT threadsafe. + *

+ * + * @see #FORMAT_DATE_TIME + * @param dateTimeString + * @return + */ + public Date parseDateTime(final String dateTimeString) { + try { + return FORMAT_DATE_TIME.get().parse(dateTimeString); + } catch (ParseException e) { + return null; + } + } + + /** + * Old parser for date_time. + * + * @param dateTimeString + * @return + */ + private Date parseDateTimeOld(final String dateTimeString) { + try { + return FORMAT_DATE_TIME_OLD.get().parse(dateTimeString); + } catch (ParseException e) { + return null; + } + } + + /** + * Returns a {@link Date} parsed via the date {@link String} or null if the + * given string could not be parsed. Uses {@link Locale#ENGLISH}. + *

+ * Not static because {@link DateFormat} is NOT threadsafe. + *

+ * + * @see #FORMAT_DATE + * @param dateString + * @return + */ + public Date parseDate(final String dateString) { + try { + return FORMAT_DATE.get().parse(dateString); + } catch (ParseException e) { + return null; + } + } + + /** + * Old parser for date. + * + * @param dateString + * @return + */ + private Date parseDateOld(final String dateString) { + try { + return FORMAT_DATE_OLD.get().parse(dateString); + } catch (ParseException e) { + return null; + } + } + + /** + * Returns a {@link Date} parsed via the date {@link String} or null if the + * given string could not be parsed. Uses {@link Locale#ENGLISH}. + *

+ * Not static because {@link DateFormat} is NOT threadsafe. + *

+ * + * @see #FORMAT_TIME + * @param timeString + * @return + */ + public Date parseTime(final String timeString) { + try { + return FORMAT_TIME.get().parse(timeString); + } catch (ParseException e) { + return null; + } + } + + /** + * Returns a {@link String} formatted from the {@link Date}. Uses {@link Locale#ENGLISH}. + *

+ * Not static because {@link DateFormat} is NOT threadsafe. + *

+ * + * @see #FORMAT_TIME + * @param dateTime + * @return + */ + public String formatDateTime(final Date dateTime) { + if (dateTime == null) { + throw new IllegalArgumentException("dateTime must not be null!"); + } + return FORMAT_DATE_TIME.get().format(dateTime); + } + + /** + * Old format for date_time. + * + * @param dateTime + * @return + */ + public String formatDateTimeOld(final Date dateTime) { + if (dateTime == null) { + throw new IllegalArgumentException("dateTime must not be null!"); + } + return FORMAT_DATE_TIME_OLD.get().format(dateTime); + } + + /** + * Returns a {@link String} formatted from the {@link Date}. Uses {@link Locale#ENGLISH}. + *

+ * Not static because {@link DateFormat} is NOT threadsafe. + *

+ * + * @see #FORMAT_TIME + * @param date + * @return + */ + public String formatDate(final Date date) { + if (date == null) { + throw new IllegalArgumentException("date must not be null!"); + } + return FORMAT_DATE.get().format(date); + } + + /** + * Returns a {@link String} formatted from the {@link Date}. Uses {@link Locale#ENGLISH}. + *

+ * Not static because {@link DateFormat} is NOT threadsafe. + *

+ * + * @see #FORMAT_TIME + * @param time + * @return + */ + public String formatTime(final Date time) { + if (time == null) { + throw new IllegalArgumentException("time must not be null!"); + } + return FORMAT_TIME.get().format(time); + } + } + + private static final long serialVersionUID = -1369785656210631292L; + + private static final String WHITESPACE = " "; + private static final String BACKSLASH = "/"; + + private static final int CONDITION_ARRAY_REQUIRED_SIZE = 2; + private static final int CONDITION_ARRAY_CONDITION_INDEX = 1; + + private static final int CONDITION_TUPEL_REQUIRED_SIZE = 3; + private static final int CONDITION_TUPEL_ATT_INDEX = 0; + private static final int CONDITION_TUPEL_FILTER_INDEX = 1; + private static final int CONDITION_TUPEL_VALUE_INDEX = 2; + + /** the list of all conditions */ + private List conditions = new LinkedList<>(); + + /** + * an array which indicates if for the ordered filter index the old (bugged) date parsing should + * be used + */ + private boolean[] conditionsOldDateFilter; + + /** the {@link MacroHandler}, will be used to resolve filter values, can be null */ + private MacroHandler macroHandler; + + private boolean fulfillAllConditions; + + /** + * Creates a new {@link CustomFilter} instance with the {@link CustomFilters} encoded in the + * {@link List} of {@link String} arrays. The {@link Boolean} parameter defines if either all + * conditions must be fulfilled or only one of them. + * + * @param exampleSet + * @param conditions + * @param fulfillAllConditions + * @param macroHandler + * the macro handler which will be used to resolve macros for the filter value, can + * be null + * @param version + * can be used to force old behaviour. If not needed and current implementation is + * desired, can be set to null + * + */ + public CustomFilter(final ExampleSet exampleSet, final List conditions, final boolean fulfillAllConditions, + final MacroHandler macroHandler) { + if (conditions == null) { + throw new IllegalArgumentException("typeList must not be null!"); + } + + conditionsOldDateFilter = new boolean[conditions.size()]; + // check if given conditions list is well formed and valid! + int counter = 0; + for (String[] conditionArray : conditions) { + if (conditionArray.length != CONDITION_ARRAY_REQUIRED_SIZE) { + throw new IllegalArgumentException("conditions must only consist of arrays of length 2!"); + } + + String condition = conditionArray[CONDITION_ARRAY_CONDITION_INDEX]; + String[] conditionTupel = ParameterTypeTupel.transformString2Tupel(condition); + if (conditionTupel.length != CONDITION_TUPEL_REQUIRED_SIZE) { + throw new IllegalArgumentException("Malformed condition tupels! Expected size 3 but was " + + conditionTupel.length); + } + + String attName = conditionTupel[CONDITION_TUPEL_ATT_INDEX]; + Attribute att = exampleSet.getAttributes().get(attName); + String filterSymbol = conditionTupel[CONDITION_TUPEL_FILTER_INDEX]; + CustomFilters filter = CustomFilters.getBySymbol(filterSymbol); + String filterValue = conditionTupel[CONDITION_TUPEL_VALUE_INDEX]; + if (macroHandler != null) { + this.macroHandler = macroHandler; + filterValue = substituteMacros(filterValue, macroHandler); + } + if (filter == null) { + throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(), + "custom_filters.filter_not_found", filterSymbol)); + } + if (att == null) { + throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(), + "custom_filters.attribute_not_found", attName)); + } + + // special checks for numerical filters + if (filter.isNumericalFilter()) { + // check if attribute is numerical + if (att.isNominal()) { + throw new AttributeTypeException(I18N.getMessageOrNull(I18N.getErrorBundle(), + "custom_filters.numerical_comparator_type_invalid", filter.getLabel(), att.getName())); + } + if (att.isDateTime()) { + // check if filter value works for date attribute + if (filterValue == null || "".equals(filterValue) || !isStringValidDoubleValue(filter, filterValue, att)) { + throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(), + "custom_filters.illegal_date_value", filterValue, att.getName())); + } + } else if (att.isNumerical()) { + // check if filter value works for numerical attribute + if (filterValue == null || "".equals(filterValue) || !isStringValidDoubleValue(filter, filterValue, att)) { + throw new IllegalArgumentException(I18N.getMessageOrNull(I18N.getErrorBundle(), + "custom_filters.illegal_numerical_value", filterValue, att.getName())); + } + } + + // keep compatibility with processes from versions prior to 6.0.004 + // only affects DATE and DATE_TIME filters + int yearIndex = filterValue.lastIndexOf(BACKSLASH) + 1; + int firstWhitespaceIndex = filterValue.indexOf(WHITESPACE); + String yearString = null; + if (yearIndex > 0 && firstWhitespaceIndex > 0 && yearIndex < firstWhitespaceIndex) { + yearString = filterValue.substring(yearIndex, firstWhitespaceIndex); + } + + // if true, the old (bugged) parsing will be used; otherwise the new yyyy parsing + // will be used + conditionsOldDateFilter[counter] = yearString != null && yearString.length() == 2; + } else if (filter.isNominalFilter()) { + if (!att.isNominal()) { + throw new AttributeTypeException(I18N.getMessageOrNull(I18N.getErrorBundle(), + "custom_filters.nominal_comparator_type_invalid", filter.getLabel(), att.getName())); + } + } + + counter++; + } + + this.conditions = conditions; + this.fulfillAllConditions = fulfillAllConditions; + } + + /** + * The sole purpose of this constructor is to provide a constructor that matches the expected + * signature for the {@link ConditionedExampleSet} reflection invocation. However, this class + * cannot be instantiated by an ExampleSet and a String, so we always throw an + * {@link IllegalArgumentException} to signal this filter cannot be instantiated that way. + * + * @throws IllegalArgumentException + * ALWAYS THROWN! + */ + @Deprecated + public CustomFilter(final ExampleSet exampleSet, final String parameterString) throws IllegalArgumentException { + throw new IllegalArgumentException("This condition cannot be instantiated this way!"); + } + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Deprecated + @Override + public Condition duplicate() { + return this; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + for (String[] array : conditions) { + builder.append(Arrays.toString(array)); + builder.append(' '); + } + return builder.toString(); + } + + @Override + public boolean conditionOk(final Example e) { + boolean conditionsFulfilled = fulfillAllConditions ? true : false; + int counter = 0; + for (String[] conditionArray : conditions) { + // we checked for malformed conditions in the constructor so no need to do it again + String condition = conditionArray[CONDITION_ARRAY_CONDITION_INDEX]; + String[] conditionTupel = ParameterTypeTupel.transformString2Tupel(condition); + String attName = conditionTupel[CONDITION_TUPEL_ATT_INDEX]; + Attribute att = e.getAttributes().get(attName); + String filterSymbol = conditionTupel[CONDITION_TUPEL_FILTER_INDEX]; + CustomFilters filter = CustomFilters.getBySymbol(filterSymbol); + String filterValue = conditionTupel[CONDITION_TUPEL_VALUE_INDEX]; + if (macroHandler != null) { + filterValue = substituteMacros(filterValue, macroHandler); + } + + // check if condition is fulfilled + boolean fulfilled; + if (filter.isSpecialFilter()) { + fulfilled = filter.isSpecialConditionFulfilled(e.getValue(att)); + } else if (filter.isNominalFilter()) { + fulfilled = filter.isNominalConditionFulfilled(e.getNominalValue(att), filterValue); + } else { + fulfilled = checkNumericalCondition(e, att, filter, filterSymbol, filterValue, + conditionsOldDateFilter[counter]); + } + + // store result + if (fulfillAllConditions) { + conditionsFulfilled &= fulfilled; + } else { + conditionsFulfilled |= fulfilled; + } + + // shortcut for OR - one fulfilled condition is enough + if (!fulfillAllConditions && conditionsFulfilled) { + return true; + } + + counter++; + } + + return conditionsFulfilled; + } + + /** + * Returns true if the given filter is fulfilled for the given value. + * + * @param e + * @param att + * @param filter + * @param filterSymbol + * @param filterValue + * @param oldBehavior + * if true, old, bugged parsing with format dd/MM/yy will be used + * @return + */ + private boolean checkNumericalCondition(final Example e, final Attribute att, final CustomFilters filter, + final String filterSymbol, final String filterValue, final boolean oldBehavior) { + // special handling because we can have DATE_TIME, DATE and TIME strings in human readable + // format here + double doubleOriginalValue = e.getValue(att); + + double doubleFilterValue; + try { + doubleFilterValue = Double.parseDouble(filterValue); + } catch (NumberFormatException e1) { + // if we have a date we are losing precision - therefore we need to convert the original + // value back and forth once so both lose the same amount of precision - + // otherwise the filters will not work correctly + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE)) { + String formattedOriginal = filter.formatDate(new Date((long) doubleOriginalValue)); + doubleOriginalValue = filter.parseDate(formattedOriginal).getTime(); + // keep compatibility with processes from versions prior to 6.0.004 + if (oldBehavior) { + // if year consists of 2 chars, use old (bugged) version + doubleFilterValue = filter.parseDateOld(filterValue).getTime(); + } else { + // new behavior + doubleFilterValue = filter.parseDate(filterValue).getTime(); + } + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.TIME)) { + String formattedOriginal = filter.formatTime(new Date((long) doubleOriginalValue)); + doubleOriginalValue = filter.parseTime(formattedOriginal).getTime(); + doubleFilterValue = filter.parseTime(filterValue).getTime(); + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE_TIME)) { + String formattedOriginal = filter.formatDateTime(new Date((long) doubleOriginalValue)); + doubleOriginalValue = filter.parseDateTime(formattedOriginal).getTime(); + // keep compatibility with processes from versions prior to 6.0.004 + if (oldBehavior) { + // if year consists of 2 chars, use old (bugged) version + doubleFilterValue = filter.parseDateTimeOld(filterValue).getTime(); + } else { + // new behavior + doubleFilterValue = filter.parseDateTime(filterValue).getTime(); + } + } else { + // because we have checked the filters in the constructor, this is the only option + // left + // special handling for ? as missing value + doubleFilterValue = Double.NaN; + } + } + + return filter.isNumericalConditionFulfilled(doubleOriginalValue, doubleFilterValue); + } + + /** + * Tries to parse the given {@link String} to a {@link Double} and returns true if + * successful; false otherwise. + * + * @param value + * @param att + * @return + */ + private boolean isStringValidDoubleValue(final CustomFilters filter, final String value, final Attribute att) { + try { + Double.parseDouble(value); + } catch (NumberFormatException e1) { + // if we have a date we are losing precision - therefore we need to convert the original + // value back and forth once so both lose the same amount of precision - + // otherwise the filters will not work correctly + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE)) { + if (filter.parseDate(value) == null) { + return false; + } + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.TIME)) { + if (filter.parseTime(value) == null) { + return false; + } + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(att.getValueType(), Ontology.DATE_TIME)) { + if (filter.parseDateTime(value) == null) { + return false; + } + } else { + if ("?".equals(value)) { + // special handling for ? as missing value + return true; + } else { + // all parsing tries failed + return false; + } + } + } + + return true; + } + + /** + * Tries to substitute macros with their real value. + * + * @param value + * @param macroHandler + * @return + */ + private static String substituteMacros(String value, final MacroHandler macroHandler) { + int startIndex = value.indexOf("%{"); + if (startIndex == -1) { + return value; + } + try { + StringBuffer result = new StringBuffer(); + while (startIndex >= 0) { + result.append(value.substring(0, startIndex)); + int endIndex = value.indexOf("}", startIndex + 2); + String macroString = value.substring(startIndex + 2, endIndex); + String macroValue = macroHandler.getMacro(macroString); + if (macroValue != null) { + result.append(macroValue); + } else { + result.append("%{" + macroString + "}"); + } + value = value.substring(endIndex + 1); + startIndex = value.indexOf("%{"); + } + result.append(value); + return result.toString(); + } catch (Exception e) { + return value; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/ExampleSetUtilities.java b/src/main/java/com/rapidminer/example/set/ExampleSetUtilities.java new file mode 100644 index 000000000..e5bcf927b --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/ExampleSetUtilities.java @@ -0,0 +1,188 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.UserError; +import com.rapidminer.tools.Ontology; + + +/** + * This class provides global utility methods for regular operations on ExampleSets or their + * components. + * + * @author Dominik Halfkann + */ +public class ExampleSetUtilities { + + /** + * This {@link Comparator} compares {@link AttributeRole}s according to their Role. It can be + * used to sort the (special) Attributes of an {@link ExampleSet}. + * + * It enforces the following order for Attributes: ID -> Label -> Prediction -> Confidence -> + * Cluster -> Weight -> Other Special Attributes -> Other Regular Attributes + */ + public static final Comparator SPECIAL_ATTRIBUTES_ROLE_COMPARATOR = new Comparator() { + + private List priorityList = Arrays.asList(new String[] { Attributes.ID_NAME, Attributes.LABEL_NAME, + Attributes.PREDICTION_NAME, Attributes.CONFIDENCE_NAME, Attributes.CLUSTER_NAME, Attributes.WEIGHT_NAME }); + + @Override + public int compare(AttributeRole a1, AttributeRole a2) { + // the lower the priority, the earlier the attribute is being sorted + // special attributes should come before regular attributes + int priorityAttribute1 = a1.isSpecial() ? 1000 : 2000; + int priorityAttribute2 = a2.isSpecial() ? 1000 : 2000; + + // if the attribute role is in the priority list, use special priority + if (a1.isSpecial() && priorityList.contains(a1.getSpecialName())) { + priorityAttribute1 = priorityList.indexOf(a1.getSpecialName()); + } + if (a2.isSpecial() && priorityList.contains(a2.getSpecialName())) { + priorityAttribute2 = priorityList.indexOf(a2.getSpecialName()); + } + + // special priority for roles that start with "confidence_" + if (a1.isSpecial() && a1.getSpecialName().startsWith(Attributes.CONFIDENCE_NAME + "_")) { + priorityAttribute1 = priorityList.indexOf(Attributes.CONFIDENCE_NAME); + } + if (a2.isSpecial() && a2.getSpecialName().startsWith(Attributes.CONFIDENCE_NAME + "_")) { + priorityAttribute2 = priorityList.indexOf(Attributes.CONFIDENCE_NAME); + } + + return priorityAttribute1 - priorityAttribute2; + } + + }; + + /** Determines how to compare the sets of Attributes. */ + public static enum SetsCompareOption { + /** Both sets of Attributes must be the same. */ + EQUAL, + /** The second set of Attributes must be a subset of the first one. */ + ALLOW_SUBSET, + /** The second set of Attributes must be a superset of the first one. */ + ALLOW_SUPERSET, + /** Just compare matching Attributes from both sets (intersection). */ + USE_INTERSECTION + } + + /** Determines how to compare the matching Attributes regarding their types. */ + public static enum TypesCompareOption { + /** + * An Attribute from the second set must be of the same type as the corresponding Attribute + * from the first set. + */ + EQUAL, + /** + * An Attribute from the second set must be a subtype of the corresponding Attribute from + * the first set. + */ + ALLOW_SUBTYPES, + /** + * An Attribute from the second set must be a supertype of the corresponding Attribute from + * the first set. + */ + ALLOW_SUPERTYPES, + /** + * An Attribute from the second set must have the same parent as the corresponding Attribute + * from the first set. + */ + ALLOW_SAME_PARENTS, + /** ignores different Types of the Attributes */ + DONT_CARE + } + + /** + * Check if two sets of Attributes are matching. Throws an {@link UserError} if they are not + * equal with regard to the specified {@link SetsCompareOption} and {@link TypesCompareOption}. + */ + public static void checkAttributesMatching(Operator op, Attributes originalAttributes, Attributes comparedAttributes, + SetsCompareOption compareSets, TypesCompareOption compareTypes) throws UserError { + + for (Attribute originalAttribute : originalAttributes) { + if (comparedAttributes.contains(originalAttribute)) { + Attribute comparedAttribute = comparedAttributes.get(originalAttribute.getName()); + int originalValueType = originalAttribute.getValueType(); + int comparedValueType = comparedAttribute.getValueType(); + if (originalValueType != comparedValueType) { + Ontology valueTypes = Ontology.ATTRIBUTE_VALUE_TYPE; + if (compareTypes == TypesCompareOption.ALLOW_SUBTYPES) { + if (!valueTypes.isA(comparedValueType, originalValueType)) { + throw new UserError(op, 964, comparedAttribute.getName(), + Ontology.VALUE_TYPE_NAMES[comparedValueType], + Ontology.VALUE_TYPE_NAMES[originalValueType]); + } + } else if (compareTypes == TypesCompareOption.ALLOW_SUPERTYPES) { + if (!valueTypes.isA(originalValueType, comparedValueType)) { + throw new UserError(null, 965, comparedAttribute.getName(), + Ontology.VALUE_TYPE_NAMES[comparedValueType], + Ontology.VALUE_TYPE_NAMES[originalValueType]); + } + } else if (compareTypes == TypesCompareOption.ALLOW_SAME_PARENTS) { + /* + * Calculate parents. If one parent is equal to ATTRIBUITE_VALUE or less (no + * parent at all) then take the origin value. + */ + int parentOriginal = valueTypes.getParent(originalValueType); + parentOriginal = parentOriginal <= Ontology.ATTRIBUTE_VALUE ? originalValueType : parentOriginal; + int parentCompared = valueTypes.getParent(comparedValueType); + parentCompared = parentCompared <= Ontology.ATTRIBUTE_VALUE ? comparedValueType : parentCompared; + + if (!valueTypes.isA(parentCompared, parentOriginal)) { + throw new UserError(op, 965, comparedAttribute.getName(), + Ontology.VALUE_TYPE_NAMES[comparedValueType], + Ontology.VALUE_TYPE_NAMES[originalValueType]); + } + } else if (compareTypes == TypesCompareOption.EQUAL) { + throw new UserError(op, 963, comparedAttribute.getName(), + Ontology.VALUE_TYPE_NAMES[originalValueType], Ontology.VALUE_TYPE_NAMES[comparedValueType]); + } + } + } else { + if (compareSets == SetsCompareOption.EQUAL) { + throw new UserError(op, 960, originalAttribute.getName()); + } + if (compareSets == SetsCompareOption.ALLOW_SUPERSET) { + throw new UserError(op, 962, originalAttribute.getName()); + } + } + } + + for (Attribute comparedAttribute : comparedAttributes) { + if (!originalAttributes.contains(comparedAttribute)) { + if (compareSets == SetsCompareOption.EQUAL) { + throw new UserError(op, 960, comparedAttribute.getName()); + } + if (compareSets == SetsCompareOption.ALLOW_SUBSET) { + throw new UserError(op, 961, comparedAttribute.getName()); + } + } + } + + } +} diff --git a/src/main/java/com/rapidminer/example/set/ExpressionFilter.java b/src/main/java/com/rapidminer/example/set/ExpressionFilter.java new file mode 100644 index 000000000..8c5f6430b --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/ExpressionFilter.java @@ -0,0 +1,143 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.tools.ExpressionEvaluationException; +import com.rapidminer.tools.I18N; +import com.rapidminer.tools.expression.ExampleResolver; +import com.rapidminer.tools.expression.Expression; +import com.rapidminer.tools.expression.ExpressionException; +import com.rapidminer.tools.expression.ExpressionType; +import com.rapidminer.tools.expression.internal.ExpressionParserUtils; + + +/** + * The condition is fulfilled if the expression evaluates to true. Respectively the + * condition is not fulfilled if the expression evaluates to false or null + * . + * + * @author Marco Boeck + */ +public class ExpressionFilter implements Condition { + + private static final long serialVersionUID = -8663210021090219277L; + + private String expression; + + private ExampleResolver resolver; + + private ExpressionType type; + + private Expression result; + + /** + * Creates a new {@link ExpressionFilter} instance with the given expression. The expression is + * evaluated via the expression parser and examples are ok if the expression evaluates to + * true. + * + * @param exampleSet + * @param expression + * @param process + * @param compatibilityLevel + * @throws ExpressionException + */ + public ExpressionFilter(ExampleSet exampleSet, String expression, Operator operator) throws ExpressionException { + if (exampleSet == null) { + throw new IllegalArgumentException("exampleSet must not be null!"); + } + if (expression == null) { + throw new IllegalArgumentException("expression must not be null!"); + } + if (operator == null) { + throw new IllegalArgumentException("operator must not be null!"); + } + + this.expression = expression; + this.resolver = new ExampleResolver(exampleSet); + + this.result = ExpressionParserUtils.createAllModulesParser(operator, resolver).parse(expression); + this.type = result.getExpressionType(); + } + + /** + * The sole purpose of this constructor is to provide a constructor that matches the expected + * signature for the {@link ConditionedExampleSet} reflection invocation. However, this class + * cannot be instantiated by an ExampleSet and a String, so we always throw an + * {@link IllegalArgumentException} to signal this filter cannot be instantiated that way. + * + * @throws IllegalArgumentException + * ALWAYS THROWN! + */ + @Deprecated + public ExpressionFilter(ExampleSet exampleSet, String parameterString) throws IllegalArgumentException { + throw new IllegalArgumentException("This condition cannot be instantiated this way!"); + } + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + @Override + public String toString() { + return expression; + } + + /** Returns true if all conditions are fulfilled for the given example. */ + @Override + public boolean conditionOk(Example e) throws ExpressionEvaluationException { + try { + resolver.bind(e); + + if (type == ExpressionType.BOOLEAN) { + Boolean resultValue = result.evaluateBoolean(); + if (resultValue == null) { + return false; + } + return resultValue; + } else if (type == ExpressionType.DOUBLE) { + double resultValue = result.evaluateNumerical(); + if (resultValue == 1d || resultValue == 0d) { + return resultValue == 1d; + } + } + throw new ExpressionEvaluationException( + I18N.getMessageOrNull(I18N.getErrorBundle(), "expression_filter.expression_not_boolean", expression)); + } catch (ExpressionException e1) { + // all parsing tries failed, show warning and return false + throw new ExpressionEvaluationException( + I18N.getMessageOrNull(I18N.getErrorBundle(), "expression_filter.parser_parsing_failed", expression)); + } finally { + // avoid memory leak + resolver.unbind(); + } + } + +} diff --git a/src/main/java/com/rapidminer/example/set/HeaderExampleSet.java b/src/main/java/com/rapidminer/example/set/HeaderExampleSet.java new file mode 100644 index 000000000..6545b4303 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/HeaderExampleSet.java @@ -0,0 +1,89 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; + +import java.util.Iterator; + + +/** + * This example set is a clone of the attributes without reference to any data. Therefore it can be + * used as a data header description. Since no data reference exist, all example based methods will + * throw an {@link UnsupportedOperationException}. + * + * @author Ingo Mierswa + */ +public class HeaderExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = -255270841843010670L; + + /** The parent example set. */ + private Attributes attributes; + + public HeaderExampleSet(ExampleSet parent) { + cloneAnnotationsFrom(parent); + this.attributes = (Attributes) parent.getAttributes().clone(); + } + + /** Header example set clone constructor. */ + public HeaderExampleSet(HeaderExampleSet other) { + cloneAnnotationsFrom(other); + this.attributes = (Attributes) other.attributes.clone(); + } + + @Override + public Attributes getAttributes() { + return attributes; + } + + @Override + public Example getExample(int index) { + return null; + } + + @Override + public Example getExampleFromId(double value) { + throw new UnsupportedOperationException( + "The method getExampleFromId(double) is not supported by the header example set."); + } + + @Override + public ExampleTable getExampleTable() { + throw new UnsupportedOperationException("The method getExampleTable() is not supported by the header example set."); + } + + @Override + public void remapIds() { + throw new UnsupportedOperationException("The method remapIds() is not supported by the header example set."); + } + + @Override + public int size() { + return 0; + } + + @Override + public Iterator iterator() { + throw new UnsupportedOperationException("The method iterator() is not supported by the header example set."); + } +} diff --git a/src/main/java/com/rapidminer/example/set/IndexBasedExampleSetReader.java b/src/main/java/com/rapidminer/example/set/IndexBasedExampleSetReader.java new file mode 100644 index 000000000..82e263eb4 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/IndexBasedExampleSetReader.java @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * Returns only a subset of an example set specified by an instance of {@link Partition}. + * + * @author Simon Fischer, Ingo Mierswa ingomierswa Exp $ + */ +public class IndexBasedExampleSetReader extends AbstractExampleReader { + + /** Index of the current example. */ + private int current; + + private ExampleSet parent; + + /** The next example that will be returned. */ + private Example next; + + private int size; + + public IndexBasedExampleSetReader(ExampleSet parent) { + this.parent = parent; + this.size = parent.size(); + current = -1; + hasNext(); + } + + @Override + public boolean hasNext() { + while (next == null) { + current++; + + if (current >= size) { + return false; + } + + next = parent.getExample(current); + } + return true; + } + + @Override + public Example next() { + if (!hasNext()) { + return null; + } else { + Example dummy = next; + next = null; + return dummy; + } + } + +} diff --git a/src/main/java/com/rapidminer/example/set/MappedExampleReader.java b/src/main/java/com/rapidminer/example/set/MappedExampleReader.java new file mode 100644 index 000000000..02f3a7cea --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/MappedExampleReader.java @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; + +import java.util.Iterator; + + +/** + * This example reader is based on the given mapping and skips all examples which are not part of + * the mapping. If an index occurs more than once the example will be returned the number of desired + * times. For performance reasons the mapping array must have been sorted beforehand. + * + * @author Ingo Mierswa, Martin Scholz + */ +public class MappedExampleReader extends AbstractExampleReader { + + /** The example reader that provides a complete example set. */ + private Iterator parent; + + /** The used mapping. */ + private int[] mapping; + + /** The example that will be returned by the next invocation of next(). */ + private Example currentExample; + + /** Indicates if the current example was "delivered" by a call of {@link #next()}. */ + private boolean nextInvoked = true; + + /** The current index in the mapping. */ + private int index = -1; + + /** Constructs a new mapped example reader. */ + public MappedExampleReader(Iterator parent, int[] mapping) { + this.parent = parent; + this.currentExample = null; + this.mapping = mapping; + } + + @Override + public boolean hasNext() { + if (this.nextInvoked) { + this.nextInvoked = false; + int oldMapping = -1; + if (index >= this.mapping.length - 1) { + return false; + } + if (index != -1) { + oldMapping = this.mapping[index]; + } + this.index++; + int newMapping = this.mapping[index]; + + if (newMapping != oldMapping) { + do { + if (!parent.hasNext()) { + return false; + } + this.currentExample = parent.next(); + oldMapping++; + } while (oldMapping < newMapping); + } else { + return true; + } + } + return true; + } + + @Override + public Example next() { + if (hasNext()) { + this.nextInvoked = true; + return currentExample; + } else { + return null; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/MappedExampleSet.java b/src/main/java/com/rapidminer/example/set/MappedExampleSet.java new file mode 100644 index 000000000..5dd5410c7 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/MappedExampleSet.java @@ -0,0 +1,210 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Statistics; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Random; + + +/** + *

+ * This example set uses a mapping of indices to access the examples provided by the parent example + * set. The mapping does not need to contain unique indices which is especially useful for sampling + * with replacement. For performance reasons (iterations, database access...) the mapping will be + * sorted during the construction of this example set (based on the parameter sort). + *

+ * + *

+ * Please note that the constructor takes a boolean flag indicating if the examples from the given + * array are used or if the examples which are not part of this mapping should be used. This might + * be useful in the context of bootstrapped validation for example. + *

+ * + * @author Ingo Mierswa, Martin Scholz + */ +public class MappedExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = -488025806523583178L; + + /** The parent example set. */ + private ExampleSet parent; + + /** The used mapping. */ + private int[] mapping; + + /** Constructs an example set based on the given mapping. */ + public MappedExampleSet(ExampleSet parent, int[] mapping) { + this(parent, mapping, true); + } + + /** + * Constructs an example set based on the given mapping. If the boolean flag useMappedExamples + * is false only examples which are not part of the original mapping are used. + */ + public MappedExampleSet(ExampleSet parent, int[] mapping, boolean useMappedExamples) { + this(parent, mapping, useMappedExamples, true); + } + + /** + * Constructs an example set based on the given mapping. If the boolean flag useMappedExamples + * is false only examples which are not part of the original mapping are used. If the boolean + * flag sort is false the mapping is used as is. + */ + public MappedExampleSet(ExampleSet parent, int[] mapping, boolean useMappedExamples, boolean sort) { + this.parent = (ExampleSet) parent.clone(); + this.mapping = mapping; + if (sort) { + Arrays.sort(this.mapping); + } + + if (!useMappedExamples) { + List inverseIndexList = new ArrayList(); + int currentExample = -1; + for (int m : mapping) { + if (m != currentExample) { + for (int z = currentExample + 1; z < m; z++) { + inverseIndexList.add(z); + } + currentExample = m; + } + } + this.mapping = new int[inverseIndexList.size()]; + Iterator i = inverseIndexList.iterator(); + int index = 0; + while (i.hasNext()) { + this.mapping[index++] = i.next(); + } + } + } + + /** Clone constructor. */ + public MappedExampleSet(MappedExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.mapping = exampleSet.mapping; + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof MappedExampleSet)) { + return false; + } + + MappedExampleSet other = (MappedExampleSet) o; + if (this.mapping.length != other.mapping.length) { + return false; + } + for (int i = 0; i < this.mapping.length; i++) { + if (this.mapping[i] != other.mapping[i]) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.mapping); + } + + /** Returns a {@link MappedExampleReader}. */ + @Override + public Iterator iterator() { + return new MappedExampleReader(parent.iterator(), this.mapping); + } + + /** Returns the i-th example in the mapping. */ + @Override + public Example getExample(int index) { + if ((index < 0) || (index >= this.mapping.length)) { + throw new RuntimeException("Given index '" + index + "' does not fit the mapped ExampleSet!"); + } else { + return parent.getExample(this.mapping[index]); + } + } + + /** Counts the number of examples. */ + @Override + public int size() { + return mapping.length; + } + + @Override + public Attributes getAttributes() { + return parent.getAttributes(); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + /** Creates a new mapping for the given example set by sampling with replacement. */ + public static int[] createBootstrappingMapping(ExampleSet exampleSet, int size, Random random) { + int[] mapping = new int[size]; + for (int i = 0; i < mapping.length; i++) { + mapping[i] = random.nextInt(exampleSet.size()); + } + return mapping; + } + + public static int[] createWeightedBootstrappingMapping(ExampleSet exampleSet, int size, Random random) { + Attribute weightAttribute = exampleSet.getAttributes().getSpecial(Attributes.WEIGHT_NAME); + exampleSet.recalculateAttributeStatistics(weightAttribute); + double maxWeight = exampleSet.getStatistics(weightAttribute, Statistics.MAXIMUM); + + int[] mapping = new int[size]; + for (int i = 0; i < mapping.length; i++) { + int index = -1; + do { + index = random.nextInt(exampleSet.size()); + Example example = exampleSet.getExample(index); + double currentWeight = example.getValue(weightAttribute); + if (random.nextDouble() > currentWeight / maxWeight) { + index = -1; + } + } while (index == -1); + mapping[i] = index; + } + return mapping; + } + + /* + * (non-Javadoc) + * + * @see com.rapidminer.operator.ResultObjectAdapter#getAnnotations() + */ + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/MissingAttributesCondition.java b/src/main/java/com/rapidminer/example/set/MissingAttributesCondition.java new file mode 100644 index 000000000..bfa737e04 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/MissingAttributesCondition.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This subclass of {@link Condition} serves to excludes all examples containing no missing values + * from an example set. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class MissingAttributesCondition implements Condition { + + private static final long serialVersionUID = 6872303452739421943L; + + /** + * Throws an exception since this condition does not support parameter string. + */ + public MissingAttributesCondition(ExampleSet exampleSet, String parameterString) {} + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + /** Returns true if the example does not contain missing values. */ + @Override + public boolean conditionOk(Example example) { + for (Attribute attribute : example.getAttributes()) { + if (Double.isNaN(example.getValue(attribute))) { + return true; + } + } + return false; + } +} diff --git a/src/main/java/com/rapidminer/example/set/MissingLabelsCondition.java b/src/main/java/com/rapidminer/example/set/MissingLabelsCondition.java new file mode 100644 index 000000000..427a442c4 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/MissingLabelsCondition.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This subclass of {@link Condition} serves to exclude examples with known labels from an example + * set. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class MissingLabelsCondition implements Condition { + + private static final long serialVersionUID = 6559275828082706521L; + + /** + * Throws an exception since a parameter string is not allowed for this condition. + */ + public MissingLabelsCondition(ExampleSet exampleSet, String parameterString) {} + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + /** Returns true if the label was not defined. */ + @Override + public boolean conditionOk(Example example) { + if (Double.isNaN(example.getValue(example.getAttributes().getLabel()))) { + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/ModelViewExampleSet.java b/src/main/java/com/rapidminer/example/set/ModelViewExampleSet.java new file mode 100644 index 000000000..f47487f52 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/ModelViewExampleSet.java @@ -0,0 +1,103 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; +import com.rapidminer.operator.ViewModel; + +import java.util.Iterator; + + +/** + * This is a generic example set (view on the view stack of the data) which can be used to apply any + * preprocessing model and create a view from it. + * + * @author Sebastian Land, Ingo Mierswa + */ +public class ModelViewExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = -6443667708498013284L; + + private ExampleSet parent; + + private Attributes attributes; + + public ModelViewExampleSet(ExampleSet parent, ViewModel model) { + this.parent = (ExampleSet) parent.clone(); + this.attributes = model.getTargetAttributes(parent); + } + + /** Clone constructor. */ + public ModelViewExampleSet(ModelViewExampleSet other) { + this.parent = (ExampleSet) other.parent.clone(); + this.attributes = other.attributes; + + if (other.attributes != null) { + this.attributes = (Attributes) other.attributes.clone(); + } + } + + @Override + public Attributes getAttributes() { + return this.attributes; + } + + /** + * Creates a new example set reader. + */ + @Override + public Iterator iterator() { + return new AttributesExampleReader(parent.iterator(), this); + } + + @Override + public Example getExample(int index) { + DataRow dataRow = this.parent.getExample(index).getDataRow(); + if (dataRow == null) { + return null; + } else { + return new Example(dataRow, this); + } + } + + @Override + public ExampleTable getExampleTable() { + return this.parent.getExampleTable(); + } + + @Override + public int size() { + return this.parent.size(); + } + + /* + * (non-Javadoc) + * + * @see com.rapidminer.operator.ResultObjectAdapter#getAnnotations() + */ + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/NoMissingAttributeValueCondition.java b/src/main/java/com/rapidminer/example/set/NoMissingAttributeValueCondition.java new file mode 100644 index 000000000..e7987daf0 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/NoMissingAttributeValueCondition.java @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + + +/** + * This subclass of {@link Condition} serves to excludes all examples containing missing values + * within specified attributes from an example set. The parameters might be specified using a + * regular expression as parameter string + * + * @author Sebastian Land ingomierswa Exp $ + */ +public class NoMissingAttributeValueCondition implements Condition { + + private static final long serialVersionUID = -6043772701857922762L; + + private Collection checkedAttributes = new LinkedList(); + + public NoMissingAttributeValueCondition(ExampleSet exampleSet, String parameterString) { + Iterator iterator = exampleSet.getAttributes().allAttributes(); + while (iterator.hasNext()) { + Attribute attribute = iterator.next(); + if (attribute.getName().matches(parameterString)) { + checkedAttributes.add(attribute); + } + } + } + + /** Returns true if the example does not contain missing values within regarded attributes. */ + @Override + public boolean conditionOk(Example example) { + boolean isOk = true; + for (Attribute attribute : checkedAttributes) { + isOk &= !Double.isNaN(example.getValue(attribute)); + } + return isOk; + } + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + +} diff --git a/src/main/java/com/rapidminer/example/set/NoMissingAttributesCondition.java b/src/main/java/com/rapidminer/example/set/NoMissingAttributesCondition.java new file mode 100644 index 000000000..a60e1cca0 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/NoMissingAttributesCondition.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This subclass of {@link Condition} serves to excludes all examples containing missing values from + * an example set. + * + * @author Timm Euler, Ingo Mierswa ingomierswa Exp $ + */ +public class NoMissingAttributesCondition implements Condition { + + private static final long serialVersionUID = 631871757551493977L; + + /** + * Throws an exception since this condition does not support parameter string. + */ + public NoMissingAttributesCondition(ExampleSet exampleSet, String parameterString) {} + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + /** Returns true if the example does not contain missing values. */ + @Override + public boolean conditionOk(Example example) { + for (Attribute attribute : example.getAttributes()) { + if (Double.isNaN(example.getValue(attribute))) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/rapidminer/example/set/NoMissingLabelsCondition.java b/src/main/java/com/rapidminer/example/set/NoMissingLabelsCondition.java new file mode 100644 index 000000000..ceabc30d0 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/NoMissingLabelsCondition.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This subclass of {@link Condition} serves to exclude examples with unknown labels from an example + * set. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class NoMissingLabelsCondition implements Condition { + + private static final long serialVersionUID = 8047504208389222350L; + + /** + * Throws an exception since a parameter string is not allowed for this condition. + */ + public NoMissingLabelsCondition(ExampleSet exampleSet, String parameterString) {} + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + /** Returns true if the label was defined. */ + @Override + public boolean conditionOk(Example example) { + if (Double.isNaN(example.getValue(example.getAttributes().getLabel()))) { + return false; + } else { + return true; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/NonSpecialAttributesExampleSet.java b/src/main/java/com/rapidminer/example/set/NonSpecialAttributesExampleSet.java new file mode 100644 index 000000000..e91919914 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/NonSpecialAttributesExampleSet.java @@ -0,0 +1,96 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; + +import java.util.Iterator; + + +/** + * This example set treats all special attributes as regular attributes. + * + * @author Ingo Mierswa + */ +public class NonSpecialAttributesExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = -4782316585512718459L; + + /** The parent example set. */ + private ExampleSet parent; + + public NonSpecialAttributesExampleSet(ExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.clone(); + Iterator s = this.parent.getAttributes().specialAttributes(); + while (s.hasNext()) { + AttributeRole attributeRole = s.next(); + if (attributeRole.isSpecial()) { + attributeRole.changeToRegular(); + } + } + } + + /** Clone constructor. */ + public NonSpecialAttributesExampleSet(NonSpecialAttributesExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + } + + @Override + public Attributes getAttributes() { + return this.parent.getAttributes(); + } + + /** + * Creates an iterator over all examples. + */ + @Override + public Iterator iterator() { + return new AttributesExampleReader(parent.iterator(), this); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + @Override + public Example getExample(int index) { + return this.parent.getExample(index); + } + + @Override + public int size() { + return parent.size(); + } + + /* + * (non-Javadoc) + * + * @see com.rapidminer.operator.ResultObjectAdapter#getAnnotations() + */ + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/Partition.java b/src/main/java/com/rapidminer/example/set/Partition.java new file mode 100644 index 000000000..05e7f8b04 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/Partition.java @@ -0,0 +1,289 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.tools.LogService; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; + + +/** + * Implements a partition. A partition is used to divide an example set into different parts of + * arbitrary sizes without actually make a copy of the data. Partitions are used by + * {@link SplittedExampleSet}s. Partition numbering starts at 0. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class Partition implements Cloneable, Serializable { + + private static final long serialVersionUID = 6126334515107973287L; + + /** Mask for the selected partitions. */ + private boolean[] mask; + + /** Size of the individual partitions. */ + private int[] partitionSizes; + + /** Maps every example to its partition index. */ + private int[] elements; + + /** Indicates the position of the last element for each partition. */ + private int[] lastElementIndex; + + /** + * Maps every example index to the true index of the data row in the example table. + */ + private int[] tableIndexMap = null; + + /** + * Creates a new partition of a given size consisting of ratio.length sets. The set + * i will be of size of size x ratio[i], i.e. the sum of all ratio[i] must + * be 1. Initially all partitions are selected. + */ + public Partition(double ratio[], int size, PartitionBuilder builder) { + init(ratio, size, builder); + } + + /** + * Creates a new partition of a given size consisting of noPartitions equally sized sets. + * Initially all partitions are selected. + */ + public Partition(int noPartitions, int size, PartitionBuilder builder) { + double[] ratio = new double[noPartitions]; + for (int i = 0; i < ratio.length; i++) { + ratio[i] = 1 / (double) noPartitions; + } + init(ratio, size, builder); + } + + /** Creates a partition from the given one. Partition numbering starts at 0. */ + public Partition(int[] elements, int numberOfPartitions) { + init(elements, numberOfPartitions); + } + + /** Clone constructor. */ + private Partition(Partition p) { + this.partitionSizes = new int[p.partitionSizes.length]; + System.arraycopy(p.partitionSizes, 0, this.partitionSizes, 0, p.partitionSizes.length); + + this.mask = new boolean[p.mask.length]; + System.arraycopy(p.mask, 0, this.mask, 0, p.mask.length); + + this.elements = new int[p.elements.length]; + System.arraycopy(p.elements, 0, this.elements, 0, p.elements.length); + + this.lastElementIndex = new int[p.lastElementIndex.length]; + System.arraycopy(p.lastElementIndex, 0, this.lastElementIndex, 0, p.lastElementIndex.length); + + recalculateTableIndices(); + } + + /** + * Creates a partition from the given ratios. The partition builder is used for creation. + */ + private void init(double[] ratio, int size, PartitionBuilder builder) { + // LogService.getGlobal().log("Create new partition using a '" + + // builder.getClass().getName() + "'.", LogService.STATUS); + LogService.getRoot().log(Level.FINE, "com.rapidminer.example.set.Partition.creating_new_partition_using", + builder.getClass().getName()); + elements = builder.createPartition(ratio, size); + init(elements, ratio.length); + } + + /** Private initialization method used by constructors. */ + private void init(int[] newElements, int noOfPartitions) { + // LogService.getGlobal().log("Create new partition with " + newElements.length + + // " elements and " + noOfPartitions + " partitions.", + // LogService.STATUS); + LogService.getRoot().log(Level.FINE, "com.rapidminer.example.set.Partition.creating_new_partition_with", + new Object[] { newElements.length, noOfPartitions }); + partitionSizes = new int[noOfPartitions]; + lastElementIndex = new int[noOfPartitions]; + elements = newElements; + for (int i = 0; i < elements.length; i++) { + if (elements[i] >= 0) { + partitionSizes[elements[i]]++; + lastElementIndex[elements[i]] = i; + } + } + + // select all partitions + mask = new boolean[noOfPartitions]; + for (int i = 0; i < mask.length; i++) { + mask[i] = true; + } + + recalculateTableIndices(); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Partition)) { + return false; + } + + Partition other = (Partition) o; + + for (int i = 0; i < mask.length; i++) { + if (this.mask[i] != other.mask[i]) { + return false; + } + } + + for (int i = 0; i < elements.length; i++) { + if (this.elements[i] != other.elements[i]) { + return false; + } + } + + return true; + } + + @Override + public int hashCode() { + int hc = 17; + int hashMultiplier = 59; + + hc = hc * hashMultiplier + this.mask.length; + for (int i = 1; i < mask.length; i <<= 1) { + hc = hc * hashMultiplier + Boolean.valueOf(this.mask[i]).hashCode(); + } + + hc = hc * hashMultiplier + this.elements.length; + for (int i = 1; i < elements.length; i <<= 1) { + hc = hc * hashMultiplier + Integer.valueOf(this.elements[i]).hashCode(); + } + + return hc; + } + + /** + * Returns true if the last possible index stored in lastElementIndex for all currently selected + * partitions is not yet reached. Might be used to prune iterations (especially useful for + * linear partitions). + */ + public boolean hasNext(int index) { + for (int p = 0; p < mask.length; p++) { + if (mask[p]) { + if (index <= lastElementIndex[p]) { + return true; + } + } + } + return false; + } + + /** Clears the selection, i.e. deselects all subsets. */ + public void clearSelection() { + this.mask = new boolean[mask.length]; + recalculateTableIndices(); + } + + public void invertSelection() { + for (int i = 0; i < mask.length; i++) { + mask[i] = !mask[i]; + } + recalculateTableIndices(); + }; + + /** Marks the given subset as selected. */ + public void selectSubset(int i) { + this.mask[i] = true; + recalculateTableIndices(); + } + + /** Marks the given subset as deselected. */ + public void deselectSubset(int i) { + this.mask[i] = false; + recalculateTableIndices(); + } + + /** Returns the number of subsets. */ + public int getNumberOfSubsets() { + return partitionSizes.length; + } + + /** Returns the number of selected elements. */ + public int getSelectionSize() { + int s = 0; + for (int i = 0; i < partitionSizes.length; i++) { + if (mask[i]) { + s += partitionSizes[i]; + } + } + return s; + } + + /** Returns the total number of examples. */ + public int getTotalSize() { + return elements.length; + } + + /** + * Returns true iff the example with the given index is selected according to the current + * selection mask. + */ + public boolean isSelected(int index) { + return mask[elements[index]]; + } + + /** + * Recalculates the example table indices of the currently selected examples. + */ + private void recalculateTableIndices() { + List indices = new LinkedList(); + for (int i = 0; i < elements.length; i++) { + if (mask[elements[i]]) { + indices.add(i); + } + } + tableIndexMap = new int[indices.size()]; + Iterator i = indices.iterator(); + int counter = 0; + while (i.hasNext()) { + tableIndexMap[counter++] = i.next(); + } + } + + /** + * Returns the actual example table index of the i-th example of the currently selected subset. + */ + public int mapIndex(int index) { + return tableIndexMap[index]; + } + + @Override + public String toString() { + StringBuffer str = new StringBuffer("("); + for (int i = 0; i < partitionSizes.length; i++) { + str.append((i != 0 ? "/" : "") + partitionSizes[i]); + } + str.append(")"); + return str.toString(); + } + + @Override + public Object clone() { + return new Partition(this); + } +} diff --git a/src/main/java/com/rapidminer/example/set/PartitionBuilder.java b/src/main/java/com/rapidminer/example/set/PartitionBuilder.java new file mode 100644 index 000000000..da8c061cb --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/PartitionBuilder.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +/** + * Creates partitions from ratio arrays. Subclasses might shuffle the examples before building the + * partition or apply stratification. The delivered partitions consist of an array of integer values + * with the same length as the given size. For each element the integer defines the number of the + * partition for this element. Numbering starts with 0. + * + * @author Ingo Mierswa + */ +public interface PartitionBuilder { + + /** + * Creates a partition from the given ratios. Size is the number of elements, i.e. the number of + * examples. + */ + public int[] createPartition(double[] ratio, int size); +} diff --git a/src/main/java/com/rapidminer/example/set/RemappedExampleSet.java b/src/main/java/com/rapidminer/example/set/RemappedExampleSet.java new file mode 100644 index 000000000..1f669df4f --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/RemappedExampleSet.java @@ -0,0 +1,139 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.example.table.NominalMapping; +import com.rapidminer.operator.Annotations; + + +/** + * This example set uses the mapping given by another example set and "remaps" on the fly the + * nominal values according to the given set. It also sorts the regular attributes in the order of + * the other exampleSet if possible. If additional attributes occur, they are appended on the end of + * the example set, if keepAdditional is selected. + * + * @author Ingo Mierswa, Sebastian Land + */ +public class RemappedExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = 3460640319989955936L; + + private ExampleSet parent; + + public RemappedExampleSet(ExampleSet parentSet, ExampleSet mappingSet) { + this(parentSet, mappingSet, true); + } + + public RemappedExampleSet(ExampleSet parentSet, ExampleSet _mappingSet, boolean keepAdditional) { + this.parent = (ExampleSet) parentSet.clone(); + ExampleSet mappingSet = (ExampleSet) _mappingSet.clone(); + + // check for a missing mappingSet because of compatibility + if (mappingSet != null) { + Attributes attributes = parent.getAttributes(); + + // copying attributes into name map + Map attributeMap = new LinkedHashMap<>(parent.size()); + for (Attribute attribute : attributes) { + attributeMap.put(attribute.getName(), attribute); + } + + // clearing cloned set + attributes.clearRegular(); + + // adding again in mappingSets's order + for (Attribute mapAttribute : mappingSet.getAttributes()) { + String name = mapAttribute.getName(); + Attribute attribute = attributeMap.get(name); + if (attribute != null) { + attributes.addRegular(attribute); + attributeMap.remove(name); + } + } + + if (keepAdditional) { + // adding all additional attributes + for (Attribute attribute : attributeMap.values()) { + attributes.addRegular(attribute); + } + } + + // mapping nominal values + Iterator a = this.parent.getAttributes().allAttributeRoles(); + while (a.hasNext()) { + AttributeRole role = a.next(); + Attribute currentAttribute = role.getAttribute(); + if (currentAttribute.isNominal()) { + NominalMapping mapping = null; + mapping = currentAttribute.getMapping(); + Attribute oldMappingAttribute = mappingSet.getAttributes().get(role.getAttribute().getName()); + if (oldMappingAttribute != null && oldMappingAttribute.isNominal()) { + mapping = oldMappingAttribute.getMapping(); + } + currentAttribute.addTransformation(new AttributeTransformationRemapping(mapping)); + } + } + } + } + + /** Clone constructor. */ + public RemappedExampleSet(RemappedExampleSet other) { + this.parent = (ExampleSet) other.parent.clone(); + } + + @Override + public Attributes getAttributes() { + return this.parent.getAttributes(); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + @Override + public int size() { + return parent.size(); + } + + @Override + public Iterator iterator() { + return new AttributesExampleReader(parent.iterator(), this); + } + + @Override + public Example getExample(int index) { + return this.parent.getExample(index); + } + + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/ReplaceMissingExampleSet.java b/src/main/java/com/rapidminer/example/set/ReplaceMissingExampleSet.java new file mode 100644 index 000000000..03a947aef --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/ReplaceMissingExampleSet.java @@ -0,0 +1,169 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.AttributeTransformation; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Statistics; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + + +/** + * An implementation of ExampleSet that allows the replacement of missing values on the fly. Missing + * values will be replaced by the average of all other values or by the mean. + * + * @author Ingo Mierswa + */ +public class ReplaceMissingExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = -5662936146589379273L; + + /** Currently used attribute weights. Used also for example creation. */ + private Map replacementMap; + + /** The parent example set. */ + private ExampleSet parent; + + public ReplaceMissingExampleSet(ExampleSet exampleSet) { + this(exampleSet, null); + } + + public ReplaceMissingExampleSet(ExampleSet exampleSet, Map replacementMap) { + this.parent = (ExampleSet) exampleSet.clone(); + if (replacementMap == null) { + this.replacementMap = new HashMap(); + for (Attribute attribute : parent.getAttributes()) { + addReplacement(attribute); + } + } else { + this.replacementMap = replacementMap; + } + + Iterator a = this.parent.getAttributes().allAttributeRoles(); + while (a.hasNext()) { + AttributeRole role = a.next(); + Attribute currentAttribute = role.getAttribute(); + currentAttribute.addTransformation(new AttributeTransformationReplaceMissing(this.replacementMap)); + } + } + + /** Clone constructor. */ + public ReplaceMissingExampleSet(ReplaceMissingExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.replacementMap = new HashMap(); + for (String name : exampleSet.replacementMap.keySet()) { + this.replacementMap.put(name, Double.valueOf(exampleSet.replacementMap.get(name).doubleValue())); + } + + Iterator a = this.parent.getAttributes().allAttributeRoles(); + while (a.hasNext()) { + AttributeRole role = a.next(); + Attribute currentAttribute = role.getAttribute(); + AttributeTransformation transformation = currentAttribute.getLastTransformation(); + if (transformation != null) { + if (transformation instanceof AttributeTransformationReplaceMissing) { + ((AttributeTransformationReplaceMissing) transformation).setReplacementMap(this.replacementMap); + } + } + } + } + + public Map getReplacementMap() { + return this.replacementMap; + } + + public void addReplacement(Attribute attribute) { + recalculateAttributeStatistics(attribute); + if (attribute.isNominal()) { + this.replacementMap.put(attribute.getName(), getStatistics(attribute, Statistics.MODE)); + } else { + this.replacementMap.put(attribute.getName(), getStatistics(attribute, Statistics.AVERAGE)); + } + } + + @Override + public Attributes getAttributes() { + return this.parent.getAttributes(); + } + + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof ReplaceMissingExampleSet)) { + return false; + } + boolean result = super.equals(o); + if (result) { + Map otherMap = ((ReplaceMissingExampleSet) o).replacementMap; + if (this.replacementMap.size() != otherMap.size()) { + return false; + } + for (String name : this.replacementMap.keySet()) { + if (!this.replacementMap.get(name).equals(otherMap.get(name))) { + return false; + } + } + } + return true; + } + + @Override + public int hashCode() { + return super.hashCode() ^ replacementMap.hashCode(); + } + + /** + * Creates a new example set reader. + */ + @Override + public Iterator iterator() { + return new AttributesExampleReader(parent.iterator(), this); + } + + @Override + public Example getExample(int index) { + return this.parent.getExample(index); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + @Override + public int size() { + return parent.size(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/ShuffledPartitionBuilder.java b/src/main/java/com/rapidminer/example/set/ShuffledPartitionBuilder.java new file mode 100644 index 000000000..dd2fb4fa5 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/ShuffledPartitionBuilder.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.tools.RandomGenerator; + +import java.util.Random; + + +/** + * Creates a shuffled partition for an example set. This implementation traverses the partition + * backwards, from the last element up to the second, repeatedly swapping a randomly selected + * element into the "current position". Elements are randomly selected from the portion of the list + * that runs from the first element to the current position, inclusive. + * + * @author Ingo Mierswa + */ +public class ShuffledPartitionBuilder extends SimplePartitionBuilder { + + private Random random; + + public ShuffledPartitionBuilder(boolean useLocalRandomSeed, int seed) { + this.random = RandomGenerator.getRandomGenerator(useLocalRandomSeed, seed); + } + + /** + * Returns a shuffled partition for an example set. Uses the partition delivered by the + * superclass and shuffles the elements. + */ + @Override + public int[] createPartition(double[] ratio, int size) { + int[] part = super.createPartition(ratio, size); + + // Create a random permutation of the generated array by swapping + // elements + for (int i = part.length - 1; i >= 1; i--) { + int swap = random.nextInt(i); + int dummy = part[i]; + part[i] = part[swap]; + part[swap] = dummy; + } + + return part; + } +} diff --git a/src/main/java/com/rapidminer/example/set/SimilarityExampleSet.java b/src/main/java/com/rapidminer/example/set/SimilarityExampleSet.java new file mode 100644 index 000000000..17bfeb586 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SimilarityExampleSet.java @@ -0,0 +1,188 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.SimpleAttributes; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.DoubleArrayDataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.example.table.NominalMapping; +import com.rapidminer.operator.Annotations; +import com.rapidminer.operator.similarity.ExampleSet2SimilarityExampleSet; +import com.rapidminer.tools.Ontology; +import com.rapidminer.tools.math.similarity.DistanceMeasure; + +import java.util.Iterator; + + +/** + * This similarity based example set is used for the operator + * {@link ExampleSet2SimilarityExampleSet}. + * + * @author Ingo Mierswa + */ +public class SimilarityExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = 4757975818441794105L; + + private static class IndexExampleReader extends AbstractExampleReader { + + private int index = 0; + + private ExampleSet exampleSet; + + public IndexExampleReader(ExampleSet exampleSet) { + this.exampleSet = exampleSet; + } + + @Override + public boolean hasNext() { + return index < exampleSet.size() - 1; + } + + @Override + public Example next() { + Example example = exampleSet.getExample(index); + index++; + return example; + } + } + + private ExampleSet parent; + + private Attribute parentIdAttribute; + + private Attributes attributes; + + private DistanceMeasure measure; + + public SimilarityExampleSet(ExampleSet parent, DistanceMeasure measure) { + this.parent = parent; + + this.parentIdAttribute = parent.getAttributes().getId(); + this.attributes = new SimpleAttributes(); + + Attribute firstIdAttribute = null; + Attribute secondIdAttribute = null; + firstIdAttribute = AttributeFactory.createAttribute("FIRST_ID", this.parentIdAttribute.getValueType()); + secondIdAttribute = AttributeFactory.createAttribute("SECOND_ID", this.parentIdAttribute.getValueType()); + + this.attributes.addRegular(firstIdAttribute); + this.attributes.addRegular(secondIdAttribute); + firstIdAttribute.setTableIndex(0); + secondIdAttribute.setTableIndex(1); + + // copying mapping of original id attribute + if (parentIdAttribute.isNominal()) { + NominalMapping mapping = parentIdAttribute.getMapping(); + firstIdAttribute.setMapping((NominalMapping) mapping.clone()); + secondIdAttribute.setMapping((NominalMapping) mapping.clone()); + } + + String name = "SIMILARITY"; + if (measure.isDistance()) { + name = "DISTANCE"; + } + + Attribute similarityAttribute = AttributeFactory.createAttribute(name, Ontology.REAL); + this.attributes.addRegular(similarityAttribute); + similarityAttribute.setTableIndex(2); + + this.measure = measure; + } + + /** Clone constructor. */ + public SimilarityExampleSet(SimilarityExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.parentIdAttribute = (Attribute) exampleSet.parentIdAttribute.clone(); + this.attributes = (Attributes) exampleSet.attributes.clone(); + this.measure = exampleSet.measure; + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof SimilarityExampleSet)) { + return false; + } + + SimilarityExampleSet other = (SimilarityExampleSet) o; + if (!this.measure.getClass().equals(other.measure.getClass())) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return super.hashCode() ^ this.measure.getClass().hashCode(); + } + + @Override + public Attributes getAttributes() { + return this.attributes; + } + + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } + + @Override + public Example getExample(int index) { + int firstIndex = index / this.parent.size(); + int secondIndex = index % this.parent.size(); + + Example firstExample = this.parent.getExample(firstIndex); + Example secondExample = this.parent.getExample(secondIndex); + + double[] data = new double[3]; + data[0] = firstExample.getValue(parentIdAttribute); + data[1] = secondExample.getValue(parentIdAttribute); + + if (measure.isDistance()) { + data[2] = measure.calculateDistance(firstExample, secondExample); + } else { + data[2] = measure.calculateSimilarity(firstExample, secondExample); + } + + return new Example(new DoubleArrayDataRow(data), this); + } + + @Override + public Iterator iterator() { + return new IndexExampleReader(this); + } + + @Override + public ExampleTable getExampleTable() { + return null;// this.parent.getExampleTable(); + } + + @Override + public int size() { + return this.parent.size() * this.parent.size(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/SimpleExampleReader.java b/src/main/java/com/rapidminer/example/set/SimpleExampleReader.java new file mode 100644 index 000000000..9ab964399 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SimpleExampleReader.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.DataRowReader; + + +/** + * This reader simply uses all examples from an example table. + * + * @author Ingo Mierswa Exp $ + */ +public class SimpleExampleReader extends AbstractExampleReader { + + /** The parent example reader. */ + private DataRowReader dataRowReader; + + /** The current example set. */ + private ExampleSet exampleSet; + + /** Creates a simple example reader. */ + public SimpleExampleReader(DataRowReader drr, ExampleSet exampleSet) { + this.dataRowReader = drr; + this.exampleSet = exampleSet; + } + + /** Returns true if there are more data rows. */ + @Override + public boolean hasNext() { + return dataRowReader.hasNext(); + } + + /** Returns a new example based on the current data row. */ + @Override + public Example next() { + if (!hasNext()) { + return null; + } + DataRow data = dataRowReader.next(); + if (data == null) { + return null; + } + return new Example(data, exampleSet); + } +} diff --git a/src/main/java/com/rapidminer/example/set/SimpleExampleSet.java b/src/main/java/com/rapidminer/example/set/SimpleExampleSet.java new file mode 100644 index 000000000..2d162117f --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SimpleExampleSet.java @@ -0,0 +1,177 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.SimpleAttributes; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.example.table.MemoryExampleTable; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + + +/** + * A simple implementation of ExampleSet containing a list of attributes and a special attribute + * map. The data is queried from an example table which contains the data (example sets actually are + * only views on this table and does not keep any data). This simple example set implementation + * usually is the basic example set of the multi-layered data view. + * + * @author Ingo Mierswa, Simon Fischer Exp $ + */ +public class SimpleExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = 9163340881176421801L; + + /** The table used for reading the examples from. */ + private ExampleTable exampleTable; + + /** Holds all information about the attributes. */ + private Attributes attributes = new SimpleAttributes(); + + /** + * Constructs a new SimpleExampleSet backed by the given example table. The example set + * initially does not have any special attributes but all attributes from the given table will + * be used as regular attributes. + * + * If you are constructing the example set from a {@link MemoryExampleTable}, you should use the + * method {@link MemoryExampleTable#createExampleSet()} instead unless you are absolutely sure + * what you are doing. + */ + public SimpleExampleSet(ExampleTable exampleTable) { + this(exampleTable, null, null); + } + + /** + * Constructs a new SimpleExampleSet backed by the given example table. The example set + * initially does not have any special attributes but all attributes from the given table will + * be used as regular attributes. + * + * If you are constructing the example set from a {@link MemoryExampleTable}, you should use the + * method {@link MemoryExampleTable#createExampleSet()} instead unless you are absolutely sure + * what you are doing. + */ + public SimpleExampleSet(ExampleTable exampleTable, List regularAttributes) { + this(exampleTable, regularAttributes, null); + } + + /** + * Constructs a new SimpleExampleSet backed by the given example table. All attributes in the + * table apart from the special attributes become normal (regular) attributes. The special + * attributes are specified by the given map. + * + * If you are constructing the example set from a {@link MemoryExampleTable}, you should use the + * method {@link MemoryExampleTable#createExampleSet(Map)} instead unless you are absolutely + * sure what you are doing. + */ + public SimpleExampleSet(ExampleTable exampleTable, Map specialAttributes) { + this(exampleTable, null, specialAttributes); + } + + /** + * Constructs a new SimpleExampleSet backed by the given example table. All attributes in the + * table defined in the regular attribute list apart from those (also) defined the special + * attributes become normal (regular) attributes. The special attributes are specified by the + * given map. + * + * If you are constructing the example set from a {@link MemoryExampleTable}, you should use the + * method {@link MemoryExampleTable#createExampleSet(Map)} instead unless you are absolutely + * sure what you are doing. + */ + public SimpleExampleSet(ExampleTable exampleTable, List regularAttributes, + Map specialAttributes) { + this.exampleTable = exampleTable; + List regularList = regularAttributes; + if (regularList == null) { + regularList = new LinkedList(); + for (int a = 0; a < exampleTable.getNumberOfAttributes(); a++) { + Attribute attribute = exampleTable.getAttribute(a); + if (attribute != null) { + regularList.add(attribute); + } + } + } + + for (Attribute attribute : regularList) { + if ((specialAttributes == null) || (specialAttributes.get(attribute) == null)) { + getAttributes().add(new AttributeRole((Attribute) attribute.clone())); + } + } + + if (specialAttributes != null) { + Iterator> s = specialAttributes.entrySet().iterator(); + while (s.hasNext()) { + Map.Entry entry = s.next(); + getAttributes().setSpecialAttribute((Attribute) entry.getKey().clone(), entry.getValue()); + } + } + } + + /** + * Clone constructor. The example table is copied by reference, the attributes are copied by a + * deep clone. + * + * Don't use this method directly but use the clone method instead. + */ + public SimpleExampleSet(SimpleExampleSet exampleSet) { + cloneAnnotationsFrom(exampleSet); + this.exampleTable = exampleSet.exampleTable; + this.attributes = (Attributes) exampleSet.getAttributes().clone(); + } + + // --- attributes --- + + @Override + public Attributes getAttributes() { + return attributes; + } + + // --- examples --- + + @Override + public ExampleTable getExampleTable() { + return exampleTable; + } + + @Override + public int size() { + return exampleTable.size(); + } + + @Override + public Example getExample(int index) { + DataRow dataRow = getExampleTable().getDataRow(index); + if (dataRow == null) { + return null; + } else { + return new Example(dataRow, this); + } + } + + @Override + public Iterator iterator() { + return new SimpleExampleReader(getExampleTable().getDataRowReader(), this); + } +} diff --git a/src/main/java/com/rapidminer/example/set/SimplePartitionBuilder.java b/src/main/java/com/rapidminer/example/set/SimplePartitionBuilder.java new file mode 100644 index 000000000..052a57c15 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SimplePartitionBuilder.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +/** + * Creates a simple non-shuffled partition for an example set. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class SimplePartitionBuilder implements PartitionBuilder { + + /** Returns a simple non-shuffled partition for an example set. */ + @Override + public int[] createPartition(double[] ratio, int size) { + // determine partition starts + int[] startNewP = new int[ratio.length + 1]; + startNewP[0] = 0; + double ratioSum = 0; + for (int i = 1; i < startNewP.length; i++) { + ratioSum += ratio[i - 1]; + startNewP[i] = (int) Math.round(size * ratioSum); + } + + // create a simple partition + int p = 0; + int[] part = new int[size]; + for (int i = 0; i < part.length; i++) { + if (i >= startNewP[p + 1]) { + p++; + } + part[i] = p; + } + + return part; + } +} diff --git a/src/main/java/com/rapidminer/example/set/SingleExampleExampleSet.java b/src/main/java/com/rapidminer/example/set/SingleExampleExampleSet.java new file mode 100644 index 000000000..783636c9b --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SingleExampleExampleSet.java @@ -0,0 +1,133 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; + +import java.util.Iterator; + + +/** + * This view can be used to wrap a single example. + * + * @author Ingo Mierswa + */ +public class SingleExampleExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = -4817219403776439504L; + + /** This class is used as a data iterator for the single example example set. */ + private static class SingleExampleIterator extends AbstractExampleReader { + + private boolean nextCalled = false; + + private DataRow dataRow; + + private SingleExampleExampleSet exampleSet; + + public SingleExampleIterator(DataRow dataRow, SingleExampleExampleSet exampleSet) { + this.dataRow = dataRow; + this.exampleSet = exampleSet; + } + + @Override + public boolean hasNext() { + return !nextCalled; + } + + @Override + public Example next() { + if (!nextCalled) { + nextCalled = true; + return new Example(dataRow, exampleSet); + } else { + return null; + } + } + } + + private ExampleSet parent; + + private Example example; + + public SingleExampleExampleSet(ExampleSet exampleSet, Example example) { + this.parent = (ExampleSet) exampleSet.clone(); + this.example = example; + } + + public SingleExampleExampleSet(SingleExampleExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.example = exampleSet.example; + } + + @Override + public Iterator iterator() { + return new SingleExampleIterator(example.getDataRow(), this); + } + + @Override + public Example getExample(int index) { + if (index == 0) { + return new Example(example.getDataRow(), this); + } else { + return null; + } + } + + @Override + public int size() { + return 1; + } + + @Override + public Example getExampleFromId(double id) { + Attribute idAttribute = getAttributes().getId(); + if (idAttribute != null) { + Example newExample = new Example(example.getDataRow(), this); + if (newExample.getValue(idAttribute) == id) { + return newExample; + } else { + return null; + } + } else { + return null; + } + } + + @Override + public Attributes getAttributes() { + return parent.getAttributes(); + } + + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/SkipNANExampleReader.java b/src/main/java/com/rapidminer/example/set/SkipNANExampleReader.java new file mode 100644 index 000000000..75df4f6ce --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SkipNANExampleReader.java @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; + +import java.util.Iterator; + + +/** + * This ExampleReader skips all examples containing attribute values that are not a number. + * + * @author Ingo Mierswa, Simon Fischer Exp $ + */ +public class SkipNANExampleReader extends AbstractExampleReader { + + private Iterator reader; + + private Example currentExample; + + public SkipNANExampleReader(Iterator reader) { + this.reader = reader; + this.currentExample = null; + } + + @Override + public boolean hasNext() { + if (currentExample == null) { + while (reader.hasNext()) { + Example e = reader.next(); + if (!containsNAN(e)) { + currentExample = e; + return true; + } + } + return false; + } else { + return true; + } + } + + @Override + public Example next() { + hasNext(); + Example dummy = currentExample; + currentExample = null; + return dummy; + } + + private boolean containsNAN(Example e) { + for (Attribute attribute : e.getAttributes()) { + if (Double.isNaN(e.getValue(attribute))) { + return true; + } + } + return false; + } + +} diff --git a/src/main/java/com/rapidminer/example/set/SortedExampleReader.java b/src/main/java/com/rapidminer/example/set/SortedExampleReader.java new file mode 100644 index 000000000..24a9a01a6 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SortedExampleReader.java @@ -0,0 +1,76 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This example reader is based on the given mapping and skips all examples which are not part of + * the mapping. This implementation is quite inefficient on databases and other non-memory example + * tables and should therefore only be used for small data sets. + * + * @author Ingo Mierswa, Sebastian Land + */ +public class SortedExampleReader extends AbstractExampleReader { + + /** The parent example set. */ + private ExampleSet parent; + + /** The current index in the mapping. */ + private int currentIndex; + + /** Indicates if the current example was "delivered" by a call of {@link #next()}. */ + private boolean nextInvoked = true; + + /** The example that will be returned by the next invocation of next(). */ + private Example currentExample = null; + + /** Constructs a new mapped example reader. */ + public SortedExampleReader(ExampleSet parent) { + this.parent = parent; + this.currentIndex = -1; + } + + @Override + public boolean hasNext() { + if (this.nextInvoked) { + this.nextInvoked = false; + this.currentIndex++; + if (this.currentIndex < parent.size()) { + this.currentExample = this.parent.getExample(this.currentIndex); + return true; + } else { + return false; + } + } + return (this.currentIndex < parent.size()); + } + + @Override + public Example next() { + if (hasNext()) { + this.nextInvoked = true; + return currentExample; + } else { + return null; + } + } +} diff --git a/src/main/java/com/rapidminer/example/set/SortedExampleSet.java b/src/main/java/com/rapidminer/example/set/SortedExampleSet.java new file mode 100644 index 000000000..a262093a5 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SortedExampleSet.java @@ -0,0 +1,246 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; +import com.rapidminer.tools.Ontology; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + + +/** + *

+ * This example set uses a mapping of indices to access the examples provided by the parent example + * set. In contrast to the mapped example set, where the sorting would have been disturbed for + * performance reasons this class simply use the given mapping. A convenience constructor exist to + * create a view based on the sorting based on a specific attribute. + *

+ * + * @author Ingo Mierswa, Nils Woehler + */ +public class SortedExampleSet extends AbstractExampleSet { + + private static final long serialVersionUID = 3937175786207007275L; + + public static final String[] SORTING_DIRECTIONS = { "increasing", "decreasing" }; + + public static final int INCREASING = 0; + public static final int DECREASING = 1; + + private static class SortingIndex { + + final private Object key; + final private int index; + + public SortingIndex(Object key, int index) { + this.key = key; + this.index = index; + } + + public int getIndex() { + return index; + } + + public Date getKeyAsDate() { + return (Date) key; + } + + public String getKeyAsString() { + return (String) key; + } + + public Double getKeyAsDouble() { + return (Double) key; + } + + @Override + public String toString() { + return key + " --> " + index; + } + + } + + /** The parent example set. */ + private ExampleSet parent; + + /** The used mapping. */ + private int[] mapping; + + public SortedExampleSet(ExampleSet parent, final Attribute sortingAttribute, int sortingDirection) { + this.parent = (ExampleSet) parent.clone(); + List sortingIndex = new ArrayList(parent.size()); + + // create sort index + Integer counter = 0; + Iterator i = parent.iterator(); + while (i.hasNext()) { + Example example = i.next(); + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(sortingAttribute.getValueType(), Ontology.DATE_TIME)) { + sortingIndex.add(new SortingIndex(example.getDateValue(sortingAttribute), counter)); + } else if (sortingAttribute.isNumerical()) { + sortingIndex.add(new SortingIndex(example.getNumericalValue(sortingAttribute), counter)); + + } else { + sortingIndex.add(new SortingIndex(example.getNominalValue(sortingAttribute), counter)); + + } + counter++; + } + + // create comparator + Comparator sortComparator = new Comparator() { + + @Override + public int compare(SortingIndex o1, SortingIndex o2) { + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(sortingAttribute.getValueType(), Ontology.DATE_TIME)) { + Date firstDate = o1.getKeyAsDate(); + Date secondDate = o2.getKeyAsDate(); + if (firstDate == secondDate || firstDate == null) { + return 0; + } else { + return firstDate.compareTo(secondDate); + } + } else if (sortingAttribute.isNumerical()) { + Double firstDouble = o1.getKeyAsDouble(); + Double secondDouble = o2.getKeyAsDouble(); + if (firstDouble == secondDouble || firstDouble == null) { + return 0; + } else { + return firstDouble.compareTo(secondDouble); + } + } else if (sortingAttribute.isNominal()) { + String firstString = o1.getKeyAsString(); + String secondString = o2.getKeyAsString(); + if (firstString == secondString || firstString == null) { + return 0; + } else { + return firstString.compareTo(secondString); + } + } + return 0; + } + }; + + // sort + if (sortingDirection == INCREASING) { + Collections.sort(sortingIndex, sortComparator); + } else { + Collections.sort(sortingIndex, Collections.reverseOrder(sortComparator)); + } + + // change mapping + int[] mapping = new int[parent.size()]; + counter = 0; + Iterator k = sortingIndex.iterator(); + while (k.hasNext()) { + Integer index = k.next().getIndex(); + mapping[counter] = index; + counter++; + } + + this.mapping = mapping; + } + + /** Constructs an example set based on the given sort mapping. */ + public SortedExampleSet(ExampleSet parent, int[] mapping) { + this.parent = (ExampleSet) parent.clone(); + this.mapping = mapping; + } + + /** Clone constructor. */ + public SortedExampleSet(SortedExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.mapping = new int[exampleSet.mapping.length]; + System.arraycopy(exampleSet.mapping, 0, this.mapping, 0, exampleSet.mapping.length); + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof SortedExampleSet)) { + return false; + } + + SortedExampleSet other = (SortedExampleSet) o; + if (this.mapping.length != other.mapping.length) { + return false; + } + for (int i = 0; i < this.mapping.length; i++) { + if (this.mapping[i] != other.mapping[i]) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + return super.hashCode() ^ Arrays.hashCode(this.mapping); + } + + /** Returns a {@link SortedExampleReader}. */ + @Override + public Iterator iterator() { + return new SortedExampleReader(this); + } + + /** Returns the i-th example in the mapping. */ + @Override + public Example getExample(int index) { + if ((index < 0) || (index >= this.mapping.length)) { + throw new RuntimeException("Given index '" + index + "' does not fit the mapped ExampleSet!"); + } else { + return this.parent.getExample(this.mapping[index]); + } + } + + /** Counts the number of examples. */ + @Override + public int size() { + return mapping.length; + } + + @Override + public Attributes getAttributes() { + return this.parent.getAttributes(); + } + + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } + + @Override + public ExampleTable getExampleTable() { + return this.parent.getExampleTable(); + } +} diff --git a/src/main/java/com/rapidminer/example/set/SplittedExampleSet.java b/src/main/java/com/rapidminer/example/set/SplittedExampleSet.java new file mode 100644 index 000000000..888c4f36a --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/SplittedExampleSet.java @@ -0,0 +1,357 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.operator.Annotations; +import com.rapidminer.operator.OperatorVersion; +import com.rapidminer.operator.UserError; +import com.rapidminer.tools.Tools; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + + +/** + * An example set that can be split into subsets by using a {@link Partition}. + * + * @author Simon Fischer, Ingo Mierswa, Felix Jungermann + */ +public class SplittedExampleSet extends AbstractExampleSet { + + public static final OperatorVersion VERSION_SAMPLING_CHANGED = new OperatorVersion(5, 1, 2); + + private static final long serialVersionUID = 4573262969007377183L; + + /** Indicates a non-shuffled sampling for partition building. */ + public static final String[] SAMPLING_NAMES = { "linear sampling", "shuffled sampling", "stratified sampling", "automatic" }; + + /** Indicates a non-shuffled sampling for partition building. */ + public static final int LINEAR_SAMPLING = 0; + + /** Indicates a shuffled sampling for partition building. */ + public static final int SHUFFLED_SAMPLING = 1; + + /** Indicates a stratified shuffled sampling for partition building. */ + public static final int STRATIFIED_SAMPLING = 2; + + /** + * Indicates the usage of the automatic mode, where stratified sampling + * is used per default for partition building. If it isn't applicable, shuffled + * sampling will be used instead. + */ + public static final int AUTOMATIC = 3; + + /** The partition. */ + private Partition partition; + + /** The parent example set. */ + private ExampleSet parent; + + /** Constructs a SplittedExampleSet with the given partition. */ + public SplittedExampleSet(ExampleSet exampleSet, Partition partition) { + this.parent = (ExampleSet) exampleSet.clone(); + this.partition = partition; + } + + /** + * Creates an example set that is splitted into two subsets using the given sampling type. If + * autoSwitchToShuffled is true, the sampling type is switched from Stratified to Shuffled + * automatically without error when no classification label is present. This shouldn't be used, + * but it keeps compatibility to previous versions. + * + * + * @throws UserError + */ + public SplittedExampleSet(ExampleSet exampleSet, double splitRatio, int samplingType, boolean useLocalRandomSeed, + int seed, boolean autoSwitchToShuffled) throws UserError { + this(exampleSet, new double[] { splitRatio, 1 - splitRatio }, samplingType, useLocalRandomSeed, seed, + autoSwitchToShuffled); + } + + /** + * Creates an example set that is splitted into two subsets using the given sampling type. + * + * @throws UserError + */ + public SplittedExampleSet(ExampleSet exampleSet, double splitRatio, int samplingType, boolean useLocalRandomSeed, + int seed) throws UserError { + this(exampleSet, new double[] { splitRatio, 1 - splitRatio }, samplingType, useLocalRandomSeed, seed); + } + + /** + * Creates an example set that is splitted into n subsets with the given sampling type. + * + * @throws UserError + */ + public SplittedExampleSet(ExampleSet exampleSet, double[] splitRatios, int samplingType, boolean useLocalRandomSeed, + int seed) throws UserError { + this(exampleSet, new Partition(splitRatios, exampleSet.size(), createPartitionBuilder(exampleSet, samplingType, + useLocalRandomSeed, seed, true))); + } + + /** + * Creates an example set that is splitted into n subsets with the given sampling type. If + * autoSwitchToShuffled is true, the sampling type is switched from Stratified to Shuffled + * automatically without error when no classification label is present. This shouldn't be used, + * but it keeps compatibility to previous versions. + * + * @throws UserError + */ + public SplittedExampleSet(ExampleSet exampleSet, double[] splitRatios, int samplingType, boolean useLocalRandomSeed, + int seed, boolean autoSwitchToShuffled) throws UserError { + this(exampleSet, new Partition(splitRatios, exampleSet.size(), createPartitionBuilder(exampleSet, samplingType, + useLocalRandomSeed, seed, autoSwitchToShuffled))); + } + + /** + * Creates an example set that is splitted into numberOfSubsets parts with the given + * sampling type. + * + * @throws UserError + */ + public SplittedExampleSet(ExampleSet exampleSet, int numberOfSubsets, int samplingType, boolean useLocalRandomSeed, + int seed) throws UserError { + this(exampleSet, new Partition(numberOfSubsets, exampleSet.size(), createPartitionBuilder(exampleSet, samplingType, + useLocalRandomSeed, seed, true))); + } + + /** + * Creates an example set that is splitted into numberOfSubsets parts with the given + * sampling type. If autoSwitchToShuffled is true, the sampling type is switched from Stratified + * to Shuffled automatically without error when no classification label is present. This + * shouldn't be used, but it keeps compatibility to previous versions. + * + * @throws UserError + */ + public SplittedExampleSet(ExampleSet exampleSet, int numberOfSubsets, int samplingType, boolean useLocalRandomSeed, + int seed, boolean autoSwitchToShuffled) throws UserError { + this(exampleSet, new Partition(numberOfSubsets, exampleSet.size(), createPartitionBuilder(exampleSet, samplingType, + useLocalRandomSeed, seed, autoSwitchToShuffled))); + } + + /** Clone constructor. */ + public SplittedExampleSet(SplittedExampleSet exampleSet) { + this.parent = (ExampleSet) exampleSet.parent.clone(); + this.partition = (Partition) exampleSet.partition.clone(); + } + + @Override + public boolean equals(Object o) { + if (!super.equals(o)) { + return false; + } + if (!(o instanceof SplittedExampleSet)) { + return false; + } + return this.partition.equals(((SplittedExampleSet) o).partition); + } + + @Override + public int hashCode() { + return super.hashCode() ^ partition.hashCode(); + } + + /** + * Creates the partition builder for the given sampling type. If autoSwitchToShuffled is true, + * it will be changed to shuffled sampling if Stratified + * + * @throws UserError + */ + private static PartitionBuilder createPartitionBuilder(ExampleSet exampleSet, int samplingType, + boolean useLocalRandomSeed, int seed, boolean autoSwitchToShuffled) throws UserError { + PartitionBuilder builder = null; + switch (samplingType) { + case LINEAR_SAMPLING: + builder = new SimplePartitionBuilder(); + break; + case SHUFFLED_SAMPLING: + builder = new ShuffledPartitionBuilder(useLocalRandomSeed, seed); + break; + case STRATIFIED_SAMPLING: + case AUTOMATIC: + default: + Attribute label = exampleSet.getAttributes().getLabel(); + if ((label != null) && (label.isNominal())) { + builder = new StratifiedPartitionBuilder(exampleSet, useLocalRandomSeed, seed); + } else { + if (autoSwitchToShuffled || samplingType == AUTOMATIC) { + if (label == null || !label.isNominal()) { + exampleSet + .getLog() + .logWarning( + "Example set has no nominal label: using shuffled partition instead of stratified partition"); + return new ShuffledPartitionBuilder(useLocalRandomSeed, seed); + } + } + + if (label == null) { + throw new UserError(null, 105); + } + if (!label.isNominal()) { + throw new UserError(null, 101, "stratified sampling", label.getName()); + } + builder = new ShuffledPartitionBuilder(useLocalRandomSeed, seed); + } + break; + } + return builder; + } + + /** Adds the given subset. */ + public void selectAdditionalSubset(int index) { + partition.selectSubset(index); + } + + /** Selects exactly one subset. */ + public void selectSingleSubset(int index) { + partition.clearSelection(); + partition.selectSubset(index); + } + + /** Selects all but one subset. */ + public void selectAllSubsetsBut(int index) { + partition.clearSelection(); + for (int i = 0; i < partition.getNumberOfSubsets(); i++) { + if (i != index) { + partition.selectSubset(i); + } + } + } + + /** Selects all subsets. */ + public void selectAllSubsets() { + partition.clearSelection(); + for (int i = 0; i < partition.getNumberOfSubsets(); i++) { + partition.selectSubset(i); + } + } + + /** Inverts the current selection */ + public void invertSelection() { + partition.invertSelection(); + } + + /** Clears the current selection */ + public void clearSelection() { + partition.clearSelection(); + } + + /** Returns the number of subsets. */ + public int getNumberOfSubsets() { + return partition.getNumberOfSubsets(); + } + + /** Returns an example reader that splits all examples that are not selected. */ + @Override + public Iterator iterator() { + return new IndexBasedExampleSetReader(this); + } + + @Override + public int size() { + return partition.getSelectionSize(); + } + + /** + * Searches i-th example in the currently selected partition. This is done in constant time. + */ + @Override + public Example getExample(int index) { + int actualIndex = partition.mapIndex(index); + return this.parent.getExample(actualIndex); + } + + /** Returns the index of the example in the parent example set. */ + public int getActualParentIndex(int index) { + return partition.mapIndex(index); + } + + @Override + public ExampleTable getExampleTable() { + return parent.getExampleTable(); + } + + @Override + public Attributes getAttributes() { + return this.parent.getAttributes(); + } + + @Override + public Annotations getAnnotations() { + return parent.getAnnotations(); + } + + // -------------------- Factory methods -------------------- + + /** + * Works only for nominal and integer attributes. If k is the number of different values, + * this method splits the example set into k subsets according to the value of the given + * attribute. + */ + public static SplittedExampleSet splitByAttribute(ExampleSet exampleSet, Attribute attribute) { + int[] elements = new int[exampleSet.size()]; + int i = 0; + Map indexMap = new HashMap(); + AtomicInteger currentIndex = new AtomicInteger(0); + for (Example example : exampleSet) { + int value = (int) example.getValue(attribute); + Integer indexObject = indexMap.get(value); + if (indexObject == null) { + indexMap.put(value, currentIndex.getAndIncrement()); + } + int intValue = indexMap.get(value).intValue(); + elements[i++] = intValue; + } + + int maxNumber = indexMap.size(); + indexMap.clear(); + Partition partition = new Partition(elements, maxNumber); + return new SplittedExampleSet(exampleSet, partition); + } + + /** + * Works only for real-value attributes. Returns an example set splitted into two parts + * containing all examples providing a greater (smaller) value for the given attribute than the + * given value. The first partition contains all examples providing a smaller or the same value + * than the given one. + */ + public static SplittedExampleSet splitByAttribute(ExampleSet exampleSet, Attribute attribute, double value) { + int[] elements = new int[exampleSet.size()]; + Iterator reader = exampleSet.iterator(); + int i = 0; + while (reader.hasNext()) { + Example example = reader.next(); + double currentValue = example.getValue(attribute); + if (Tools.isLessEqual(currentValue, value)) { + elements[i++] = 0; + } else { + elements[i++] = 1; + } + } + Partition partition = new Partition(elements, 2); + return new SplittedExampleSet(exampleSet, partition); + } +} diff --git a/src/main/java/com/rapidminer/example/set/StratifiedPartitionBuilder.java b/src/main/java/com/rapidminer/example/set/StratifiedPartitionBuilder.java new file mode 100644 index 000000000..6a68e6592 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/StratifiedPartitionBuilder.java @@ -0,0 +1,253 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.logging.Level; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.RandomGenerator; + + +/** + * Creates a shuffled and stratified partition for an example set. The example set must have an + * nominal label. This partition builder can work in two modes: + *
    + *
  1. The first working mode is automatically used for generic types of ratio arrays, especially + * for those with different sizes. Due to to this fact it however cannot longer be guaranteed that + * each fold exactly contains the correct number of examples and each class at least once.
  2. + *
  3. In contrast to the first mode the correct partition can at least be guaranteed for ratio + * arrays containing the same ratio value for all folds. The second mode is automatically performed + * in this case (e.g. for cross validation).
  4. + * + * @author Ingo Mierswa + */ +public class StratifiedPartitionBuilder implements PartitionBuilder { + + /** Helper class for sorting according to class values. */ + private static class ExampleIndex implements Comparable { + + int exampleIndex; + + String className; + + public ExampleIndex(int exampleIndex, String className) { + this.exampleIndex = exampleIndex; + this.className = className; + } + + @Override + public int compareTo(ExampleIndex e) { + return this.className.compareTo(e.className); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof ExampleIndex)) { + return false; + } else { + ExampleIndex other = (ExampleIndex) o; + return this.exampleIndex == other.exampleIndex; + } + } + + @Override + public int hashCode() { + return Integer.valueOf(this.exampleIndex).hashCode(); + } + + @Override + public String toString() { + return exampleIndex + "(" + className + ")"; + } + } + + private ExampleSet exampleSet; + + private Random random; + + public StratifiedPartitionBuilder(ExampleSet exampleSet, boolean useLocalRandomSeed, int seed) { + this.exampleSet = exampleSet; + this.random = RandomGenerator.getRandomGenerator(useLocalRandomSeed, seed); + } + + /** + * Returns a stratified partition for the given example set. The examples must have an nominal + * label. + */ + @Override + public int[] createPartition(double[] ratio, int size) { + Attribute label = exampleSet.getAttributes().getLabel(); + + // typical errors + if (size != exampleSet.size()) { + throw new RuntimeException( + "Cannot create stratified Partition: given size and size of the example set must be equal!"); + } + + if (label == null) { + throw new RuntimeException("Cannot create stratified Partition: example set must have a label!"); + } + + if (!label.isNominal()) { + throw new RuntimeException("Cannot create stratified Partition: label of example set must be nominal!"); + } + + double firstValue = ratio[0]; + for (int i = 1; i < ratio.length; i++) { + if (ratio[i] != firstValue) { + LogService.getRoot().log(Level.FINE, + "com.rapidminer.example.set.StratifiedPartitionBuilder.not_all_ratio_values_are_equal"); + return createNonEqualPartition(ratio, size, label); + } + } + LogService.getRoot().log(Level.FINE, + "com.rapidminer.example.set.StratifiedPartitionBuilder.all_ratio_values_are_equal"); + return createEqualPartition(ratio, size, label); + } + + /** + * Returns a stratified partition for the given example set. The examples must have a nominal + * label. + */ + private int[] createEqualPartition(double[] ratio, int size, Attribute label) { + // fill example list with indices and classes + List examples = new ArrayList(size); + Iterator reader = exampleSet.iterator(); + int index = 0; + while (reader.hasNext()) { + Example example = reader.next(); + examples.add(new ExampleIndex(index++, example.getNominalValue(label))); + } + + // shuffling + Collections.shuffle(examples, random); + + // sort by class + Collections.sort(examples); + + // divide classes _equal_ into potential partitions + List newExamples = new ArrayList(size); + int start = 0; + int numberOfPartitions = ratio.length; + while (newExamples.size() < size) { + for (int i = start; i < examples.size(); i += numberOfPartitions) { + newExamples.add(examples.get(i)); + } + start++; + } + + // build partition starts + int[] startNewP = new int[ratio.length + 1]; + startNewP[0] = 0; + double ratioSum = 0; + for (int i = 1; i < startNewP.length; i++) { + ratioSum += ratio[i - 1]; + startNewP[i] = (int) Math.round(newExamples.size() * ratioSum); + } + + // create a simple partition from the stratified shuffled example + // indices and partition starts + int[] part = new int[newExamples.size()]; + int p = 0; + int counter = 0; + Iterator n = newExamples.iterator(); + while (n.hasNext()) { + if (counter >= startNewP[p + 1]) { + p++; + } + ExampleIndex exampleIndex = n.next(); + part[exampleIndex.exampleIndex] = p; + counter++; + } + + return part; + } + + /** + * Returns a stratified partition for the given example set. The examples must have an nominal + * label. In contrast to {@link #createEqualPartition(double[], int, Attribute)} this method + * does not require the equal ratio values. + */ + private int[] createNonEqualPartition(double[] ratio, int size, Attribute label) { + // fill list with example indices for each class + Map> classLists = new LinkedHashMap>(); + Iterator reader = exampleSet.iterator(); + int index = 0; + while (reader.hasNext()) { + Example example = reader.next(); + String value = example.getNominalValue(label); + List classList = classLists.get(value); + if (classList == null) { + classList = new LinkedList(); + classList.add(index++); + classLists.put(value, classList); + } else { + classList.add(index++); + } + } + + int[] part = new int[exampleSet.size()]; + + // shuffle each class list and create a partition for each class + // seperately + Iterator> c = classLists.values().iterator(); + while (c.hasNext()) { + List classList = c.next(); + + // shuffle + Collections.shuffle(classList, random); + + // build partition starts + int[] startNewP = new int[ratio.length + 1]; + startNewP[0] = 0; + double ratioSum = 0; + for (int i = 1; i < startNewP.length; i++) { + ratioSum += ratio[i - 1]; + startNewP[i] = (int) Math.round(classList.size() * ratioSum); + } + + // create a simple partition from the shuffled example indices and + // partition starts + int p = 0; + int counter = 0; + Iterator n = classList.iterator(); + while (n.hasNext()) { + if (counter >= startNewP[p + 1]) { + p++; + } + Integer exampleIndex = n.next(); + part[exampleIndex.intValue()] = p; + counter++; + } + } + + return part; + } +} diff --git a/src/main/java/com/rapidminer/example/set/WrongPredictionCondition.java b/src/main/java/com/rapidminer/example/set/WrongPredictionCondition.java new file mode 100644 index 000000000..6f40a2fdf --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/WrongPredictionCondition.java @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.set; + +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; + + +/** + * This subclass of {@link Condition} serves to accept all examples which are wrongly predicted. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class WrongPredictionCondition implements Condition { + + private static final long serialVersionUID = -3254098600455281034L; + + /** Creates a new condition. */ + public WrongPredictionCondition() {} + + /** + * Throws an exception since this condition does not support parameter string. + */ + public WrongPredictionCondition(ExampleSet exampleSet, String parameterString) { + if (exampleSet.getAttributes().getLabel() == null) { + throw new IllegalArgumentException("FalsePredictionCondition needs an example set with label attribute!"); + } + if (exampleSet.getAttributes().getPredictedLabel() == null) { + throw new IllegalArgumentException( + "FalsePredictionCondition needs an example set with predicted label attribute!"); + } + } + + /** + * Since the condition cannot be altered after creation we can just return the condition object + * itself. + * + * @deprecated Conditions should not be able to be changed dynamically and hence there is no + * need for a copy + */ + @Override + @Deprecated + public Condition duplicate() { + return this; + } + + /** Returns true if the example wrongly classified. */ + @Override + public boolean conditionOk(Example example) { + return !example.equalValue(example.getAttributes().getLabel(), example.getAttributes().getPredictedLabel()); + } +} diff --git a/src/main/java/com/rapidminer/example/set/package.html b/src/main/java/com/rapidminer/example/set/package.html new file mode 100644 index 000000000..cd7de76f4 --- /dev/null +++ b/src/main/java/com/rapidminer/example/set/package.html @@ -0,0 +1,14 @@ + + + + + + + + +The available views (example sets) on the example tables. Please note that +an example set never contain any data. Several views can be stacked what we +call multi-layer data view concept. + + + diff --git a/src/main/java/com/rapidminer/example/table/AbstractAttribute.java b/src/main/java/com/rapidminer/example/table/AbstractAttribute.java new file mode 100644 index 000000000..53681b62a --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/AbstractAttribute.java @@ -0,0 +1,348 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeDescription; +import com.rapidminer.example.AttributeTransformation; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Statistics; +import com.rapidminer.operator.Annotations; +import com.rapidminer.tools.Ontology; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + + +/** + * This is a possible abstract superclass for all attribute implementations. Most methods of + * {@link Attribute} are already implemented here. + * + * @author Ingo Mierswa + */ +public abstract class AbstractAttribute implements Attribute { + + private static final long serialVersionUID = -9167755945651618227L; + + private transient List owners = new LinkedList(); + + /** The basic information about the attribute. Will only be shallowly cloned. */ + private AttributeDescription attributeDescription; + + private final LinkedList transformations = new LinkedList(); + + /** Contains all attribute statistics calculation algorithms. */ + private List statistics = new LinkedList(); + + /** The current attribute construction description object. */ + private String constructionDescription = null; + + private Annotations annotations = new Annotations(); + + // -------------------------------------------------------------------------------- + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + * This constructor should only be used for attributes which were not generated with help of a + * generator, i.e. this attribute has no function arguments. Only the last transformation is + * cloned, the other transformations are cloned by reference. + */ + protected AbstractAttribute(AbstractAttribute attribute) { + this.attributeDescription = attribute.attributeDescription; + + // copy statistics + this.statistics = new LinkedList(); + for (Statistics statistics : attribute.statistics) { + this.statistics.add((Statistics) statistics.clone()); + } + + // copy transformations if necessary (only the transformation on top of the view stack!) + int counter = 0; + for (AttributeTransformation transformation : attribute.transformations) { + if (counter < attribute.transformations.size() - 1) { + addTransformation(transformation); + } else { + addTransformation((AttributeTransformation) transformation.clone()); + } + counter++; + } + + // copy construction description + this.constructionDescription = attribute.constructionDescription; + + // copy annotations + annotations.putAll(attribute.getAnnotations()); + } + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + * This constructor should only be used for attributes which were not generated with help of a + * generator, i.e. this attribute has no function arguments. + */ + protected AbstractAttribute(String name, int valueType) { + this.attributeDescription = new AttributeDescription(this, name, valueType, Ontology.SINGLE_VALUE, 0.0d, + UNDEFINED_ATTRIBUTE_INDEX); + this.constructionDescription = name; + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + if (owners == null) { + owners = new LinkedList(); + } + if (annotations == null) { + annotations = new Annotations(); + } + } + + @Override + public void addOwner(Attributes attributes) { + this.owners.add(attributes); + } + + @Override + public void removeOwner(Attributes attributes) { + this.owners.remove(attributes); + } + + /** Clones this attribute. */ + @Override + public abstract Object clone(); + + /** + * Returns true if the given attribute has the same name and the same table index. + */ + @Override + public boolean equals(Object o) { + if (!(o instanceof AbstractAttribute)) { + return false; + } + AbstractAttribute a = (AbstractAttribute) o; + return this.attributeDescription.equals(a.attributeDescription); + } + + @Override + public int hashCode() { + return attributeDescription.hashCode(); + } + + @Override + public void addTransformation(AttributeTransformation transformation) { + this.transformations.add(transformation); + } + + @Override + public void clearTransformations() { + this.transformations.clear(); + } + + @Override + public AttributeTransformation getLastTransformation() { + if (this.transformations.size() > 0) { + return this.transformations.getLast(); + } else { + return null; + } + } + + @Override + public double getValue(DataRow row) { + double tableValue = row.get(getTableIndex(), getDefault()); + double result = tableValue; + for (AttributeTransformation transformation : transformations) { + result = transformation.transform(this, result); + } + return result; + } + + @Override + public void setValue(DataRow row, double value) { + double newValue = value; + for (AttributeTransformation transformation : transformations) { + if (transformation.isReversable()) { + newValue = transformation.inverseTransform(this, newValue); + } else { + throw new RuntimeException( + "Cannot set value for attribute using irreversible transformations. This process will probably work if you deactivate create_view in preprocessing operators."); + } + } + row.set(getTableIndex(), newValue, getDefault()); + } + + /** Returns the name of the attribute. */ + @Override + public String getName() { + return this.attributeDescription.getName(); + } + + /** Sets the name of the attribute. */ + @Override + public void setName(String v) { + if (v.equals(this.attributeDescription.getName())) { + return; + } + for (Attributes attributes : owners) { + attributes.rename(this, v); + } + this.attributeDescription = (AttributeDescription) this.attributeDescription.clone(); + this.attributeDescription.setName(v); + } + + /** Returns the index in the example table. */ + @Override + public int getTableIndex() { + return this.attributeDescription.getTableIndex(); + } + + /** Sets the index in the example table. */ + @Override + public void setTableIndex(int i) { + this.attributeDescription = (AttributeDescription) this.attributeDescription.clone(); + this.attributeDescription.setTableIndex(i); + } + + // --- meta data of data --- + + /** + * Returns the block type of this attribute. + * + * @see com.rapidminer.tools.Ontology#ATTRIBUTE_BLOCK_TYPE + */ + @Override + public int getBlockType() { + return this.attributeDescription.getBlockType(); + } + + /** + * Sets the block type of this attribute. + * + * @see com.rapidminer.tools.Ontology#ATTRIBUTE_BLOCK_TYPE + */ + @Override + public void setBlockType(int b) { + this.attributeDescription = (AttributeDescription) this.attributeDescription.clone(); + this.attributeDescription.setBlockType(b); + } + + /** + * Returns the value type of this attribute. + * + * @see com.rapidminer.tools.Ontology#ATTRIBUTE_VALUE_TYPE + */ + @Override + public int getValueType() { + return this.attributeDescription.getValueType(); + } + + /** Returns the attribute statistics. */ + @Override + public Iterator getAllStatistics() { + return this.statistics.iterator(); + } + + @Override + public void registerStatistics(Statistics statistics) { + this.statistics.add(statistics); + } + + /** + * Returns the attribute statistics. + * + * @deprecated Please use the method {@link ExampleSet#getStatistics(Attribute, String)} + * instead. + */ + @Override + @Deprecated + public double getStatistics(String name) { + return getStatistics(name, null); + } + + /** + * Returns the attribute statistics. + * + * @deprecated Please use the method {@link ExampleSet#getStatistics(Attribute, String)} + * instead. + */ + @Override + @Deprecated + public double getStatistics(String name, String parameter) { + for (Statistics statistics : this.statistics) { + if (statistics.handleStatistics(name)) { + return statistics.getStatistics(this, name, parameter); + } + } + throw new RuntimeException("No statistics object was available for attribute statistics '" + name + "'!"); + } + + /** Returns the construction description. */ + @Override + public String getConstruction() { + return this.constructionDescription; + } + + /** Returns the construction description. */ + @Override + public void setConstruction(String description) { + this.constructionDescription = description; + } + + // ================================================================================ + // default value + // ================================================================================ + + @Override + public void setDefault(double value) { + this.attributeDescription = (AttributeDescription) this.attributeDescription.clone(); + this.attributeDescription.setDefault(value); + } + + @Override + public double getDefault() { + return this.attributeDescription.getDefault(); + } + + // ================================================================================ + // string and result methods + // ================================================================================ + + /** Returns a human readable string that describes this attribute. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + result.append("#"); + result.append(this.attributeDescription.getTableIndex()); + result.append(": "); + result.append(this.attributeDescription.getName()); + result.append(" ("); + result.append(Ontology.ATTRIBUTE_VALUE_TYPE.mapIndex(this.attributeDescription.getValueType())); + result.append("/"); + result.append(Ontology.ATTRIBUTE_BLOCK_TYPE.mapIndex(this.attributeDescription.getBlockType())); + result.append(")"); + return result.toString(); + } + + @Override + public Annotations getAnnotations() { + return annotations; + } +} diff --git a/src/main/java/com/rapidminer/example/table/AbstractDataRowReader.java b/src/main/java/com/rapidminer/example/table/AbstractDataRowReader.java new file mode 100644 index 000000000..3fdd21ae3 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/AbstractDataRowReader.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Reads a sequence of DataRows, e.g. from memory, a file or a database. + * + * @author Simon Fischer, Ingo Mierswa ingomierswa Exp $ + */ +public abstract class AbstractDataRowReader implements DataRowReader { + + private DataRowFactory factory; + + public AbstractDataRowReader(DataRowFactory factory) { + this.factory = factory; + } + + public DataRowFactory getFactory() { + return factory; + } + + /** + * Will throw a new {@link UnsupportedOperationException} since {@link DataRowReader} does not + * have to implement remove. + */ + @Override + public void remove() { + throw new UnsupportedOperationException("The method 'remove' is not supported by DataRowReaders!"); + } +} diff --git a/src/main/java/com/rapidminer/example/table/AbstractExampleTable.java b/src/main/java/com/rapidminer/example/table/AbstractExampleTable.java new file mode 100644 index 000000000..470c65b4c --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/AbstractExampleTable.java @@ -0,0 +1,308 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.Attributes; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.set.SimpleExampleSet; +import com.rapidminer.operator.OperatorException; +import com.rapidminer.operator.error.AttributeNotFoundError; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.att.AttributeSet; + + +/** + * This class is the core data supplier for example sets. Several example sets can use the same data + * and access the attribute values by reference. + * + * @author Ingo Mierswa + */ +public abstract class AbstractExampleTable implements ExampleTable { + + /** + * + */ + private static final long serialVersionUID = -6996954528182122684L; + + /** + * List of instances of {@link Attribute}. The i-th entry in the list belongs to the + * i-th data column. Whenever attributes are removed from the list of attributes (e.g. + * they were intermediate predicted labels used only within a validation chain), the succeeding + * entries do not move up, but the entry is replaced by a null entry and this index is added to + * {@link AbstractExampleTable#unusedColumnList} as an Integer. + */ + private List attributes = new ArrayList<>(); + + /** + * List of Integers referencing indices of columns that were removed, e.g. predicted labels that + * were used within a validation chain but are not needed any longer. Any of the columns in this + * list may be used when a new attribute is created. The list is used as a queue. + */ + private List unusedColumnList = new LinkedList<>(); + + /** + * Creates a new ExampleTable. + * + * @param attributes + * List of {@link Attribute}. The indices of the attibutes are set to values + * reflecting their position in the list. + */ + public AbstractExampleTable(List attributes) { + addAttributes(attributes); + } + + // ------------------------------------------------------------ + + /** Returns a new array containing all {@link Attribute}s. */ + @Override + public Attribute[] getAttributes() { + Attribute[] attribute = new Attribute[attributes.size()]; + attributes.toArray(attribute); + return attribute; + } + + /** + * Returns the attribute of the column number i. Attention: This value may return null if + * the column was marked unused. + */ + @Override + public Attribute getAttribute(int i) { + return attributes.get(i); + } + + /** Returns the attribute with the given name. */ + @Override + public Attribute findAttribute(String name) throws OperatorException { + if (name == null) { + return null; + } + Iterator i = attributes.iterator(); + while (i.hasNext()) { + Attribute att = i.next(); + if (att != null) { + if (att.getName().equals(name)) { + return att; + } + } + } + throw new AttributeNotFoundError(null, null, name); + } + + /** + * Adds all {@link Attribute}s in newAttributes to the end of the list of + * attributes, creating new data columns if necessary. + */ + @Override + public void addAttributes(Collection newAttributes) { + Iterator i = newAttributes.iterator(); + while (i.hasNext()) { + addAttribute(i.next()); + } + } + + /** + * Adds the attribute to the list of attributes assigning it a free column index. If the name is + * already in use, the attribute will be renamed. + */ + @Override + public int addAttribute(Attribute a) { + + if (a == null) { + throw new IllegalArgumentException("Attribute must not be null"); + } else { + int index = -1; + Attribute original = a; + a = (Attribute) a.clone(); + + if (unusedColumnList.size() > 0) { + // if seems to be something free: Synchronize and check again + synchronized (unusedColumnList) { + if (unusedColumnList.size() > 0) { + index = unusedColumnList.remove(0); + attributes.set(index, a); + } else { + index = attributes.size(); + attributes.add(a); + } + } + } else { + index = attributes.size(); + attributes.add(a); + } + + a.setTableIndex(index); + original.setTableIndex(index); + return index; + } + + } + + /** + * Equivalent to calling removeAttribute(attribute.getTableIndex()). + */ + @Override + public void removeAttribute(Attribute attribute) { + removeAttribute(attribute.getTableIndex()); + } + + /** + * Sets the attribute with the given index to null. Afterwards, this column can be reused. + * Callers must make sure, that no other example set contains a reference to this column. + * Otherwise its data will be messed up. Usually this is only possible if an operator generates + * intermediate attributes, like a validation chain or a feature generator. If the attribute + * already was removed, this method returns silently. + */ + @Override + public synchronized void removeAttribute(int index) { + Attribute a = attributes.get(index); + if (a == null) { + return; + } + attributes.set(index, null); + unusedColumnList.add(index); + } + + /** + * Returns the number of attributes. Attention: Callers that use a for-loop and retrieving + * {@link Attribute}s by calling {@link AbstractExampleTable#getAttribute(int)} must keep in + * mind, that some of these attributes may be null. + */ + @Override + public int getNumberOfAttributes() { + return attributes.size(); + } + + /** + * Returns the number of non null attributes. Attention: Since there are null attributes + * in the list, the return value of this method must not be used in a for-loop! + * + * @see ExampleTable#getNumberOfAttributes(). + */ + @Override + public int getAttributeCount() { + return attributes.size() - unusedColumnList.size(); + } + + // ------------------------------------------------------------ + + /** + * Returns a new example set with all attributes switched on. The given attribute will be used + * as a special label attribute for learning. + */ + @Override + public ExampleSet createExampleSet(Attribute labelAttribute) { + return createExampleSet(labelAttribute, null, null); + } + + /** + * Returns a new example set with all attributes switched on. The given attributes will be used + * as a special label attribute for learning, as (example) weight attribute, and as id + * attribute. + */ + @Override + public ExampleSet createExampleSet(Attribute labelAttribute, Attribute weightAttribute, Attribute idAttribute) { + Map specialAttributes = new HashMap<>(); + if (labelAttribute != null) { + specialAttributes.put(labelAttribute, Attributes.LABEL_NAME); + } + if (weightAttribute != null) { + specialAttributes.put(weightAttribute, Attributes.WEIGHT_NAME); + } + if (idAttribute != null) { + specialAttributes.put(idAttribute, Attributes.ID_NAME); + } + return new SimpleExampleSet(this, specialAttributes); + } + + /** + * Returns a new example set with all attributes switched on. The iterator over the attribute + * roles will define the special attributes. + */ + @Override + public ExampleSet createExampleSet(Iterator newSpecialAttributes) { + Map specialAttributes = new HashMap<>(); + while (newSpecialAttributes.hasNext()) { + AttributeRole role = newSpecialAttributes.next(); + specialAttributes.put(role.getAttribute(), role.getSpecialName()); + } + return new SimpleExampleSet(this, specialAttributes); + } + + /** + * Returns a new example set with all attributes of the {@link ExampleTable} and with the + * special roles defined by the given attribute set. + */ + @Override + public ExampleSet createExampleSet(AttributeSet attributeSet) { + Map specialAttributes = new HashMap<>(); + Iterator i = attributeSet.getSpecialNames().iterator(); + while (i.hasNext()) { + String name = i.next(); + specialAttributes.put(attributeSet.getSpecialAttribute(name), name); + } + return createExampleSet(specialAttributes); + } + + /** + * Returns a new example set with all attributes switched on. All attributes given at creation + * time will be regular. + */ + @Override + public ExampleSet createExampleSet() { + return createExampleSet(new HashMap()); + } + + /** + * Returns a new example set with all attributes switched on. The attributes in the given map + * will be used as special attributes with the specified names, all other attributes given at + * creation time will be regular. + */ + @Override + public ExampleSet createExampleSet(Map specialAttributes) { + return new SimpleExampleSet(this, specialAttributes); + } + + // ------------------------------------------------------------ + + @Override + public String toString() { + return "ExampleTable, " + attributes.size() + " attributes, " + size() + " data rows," + Tools.getLineSeparator() + + "attributes: " + attributes; + } + + @Override + public String toDataString() { + StringBuffer result = new StringBuffer(toString() + Tools.getLineSeparator()); + DataRowReader reader = getDataRowReader(); + while (reader.hasNext()) { + result.append(reader.next().toString() + Tools.getLineSeparator()); + } + return result.toString(); + } +} diff --git a/src/main/java/com/rapidminer/example/table/AbstractSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/AbstractSparseArrayDataRow.java new file mode 100644 index 000000000..8b3de9d13 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/AbstractSparseArrayDataRow.java @@ -0,0 +1,267 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Tools; + + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. + * + * @author Niraj Aswani, Julien Nioche, Ingo Mierswa, Shevek + */ +public abstract class AbstractSparseArrayDataRow extends DataRow implements SparseDataRow { + + /** + * + */ + private static final long serialVersionUID = 4946925205115859758L; + + /** Stores the used attribute indices. */ + private int[] x; + + /** Number of inserted elements. */ + private int counter = 0; + + /** Creates an empty sparse array data row with size 0. */ + public AbstractSparseArrayDataRow() { + this(0); + } + + /* + * Note: DataRowFactory calls this with attributes.size, which is probably wrong if the data row + * is meant to be sparse - we never intend to have that many attributes. + */ + + /** Creates a sparse array data row of the given size. */ + public AbstractSparseArrayDataRow(int size) { + x = new int[size]; + for (int i = 0; i < x.length; i++) { + x[i] = Integer.MAX_VALUE; + } + } + + // ====================== + // abstract methods + // ====================== + + /* + * Implementations of this are not as optimal as the removal of a value from the indexes array, + * since the subclass does not have access to the count variable. This could be fixed, but ... + * *shrug*. Shevek. + */ + protected abstract void removeValue(int index); + + protected abstract void resizeValues(int length); + + protected abstract void setValue(int index, double value); + + protected abstract double getValue(int index); + + /* This could be implemented using get() and set() */ + protected abstract void swapValues(int a, int b); + + /* This could be implemented using get() */ + protected abstract double[] getAllValues(); + + /** Sorts the arrays in the given range. */ + private void sort(int off, int len) { + // Insertion sort on smallest arrays + if (len < 7) { + for (int i = off; i < len + off; i++) { + for (int j = i; j > off && x[j - 1] > x[j]; j--) { + swap(j, j - 1); + } + } + return; + } + + // Choose a partition element, v + int m = off + (len >> 1); // Small arrays, middle element + if (len > 7) { + int l = off; + int n = off + len - 1; + if (len > 40) { // Big arrays, pseudomedian of 9 + int s = len / 8; + l = med3(l, l + s, l + 2 * s); + m = med3(m - s, m, m + s); + n = med3(n - 2 * s, n - s, n); + } + m = med3(l, m, n); // Mid-size, med of 3 + } + long v = x[m]; + + // Establish Invariant: v* (v)* v* + int a = off, b = a, c = off + len - 1, d = c; + while (true) { + while (b <= c && x[b] <= v) { + if (x[b] == v) { + swap(a++, b); + } + b++; + } + while (c >= b && x[c] >= v) { + if (x[c] == v) { + swap(c, d--); + } + c--; + } + if (b > c) { + break; + } + swap(b++, c--); + } + + // Swap partition elements back to middle + int s, n = off + len; + s = Math.min(a - off, b - a); + vecswap(off, b - s, s); + s = Math.min(d - c, n - d - 1); + vecswap(b, n - s, s); + + // Recursively sort non-partition-elements + if ((s = b - a) > 1) { + sort(off, s); + } + if ((s = d - c) > 1) { + sort(n - s, s); + } + } + + /** Swaps the next n elements from a and b. */ + private void vecswap(int a, int b, int n) { + for (int i = 0; i < n; i++, a++, b++) { + swap(a, b); + } + } + + private int med3(int a, int b, int c) { + return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a) : (x[b] > x[c] ? b : x[a] > x[c] ? c : a)); + } + + /** + * Swaps x[a] with x[b]. + */ + protected void swap(int a, int b) { + int t = x[a]; + x[a] = x[b]; + x[b] = t; + swapValues(a, b); + } + + /** Returns the desired data for the given attribute. */ + @Override + protected double get(int val, double defaultValue) { + int index = java.util.Arrays.binarySearch(x, val); + if (index < 0) { + return defaultValue; + } else { + return getValue(index); + } + } + + /** Sets the given data for the given attribute. */ + @Override + protected void set(int index, double value, double defaultValue) { + // first search if it is already available + // we need to replace the value + // return a negative int if the value is not in the array + // the list is ALWAYS sorted + + int index1 = java.util.Arrays.binarySearch(x, index); + + if (Tools.isDefault(defaultValue, value)) { + if (index1 >= 0) { // (old value != deflt) AND new is default --> + // remove entry from arrays + System.arraycopy(x, index1 + 1, x, index1, (counter - (index1 + 1))); + x[counter - 1] = Integer.MAX_VALUE; + removeValue(index1); + counter--; + } + } else { + if (index1 < 0) { // a new entry + if (counter >= x.length) { // need more space + int newlength = x.length + (x.length >> 1) + 1; + int[] y = new int[newlength]; + System.arraycopy(x, 0, y, 0, x.length); + for (int i = x.length; i < y.length; i++) { + y[i] = Integer.MAX_VALUE; + } + x = y; + resizeValues(newlength); + } + + // adds the new value at the end of the array + x[counter] = index; + setValue(counter, value); + + // compare to the one before him + if ((counter > 0) && (index < x[counter - 1])) { + sort(0, x.length); + } + counter++; + } else { // replace existing value + setValue(index1, value); + } + } + } + + @Override + public int[] getNonDefaultIndices() { + trim(); + return this.x; + } + + @Override + public double[] getNonDefaultValues() { + trim(); + return getAllValues(); + } + + /** Does nothing. */ + @Override + public void ensureNumberOfColumns(int numberOfColumns) {} + + /** Trims the data row to the number of actually used elements. */ + @Override + public void trim() { + if (counter < x.length) { + int[] y = new int[counter]; + System.arraycopy(x, 0, y, 0, counter); + x = y; + resizeValues(counter); + } + } + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < x.length; i++) { + if (i != 0) { + result.append(", "); + } + result.append(x[i] + ":" + getValue(i)); + } + result.append(", counter: " + counter); + return result.toString(); + } +} diff --git a/src/main/java/com/rapidminer/example/table/AttributeFactory.java b/src/main/java/com/rapidminer/example/table/AttributeFactory.java new file mode 100644 index 000000000..2ead74818 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/AttributeFactory.java @@ -0,0 +1,168 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.Ontology; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; + + +/** + * This class is used to create and clone attributes. It should be used to create attributes instead + * of directly creating them by using constructors. Additionally, it provides some helper methods + * for attribute creation purposes (name creation, block numbers,...). + * + * @author Ingo Mierswa Exp $ + */ +public class AttributeFactory { + + /** The prefix of the name of generated attributes. */ + private static final String GENSYM_PREFIX = "gensym"; + + /** + * The current highest id counters for generated attribute names. The counter will be increased + * each time an attribute name is generated more than once. + */ + private static Map nameCounters = new HashMap(); + + static { + resetNameCounters(); + } + + /** Creates a simple single attribute depending on the given value type. */ + public static Attribute createAttribute(String name, int valueType) { + String attributeName = (name != null) ? new String(name) : createName(); // we copy the name + // if the + // underlying + // char array + // value is + // larger than + // needed + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.DATE_TIME)) { + return new DateAttribute(attributeName, valueType); + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.BINOMINAL)) { + return new BinominalAttribute(attributeName); + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL)) { + return new PolynominalAttribute(attributeName, valueType); + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NUMERICAL)) { + return new NumericalAttribute(attributeName, valueType); + } else { + throw new RuntimeException("AttributeFactory: cannot create attribute with value type '" + + Ontology.ATTRIBUTE_VALUE_TYPE.mapIndex(valueType) + "' (" + valueType + ")!"); + } + } + + /** + * Creates a simple single attribute depending on the given value type. The name is randomly + * created. This attribute can also be used for generators to define their desired input + * attributes for compatibility checks. + */ + public static Attribute createAttribute(int valueType) { + return createAttribute(createName(), valueType); + } + + /** Creates a simple attribute depending on the given value type. */ + public static Attribute createAttribute(int valueType, int blockType, String constructionDescription) { + Attribute attribute = createAttribute(valueType); + attribute.setBlockType(blockType); + attribute.setConstruction(constructionDescription); + return attribute; + } + + /** Creates a simple attribute depending on the given value type. */ + public static Attribute createAttribute(String name, int valueType, int blockType) { + Attribute attribute = createAttribute(name, valueType); + attribute.setBlockType(blockType); + return attribute; + } + + // ================================================================================ + + /** + * Simple clone factory method for attributes. Invokes + * {@link #createAttribute(Attribute att, String name)} with name = null. + */ + public static Attribute createAttribute(Attribute attribute) { + return createAttribute(attribute, null); + } + + /** + * Simple clone factory method for attributes. Returns the clone of the given attribute and sets + * the function name to the given one if not null. In this case the attribute is used as an + * argument of returned attribute. This method might be usefull for example to create a + * prediction attribute with the same properties as the original label attribute. + */ + public static Attribute createAttribute(Attribute attribute, String functionName) { + Attribute result = (Attribute) attribute.clone(); + if (functionName == null) { + result.setName(attribute.getName()); + } else { + result.setName(functionName + "(" + attribute.getName() + ")"); + result.setConstruction(functionName + "(" + attribute.getName() + ")"); + } + return result; + } + + // ================================================================================ + // changes the value type of the given attribute + // ================================================================================ + + /** + * Changes the value type of the given attribute and returns a new attribute with the same + * properties but the new value type. Since values within examples are not altered it is not + * suggested to use this method to change attributes within an exampleset in use. Operators + * should create a new attribute to ensure parallel executability. + */ + public static Attribute changeValueType(Attribute attribute, int valueType) { + Attribute result = createAttribute(attribute.getName(), valueType); + if (attribute.isNominal() && result.isNominal()) { + result.setMapping(attribute.getMapping()); + } + result.setTableIndex(attribute.getTableIndex()); + return result; + } + + // ================================================================================ + // helper methods + // ================================================================================ + + /** Resets the counters for the generated attribute names. */ + public static void resetNameCounters() { + nameCounters.clear(); + } + + /** Creates a new unsused attribute name. */ + public static String createName() { + return createName(GENSYM_PREFIX); + } + + /** Creates a new unsused attribute name with a given prefix. */ + public static String createName(String prefix) { + AtomicInteger counter = nameCounters.get(prefix); + if (counter == null) { + nameCounters.put(prefix, new AtomicInteger(1)); + return prefix; + } else { + return prefix + counter.getAndIncrement(); + } + } +} diff --git a/src/main/java/com/rapidminer/example/table/BinominalAttribute.java b/src/main/java/com/rapidminer/example/table/BinominalAttribute.java new file mode 100644 index 000000000..0daf650e3 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/BinominalAttribute.java @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.tools.Ontology; + + +/** + * This class holds all information on a single binary attribute. In addition to the generic + * attribute fields this class keeps information about the both values and the value to index + * mappings. If one of the methods designed for numerical attributes was invoked a RuntimeException + * will be thrown. + * + * @author Ingo Mierswa + */ +public class BinominalAttribute extends NominalAttribute { + + private static final long serialVersionUID = 2932687830235332221L; + + private NominalMapping nominalMapping = new BinominalMapping(); + + /** + * Creates a simple binary attribute which is not part of a series and does not provide a unit + * string. + */ + /* pp */BinominalAttribute(String name) { + super(name, Ontology.BINOMINAL); + } + + /** + * Clone constructor. + */ + private BinominalAttribute(BinominalAttribute a) { + super(a); + // this.nominalMapping = (NominalMapping)a.nominalMapping.clone(); + this.nominalMapping = a.nominalMapping; + } + + /** Clones this attribute. */ + @Override + public Object clone() { + return new BinominalAttribute(this); + } + + @Override + public NominalMapping getMapping() { + return this.nominalMapping; + } + + @Override + public void setMapping(NominalMapping newMapping) { + this.nominalMapping = newMapping; + } + + @Override + public boolean isDateTime() { + return false; + } +} diff --git a/src/main/java/com/rapidminer/example/table/BinominalMapping.java b/src/main/java/com/rapidminer/example/table/BinominalMapping.java new file mode 100644 index 000000000..97410f17e --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/BinominalMapping.java @@ -0,0 +1,252 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.AttributeTypeException; +import com.rapidminer.example.Example; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + + +/** + * This is an efficient implementation of a {@link NominalMapping} which can be used for binominal + * attributes, i.e. for attributes with only two different values. + * + * @author Ingo Mierswa + */ +public class BinominalMapping implements NominalMapping { + + private static final long serialVersionUID = 6566553739308153153L; + + /** The index of the first value. */ + private static final int FIRST_VALUE_INDEX = 0; + + /** The index of the second value. */ + private static final int SECOND_VALUE_INDEX = 1; + + /** + * Nominal index of the value that will be treated as the "positive" value of this attribute. + */ + public static final int POSITIVE_INDEX = SECOND_VALUE_INDEX; + + /** + * Nominal index of the value that will be treated as the "negative" value of this attribute. + */ + public static final int NEGATIVE_INDEX = FIRST_VALUE_INDEX; + + /** The first nominal value. */ + private String firstValue = null; + + /** The second nominal value. */ + private String secondValue = null; + + public BinominalMapping() {} + + /** Clone constructor. */ + private BinominalMapping(BinominalMapping mapping) { + this.firstValue = mapping.firstValue; + this.secondValue = mapping.secondValue; + } + + /** Clone constructor. */ + /* pp */BinominalMapping(NominalMapping mapping) { + if (mapping.size() > 0) { + firstValue = mapping.mapIndex(0); + } + if (mapping.size() > 1) { + secondValue = mapping.mapIndex(1); + } + } + + @Override + public Object clone() { + return new BinominalMapping(this); + } + + @Override + public boolean equals(NominalMapping mapping) { + if (mapping.size() != size()) { + return false; + } + for (String value : mapping.getValues()) { + if (!value.equals(firstValue) && !value.equals(secondValue)) { + return false; + } + } + return true; + } + + /** + * Returns the index for the nominal attribute value str. If the string is unknown, + * a new index value is assigned. Returns -1, if str is null. + */ + @Override + public int mapString(String str) { + if (str == null) { + return -1; + } + // lookup string + int index = getIndex(str); + if (index < 0) { + // if string is not found, set it + if (firstValue == null) { + firstValue = new String(str); // we copy the string if the underlying char array + // value is larger than needed + return FIRST_VALUE_INDEX; + } else if (secondValue == null) { + secondValue = new String(str); // we copy the string if the underlying char array + // value is larger than needed + return SECOND_VALUE_INDEX; + } else { + throw new AttributeTypeException( + "Cannot map another string for binary attribute: already mapped two strings (" + firstValue + ", " + + secondValue + "). The third string that was tried to add: '" + str + "'"); + } + } else { + return index; + } + } + + /** + * Returns the index of the given nominal value or -1 if this value was not mapped before by + * invoking the method {@link #mapIndex(int)}. + */ + @Override + public int getIndex(String str) { + if (str.equals(firstValue)) { + return FIRST_VALUE_INDEX; + } else if (str.equals(secondValue)) { + return SECOND_VALUE_INDEX; + } else { + return -1; + } + } + + /** + * Returns the attribute value, that is associated with this index. Index counting starts with + * 0. WARNING: In order to iterate over all values please use the collection returned by + * {@link #getValues()}. + */ + @Override + public String mapIndex(int index) { + switch (index) { + case FIRST_VALUE_INDEX: + return firstValue; + case SECOND_VALUE_INDEX: + return secondValue; + default: + throw new AttributeTypeException("Cannot map index of binary attribute to nominal value: index " + index + + " is out of bounds!"); + } + } + + /** + * Sets the given mapping. Please note that this will overwrite existing mappings and might + * cause data changes in this way. + */ + @Override + public void setMapping(String nominalValue, int index) { + if (index == FIRST_VALUE_INDEX) { + firstValue = nominalValue; + } else if (index == SECOND_VALUE_INDEX) { + secondValue = nominalValue; + } else { + throw new AttributeTypeException("Cannot set mapping of binary attribute to index '" + index + "'."); + } + } + + /** + * Returns the index of the first value if this attribute is a classification attribute, i.e. if + * it is binominal. + */ + @Override + public int getNegativeIndex() { + return NEGATIVE_INDEX; + } + + /** + * Returns the index of the second value if this attribute is a classification attribute. Works + * for all binominal attributes. + */ + @Override + public int getPositiveIndex() { + return POSITIVE_INDEX; + } + + @Override + public String getNegativeString() { + return firstValue; + } + + @Override + public String getPositiveString() { + return secondValue; + } + + /** Returns the values of the attribute as an enumeration of strings. */ + @Override + public List getValues() { + if (firstValue == null) { + return new LinkedList(); + } else if (secondValue == null) { + return Arrays.asList(new String[] { firstValue }); + } else { + return Arrays.asList(new String[] { firstValue, secondValue }); + } + } + + /** Returns the number of different nominal values. */ + @Override + public int size() { + if (firstValue == null) { + return 0; + } else if (secondValue == null) { + return 1; + } else { + return 2; + } + } + + /** + * This method rearranges the string to number mappings such that they are in alphabetical + * order.
    + * VERY IMPORTANT NOTE: Do not call this method when this attribute is already associated + * with an {@link AbstractExampleTable} and it already contains {@link Example}s. All examples + * will be messed up! + */ + @Override + public void sortMappings() { + if (size() == 2) { + if (firstValue.compareTo(secondValue) > 0) { + String dummy = secondValue; + secondValue = firstValue; + firstValue = dummy; + } + } + } + + /** Clears all mappings for nominal values. */ + @Override + public void clear() { + firstValue = null; + secondValue = null; + } +} diff --git a/src/main/java/com/rapidminer/example/table/BooleanArrayDataRow.java b/src/main/java/com/rapidminer/example/table/BooleanArrayDataRow.java new file mode 100644 index 000000000..08d5ec686 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/BooleanArrayDataRow.java @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed up by a boolean array. Please note that for almost no + * practical applications the usage of this data row type is recommended. It might however come + * handy in case of association rule learning or after a discretization step. + * + * @author Ingo Mierswa + */ +public class BooleanArrayDataRow extends DataRow { + + private static final long serialVersionUID = -432265332489304646L; + + /** Holds the data for all attributes. */ + private boolean[] data; + + /** Creates a new data row backed by an primitive array. */ + public BooleanArrayDataRow(boolean[] data) { + this.data = data; + } + + /** + * Returns the value for the desired index. This method should only be used by attributes. + */ + @Override + protected double get(int index, double defaultValue) { + if (data[index]) { + return 1.0d; + } else { + return 0.0d; + } + } + + /** + * Sets the value for the given index. This method should only be used by attributes. + */ + @Override + protected void set(int index, double value, double defaultValue) { + data[index] = value == 0.0d ? false : true; + } + + /** + * Creates a new array of the given size if necessary and copies the data into the new array. + */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + if (data.length >= numberOfColumns) { + return; + } + boolean[] newData = new boolean[numberOfColumns]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < data.length; i++) { + result.append((i == 0 ? "" : ",") + data[i]); + } + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_BOOLEAN_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/BooleanSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/BooleanSparseArrayDataRow.java new file mode 100644 index 000000000..6f13102a6 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/BooleanSparseArrayDataRow.java @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. This implementation uses boolean arrays instead of double arrays which + * will reduce the used memory even more. + * + * @author Ingo Mierswa + */ +public class BooleanSparseArrayDataRow extends AbstractSparseArrayDataRow { + + private static final long serialVersionUID = -4373978993763834478L; + + /** Stores the used attribute values. */ + private boolean[] values; + + /** Creates an empty sparse array data row with size 0. */ + public BooleanSparseArrayDataRow() { + this(0); + } + + /** Creates a sparse array data row of the given size. */ + public BooleanSparseArrayDataRow(int size) { + super(size); + values = new boolean[size]; + } + + /** + * Swaps x[a] with x[b]. + */ + @Override + protected void swapValues(int a, int b) { + boolean tt = values[a]; + values[a] = values[b]; + values[b] = tt; + } + + @Override + public void resizeValues(int length) { + boolean[] d = new boolean[length]; + System.arraycopy(values, 0, d, 0, Math.min(values.length, length)); + values = d; + } + + @Override + public void removeValue(int index) { + System.arraycopy(values, index + 1, values, index, (values.length - (index + 1))); + } + + /** Returns the desired data for the given attribute. */ + @Override + public double getValue(int index) { + return values[index] ? 1.0d : 0.0d; + } + + /** Sets the given data for the given attribute. */ + @Override + public void setValue(int index, double v) { + values[index] = (v == 0.0d ? false : true); + } + + @Override + protected double[] getAllValues() { + double[] result = new double[this.values.length]; + for (int i = 0; i < result.length; i++) { + result[i] = this.values[i] ? 1.0d : 0.0d; + } + return result; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_BOOLEAN_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/ByteArrayDataRow.java b/src/main/java/com/rapidminer/example/table/ByteArrayDataRow.java new file mode 100644 index 000000000..499ebe84e --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ByteArrayDataRow.java @@ -0,0 +1,87 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by a byte array. Please note that using this data row is + * quite efficient but only supports 256 different values (integers between -127 and 128 or 256 + * different nominal values for each column). + * + * @author Ingo Mierswa + */ +public class ByteArrayDataRow extends DataRow { + + private static final long serialVersionUID = -1428468572995891360L; + + /** Holds the data for all attributes. */ + private byte[] data; + + /** Creates a new data row backed by an primitive array. */ + public ByteArrayDataRow(byte[] data) { + this.data = data; + } + + /** + * Returns the value for the desired index. This method should only be used by attributes. + */ + @Override + protected double get(int index, double defaultValue) { + return data[index]; + } + + /** + * Sets the value for the given index. This method should only be used by attributes. + */ + @Override + protected void set(int index, double value, double defaultValue) { + data[index] = (byte) value; + } + + /** + * Creates a new array of the given size if necessary and copies the data into the new array. + */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + if (data.length >= numberOfColumns) { + return; + } + byte[] newData = new byte[numberOfColumns]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < data.length; i++) { + result.append((i == 0 ? "" : ",") + data[i]); + } + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_BYTE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/ByteSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/ByteSparseArrayDataRow.java new file mode 100644 index 000000000..5e9fb5ee1 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ByteSparseArrayDataRow.java @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. This implementation uses byte arrays instead of double arrays which + * will reduce the used memory even more. + * + * @author Ingo Mierswa + */ +public class ByteSparseArrayDataRow extends AbstractSparseArrayDataRow { + + private static final long serialVersionUID = -262171191423803150L; + + /** Stores the used attribute values. */ + private byte[] values; + + /** Creates an empty sparse array data row with size 0. */ + public ByteSparseArrayDataRow() { + this(0); + } + + /** Creates a sparse array data row of the given size. */ + public ByteSparseArrayDataRow(int size) { + super(size); + values = new byte[size]; + } + + /** + * Swaps x[a] with x[b]. + */ + @Override + protected void swapValues(int a, int b) { + byte tt = values[a]; + values[a] = values[b]; + values[b] = tt; + } + + @Override + public void resizeValues(int length) { + byte[] d = new byte[length]; + System.arraycopy(values, 0, d, 0, Math.min(values.length, length)); + values = d; + } + + @Override + public void removeValue(int index) { + System.arraycopy(values, index + 1, values, index, (values.length - (index + 1))); + } + + /** Returns the desired data for the given attribute. */ + @Override + public double getValue(int index) { + return values[index]; + } + + /** Sets the given data for the given attribute. */ + @Override + public void setValue(int index, double v) { + values[index] = (byte) v; + } + + @Override + protected double[] getAllValues() { + double[] result = new double[this.values.length]; + for (int i = 0; i < result.length; i++) { + result[i] = this.values[i]; + } + return result; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_BYTE_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/DataRow.java b/src/main/java/com/rapidminer/example/table/DataRow.java new file mode 100644 index 000000000..63c5d8c16 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DataRow.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; + +import java.io.Serializable; + + +/** + * This interface defines methods for all entries of ExampleTable implementations. It provides a set + * and get method for the data. Subclasses may use a double array, a sparse representation, a file + * or a database. + * + * @author Simon Fischer, Ingo Mierswa + */ +public abstract class DataRow implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -3482048832637144523L; + + /** Returns the value for the given index. */ + protected abstract double get(int index, double defaultValue); + + /** Sets the given data for the given index. */ + protected abstract void set(int index, double value, double defaultValue); + + /** + * Ensures that neither get(i) nor put(i,v) throw a runtime exception + * for all 0 <= i <= numberOfColumns. + */ + protected abstract void ensureNumberOfColumns(int numberOfColumns); + + /** Trims the number of columns to the actually needed number. */ + public abstract void trim(); + + /** + * This returns the type of this particular {@link DataRow} implementation according to the list + * in the {@link DataRowFactory}. + */ + public abstract int getType(); + + /** Returns a string representation for this data row. */ + @Override + public abstract String toString(); + + /** + * Returns the value stored at the given {@link Attribute}'s index. Returns Double.NaN if the + * given attribute is null. + */ + public double get(Attribute attribute) { + if (attribute == null) { + return Double.NaN; + } else { + try { + return attribute.getValue(this); + } catch (ArrayIndexOutOfBoundsException e) { + throw new ArrayIndexOutOfBoundsException("DataRow: table index " + attribute.getTableIndex() + + " of Attribute " + attribute.getName() + " is out of bounds."); + } + } + } + + /** Sets the value of the {@link Attribute} to value. */ + public void set(Attribute attribute, double value) { + attribute.setValue(this, value); + } +} diff --git a/src/main/java/com/rapidminer/example/table/DataRowFactory.java b/src/main/java/com/rapidminer/example/table/DataRowFactory.java new file mode 100644 index 000000000..9478d30fb --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DataRowFactory.java @@ -0,0 +1,279 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import java.util.logging.Level; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Tools; + + +/** + * Factory class for DataRow objects. One factory should be used for one ExampleTable only. This + * class is necessary to customize implementations of DataRowReader to create DataRows of arbitrary + * type. + * + * @author Ingo Mierswa, Simon Fischer + */ +public class DataRowFactory { + + public static final String[] TYPE_NAMES = { "double_array", "float_array", "long_array", "int_array", "short_array", + "byte_array", "boolean_array", "double_sparse_array", "float_sparse_array", "long_sparse_array", + "int_sparse_array", "short_sparse_array", "byte_sparse_array", "boolean_sparse_array", "sparse_map" }; + + public static final int FIRST_TYPE_INDEX = 0; + + public static final int TYPE_DOUBLE_ARRAY = 0; + + public static final int TYPE_FLOAT_ARRAY = 1; + + public static final int TYPE_LONG_ARRAY = 2; + + public static final int TYPE_INT_ARRAY = 3; + + public static final int TYPE_SHORT_ARRAY = 4; + + public static final int TYPE_BYTE_ARRAY = 5; + + public static final int TYPE_BOOLEAN_ARRAY = 6; + + public static final int TYPE_DOUBLE_SPARSE_ARRAY = 7; + + public static final int TYPE_FLOAT_SPARSE_ARRAY = 8; + + public static final int TYPE_LONG_SPARSE_ARRAY = 9; + + public static final int TYPE_INT_SPARSE_ARRAY = 10; + + public static final int TYPE_SHORT_SPARSE_ARRAY = 11; + + public static final int TYPE_BYTE_SPARSE_ARRAY = 12; + + public static final int TYPE_BOOLEAN_SPARSE_ARRAY = 13; + + public static final int TYPE_SPARSE_MAP = 14; + + public static final int LAST_TYPE_INDEX = 14; + + public static final int TYPE_SPECIAL = -1; + + public static final char POINT_AS_DECIMAL_CHARACTER = '.'; + + /** + * The type can be one out of TYPE_DOUBLE_ARRAY, TYPE_FLOAT_ARRAY, TYPE_LONG_ARRAY, + * TYPE_INT_ARRAY, TYPE_SHORT_ARRAY, TYPE_BYTE_ARRAY, TYPE_BOOLEAN_ARRAY, + * TYPE_DOUBLE_SPARSE_ARRAY, TYPE_FLOAT_SPARSE_ARRAY, TYPE_LONG_SPARSE_ARRAY, + * TYPE_INT_SPARSE_ARRAY, TYPE_SHORT_SPARSE_ARRAY, TYPE_BYTE_SPARSE_ARRAY, + * TYPE_BOOLEAN_SPARSE_ARRAY, or TYPE_SPARSE_MAP. + */ + private int type; + + /** The decimal point character. */ + private char decimalPointCharacter = POINT_AS_DECIMAL_CHARACTER; + + /** + * @param type + * must be one out of TYPE_DOUBLE_ARRAY, TYPE_FLOAT_ARRAY, TYPE_LONG_ARRAY, + * TYPE_INT_ARRAY, TYPE_SHORT_ARRAY, TYPE_BYTE_ARRAY, TYPE_BOOLEAN_ARRAY, + * TYPE_DOUBLE_SPARSE_ARRAY, TYPE_FLOAT_SPARSE_ARRAY, TYPE_SHORT_SPARSE_ARRAY, + * TYPE_BYTE_SPARSE_ARRAY, TYPE_BOOLEAN_SPARSE_ARRAY, or TYPE_SPARSE_MAP. + * @deprecated Please do not use this constructor any longer. Use the constructor + * {@link #DataRowFactory(int, char)} instead. + */ + @Deprecated + public DataRowFactory(int type) { + this(type, POINT_AS_DECIMAL_CHARACTER); + } + + /** + * @param type + * must be one out of TYPE_DOUBLE_ARRAY, TYPE_FLOAT_ARRAY, TYPE_LONG_ARRAY, + * TYPE_INT_ARRAY, TYPE_SHORT_ARRAY, TYPE_BYTE_ARRAY, TYPE_BOOLEAN_ARRAY, + * TYPE_DOUBLE_SPARSE_ARRAY, TYPE_FLOAT_SPARSE_ARRAY, TYPE_LONG_SPARSE_ARRAY, + * TYPE_INT_SPARSE_ARRAY, TYPE_SHORT_SPARSE_ARRAY, TYPE_BYTE_SPARSE_ARRAY, + * TYPE_BOOLEAN_SPARSE_ARRAY, or TYPE_SPARSE_MAP. + * @param decimalPointCharacter + * the letter for decimal points, usually '.' + */ + public DataRowFactory(int type, char decimalPointCharacter) { + if (type < FIRST_TYPE_INDEX || type > LAST_TYPE_INDEX) { + throw new IllegalArgumentException("Illegal data row type: " + type); + } + this.type = type; + this.decimalPointCharacter = decimalPointCharacter; + } + + /** Creates a new DataRow with the given initial capacity. */ + public DataRow create(int size) { + DataRow row = null; + switch (type) { + case TYPE_DOUBLE_ARRAY: + row = new DoubleArrayDataRow(new double[size]); + break; + case TYPE_FLOAT_ARRAY: + row = new FloatArrayDataRow(new float[size]); + break; + case TYPE_LONG_ARRAY: + row = new LongArrayDataRow(new long[size]); + break; + case TYPE_INT_ARRAY: + row = new IntArrayDataRow(new int[size]); + break; + case TYPE_SHORT_ARRAY: + row = new ShortArrayDataRow(new short[size]); + break; + case TYPE_BYTE_ARRAY: + row = new ByteArrayDataRow(new byte[size]); + break; + case TYPE_BOOLEAN_ARRAY: + row = new BooleanArrayDataRow(new boolean[size]); + break; + case TYPE_DOUBLE_SPARSE_ARRAY: + row = new DoubleSparseArrayDataRow(16); + break; + case TYPE_FLOAT_SPARSE_ARRAY: + row = new FloatSparseArrayDataRow(size >> 2); + break; + case TYPE_LONG_SPARSE_ARRAY: + row = new LongSparseArrayDataRow(size >> 2); + break; + case TYPE_INT_SPARSE_ARRAY: + row = new IntSparseArrayDataRow(size >> 2); + break; + case TYPE_SHORT_SPARSE_ARRAY: + row = new ShortSparseArrayDataRow(size >> 2); + break; + case TYPE_BYTE_SPARSE_ARRAY: + row = new ByteSparseArrayDataRow(size >> 2); + break; + case TYPE_BOOLEAN_SPARSE_ARRAY: + row = new BooleanSparseArrayDataRow(size >> 2); + break; + case TYPE_SPARSE_MAP: + row = new SparseMapDataRow(); + break; + default: + } + return row; + } + + /** + * Creates a data row from an array of Strings. If the corresponding attribute is nominal, the + * string is mapped to its index, otherwise it is parsed using + * Double.parseDouble(String) . + * + * @see FileDataRowReader + */ + public DataRow create(String[] strings, Attribute[] attributes) { + DataRow dataRow = create(strings.length); + for (int i = 0; i < strings.length; i++) { + if (strings[i] != null) { + strings[i] = strings[i].trim(); + } + if (strings[i] != null && strings[i].length() > 0 && !strings[i].equals("?")) { + if (attributes[i].isNominal()) { + String unescaped = Tools.unescape(strings[i]); + dataRow.set(attributes[i], attributes[i].getMapping().mapString(unescaped)); + } else { + dataRow.set(attributes[i], string2Double(strings[i], this.decimalPointCharacter)); + } + } else { + dataRow.set(attributes[i], Double.NaN); + } + } + dataRow.trim(); + return dataRow; + } + + /** + * Creates a data row from an Object array. The classes of the object must match the value type + * of the corresponding {@link Attribute}. If the corresponding attribute is nominal, + * data[i] will be cast to String. If it is numerical, it will be cast to Number. + * + * @throws ClassCastException + * if data class does not match attribute type + * @see DatabaseDataRowReader + */ + public DataRow create(Object[] data, Attribute[] attributes) { + DataRow dataRow = create(data.length); + for (int i = 0; i < data.length; i++) { + if (data[i] != null) { + if (attributes[i].isNominal()) { + dataRow.set(attributes[i], attributes[i].getMapping().mapString(((String) data[i]).trim())); + } else { + dataRow.set(attributes[i], ((Number) data[i]).doubleValue()); + } + } else { + dataRow.set(attributes[i], Double.NaN); + } + } + dataRow.trim(); + return dataRow; + } + + /** + * Creates a data row from an Object array. The classes of the object must match the value type + * of the corresponding {@link Attribute}. If the corresponding attribute is nominal, + * data[i] will be cast to String. If it is numerical, it will be cast to Number. + * + * @throws ClassCastException + * if data class does not match attribute type + * @see DatabaseDataRowReader + */ + public DataRow create(Double[] data, Attribute[] attributes) { + DataRow dataRow = create(data.length); + for (int i = 0; i < data.length; i++) { + if (data[i] != null) { + if (attributes[i].isNominal()) { + dataRow.set(attributes[i], attributes[i].getMapping().mapString(String.valueOf(data[i]).trim())); + } else { + dataRow.set(attributes[i], ((Number) data[i]).doubleValue()); + } + } else { + dataRow.set(attributes[i], Double.NaN); + } + } + dataRow.trim(); + return dataRow; + } + + /** Returns the type of the created data rows. */ + public int getType() { + return type; + } + + // -------------------------------------------------------------------------------- + + private static final double string2Double(String str, char decimalPointCharacter) { + if (str == null) { + return Double.NaN; + } + try { + str = str.replace(decimalPointCharacter, POINT_AS_DECIMAL_CHARACTER); + return Double.parseDouble(str); + } catch (NumberFormatException e) { + // LogService.getGlobal().log("DataRowFactory.string2Double(String): '" + str + + // "' is not a valid number!", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, + "com.rapidminer.example.table.DataRowFactory.datarowfactory_is_not_a_valid_number", str); + return Double.NaN; + } + } +} diff --git a/src/main/java/com/rapidminer/example/table/DataRowReader.java b/src/main/java/com/rapidminer/example/table/DataRowReader.java new file mode 100644 index 000000000..f07ed97d1 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DataRowReader.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import java.util.Iterator; + + +/** + * Reads a sequence of {@link DataRow}s, e.g. from memory, a file or a database. Please note that + * implementing classes do not have to support the remove operation! + * + * @author Ingo Mierswa, Simon Fischer + */ +public interface DataRowReader extends Iterator { + +} diff --git a/src/main/java/com/rapidminer/example/table/DatabaseDataRow.java b/src/main/java/com/rapidminer/example/table/DatabaseDataRow.java new file mode 100644 index 000000000..3d3511de0 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DatabaseDataRow.java @@ -0,0 +1,208 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.Ontology; + +import java.io.BufferedReader; +import java.io.IOException; +import java.sql.Clob; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.sql.Types; + + +/** + * Reads datarows from a data base. + * + * @author Ingo Mierswa, Simon Fischer + */ +public class DatabaseDataRow extends DataRow { + + private static final long serialVersionUID = 4043965829002723585L; + + /** The result set which backs this data row. */ + private transient ResultSet resultSet; + + /** The current row of the result set. Only used for checks */ + private int row; + + /** The last attribute for which a query should be / was performed. */ + private Attribute lastAttribute = null; + + /** + * Creates a data row from the given result set. The current row of the result set if used as + * data source. + */ + public DatabaseDataRow(ResultSet resultSet) throws SQLException { + this.resultSet = resultSet; + this.row = resultSet.getRow(); + } + + /** Ensures that the current row is the current row of the result set. */ + private void ensureRowCorrect() throws SQLException { + if (row != resultSet.getRow()) { + throw new RuntimeException("DatabaseDataRow: ResultSet was modified since creation of row!"); + } + } + + /** Returns the desired data for the given attribute. */ + @Override + public double get(Attribute attribute) { + try { + ensureRowCorrect(); + } catch (SQLException e) { + throw new RuntimeException("Cannot read data: " + e); + } + this.lastAttribute = attribute; + double value = attribute.getValue(this); + this.lastAttribute = null; + return value; + } + + /** Sets the given data for the given attribute. */ + @Override + public void set(Attribute attribute, double value) { + try { + ensureRowCorrect(); + } catch (SQLException e) { + throw new RuntimeException("Cannot update data: " + e, e); + } + this.lastAttribute = attribute; + attribute.setValue(this, value); + this.lastAttribute = null; + } + + @Override + protected double get(int index, double defaultValue) { + if (lastAttribute == null) { + throw new RuntimeException( + "Cannot read data, please use get(Attribute) method instead of get(int, double) in DatabaseDataRow."); + } else { + try { + return readColumn(this.resultSet, lastAttribute); + } catch (SQLException e) { + throw new RuntimeException("Cannot read data: " + e, e); + } + } + } + + @Override + protected void set(int index, double value, double defaultValue) { + try { + String name = this.lastAttribute.getName(); + if (Double.isNaN(value)) { + resultSet.updateNull(name); + } else { + if (this.lastAttribute.isNominal()) { + resultSet.updateString(name, this.lastAttribute.getMapping().mapIndex((int) value)); + } else { + resultSet.updateDouble(name, value); + } + } + resultSet.updateRow(); + } catch (SQLException e) { + throw new RuntimeException("Cannot update data: " + e, e); + } + } + + /** Does nothing. */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) {} + + /** Does nothing. */ + @Override + public void trim() {} + + @Override + public String toString() { + return "Database Data Row"; + } + + /** Reads the data for the given attribute from the result set. */ + public static double readColumn(ResultSet resultSet, Attribute attribute) throws SQLException { + ResultSetMetaData metaData = resultSet.getMetaData(); + String name = attribute.getName(); + int valueType = attribute.getValueType(); + double value; + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.DATE_TIME)) { + Timestamp timestamp = resultSet.getTimestamp(name); + if (resultSet.wasNull()) { + value = Double.NaN; + } else { + value = timestamp.getTime(); + } + } else if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NUMERICAL)) { + value = resultSet.getDouble(name); + if (resultSet.wasNull()) { + value = Double.NaN; + } + } else { + if (Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL)) { + String valueString = null; + int tableIndex = attribute.getTableIndex() + 1; + if (metaData.getColumnType(tableIndex) == Types.CLOB) { + Clob clob = resultSet.getClob(name); + if (clob != null) { + BufferedReader in = null; + try { + in = new BufferedReader(clob.getCharacterStream()); + String line = null; + try { + StringBuffer buffer = new StringBuffer(); + while ((line = in.readLine()) != null) { + buffer.append(line + "\n"); + } + valueString = buffer.toString(); + } catch (IOException e) { + value = Double.NaN; + } + } finally { + try { + in.close(); + } catch (IOException e) { + } + } + } else { + valueString = null; + } + } else { + valueString = resultSet.getString(name); + } + if (resultSet.wasNull() || valueString == null) { + value = Double.NaN; + } else { + value = attribute.getMapping().mapString(valueString); + } + } else { + value = Double.NaN; + } + } + + return value; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_SPECIAL; + } +} diff --git a/src/main/java/com/rapidminer/example/table/DatabaseDataRowReader.java b/src/main/java/com/rapidminer/example/table/DatabaseDataRowReader.java new file mode 100644 index 000000000..2bae616bf --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DatabaseDataRowReader.java @@ -0,0 +1,113 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.LogService; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.logging.Level; + + +/** + * Unlike a {@link FileDataRowReader} that reads examples from a file, objects of this class read + * examples from a {@link ResultSet}, a data structure that is returned from a database query. + * + * @see com.rapidminer.tools.jdbc.DatabaseHandler + * @see com.rapidminer.operator.io.DatabaseDataReader + * @see com.rapidminer.operator.io.KDBExampleSource + * @author Simon Fischer, Ingo Mierswa ingomierswa Exp $ + */ +public class DatabaseDataRowReader implements DataRowReader { + + private ResultSet resultSet; + + private static final int DONT_KNOW_YET = 0; + + private static final int YES = 1; + + private static final int NO = 2; + + private int hasNext = DONT_KNOW_YET; + + /** + * Creates a datarow reader from a ResultSet. The column meta data must be tranformed to an + * {@link Attribute} array. + */ + public DatabaseDataRowReader(ResultSet resultSet) throws SQLException { + this.resultSet = resultSet; + this.resultSet.beforeFirst(); + } + + @Override + public boolean hasNext() { + switch (hasNext) { + case YES: + return true; + case NO: + return false; + case DONT_KNOW_YET: + try { + if (resultSet.next()) { + hasNext = YES; + return true; + } else { + hasNext = NO; + return false; + } + } catch (SQLException e) { + // LogService.getGlobal().logError("While reading examples from result set: " + + // e.getMessage()); + LogService + .getRoot() + .log(Level.SEVERE, + "com.rapidminer.example.table.DatabaseDataRowReader.error_while_reading_examples_from_result_set", + e.getMessage()); + return false; + } + default: + // impossible + return false; + } + } + + @Override + public DataRow next() { + if (hasNext()) { + hasNext = DONT_KNOW_YET; + try { + return new DatabaseDataRow(resultSet); + } catch (SQLException sqle) { + throw new RuntimeException("Error accessing the result of a query:" + sqle.toString(), sqle); + } + } else { + return null; + } + } + + /** + * Will throw a new {@link UnsupportedOperationException} since {@link DataRowReader} does not + * have to implement remove. + */ + @Override + public void remove() { + throw new UnsupportedOperationException("The method 'remove' is not supported by DataRowReaders on databases!"); + } +} diff --git a/src/main/java/com/rapidminer/example/table/DateAttribute.java b/src/main/java/com/rapidminer/example/table/DateAttribute.java new file mode 100644 index 000000000..843dc7f60 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DateAttribute.java @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import java.util.Date; + +import com.rapidminer.example.MinMaxStatistics; +import com.rapidminer.example.UnknownStatistics; +import com.rapidminer.tools.Ontology; +import com.rapidminer.tools.Tools; + + +/** + * This class holds all information on a single date attribute. In addition to the information of + * the superclass, this is some statistics data like minimum, maximum and average of the values. + * + * @author Ingo Mierswa + */ +public class DateAttribute extends AbstractAttribute { + + private static final long serialVersionUID = -685655991653799960L; + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + */ + protected DateAttribute(String name) { + this(name, Ontology.DATE); + } + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + */ + protected DateAttribute(String name, int valueType) { + super(name, valueType); + registerStatistics(new MinMaxStatistics()); + registerStatistics(new UnknownStatistics()); + } + + /** + * Clone constructor. + */ + private DateAttribute(DateAttribute a) { + super(a); + } + + @Override + public Object clone() { + return new DateAttribute(this); + } + + @Override + public String getAsString(double value, int digits, boolean quoteNominal) { + if (Double.isNaN(value)) { + return "?"; + } else { + long milliseconds = (long) value; + String result = null; + if (getValueType() == Ontology.DATE) { + result = Tools.formatDate(new Date(milliseconds)); + } else if (getValueType() == Ontology.TIME) { + result = Tools.formatTime(new Date(milliseconds)); + } else if (getValueType() == Ontology.DATE_TIME) { + result = Tools.formatDateTime(new Date(milliseconds), "dd/MM/yyyy HH:mm:ss aa zzz"); + } + if (quoteNominal) { + result = "\"" + result + "\""; + } + return result; + } + } + + /** Returns null. */ + @Override + public NominalMapping getMapping() { + throw new UnsupportedOperationException( + "The method getNominalMapping() is not supported by date attributes! You probably tried to execute an operator on a date or time data which is only able to handle nominal values. You could use one of the Date to Nominal operator before this application."); + } + + /** Returns false. */ + @Override + public boolean isNominal() { + return false; + } + + @Override + public boolean isNumerical() { + return false; + } + + /** Do nothing. */ + @Override + public void setMapping(NominalMapping nominalMapping) {} + + @Override + public boolean isDateTime() { + return true; + } +} diff --git a/src/main/java/com/rapidminer/example/table/DoubleArrayDataRow.java b/src/main/java/com/rapidminer/example/table/DoubleArrayDataRow.java new file mode 100644 index 000000000..d7743e7a0 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DoubleArrayDataRow.java @@ -0,0 +1,88 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by a double array. + * + * @author Simon Fischer, Ingo Mierswa Exp $ + */ +public class DoubleArrayDataRow extends DataRow { + + private static final long serialVersionUID = -6335785895337884919L; + + /** Holds the data for all attributes. */ + private double[] data; + + /** Creates a new data row backed by an primitive array. */ + public DoubleArrayDataRow(double[] data) { + this.data = data; + } + + public DoubleArrayDataRow(DoubleArrayDataRow dataRow) { + this.data = dataRow.getData(); + } + + public double[] getData() { + return data; + } + + @Override + protected double get(int index, double defaultValue) { + return data[index]; + } + + /** Sets the given data for the given index. */ + @Override + protected void set(int index, double value, double defaultValue) { + data[index] = value; + } + + /** + * Creates a new array of the given size if necessary and copies the data into the new array. + */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + if (data.length >= numberOfColumns) { + return; + } + double[] newData = new double[numberOfColumns]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < data.length; i++) { + result.append((i == 0 ? "" : ",") + data[i]); + } + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_DOUBLE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/DoubleSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/DoubleSparseArrayDataRow.java new file mode 100644 index 000000000..8301887d6 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/DoubleSparseArrayDataRow.java @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. + * + * @author Niraj Aswani, Julien Nioche, Ingo Mierswa, Shevek Exp $ + */ +public class DoubleSparseArrayDataRow extends AbstractSparseArrayDataRow { + + private static final long serialVersionUID = 9137639592169696234L; + + /** Stores the used attribute values. */ + private double[] values; + + /** Creates an empty sparse array data row with size 0. */ + public DoubleSparseArrayDataRow() { + this(0); + } + + /** Creates a sparse array data row of the given size. */ + public DoubleSparseArrayDataRow(int size) { + super(size); + values = new double[size]; + } + + @Override + protected void swapValues(int a, int b) { + double tt = values[a]; + values[a] = values[b]; + values[b] = tt; + } + + @Override + public void resizeValues(int length) { + double[] d = new double[length]; + System.arraycopy(values, 0, d, 0, Math.min(values.length, length)); + values = d; + } + + @Override + public void removeValue(int index) { + System.arraycopy(values, index + 1, values, index, (values.length - (index + 1))); + } + + /** Returns the desired data for the given attribute. */ + @Override + public double getValue(int index) { + return values[index]; + } + + /** Sets the given data for the given attribute. */ + @Override + public void setValue(int index, double v) { + values[index] = v; + } + + @Override + protected double[] getAllValues() { + return this.values; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_DOUBLE_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/ExampleTable.java b/src/main/java/com/rapidminer/example/table/ExampleTable.java new file mode 100644 index 000000000..6c8f85f09 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ExampleTable.java @@ -0,0 +1,170 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.AttributeRole; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.operator.OperatorException; +import com.rapidminer.tools.att.AttributeSet; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; + + +/** + *

    + * This class is the core data supplier for example sets. Several example sets can use the same data + * and access the attribute values by reference. Thats means that ExampleTable contains all data + * like in a database management systems and all {@link ExampleSet}s are only views on the data. The + * ExampleSets themself do hence not contain any data rows and can be cloned without copying the + * data. + *

    + * + *

    + * Changing the data in the ExampleTable will change the data for all views (ExampleSets). On the + * other hand, the changes for one view (ExampleSet) like adding or removing {@link Attribute}s will + * not change the ExampleTable and will also not change other views (ExampleSets). + *

    + * + * @author Ingo Mierswa + */ +public interface ExampleTable extends Serializable { + + /** Returns the number of examples. */ + public int size(); + + /** + * Returns an Iterator for example data given as DataRow objects. This should be + * used in all cases where iteration is desired. Since {@link #getDataRow(int)} does not ensure + * to work in an efficient way the usage of this method is preferred (instead using for-loops). + */ + public DataRowReader getDataRowReader(); + + /** + * Returns the i-th data row. Calling methods cannot rely on the efficiency of this method. + * Memory based example tables should return the data row in O(1). + */ + public DataRow getDataRow(int index); + + /** Returns a new array containing all {@link Attribute}s. */ + public Attribute[] getAttributes(); + + /** + * Returns the attribute of the column number i. Attention: This value may return null if + * the column was marked unused. + */ + public Attribute getAttribute(int i); + + /** + * Returns the attribute with the given name. CAUTION: This does only return the first attribute + * found with this name. Since there is no guarantee that names are unique, this might not + * deliver the desired result. + */ + public Attribute findAttribute(String name) throws OperatorException; + + /** + * Adds all {@link Attribute}s in newAttributes to the end of the list of + * attributes, creating new data columns if necessary. + */ + public void addAttributes(Collection newAttributes); + + /** + * Adds a clone of the attribute a to the list of attributes assigning it a free + * column index. The column index is also set on a. + */ + public int addAttribute(Attribute a); + + /** + * Equivalent to calling removeAttribute(attribute.getTableIndex()). + */ + public void removeAttribute(Attribute attribute); + + /** + * Sets the attribute with the given index to null. Afterwards, this column can be reused. + * Callers must make sure, that no other example set contains a reference to this column. + * Otherwise its data will be messed up. Usually this is only possible if an operator generates + * intermediate attributes, like a validation chain or a feature generator. If the attribute + * already was removed, this method returns silently. + */ + public void removeAttribute(int index); + + /** + * Returns the number of attributes. Attention: Callers that use a for-loop and retrieving + * {@link Attribute}s by calling {@link AbstractExampleTable#getAttribute(int)} must keep in + * mind, that some of these attributes may be null. + */ + public int getNumberOfAttributes(); + + /** + * Returns the number of non null attributes. Attention: Since there might be null + * attributes in the table, the return value of this method must not be used in a for-loop! + * + * @see ExampleTable#getNumberOfAttributes(). + */ + public int getAttributeCount(); + + /** + * Returns a new example set with all attributes switched on. The given attribute will be used + * as a special label attribute for learning. + */ + public ExampleSet createExampleSet(Attribute labelAttribute); + + /* + * Returns a new example set with all attributes switched on. The iterator over the attribute + * roles will define the special attributes. + */ + public ExampleSet createExampleSet(Iterator newSpecialAttributes); + + /** + * Returns a new example set with all attributes switched on. The given attributes will be used + * as a special label attribute for learning, as (example) weight attribute, and as id + * attribute. + */ + public ExampleSet createExampleSet(Attribute labelAttribute, Attribute weightAttribute, Attribute idAttribute); + + /** + * Returns a new example set with all attributes of the {@link ExampleTable} and with the + * special roles defined by the given attribute set. + */ + public ExampleSet createExampleSet(AttributeSet attributeSet); + + /** + * Returns a new example set with all attributes switched on. The attributes in the given map + * will be used as special attributes, all other attributes given at creation time will be + * regular. + */ + public ExampleSet createExampleSet(Map specialAttributes); + + /** + * Returns a new example set with all attributes switched on. All attributes will be used as + * regular attributes. + */ + public ExampleSet createExampleSet(); + + /** Returns a string representation of this example table. */ + @Override + public String toString(); + + /** Dumps the complete data as string. */ + public String toDataString(); + +} diff --git a/src/main/java/com/rapidminer/example/table/FastSparseDoubleArrayDataRow.java b/src/main/java/com/rapidminer/example/table/FastSparseDoubleArrayDataRow.java new file mode 100644 index 000000000..7bd99fde3 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/FastSparseDoubleArrayDataRow.java @@ -0,0 +1,133 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Tools; + +import java.util.Arrays; + + +/** + * This implementation of a sparse DataRow makes use of the binary search index to maintain a sorted + * list of indices to save the effort of re sorting on adding a new index. + * + * @author Sebastian Land, Tobias Malbrecht + */ +public class FastSparseDoubleArrayDataRow extends DataRow { + + private static final long serialVersionUID = -4709836940912838649L; + + private double[] values; + private int[] tableIndices; + + private int numberOfValues = 0; + + public FastSparseDoubleArrayDataRow(int initialSize) { + this.values = new double[initialSize]; + this.tableIndices = new int[initialSize]; + } + + @Override + protected double get(int index, double defaultValue) { + int valueIndex = Arrays.binarySearch(tableIndices, 0, numberOfValues, index); + if (valueIndex >= 0) { + return values[valueIndex]; + } + return defaultValue; + } + + @Override + protected void set(int index, double value, double defaultValue) { + assert (numberOfValues <= tableIndices.length); + assert (tableIndices.length == values.length); + int valueIndex = Arrays.binarySearch(tableIndices, 0, numberOfValues, index); + if (valueIndex > 0) { + // if index already has a value: test if new values is equal to defaultValue + if (Tools.isDefault(defaultValue, value)) { + // new value is default + if (valueIndex + 1 < values.length) { + // if it is not last: copy all subsequent one in front + System.arraycopy(values, valueIndex + 1, values, valueIndex, values.length - valueIndex - 1); + System.arraycopy(tableIndices, valueIndex + 1, tableIndices, valueIndex, values.length - valueIndex - 1); + } + numberOfValues--; + } else { + // old value must simply be overridden + values[valueIndex] = value; + } + } else if (!Tools.isDefault(defaultValue, value)) { + // index is unknown and value different from defaultValue, we have to insert it + int insertionIndex = -(valueIndex + 1); + if (numberOfValues == tableIndices.length) { + // no space left: enlarge array + double[] newValues = new double[values.length + (values.length >> 1) + 1]; + int[] newTableIndices = new int[values.length + (values.length >> 1) + 1]; + // copy the two halves before and after the insertion point + System.arraycopy(values, 0, newValues, 0, insertionIndex); + System.arraycopy(values, insertionIndex, newValues, insertionIndex + 1, numberOfValues - insertionIndex); + System.arraycopy(tableIndices, 0, newTableIndices, 0, insertionIndex); + System.arraycopy(tableIndices, insertionIndex, newTableIndices, insertionIndex + 1, numberOfValues + - insertionIndex); + values = newValues; + tableIndices = newTableIndices; + } else { + // enough space: shift subsequent arrays + System.arraycopy(values, insertionIndex, values, insertionIndex + 1, numberOfValues - insertionIndex); + System.arraycopy(tableIndices, insertionIndex, tableIndices, insertionIndex + 1, numberOfValues + - insertionIndex); + } + // finally setting value + tableIndices[insertionIndex] = index; + values[insertionIndex] = value; + + // and increase counter + numberOfValues++; + } + } + + @Override + public void trim() { + values = Arrays.copyOfRange(values, 0, numberOfValues); + tableIndices = Arrays.copyOfRange(tableIndices, 0, numberOfValues); + } + + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + // Do nothing since a runtime exception is never thrown: Default value is returned for + // unknown indices anyway. + } + + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < tableIndices.length; i++) { + if (i != 0) { + result.append(", "); + } + result.append(tableIndices[i] + ":" + values[i]); + } + result.append(", counter: " + numberOfValues); + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_DOUBLE_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/FileDataRowReader.java b/src/main/java/com/rapidminer/example/table/FileDataRowReader.java new file mode 100644 index 000000000..01ee39b80 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/FileDataRowReader.java @@ -0,0 +1,294 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.RandomGenerator; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.att.AttributeDataSource; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; + + +/** + *

    + * FileDataRowReader implements a DataRowReader that reads DataRows from a file. This is the main + * data reader for many file formats (including csv) and is used by the ExampleSource operator and + * the attribute editor. + *

    + * + *

    + * This class supports the reading of data from multiple source files. Each attribute (including + * special attributes like labels, weights, ...) might be read from another file. Please note that + * only the minimum number of lines of all files will be read, i.e. if one of the data source files + * has less lines than the others, only this number of data rows will be read. + *

    + * + *

    + * The split points can be defined with regular expressions (please refer to the Java API). Quoting + * is possible but not suggested since the runtime is higher. The user should ensure that the split + * characters are not included in the data columns. Please refer to {@link RapidMinerLineReader} for + * further information. + *

    + * + *

    + * Unknown attribute values can be marked with empty strings or "?". + *

    + * + * @author Ingo Mierswa Exp $ + */ +public class FileDataRowReader extends AbstractDataRowReader { + + private static final int FILE_NR = 0; + + private static final int COLUMN_NR = 1; + + /** The file readers. */ + private BufferedReader[] fileReader; + + /** The attribute descriptions. */ + private Attribute[] attributes; + + /** Remember if an end of file has occured. */ + private boolean eof; + + /** Remember if a line has already been read. */ + private boolean lineRead; + + /** The sample ratio. */ + private double sampleRatio = 1.0d; + + /** The maximum number of examples to read (sampling). */ + private int maxNumber = -1; + + /** The number of lines read so far (i.e. the number of examples). */ + private int linesRead = 0; + + /** + * This array hold the current data. The first dimension is used for distinguishing different + * sources and the second for data read from the corresponding source. + */ + private String[][] currentData; + + /** + * This array holds the information how many columns each data source should provide. Otherwise + * an IOException will be thrown. This information is only used for checks and error + * improvement. + */ + private int[] expectedNumberOfColumns; + + /** This reader maps lines read from a file to RapidMiner columns. */ + private RapidMinerLineReader rapidMinerLineReader; + + /** The random generator used for sampling. */ + private RandomGenerator random; + + /** + * Array of size [number of attributes][2]. For each attribute i the value of + * dataSourceIndex[i][FILE_NR] is used as an index to {@link #fileReader} and the value of + * dataSourceIndex[i][TOKEN_NR] specifies the index of the column to use for attribute i. + */ + private int[][] dataSourceIndex; + + /** + * Constructs a new FileDataRowReader. + * + * @param factory + * Factory used to create data rows. + * @param attributeDataSources + * List of {@link AttributeDataSource}s. + * @param sampleRatio + * the ratio of examples which will be read. Only used if sampleSize is -1. + * @param sampleSize + * Limit sample to the first sampleSize lines read from files. -1 for no limit, then + * the sampleRatio will be used. + * @param separatorsRegExpr + * a regular expression describing the separator characters for the columns of each + * line + * @param commentChars + * defines which characters are used to comment the rest of a line + * @param useQuotes + * indicates if quotes should be used and parsed. Slows down reading and should be + * avoided if possible + * @param random + * the random generator used for sampling + */ + public FileDataRowReader(DataRowFactory factory, List attributeDataSources, double sampleRatio, + int sampleSize, String separatorsRegExpr, char[] commentChars, boolean useQuotes, char quoteChar, + char escapeChar, boolean trimLines, boolean skipErrorLines, Charset encoding, RandomGenerator random) + throws IOException { + super(factory); + this.sampleRatio = sampleRatio; + this.maxNumber = sampleSize; + this.attributes = new Attribute[attributeDataSources.size()]; + this.dataSourceIndex = new int[attributeDataSources.size()][2]; + this.rapidMinerLineReader = new RapidMinerLineReader(separatorsRegExpr, commentChars, useQuotes, quoteChar, + escapeChar, trimLines, skipErrorLines); + this.random = random; + initReader(factory, attributeDataSources, sampleSize, separatorsRegExpr, useQuotes, encoding); + } + + /** Read the complete data. */ + private void initReader(DataRowFactory factory, List attributeDataSources, int sampleSize, + String separatorsRegExpr, boolean useQuotes, Charset encoding) throws IOException { + // map all files used to indices + List readerList = new LinkedList(); + Map fileMap = new HashMap(); + Iterator i = attributeDataSources.iterator(); + int attribute = 0; + int greatestFileIndex = -1; + List columnCounters = new ArrayList(); + while (i.hasNext()) { + AttributeDataSource ads = i.next(); + attributes[attribute] = ads.getAttribute(); + File file = ads.getFile(); + Integer fileIndex = fileMap.get(file); + // new file found? -> create reader and map to index number + if (fileIndex == null) { + fileIndex = Integer.valueOf(++greatestFileIndex); + fileMap.put(file, fileIndex); + readerList.add(Tools.getReader(file, encoding)); + columnCounters.add(new AtomicInteger(1)); + } else { + AtomicInteger counter = columnCounters.get(fileIndex.intValue()); + counter.incrementAndGet(); + } + dataSourceIndex[attribute][FILE_NR] = fileIndex.intValue(); + dataSourceIndex[attribute][COLUMN_NR] = ads.getColumn(); + attribute++; + } + + this.fileReader = new BufferedReader[readerList.size()]; + readerList.toArray(this.fileReader); + currentData = new String[this.fileReader.length][]; + + // create counters + expectedNumberOfColumns = new int[columnCounters.size()]; + Iterator j = columnCounters.iterator(); + int k = 0; + while (j.hasNext()) { + expectedNumberOfColumns[k++] = j.next().intValue(); + } + } + + /** Skips the next line, if present. */ + public void skipLine() { + try { + readLine(); + } catch (Exception e) { + // LogService.getGlobal().log("Problem during skipping of line: " + e.getMessage(), + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.table.FileDataRowReader.problem_during_skipping_of_line", e.getMessage()); + } + } + + /** + * Reads a line of data from all file readers. Returns true if the line was readable, i.e. the + * end of the source files was not yet reached. + */ + private boolean readLine() throws IOException { + boolean eofReached = false; + boolean ok = false; + while (!ok) { + for (int i = 0; i < fileReader.length; i++) { + currentData[i] = rapidMinerLineReader.readLine(fileReader[i], expectedNumberOfColumns[i]); + if (currentData[i] == null) { + eofReached = true; + break; + } + } + if ((eofReached) || (maxNumber != -1) || (sampleRatio == 1.0d) || (random.nextDouble() < sampleRatio)) { + ok = true; + } + } + if (eofReached) { + for (int i = 0; i < fileReader.length; i++) { + fileReader[i].close(); + } + return false; + } else { + return true; + } + } + + /** + * Checks if another line exists and reads. The next line is only read once even if this method + * is invoked more than once. + */ + @Override + public boolean hasNext() { + if ((maxNumber > -1) && (linesRead >= maxNumber)) { + return false; + } + + if (lineRead) { + return !eof; + } + + try { + eof = !readLine(); + } catch (IOException e) { + LogService.getGlobal().log(e.getMessage(), LogService.ERROR); + return false; + } + lineRead = true; + + return (!eof); + } + + /** Returns the next Example. */ + @Override + public DataRow next() { + if (eof == true) { + return null; + } + if (!lineRead) { + if (!hasNext()) { + return null; + } + } + + String[] data = new String[attributes.length]; + for (int i = 0; i < attributes.length; i++) { + if (dataSourceIndex[i][1] == -1) { + data[i] = null; + } else { + data[i] = currentData[dataSourceIndex[i][0]][dataSourceIndex[i][1]]; + } + } + + DataRow dataRow = getFactory().create(data, attributes); + linesRead++; + lineRead = false; + return dataRow; + } +} diff --git a/src/main/java/com/rapidminer/example/table/FloatArrayDataRow.java b/src/main/java/com/rapidminer/example/table/FloatArrayDataRow.java new file mode 100644 index 000000000..1a9a99eed --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/FloatArrayDataRow.java @@ -0,0 +1,85 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by a float array. Please note that for most applications + * the precision of floats should be high enough. The highest precision is provided by + * {@link com.rapidminer.example.table.DoubleArrayDataRow}s but these need the double amount + * compared to these float representations which are therefore a good trade-off between precision + * and memory usage. + * + * @author Ingo Mierswa + */ +public class FloatArrayDataRow extends DataRow { + + private static final long serialVersionUID = -3691818538613297744L; + + /** Holds the data for all attributes. */ + private float[] data; + + /** Creates a new data row backed by an primitive array. */ + public FloatArrayDataRow(float[] data) { + this.data = data; + } + + /** Returns the desired data for the given index. */ + @Override + protected double get(int index, double defaultValue) { + return data[index]; + } + + /** Sets the given data for the given index. */ + @Override + protected void set(int index, double value, double defaultValue) { + data[index] = (float) value; + } + + /** + * Creates a new array of the given size if necessary and copies the data into the new array. + */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + if (data.length >= numberOfColumns) { + return; + } + float[] newData = new float[numberOfColumns]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < data.length; i++) { + result.append((i == 0 ? "" : ",") + data[i]); + } + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_FLOAT_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/FloatSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/FloatSparseArrayDataRow.java new file mode 100644 index 000000000..6b78a07fb --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/FloatSparseArrayDataRow.java @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. This implementation uses float arrays instead of double arrays which + * might reduce the used memory even more. + * + * @author Ingo Mierswa, Shevek + */ +public class FloatSparseArrayDataRow extends AbstractSparseArrayDataRow { + + private static final long serialVersionUID = -2445500346242180129L; + + /** Stores the used attribute values. */ + private float[] values; + + /** Creates an empty sparse array data row with size 0. */ + public FloatSparseArrayDataRow() { + this(0); + } + + /** Creates a sparse array data row of the given size. */ + public FloatSparseArrayDataRow(int size) { + super(size); + values = new float[size]; + } + + @Override + protected void swapValues(int a, int b) { + float tt = values[a]; + values[a] = values[b]; + values[b] = tt; + } + + @Override + public void resizeValues(int length) { + float[] d = new float[length]; + System.arraycopy(values, 0, d, 0, Math.min(values.length, length)); + values = d; + } + + @Override + public void removeValue(int index) { + System.arraycopy(values, index + 1, values, index, (values.length - (index + 1))); + } + + /** Returns the desired data for the given attribute. */ + @Override + public double getValue(int index) { + return values[index]; + } + + /** Sets the given data for the given attribute. */ + @Override + public void setValue(int index, double v) { + values[index] = (float) v; + } + + @Override + protected double[] getAllValues() { + double[] result = new double[this.values.length]; + for (int i = 0; i < result.length; i++) { + result[i] = this.values[i]; + } + return result; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_FLOAT_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/IntArrayDataRow.java b/src/main/java/com/rapidminer/example/table/IntArrayDataRow.java new file mode 100644 index 000000000..cd820c4ef --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/IntArrayDataRow.java @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by an integer array. + * + * @author Ingo Mierswa Exp $ + */ +public class IntArrayDataRow extends DataRow { + + private static final long serialVersionUID = -8089560930865510003L; + + /** Holds the data for all attributes. */ + private int[] data; + + /** Creates a new data row backed by an primitive array. */ + public IntArrayDataRow(int[] data) { + this.data = data; + } + + @Override + protected double get(int index, double defaultValue) { + return data[index]; + } + + /** Sets the given data for the given index. */ + @Override + protected void set(int index, double value, double defaultValue) { + data[index] = (int) value; + } + + /** + * Creates a new array of the given size if necessary and copies the data into the new array. + */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + if (data.length >= numberOfColumns) { + return; + } + int[] newData = new int[numberOfColumns]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < data.length; i++) { + result.append((i == 0 ? "" : ",") + data[i]); + } + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_INT_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/IntSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/IntSparseArrayDataRow.java new file mode 100644 index 000000000..41632cc23 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/IntSparseArrayDataRow.java @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. This implementation uses integer arrays instead of double arrays which + * will reduce the used memory even more. + * + * @author Ingo Mierswa + */ +public class IntSparseArrayDataRow extends AbstractSparseArrayDataRow { + + private static final long serialVersionUID = -4642005554786017231L; + + /** Stores the used attribute values. */ + private int[] values; + + /** Creates an empty sparse array data row with size 0. */ + public IntSparseArrayDataRow() { + this(0); + } + + /** Creates a sparse array data row of the given size. */ + public IntSparseArrayDataRow(int size) { + super(size); + values = new int[size]; + } + + /** + * Swaps x[a] with x[b]. + */ + @Override + protected void swapValues(int a, int b) { + int tt = values[a]; + values[a] = values[b]; + values[b] = tt; + } + + @Override + public void resizeValues(int length) { + int[] d = new int[length]; + System.arraycopy(values, 0, d, 0, Math.min(values.length, length)); + values = d; + } + + @Override + public void removeValue(int index) { + System.arraycopy(values, index + 1, values, index, (values.length - (index + 1))); + } + + /** Returns the desired data for the given attribute. */ + @Override + public double getValue(int index) { + return values[index]; + } + + /** Sets the given data for the given attribute. */ + @Override + public void setValue(int index, double v) { + values[index] = (int) v; + } + + @Override + protected double[] getAllValues() { + double[] result = new double[this.values.length]; + for (int i = 0; i < result.length; i++) { + result[i] = this.values[i]; + } + return result; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_INT_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/ListDataRowReader.java b/src/main/java/com/rapidminer/example/table/ListDataRowReader.java new file mode 100644 index 000000000..d5acf6074 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ListDataRowReader.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import java.util.Iterator; + + +/** + * Iterates over a list of DataRows. Actually a misnomer because this class does not use a list but + * an iterator over an arbitrary collection. + * + * @author Ingo Mierswa Exp $ + */ +public class ListDataRowReader implements DataRowReader { + + private Iterator iterator; + + public ListDataRowReader(Iterator i) { + this.iterator = i; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public DataRow next() { + return iterator.next(); + } + + /** + * Will throw a new {@link UnsupportedOperationException} since {@link DataRowReader} does not + * have to implement remove. + */ + @Override + public void remove() { + throw new UnsupportedOperationException("The method 'remove' is not supported by DataRowReaders!"); + } +} diff --git a/src/main/java/com/rapidminer/example/table/LongArrayDataRow.java b/src/main/java/com/rapidminer/example/table/LongArrayDataRow.java new file mode 100644 index 000000000..521b8ac64 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/LongArrayDataRow.java @@ -0,0 +1,80 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by a long array. + * + * @author Ingo Mierswa Exp $ + */ +public class LongArrayDataRow extends DataRow { + + private static final long serialVersionUID = 8652466671294511853L; + + /** Holds the data for all attributes. */ + private long[] data; + + /** Creates a new data row backed by an primitive array. */ + public LongArrayDataRow(long[] data) { + this.data = data; + } + + @Override + protected double get(int index, double defaultValue) { + return data[index]; + } + + /** Sets the given data for the given index. */ + @Override + protected void set(int index, double value, double defaultValue) { + data[index] = (long) value; + } + + /** + * Creates a new array of the given size if necessary and copies the data into the new array. + */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + if (data.length >= numberOfColumns) { + return; + } + long[] newData = new long[numberOfColumns]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < data.length; i++) { + result.append((i == 0 ? "" : ",") + data[i]); + } + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_LONG_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/LongSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/LongSparseArrayDataRow.java new file mode 100644 index 000000000..ab743a4ce --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/LongSparseArrayDataRow.java @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. This implementation uses long arrays instead of double arrays which + * will reduce the used memory even more. + * + * @author Ingo Mierswa + */ +public class LongSparseArrayDataRow extends AbstractSparseArrayDataRow { + + private static final long serialVersionUID = 7128381338958693751L; + + /** Stores the used attribute values. */ + private long[] values; + + /** Creates an empty sparse array data row with size 0. */ + public LongSparseArrayDataRow() { + this(0); + } + + /** Creates a sparse array data row of the given size. */ + public LongSparseArrayDataRow(int size) { + super(size); + values = new long[size]; + } + + /** + * Swaps x[a] with x[b]. + */ + @Override + protected void swapValues(int a, int b) { + long tt = values[a]; + values[a] = values[b]; + values[b] = tt; + } + + @Override + public void resizeValues(int length) { + long[] d = new long[length]; + System.arraycopy(values, 0, d, 0, Math.min(values.length, length)); + values = d; + } + + @Override + public void removeValue(int index) { + System.arraycopy(values, index + 1, values, index, (values.length - (index + 1))); + } + + /** Returns the desired data for the given attribute. */ + @Override + public double getValue(int index) { + return values[index]; + } + + /** Sets the given data for the given attribute. */ + @Override + public void setValue(int index, double v) { + values[index] = (long) v; + } + + @Override + protected double[] getAllValues() { + double[] result = new double[this.values.length]; + for (int i = 0; i < result.length; i++) { + result[i] = this.values[i]; + } + return result; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_LONG_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/MemoryExampleTable.java b/src/main/java/com/rapidminer/example/table/MemoryExampleTable.java new file mode 100644 index 000000000..8d759baf2 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/MemoryExampleTable.java @@ -0,0 +1,262 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.logging.Level; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.LogService; + + +/** + * This class is the core data supplier for example sets. Several example sets can use the same data + * and access the attribute values by reference. In this case the data is hold in the main memory + * during the process. + * + * @author Ingo Mierswa + */ +public class MemoryExampleTable extends AbstractExampleTable { + + private static final long serialVersionUID = -3000023475208774934L; + + /** List of {@link DataRow}s. */ + private List dataList = new ArrayList(); + + /** Number of columns. */ + private int columns; + + /** Number of columns to add when new columns are allocated. */ + private static final int INCREMENT = 10; + + /** + * Creates a new instance of MemoryExampleTable. + * + * @param attributes + * Array of {@link Attribute} containing the attributes of the columns. None of these + * must be null. + */ + public MemoryExampleTable(Attribute... attributes) { + this(Arrays.asList(attributes)); + } + + /** + * Creates a new instance of MemoryExampleTable. + * + * @param attributes + * List of {@link Attribute} containing the attributes of the columns. None of these + * must be null. + */ + public MemoryExampleTable(List attributes) { + super(attributes); + this.columns = attributes.size(); + } + + /** + * Creates a new instance of MemoryExampleTable. + * + * @param attributes + * List of {@link Attribute} containing the attributes of the columns. None of these + * must be null. + * @param size + * initial size of this example table. All values will be Double.NaN. + */ + public MemoryExampleTable(List attributes, DataRowFactory factory, int size) { + this(attributes); + dataList = new ArrayList(size); + for (int i = 0; i < size; i++) { + DataRow dataRow = factory.create(attributes.size()); + for (Attribute attribute : attributes) { + dataRow.set(attribute, Double.NaN); + } + dataList.add(dataRow); + } + } + + /** + * Creates an empty memory example table and fills it with the data rows read from i. + */ + public MemoryExampleTable(List attributes, DataRowReader i) { + this(attributes, i, false); + } + + /** + * Creates an empty memory example table and fills it with the data rows read from i. + */ + public MemoryExampleTable(List attributes, DataRowReader i, boolean permute) { + this(attributes); + readExamples(i, permute); + } + + /** + * Reads the examples into memory in the order they are delivered by the given reader. Removes + * all old data rows first. + */ + public void readExamples(DataRowReader i) { + readExamples(i, false); + } + + /** + * Reads the examples into memory and permutes the order. Removes all old data rows first. + */ + public void readExamples(DataRowReader i, boolean permute) { + readExamples(i, permute, null); + } + + /** + * Reads the examples into memory and permutes the order. Removes all old data rows first. + */ + public void readExamples(DataRowReader i, boolean permute, Random random) { + dataList.clear(); + while (i.hasNext()) { + if (permute) { + if (random == null) { + random = new Random(); + } + int index = random.nextInt(dataList.size() + 1); + dataList.add(index, i.next()); + } else { + dataList.add(i.next()); + } + } + } + + /** Returns a new data row reader. */ + @Override + public DataRowReader getDataRowReader() { + return new ListDataRowReader(dataList.iterator()); + } + + /** Returns the data row with the given index. */ + @Override + public DataRow getDataRow(int index) { + return dataList.get(index); + } + + /** Returns the size of this example table, i.e. the number of data rows. */ + @Override + public int size() { + return dataList.size(); + } + + /** + * Convenience method allowing the adding of data rows without a data row reader. This will trim + * the data row before to save memory. + */ + public void addDataRow(DataRow dataRow) { + dataRow.trim(); + dataList.add(dataRow); + + // this has to be called in order to make sure, the row matches the current column count. + dataRow.ensureNumberOfColumns(columns); + } + + /** Convenience method for removing data rows. */ + public boolean removeDataRow(DataRow dataRow) { + return dataList.remove(dataRow); + } + + /** Convenience method for removing data rows. */ + public DataRow removeDataRow(int index) { + return dataList.remove(index); + } + + /** Clears the table. */ + public void clear() { + dataList.clear(); + } + + /** + * Adds all {@link Attribute}s in newAttributes to the end of the list of + * attributes, creating new data columns if necessary. This method is much faster than calling + * repeatedly addAttribute, because this would cause the data rows to be enlarged and hence + * copied many times. + */ + @Override + public void addAttributes(Collection newAttributes) { + if (dataList != null) { + if (getNumberOfAttributes() + newAttributes.size() > columns) { + columns = getNumberOfAttributes() + newAttributes.size(); + Iterator i = dataList.iterator(); + while (i.hasNext()) { + i.next().ensureNumberOfColumns(columns); + } + } + } + // adding attributes + Iterator i = newAttributes.iterator(); + while (i.hasNext()) { + addAttribute(i.next()); + } + } + + /** + * Adds a new attribute to this example table by invoking the super method. If the number of + * attributes reaches a threshold, the number of attributes is increased by INCREMENT + * attributes. This avoids a large number of array copies in cases like automatic feature + * construction etc. + */ + @Override + public synchronized int addAttribute(Attribute attribute) { + int index = super.addAttribute(attribute); + if (dataList == null) { + return index; + } + int n = getNumberOfAttributes(); + if (n <= columns) { + return index; + } + int newSize = n + INCREMENT; + LogService.getRoot().log(Level.FINE, "com.rapidminer.example.table.MemoryExampleTable.rezising_example_table", + new Object[] { columns, newSize }); + columns = newSize; + + if (dataList != null) { + Iterator i = dataList.iterator(); + while (i.hasNext()) { + i.next().ensureNumberOfColumns(columns); + } + } + return index; + } + + public static MemoryExampleTable createCompleteCopy(ExampleTable oldTable) { + MemoryExampleTable table = new MemoryExampleTable(Arrays.asList(oldTable.getAttributes())); + DataRowReader reader = oldTable.getDataRowReader(); + while (reader.hasNext()) { + DataRow dataRow = reader.next(); + double[] newDataRowData = new double[oldTable.getNumberOfAttributes()]; + for (int a = 0; a < oldTable.getNumberOfAttributes(); a++) { + Attribute attribute = oldTable.getAttribute(a); + if (attribute != null) { + newDataRowData[a] = dataRow.get(attribute); + } else { + newDataRowData[a] = Double.NaN; + } + } + table.addDataRow(new DoubleArrayDataRow(newDataRowData)); + } + return table; + } +} diff --git a/src/main/java/com/rapidminer/example/table/NominalAttribute.java b/src/main/java/com/rapidminer/example/table/NominalAttribute.java new file mode 100644 index 000000000..3f4af9659 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/NominalAttribute.java @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.NominalStatistics; +import com.rapidminer.example.UnknownStatistics; +import com.rapidminer.tools.Tools; + + +/** + * This class holds all information on a single nominal attribute. In addition to the generic + * attribute fields this class keeps information about the nominal values and the value to index + * mappings. If one of the methods designed for numerical attributes was invoked a RuntimeException + * will be thrown. + * + * It will be guaranteed that all values are mapped to indices without any missing values. This + * could, however, be changed in future versions thus operators should not rely on this fact. + * + * @author Ingo Mierswa Exp $ + */ +public abstract class NominalAttribute extends AbstractAttribute { + + private static final long serialVersionUID = -3830980883541763869L; + + protected NominalAttribute(String name, int valueType) { + super(name, valueType); + registerStatistics(new NominalStatistics()); + registerStatistics(new UnknownStatistics()); + } + + protected NominalAttribute(NominalAttribute other) { + super(other); + } + + @Override + public boolean isNominal() { + return true; + } + + @Override + public boolean isNumerical() { + return false; + } + + /** + * Returns a string representation and maps the value to a string if type is nominal. The number + * of digits is ignored. + */ + @Override + public String getAsString(double value, int digits, boolean quoteNominal) { + if (Double.isNaN(value)) { + return "?"; + } else { + try { + String result = getMapping().mapIndex((int) value); + if (quoteNominal) { + result = Tools.escape(result); + result = "\"" + result + "\""; + } + return result; + } catch (Throwable e) { + return "?"; + } + } + } +} diff --git a/src/main/java/com/rapidminer/example/table/NominalMapping.java b/src/main/java/com/rapidminer/example/table/NominalMapping.java new file mode 100644 index 000000000..8dbaceb40 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/NominalMapping.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Example; + +import java.io.Serializable; +import java.util.List; + + +/** + * This class is used to map between the nominal values for a certain attribute and the internal + * double value representations which is used for nominal values in order to reduce memory usage. + * + * @author Ingo Mierswa + */ +public interface NominalMapping extends Cloneable, Serializable { + + /** + * This should return true if all the mappings contain the same values regardless of their + * internal order. + */ + public boolean equals(NominalMapping mapping); + + /** Should return a deep clone of this nominal mapping. */ + public Object clone(); + + /** + * Returns the index of a positive class (if available). Returns -1 otherwise. + */ + public int getPositiveIndex(); + + /** + * Returns the nominal value of a positive class (if available). Returns null otherwise. + */ + public String getPositiveString(); + + /** + * Returns the index of a negative class (if available). Returns -1 otherwise. + */ + public int getNegativeIndex(); + + /** + * Returns the nominal value of a negative class (if available). Returns null otherwise. + */ + public String getNegativeString(); + + /** + * Returns the internal double representation (actually an integer index) for the given nominal + * value without creating a mapping if none exists. + * + * @return the integer of the index or -1 if no mapping for this value exists + */ + public int getIndex(String nominalValue); + + /** + * Returns the internal double representation (actually an integer index) for the given nominal + * value. This method creates a mapping if it did not exist before. + */ + public int mapString(String nominalValue); + + /** + * Returns the nominal value for an internal double representation (actually an integer index). + * This method only works for nominal values which were formerly mapped via + * {@link #mapString(String)}. + */ + public String mapIndex(int index); + + /** + * Sets the given mapping. This might be practical for example for replacing a nominal value + * (without a data scan!). + */ + public void setMapping(String nominalValue, int index); + + /** + * Returns a list of all nominal values which were mapped via {@link #mapString(String)} until + * now. + */ + public List getValues(); + + /** + * Returns the number of different nominal values which were mapped via + * {@link #mapString(String)} until now. + */ + public int size(); + + /** + * This method rearranges the string to number mappings such that they are in alphabetical + * order.
    + * VERY IMPORTANT NOTE: Do not call this method when this attribute is already associated + * with an {@link AbstractExampleTable} and it already contains {@link Example}s. All examples + * will be messed up otherwise! + */ + public void sortMappings(); + + /** Clears the mapping. */ + public void clear(); + +} diff --git a/src/main/java/com/rapidminer/example/table/NonWritableDataRow.java b/src/main/java/com/rapidminer/example/table/NonWritableDataRow.java new file mode 100644 index 000000000..591bb184f --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/NonWritableDataRow.java @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * This data row can be wrapped around another data row (delegate) in order to prevent writing + * access. This might be useful, for example, for database access. + * + * @author Ingo Mierswa + */ +public class NonWritableDataRow extends DataRow { + + private static final long serialVersionUID = 6148646678312194050L; + + private DataRow delegate; + + public NonWritableDataRow(DataRow delegate) { + this.delegate = delegate; + } + + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + this.delegate.ensureNumberOfColumns(numberOfColumns); + } + + @Override + protected double get(int index, double defaultValue) { + return delegate.get(index, defaultValue); + } + + @Override + protected void set(int index, double value, double defaultValue) { + throw new UnsupportedOperationException( + "The 'set' operation (writing data) is not supported for this type of underlying example tables, e.g. it is not supported for a data table backed up by a database. Please transform into a memory based data table first, for example with the batch processing operator, or materialize the data table in memory."); + } + + @Override + public String toString() { + return delegate.toString(); + } + + @Override + public void trim() { + delegate.trim(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_SPECIAL; + } +} diff --git a/src/main/java/com/rapidminer/example/table/NumericalAttribute.java b/src/main/java/com/rapidminer/example/table/NumericalAttribute.java new file mode 100644 index 000000000..92c09acc3 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/NumericalAttribute.java @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.MinMaxStatistics; +import com.rapidminer.example.NumericalStatistics; +import com.rapidminer.example.UnknownStatistics; +import com.rapidminer.example.WeightedNumericalStatistics; +import com.rapidminer.tools.Ontology; + + +/** + * This class holds all information on a single numerical attribute. In addition to the information + * of the superclass this is some statistics data like minimum, maximum and average of the values. + * + * @author Ingo Mierswa + */ +public class NumericalAttribute extends AbstractAttribute { + + private static final long serialVersionUID = -7425486508057529570L; + + /** + * Indicates the default number of fraction digits which is defined by the system property + * rapidminer.gui.fractiondigits.numbers. + */ + public static final int DEFAULT_NUMBER_OF_DIGITS = -1; + + /** Indicates an unlimited number of fraction digits. */ + public static final int UNLIMITED_NUMBER_OF_DIGITS = -2; + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + */ + protected NumericalAttribute(String name) { + this(name, Ontology.NUMERICAL); + } + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + */ + /* pp */NumericalAttribute(String name, int valueType) { + super(name, valueType); + registerStatistics(new NumericalStatistics()); + registerStatistics(new WeightedNumericalStatistics()); + registerStatistics(new MinMaxStatistics()); + registerStatistics(new UnknownStatistics()); + } + + /** + * Clone constructor. + */ + private NumericalAttribute(NumericalAttribute a) { + super(a); + } + + /** Clones this attribute. */ + @Override + public Object clone() { + return new NumericalAttribute(this); + } + + @Override + public boolean isNominal() { + return false; + } + + @Override + public boolean isNumerical() { + return true; + } + + @Override + public NominalMapping getMapping() { + throw new UnsupportedOperationException( + "The method getNominalMapping() is not supported by numerical attributes! You probably tried to execute an operator on a numerical data which is only able to handle nominal values. You could use one of the discretization operators before this application."); + } + + /** Does nothing. */ + @Override + public void setMapping(NominalMapping mapping) {} + + /** + * Returns a string representation of value. If the numberOfDigits is greater than 0 this number + * is used to format the string. Otherwise the value of the system property + * rapidminer.gui.fractiondigits.numbers will be used (see {@link com.rapidminer.tools.Tools} in + * case of DEFAULT_NUMBER_OF_DIGITS or an unlimited number of digits in case of + * UNLIMITED_NUMBER_OF_DIGITS. For the value NaN a "?" will be returned. + */ + @Override + public String getAsString(double value, int numberOfDigits, boolean quoteNominal) { + if (Double.isNaN(value)) { + return "?"; + } else { + switch (numberOfDigits) { + case UNLIMITED_NUMBER_OF_DIGITS: + return Double.toString(value); + case DEFAULT_NUMBER_OF_DIGITS: + return com.rapidminer.tools.Tools.formatIntegerIfPossible(value, -1); + default: + return com.rapidminer.tools.Tools.formatIntegerIfPossible(value, numberOfDigits); + } + } + } + + @Override + public boolean isDateTime() { + return false; + } +} diff --git a/src/main/java/com/rapidminer/example/table/PolynominalAttribute.java b/src/main/java/com/rapidminer/example/table/PolynominalAttribute.java new file mode 100644 index 000000000..909853fc0 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/PolynominalAttribute.java @@ -0,0 +1,120 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.tools.Ontology; + +import java.util.Iterator; + + +/** + * This class holds all information on a single nominal attribute. In addition to the generic + * attribute fields this class keeps information about the nominal values and the value to index + * mappings. If one of the methods designed for numerical attributes was invoked a RuntimeException + * will be thrown. + * + * It will be guaranteed that all values are mapped to indices without any missing values. This + * could, however, be changed in future versions thus operators should not rely on this fact. + * + * This class is one of the two available implementations of {@link NominalAttribute} available in + * RapidMiner. In contrast to the {@link BinominalAttribute}, which stores the possible values + * internally very efficient, this class allows an arbitrary number of nominal values and uses a + * {@link PolynominalMapping} for the internal representation mapping. + * + * @author Ingo Mierswa Exp $ + */ +public class PolynominalAttribute extends NominalAttribute { + + private static final long serialVersionUID = 3713022530244256813L; + + /** The maximum number of nominal values displayed in result strings. */ + private static final int MAX_NUMBER_OF_SHOWN_NOMINAL_VALUES = 100; + + private NominalMapping nominalMapping = new PolynominalMapping(); + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + */ + /* pp */PolynominalAttribute(String name) { + this(name, Ontology.NOMINAL); + } + + /** + * Creates a simple attribute which is not part of a series and does not provide a unit string. + */ + /* pp */PolynominalAttribute(String name, int valueType) { + super(name, valueType); + } + + /** + * Clone constructor. + */ + private PolynominalAttribute(PolynominalAttribute a) { + super(a); + // this.nominalMapping = (NominalMapping)a.nominalMapping.clone(); + this.nominalMapping = a.nominalMapping; + } + + /** Clones this attribute. */ + @Override + public Object clone() { + return new PolynominalAttribute(this); + } + + @Override + public NominalMapping getMapping() { + return this.nominalMapping; + } + + @Override + public void setMapping(NominalMapping newMapping) { + this.nominalMapping = new PolynominalMapping(newMapping); + } + + // ================================================================================ + // string and result methods + // ================================================================================ + + @Override + public String toString() { + StringBuffer result = new StringBuffer(super.toString()); + result.append("/values=["); + Iterator i = this.nominalMapping.getValues().iterator(); + int index = 0; + while (i.hasNext()) { + if (index >= MAX_NUMBER_OF_SHOWN_NOMINAL_VALUES) { + result.append(", ... (" + (this.nominalMapping.getValues().size() - MAX_NUMBER_OF_SHOWN_NOMINAL_VALUES) + + " values) ..."); + break; + } + if (index != 0) { + result.append(", "); + } + result.append(i.next()); + index++; + } + result.append("]"); + return result.toString(); + } + + @Override + public boolean isDateTime() { + return false; + } +} diff --git a/src/main/java/com/rapidminer/example/table/PolynominalMapping.java b/src/main/java/com/rapidminer/example/table/PolynominalMapping.java new file mode 100644 index 000000000..d4fb00fc9 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/PolynominalMapping.java @@ -0,0 +1,252 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import com.rapidminer.example.AttributeTypeException; +import com.rapidminer.example.Example; +import com.rapidminer.tools.Tools; + + +/** + * This is an implementation of {@link NominalMapping} which can be used for nominal attributes with + * an arbitrary number of different values. + * + * @author Ingo Mierswa + */ +public class PolynominalMapping implements NominalMapping { + + private static final long serialVersionUID = 5021638750496191771L; + + /** The map between symbolic values and their indices. */ + private final Map symbolToIndexMap = new HashMap<>(); + + /** The map between indices of nominal values and the actual nominal value. */ + private final List indexToSymbolMap = new ArrayList<>(); + + public PolynominalMapping() {} + + public PolynominalMapping(Map map) { + this.symbolToIndexMap.clear(); + this.indexToSymbolMap.clear(); + for (Map.Entry entry : map.entrySet()) { + int index = entry.getKey(); + String value = entry.getValue(); + this.symbolToIndexMap.put(value, index); + while (this.indexToSymbolMap.size() <= index) { + this.indexToSymbolMap.add(null); + } + this.indexToSymbolMap.set(index, value); + } + } + + /* pp */PolynominalMapping(NominalMapping mapping) { + this.symbolToIndexMap.clear(); + this.indexToSymbolMap.clear(); + for (int i = 0; i < mapping.size(); i++) { + int index = i; + String value = mapping.mapIndex(index); + this.symbolToIndexMap.put(value, index); + this.indexToSymbolMap.add(value); + } + } + + @Override + public Object clone() { + return new PolynominalMapping(this); + } + + @Override + public boolean equals(NominalMapping mapping) { + if (mapping.size() != size()) { + return false; + } + for (String value : mapping.getValues()) { + if (!symbolToIndexMap.containsKey(value)) { + return false; + } + } + return true; + } + + /** + * Returns the index for the nominal attribute value str. If the string is unknown, + * a new index value is assigned. Returns -1, if str is null. + */ + @Override + public int mapString(String str) { + if (str == null) { + return -1; + } + // lookup string in hashtable + int index = getIndex(str); + // if string is not yet in the map, add it + if (index < 0) { + // new string -> insert + str = new String(str); // we copy the name if the underlying char array value is larger + // than needed + indexToSymbolMap.add(str); + index = indexToSymbolMap.size() - 1; + symbolToIndexMap.put(str, index); + } + return index; + } + + /** + * Returns the index of the given nominal value or -1 if this value was not mapped before by + * invoking the method {@link #mapIndex(int)}. + */ + @Override + public int getIndex(String str) { + Integer index = symbolToIndexMap.get(str); + if (index == null) { + return -1; + } else { + return index.intValue(); + } + } + + /** + * Returns the attribute value, that is associated with this index. Index counting starts with + * 0. WARNING: In order to iterate over all values please use the collection returned by + * {@link #getValues()}. + */ + @Override + public String mapIndex(int index) { + if (index < 0 || index >= indexToSymbolMap.size()) { + throw new AttributeTypeException("Cannot map index of nominal attribute to nominal value: index " + index + + " is out of bounds!"); + } + return indexToSymbolMap.get(index); + } + + /** + * Sets the given mapping. Please note that this will overwrite existing mappings and might + * cause data changes in this way. + */ + @Override + public void setMapping(String nominalValue, int index) { + String oldValue = indexToSymbolMap.get(index); + indexToSymbolMap.set(index, nominalValue); + symbolToIndexMap.remove(oldValue); + symbolToIndexMap.put(nominalValue, index); + } + + /** + * Returns the index of the first value if this attribute is a classification attribute, i.e. if + * it is binominal. + */ + @Override + public int getNegativeIndex() { + ensureClassification(); + if (mapIndex(0) == null) { + throw new AttributeTypeException("Attribute: Cannot use FIRST_CLASS_INDEX for negative class!"); + } + return 0; + } + + /** + * Returns the index of the second value if this attribute is a classification attribute. Works + * for all binominal attributes. + */ + @Override + public int getPositiveIndex() { + ensureClassification(); + if (mapIndex(0) == null) { + throw new AttributeTypeException("Attribute: Cannot use FIRST_CLASS_INDEX for negative class!"); + } + Iterator i = symbolToIndexMap.values().iterator(); + while (i.hasNext()) { + int index = i.next(); + if (index != 0) { + return index; + } + } + throw new AttributeTypeException("Attribute: No other class than FIRST_CLASS_INDEX found!"); + } + + @Override + public String getNegativeString() { + return mapIndex(getNegativeIndex()); + } + + @Override + public String getPositiveString() { + return mapIndex(getPositiveIndex()); + } + + /** Returns the values of the attribute as an enumeration of strings. */ + @Override + public List getValues() { + return indexToSymbolMap; + } + + /** Returns the number of different nominal values. */ + @Override + public int size() { + return indexToSymbolMap.size(); + } + + /** + * This method rearranges the string to number mappings such that they are in alphabetical + * order.
    + * VERY IMPORTANT NOTE: Do not call this method when this attribute is already associated + * with an {@link ExampleTable} and it already contains {@link Example}s. All examples will be + * messed up since the indices will not be replaced in the data table. + */ + @Override + public void sortMappings() { + List allStrings = new LinkedList<>(symbolToIndexMap.keySet()); + Collections.sort(allStrings); + symbolToIndexMap.clear(); + indexToSymbolMap.clear(); + Iterator i = allStrings.iterator(); + while (i.hasNext()) { + mapString(i.next()); + } + } + + /** Clears all mappings for nominal values. */ + @Override + public void clear() { + symbolToIndexMap.clear(); + indexToSymbolMap.clear(); + } + + /** + * Throws a runtime exception if this attribute is not a classification attribute. + */ + private void ensureClassification() { + if (size() != 2) { + throw new AttributeTypeException("Attribute " + this.toString() + " is not a classification attribute!"); + } + } + + @Override + public String toString() { + return indexToSymbolMap.toString() + Tools.getLineSeparator() + symbolToIndexMap.toString(); + } +} diff --git a/src/main/java/com/rapidminer/example/table/RandomDataRowReader.java b/src/main/java/com/rapidminer/example/table/RandomDataRowReader.java new file mode 100644 index 000000000..fe215d838 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/RandomDataRowReader.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Statistics; +import com.rapidminer.tools.RandomGenerator; + + +/** + * Create data rows based on random data in the range of the minimum and maximum values of the + * attributes of the given base example set. + * + * @author Ingo Mierswa Exp $ + */ +public class RandomDataRowReader extends AbstractDataRowReader { + + private int size; + + private ExampleSet baseExampleSet; + + private Attribute[] attributes; + + private int counter = 0; + + public RandomDataRowReader(ExampleSet baseExampleSet, Attribute[] attributes, int size) { + super(new DataRowFactory(DataRowFactory.TYPE_DOUBLE_ARRAY, '.')); + this.baseExampleSet = baseExampleSet; + this.attributes = attributes; + this.size = size; + } + + @Override + public boolean hasNext() { + return (counter < size); + } + + @Override + public DataRow next() { + RandomGenerator random = RandomGenerator.getGlobalRandomGenerator(); + double[] data = new double[attributes.length]; + for (int i = 0; i < data.length; i++) { + double min = baseExampleSet.getStatistics(attributes[i], Statistics.MINIMUM); + double max = baseExampleSet.getStatistics(attributes[i], Statistics.MAXIMUM); + data[i] = random.nextDoubleInRange(min, max); + } + return new DoubleArrayDataRow(data); + } +} diff --git a/src/main/java/com/rapidminer/example/table/RandomExampleTable.java b/src/main/java/com/rapidminer/example/table/RandomExampleTable.java new file mode 100644 index 000000000..f008c568c --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/RandomExampleTable.java @@ -0,0 +1,72 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Statistics; +import com.rapidminer.tools.RandomGenerator; + +import java.util.List; + + +/** + * This class is used for example sets which should provide random values for the given attributes, + * i.e. each random value lies in the same range as values of the given attributes (min and max) of + * the base example set. Please note that the attributes must already have proper minimum and + * maximum values. The random values are constructed by a {@link RandomDataRowReader}. + * + * @author Ingo Mierswa Exp $ + */ +public class RandomExampleTable extends AbstractExampleTable { + + private static final long serialVersionUID = 5675878166499224680L; + + private ExampleSet baseExampleSet; + + private int size; + + public RandomExampleTable(ExampleSet baseExampleSet, List attributes, int size) { + super(attributes); + this.baseExampleSet = baseExampleSet; + this.size = size; + } + + @Override + public DataRowReader getDataRowReader() { + return new RandomDataRowReader(baseExampleSet, getAttributes(), size); + } + + @Override + public DataRow getDataRow(int index) { + RandomGenerator random = RandomGenerator.getGlobalRandomGenerator(); + double[] data = new double[size]; + for (int i = 0; i < data.length; i++) { + double min = baseExampleSet.getStatistics(getAttributes()[i], Statistics.MINIMUM); + double max = baseExampleSet.getStatistics(getAttributes()[i], Statistics.MAXIMUM); + data[i] = random.nextDoubleInRange(min, max); + } + return new DoubleArrayDataRow(data); + } + + @Override + public int size() { + return size; + } +} diff --git a/src/main/java/com/rapidminer/example/table/RapidMinerLineReader.java b/src/main/java/com/rapidminer/example/table/RapidMinerLineReader.java new file mode 100644 index 000000000..f7e974865 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/RapidMinerLineReader.java @@ -0,0 +1,158 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Tools; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.logging.Level; +import java.util.regex.Pattern; + + +/** + * A simple line converter for reading data from BufferedReaders. Each line is separated into + * columns using a pattern matcher based on regular expressions. In addition, comments might be also + * defined. Everything after a comment character is completely ignored. + * + * Quotes might also be used. If a columns starts with a quote (") the end of the quoted region + * is searched and the corresponding columns build a new column which replaces the old ones. Quoting + * is added for compatibility reasons only. Since parsing is slower if quoting is used, quotes + * should not be used at all. If possible please use and define a column separator which is not part + * of your data. + * + * @author Ingo Mierswa + */ +public class RapidMinerLineReader { + + /** A regular expression pattern which is used for splitting the columns. */ + private Pattern separatorPattern; + + /** The possible character for comment lines. */ + private String[] commentChars = null; + + /** Indicates if quotes should be regarded (slower!). */ + private boolean useQuotes = false; + + /** The character used for quoting. */ + private char quoteChar = '"'; + + /** The character used for escaping the quotes. */ + private char escapeChar = '\\'; + + /** Indicates if lines should be trimmed before they are splitted into columns. */ + private boolean trimLines = false; + + /** The current line number. */ + private int lineNumber = 1; + + /** Indicates if error lines should be skipped or if an error should occur. */ + private boolean skipErrorLines; + + /** Indicates if quoting (") can be used to form. */ + public RapidMinerLineReader(String separatorsRegExpr, char[] commentChars, boolean useQuotes, char quoteChar, + char escapeChar, boolean trimLines, boolean skipErrorLines) { + this.separatorPattern = Pattern.compile(separatorsRegExpr); + if (commentChars != null) { + this.commentChars = new String[commentChars.length]; + for (int i = 0; i < commentChars.length; i++) { + this.commentChars[i] = Character.toString(commentChars[i]); + } + } + this.useQuotes = useQuotes; + this.quoteChar = quoteChar; + this.escapeChar = escapeChar; + this.trimLines = trimLines; + this.skipErrorLines = skipErrorLines; + } + + /** + * Ignores comment and empty lines and returns the first line not starting with a comment. + * Returns null if no such line exists. Throws an IOException if the line does not provide the + * given expected number of columns. This check will not be performed if the given parameter + * value is -1. + */ + public String[] readLine(BufferedReader in, int expectedNumberOfColumns) throws IOException { + String line = null; + while (line == null) { + line = in.readLine(); + if (line == null) { + break; // eof + } + + if (trimLines) { + line = line.trim(); + } + + // check for comments + if (commentChars != null) { + for (int c = 0; c < commentChars.length; c++) { + if (line.indexOf(commentChars[c]) >= 0) { + line = line.substring(0, line.indexOf(commentChars[c])); + } + } + } + // comment or empty line --> next line + if (line.trim().length() == 0) { + line = null; + } + } + if (line == null) { + return null; + } + + String[] columns = null; + if (useQuotes) { + columns = Tools.quotedSplit(line, separatorPattern, quoteChar, escapeChar); + } else { + columns = separatorPattern.split(line, -1); + } + if (expectedNumberOfColumns != -1) { + if (columns.length < expectedNumberOfColumns) { + if (skipErrorLines) { + // LogService.getGlobal().log("Possible data format error: line " + lineNumber + + // " did not provide the expected number of columns (was: " + columns.length + + // ", expected: " + expectedNumberOfColumns + + // "), skip line...", LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.table.RapidMinerLineReader.possible_data_format_error", + new Object[] { lineNumber, columns.length, expectedNumberOfColumns }); + return readLine(in, expectedNumberOfColumns); + } else { + throw new IOException("Data format error in line " + lineNumber + + ": the line does not provide the expected number of columns (was: " + columns.length + + ", expected: " + expectedNumberOfColumns + ")! Stop reading..."); + } + } else if (columns.length > expectedNumberOfColumns) { + // only a warning since this might be desired if the data should + // be loaded only partially + // LogService.getGlobal().log("Possible data format error: line " + lineNumber + + // " did not provide the expected number of columns (was: " + columns.length + + // ", expected: " + expectedNumberOfColumns + ")!", + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.example.table.RapidMinerLineReader.possible_data_format_error", + new Object[] { lineNumber, columns.length, expectedNumberOfColumns }); + } + } + lineNumber++; + return columns; + } +} diff --git a/src/main/java/com/rapidminer/example/table/ResultSetDataRowReader.java b/src/main/java/com/rapidminer/example/table/ResultSetDataRowReader.java new file mode 100644 index 000000000..198995fb3 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ResultSetDataRowReader.java @@ -0,0 +1,120 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.LogService; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; +import java.util.logging.Level; + + +/** + * Unlike a {@link FileDataRowReader} that reads examples from a file, objects of this class read + * examples from a {@link ResultSet}, a data structure that is returned from a database query. + * + * @see com.rapidminer.tools.jdbc.DatabaseHandler + * @see com.rapidminer.operator.io.DatabaseDataReader + * @see com.rapidminer.operator.io.KDBExampleSource + * @author Simon Fischer, Ingo Mierswa ingomierswa Exp $ + */ +public class ResultSetDataRowReader extends AbstractDataRowReader { + + private Attribute[] attributes; + + private ResultSet resultSet; + + private static final int DONT_KNOW_YET = 0; + + private static final int YES = 1; + + private static final int NO = 2; + + private int hasNext = DONT_KNOW_YET; + + /** + * Constructor. + * + * @param attributeList + * List of attributes + * @param resultSet + * A ResultSet as returned from a database query + */ + public ResultSetDataRowReader(DataRowFactory dataRowFactory, List attributeList, ResultSet resultSet) { + super(dataRowFactory); + this.resultSet = resultSet; + this.attributes = new Attribute[attributeList.size()]; + attributeList.toArray(this.attributes); + } + + @Override + public boolean hasNext() { + switch (hasNext) { + case YES: + return true; + case NO: + return false; + case DONT_KNOW_YET: + try { + if (resultSet.next()) { + hasNext = YES; + return true; + } else { + hasNext = NO; + resultSet.close(); + return false; + } + } catch (SQLException e) { + // LogService.getGlobal().logError("While reading examples from result set: " + + // e.getMessage()); + LogService + .getRoot() + .log(Level.SEVERE, + "com.rapidminer.example.table.ResultSetDataRowReader.error_while_reading_examples_from_result_set", + e.getMessage()); + return false; + } + default: + // impossible + return false; + } + } + + @Override + public DataRow next() { + if (hasNext()) { + hasNext = DONT_KNOW_YET; + try { + DataRow row = getFactory().create(attributes.length); + for (int i = 0; i < attributes.length; i++) { + double value = DatabaseDataRow.readColumn(resultSet, attributes[i]); + row.set(attributes[i], value); + } + row.trim(); + return row; + } catch (SQLException sqle) { + throw new RuntimeException("Error accessing the result of a query:" + sqle.toString()); + } + } else { + return null; + } + } +} diff --git a/src/main/java/com/rapidminer/example/table/ShortArrayDataRow.java b/src/main/java/com/rapidminer/example/table/ShortArrayDataRow.java new file mode 100644 index 000000000..727590155 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ShortArrayDataRow.java @@ -0,0 +1,83 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by a short array. Please note that using this data row + * is quite efficient but only non-floating numbers between -32,768 to 32,767 or the same number of + * nominal values for each column. + * + * @author Ingo Mierswa + */ +public class ShortArrayDataRow extends DataRow { + + private static final long serialVersionUID = -1839048476500092847L; + + /** Holds the data for all attributes. */ + private short[] data; + + /** Creates a new data row backed by an primitive array. */ + public ShortArrayDataRow(short[] data) { + this.data = data; + } + + /** Returns the desired data for the given index. */ + @Override + protected double get(int index, double defaultValue) { + return data[index]; + } + + /** Sets the given data for the given attribute. */ + @Override + protected void set(int index, double value, double defaultValue) { + data[index] = (short) value; + } + + /** + * Creates a new array of the given size if necessary and copies the data into the new array. + */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) { + if (data.length >= numberOfColumns) { + return; + } + short[] newData = new short[numberOfColumns]; + System.arraycopy(data, 0, newData, 0, data.length); + data = newData; + } + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + StringBuffer result = new StringBuffer(); + for (int i = 0; i < data.length; i++) { + result.append((i == 0 ? "" : ",") + data[i]); + } + return result.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_SHORT_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/ShortSparseArrayDataRow.java b/src/main/java/com/rapidminer/example/table/ShortSparseArrayDataRow.java new file mode 100644 index 000000000..e747893da --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ShortSparseArrayDataRow.java @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * Implementation of DataRow that is backed by primitive arrays. Should always be used if more than + * 50% of the data is sparse. As fast (or even faster than map implementation) but needs + * considerably less memory. This implementation uses short arrays instead of double arrays which + * will reduce the used memory even more. + * + * @author Ingo Mierswa, Shevek + */ +public class ShortSparseArrayDataRow extends AbstractSparseArrayDataRow { + + private static final long serialVersionUID = 1688504268820756726L; + + /** Stores the used attribute values. */ + private short[] values; + + /** Creates an empty sparse array data row with size 0. */ + public ShortSparseArrayDataRow() { + this(0); + } + + /** Creates a sparse array data row of the given size. */ + public ShortSparseArrayDataRow(int size) { + super(size); + values = new short[size]; + } + + /** + * Swaps x[a] with x[b]. + */ + @Override + protected void swapValues(int a, int b) { + short tt = values[a]; + values[a] = values[b]; + values[b] = tt; + } + + @Override + public void resizeValues(int length) { + short[] d = new short[length]; + System.arraycopy(values, 0, d, 0, Math.min(values.length, length)); + values = d; + } + + @Override + public void removeValue(int index) { + System.arraycopy(values, index + 1, values, index, (values.length - (index + 1))); + } + + /** Returns the desired data for the given attribute. */ + @Override + public double getValue(int index) { + return values[index]; + } + + /** Sets the given data for the given attribute. */ + @Override + public void setValue(int index, double v) { + values[index] = (short) v; + } + + @Override + protected double[] getAllValues() { + double[] result = new double[this.values.length]; + for (int i = 0; i < result.length; i++) { + result[i] = this.values[i]; + } + return result; + } + + @Override + public int getType() { + return DataRowFactory.TYPE_SHORT_SPARSE_ARRAY; + } +} diff --git a/src/main/java/com/rapidminer/example/table/SimpleArrayData.java b/src/main/java/com/rapidminer/example/table/SimpleArrayData.java new file mode 100644 index 000000000..c1f33bfb1 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/SimpleArrayData.java @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +/** + * The data is hold as string array. Objects of this type are used by the SimpleArrayDataRowReader. + * + * @author Ingo Mierswa + */ +public interface SimpleArrayData { + + public String[] getData(); + +} diff --git a/src/main/java/com/rapidminer/example/table/SimpleArrayDataRowReader.java b/src/main/java/com/rapidminer/example/table/SimpleArrayDataRowReader.java new file mode 100644 index 000000000..c92174b7f --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/SimpleArrayDataRowReader.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; + +import java.util.Iterator; + + +/** + * Creates a data row reader which uses an iterator over SimpleArrayData. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class SimpleArrayDataRowReader extends AbstractDataRowReader { + + private Iterator simpleData; + + private Attribute[] attributes; + + public SimpleArrayDataRowReader(DataRowFactory factory, Attribute[] attributes, Iterator simpleData) { + super(factory); + this.attributes = attributes; + this.simpleData = simpleData; + } + + @Override + public boolean hasNext() { + return simpleData.hasNext(); + } + + @Override + public DataRow next() { + return getFactory().create((simpleData.next()).getData(), attributes); + } +} diff --git a/src/main/java/com/rapidminer/example/table/SparseDataRow.java b/src/main/java/com/rapidminer/example/table/SparseDataRow.java new file mode 100644 index 000000000..3569b4712 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/SparseDataRow.java @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.FastExample2SparseTransform; + + +/** + * This interface defines methods for sparse data rows which might be implemented to allow more + * efficient querying of the non-default values. Please refer to {@link FastExample2SparseTransform} + * for further information. + * + * @author Ingo Mierswa + */ +public interface SparseDataRow { + + /** + * Returns an array of all attribute indices with corresponding non-default values. + */ + public int[] getNonDefaultIndices(); + + /** Returns an array of all non-default attribute values. */ + public double[] getNonDefaultValues(); +} diff --git a/src/main/java/com/rapidminer/example/table/SparseFormatDataRowReader.java b/src/main/java/com/rapidminer/example/table/SparseFormatDataRowReader.java new file mode 100644 index 000000000..dbbb0bde7 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/SparseFormatDataRowReader.java @@ -0,0 +1,307 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.att.AttributeSet; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + + +/** + * Reads the data rows in sparse format. The format is specified in the class comment of + * {@link com.rapidminer.operator.io.SparseFormatExampleSource}. {@link Attribute}s may be passed to + * the reader in its constructor. If they are ommitted, they are generated on the fly. In either + * case, indices are assigned to the attributes. If an {@link AbstractExampleTable} is generated + * using instances of this class, the constructor of {@link AbstractExampleTable} will reassign + * these indexes. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class SparseFormatDataRowReader extends AbstractDataRowReader { + + /** Names of the formats. */ + public static final String[] FORMAT_NAMES = { "xy", "yx", "prefix", "separate_file", "no_label" }; + + /** Label succeeds attributes. */ + public static final int FORMAT_XY = 0; + + /** Label preceeds attributes. */ + public static final int FORMAT_YX = 1; + + /** Label has a prefix specified in the prefix map. */ + public static final int FORMAT_PREFIX = 2; + + /** Label is in separate file. */ + public static final int FORMAT_SEPARATE_FILE = 3; + + /** Label is missing. */ + public static final int FORMAT_NO_LABEL = 4; + + /** Reader for the labels. */ + private BufferedReader inAttributes, inLabels; + + /** The attribute set with regular and special attributes. */ + private AttributeSet attributeSet = null; + + /** Remember if an end of file has occured. */ + private boolean eof; + + /** Remember if a line has already been read. */ + private boolean lineRead; + + /** The maximum number of attributes to read. */ + private int maxNumber; + + /** Number of lines already read. */ + private int linesRead; + + /** The DataRow that will be returned in the next call to {@link #next()} */ + private DataRow currentDataRow; + + /** + * One out of FORMAT_XY, FORMAT_YX, FORMAT_PREFIX, FORMAT_SEPARATE_FILE, and FORMAT_NO_LABEL. + */ + private int format; + + /** + * The dimension of the examples, i.e. the total number of regular and special attributes. + */ + private int dimension; + + /** Maps prefixes to special attribute names, e.g. "l:" to "label". */ + private Map prefixMap = new HashMap(); + + private boolean useQuotesForNominalValues; + + private char quoteChar; + + /** + * Creates a new data row reader for sparse format. The attributes indices must not be set. If + * they are, they are reassigned new values when this constructor is called! + * + * @param factory + * Factory used to create {@link DataRow} instances. + * @param format + * One Out of FORMAT_XY, FORMAT_YX, FORMAT_PREFIX, and FORMAT_SEPARATE_FILE. + * @param prefixMap + * Maps prefixes to special attribute names (e.g. "l" to + * "label"). + * @param attributeSet + * Set of regular and special attributes. + * @param attributeReader + * Reader for the data + * @param labelReader + * Reader for the labels. Only necessary if format is FORMAT_SEPARATE_FILE. + * @param sampleSize + * sample size, may be -1 for no limit. + * + * @param useQuotesForNominalValues + * Determines whether nominal values are surrounded by quotes or not. If + * useQuotesForNominalValues == true the first and last character of the + * nominal values are ignored. + * @param quoteChar + * The char that is used to surround nominal values. + */ + public SparseFormatDataRowReader(DataRowFactory factory, int format, Map prefixMap, + AttributeSet attributeSet, Reader attributeReader, Reader labelReader, int sampleSize, + boolean useQuotesForNominalValues, char quoteChar) { + super(factory); + this.format = format; + this.prefixMap = prefixMap; + this.attributeSet = attributeSet; + if (attributeSet == null) { + throw new IllegalArgumentException("AttributeSet must not be null."); + } + this.dimension = attributeSet.getAllAttributes().size(); + this.maxNumber = sampleSize; + this.inAttributes = new BufferedReader(attributeReader); + if (format == FORMAT_SEPARATE_FILE) { + if (labelReader == null) { + throw new IllegalArgumentException("labelReader must not be null if format is 'separate_file'!"); + } + this.inLabels = new BufferedReader(labelReader); + } + if (format != FORMAT_NO_LABEL) { + if (attributeSet.getSpecialAttribute("label") == null) { + throw new IllegalArgumentException("If format is not no_label, label attribute must be defined."); + } + } + this.useQuotesForNominalValues = useQuotesForNominalValues; + this.quoteChar = quoteChar; + } + + /** Checks if further examples exist. Returns false if one of the files end. */ + @Override + public boolean hasNext() { + if ((maxNumber > -1) && (linesRead >= maxNumber)) { + return false; + } + if (lineRead) { + return !eof; + } + try { + eof = !readLine(); + if (eof) { + inAttributes.close(); + if (inLabels != null) { + inLabels.close(); + } + } + } catch (IOException e) { + throw new RuntimeException(e.getMessage(), e); + } + lineRead = true; + return (!eof); + } + + private boolean readLine() throws IOException { + String attributeLine = null; + do { + attributeLine = inAttributes.readLine(); + if (attributeLine == null) { + return false; + } + } while (attributeLine.startsWith("#") || (attributeLine.length() == 0)); + + this.currentDataRow = getFactory().create(dimension); + + StringTokenizer tokenizer = new StringTokenizer(attributeLine); + + String labelString = null; + if (format == FORMAT_YX) { + labelString = tokenizer.nextToken(); + } else if (format == FORMAT_SEPARATE_FILE) { + do { + labelString = inLabels.readLine(); + if (labelString == null) { + return false; + } + } while (labelString.startsWith("#") || (labelString.length() == 0)); + } + + while (tokenizer.hasMoreTokens()) { + String attributeToken = tokenizer.nextToken(); + + int colonIndex = attributeToken.indexOf(':'); + if ((format == FORMAT_XY) && (colonIndex == -1)) { + if (labelString != null) { + throw new IOException("Malformed line in examplefile: " + attributeToken); + } else { + labelString = attributeToken; + } + } else { + String pos = attributeToken.substring(0, colonIndex);// references + // the + // attribute + String value = attributeToken.substring(colonIndex + 1); // the + // attribute + // value + Attribute attribute = null; // the referenced attribute + + try { + int index = Integer.parseInt(pos) - 1; + if ((index < 0) || (index >= attributeSet.getNumberOfRegularAttributes())) { + throw new IOException("Attribute index out of range: '" + (index + 1) + + "'! Index must be between 1 and dimension " + attributeSet.getNumberOfRegularAttributes() + + "!"); + } + attribute = attributeSet.getAttribute(index); + } catch (NumberFormatException e) { + String specialAttributeName = prefixMap.get(pos); + if (specialAttributeName == null) { + attribute = attributeSet.getSpecialAttribute(pos); + if (attribute == null) { + throw new IOException( + "Illegal attribute index: '" + + pos + + "' (legal values are integers and defined prefixes for special attributes (Parameter prefix_map of SparseFormatExampleSource))!"); + } + + } else { + attribute = attributeSet.getSpecialAttribute(specialAttributeName); + } + if (attribute == null) { + throw new IOException("Unknown special attribute: " + specialAttributeName); + } + } + + if (attribute != null) { + if (attribute.isNominal()) { + if (useQuotesForNominalValues) { + String quote = Character.toString(quoteChar); + if (value.startsWith(quote) && value.endsWith(quote)) { + value = value.substring(1, value.length() - 1); + } else { + throw new RuntimeException("The value ' " + value + + " ' does not start and end with a quote character ' " + quote + " '."); + } + Tools.unescape(value); + } + currentDataRow.set(attribute, attribute.getMapping().mapString(value)); + } else { + try { + currentDataRow.set(attribute, Double.parseDouble(value)); + } catch (NumberFormatException e) { + throw new IOException("Attribute is not numerical: '" + value + "'!"); + } + } + } + } + } + + if (labelString != null) { + Attribute label = attributeSet.getSpecialAttribute("label"); + if (label.isNominal()) { + currentDataRow.set(label, label.getMapping().mapString(labelString)); + } else { + try { + currentDataRow.set(label, Double.parseDouble(labelString)); + } catch (NumberFormatException e) { + throw new IOException("Label is not numerical: '" + labelString + "'."); + } + } + } + + currentDataRow.trim(); + return true; + } + + /** Returns the next Example. */ + @Override + public DataRow next() { + if (eof == true) { + return null; + } + if (!lineRead) { + if (!hasNext()) { + return null; + } + } + linesRead++; + lineRead = false; + return currentDataRow; + } +} diff --git a/src/main/java/com/rapidminer/example/table/SparseMapDataRow.java b/src/main/java/com/rapidminer/example/table/SparseMapDataRow.java new file mode 100644 index 000000000..0e2cd3b7c --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/SparseMapDataRow.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Tools; + +import java.util.HashMap; +import java.util.Map; + + +/** + * Implementation of DataRow that is backed by a HashMap. Usually using the + * {@link DoubleSparseArrayDataRow} should be more efficient. + * + * @author Ingo Mierswa + */ +public class SparseMapDataRow extends DataRow { + + private static final long serialVersionUID = -7452459295368606029L; + + /** Maps the indices of attributes to the data. */ + private Map data = new HashMap(); + + /** Returns the desired data for the given index. */ + @Override + protected double get(int index, double defaultValue) { + Double value = data.get(index); + if (value != null) { + return value.doubleValue(); + } else { + return defaultValue; + } + } + + /** Sets the given data for the given index. */ + @Override + protected void set(int index, double value, double defaultValue) { + if (Tools.isDefault(defaultValue, value)) { + data.remove(index); + } else { + data.put(index, value); + } + } + + /** Does nothing. */ + @Override + protected void ensureNumberOfColumns(int numberOfColumns) {} + + /** Does nothing. */ + @Override + public void trim() {} + + /** Returns a string representation of the data row. */ + @Override + public String toString() { + return data.toString(); + } + + @Override + public int getType() { + return DataRowFactory.TYPE_SPARSE_MAP; + } +} diff --git a/src/main/java/com/rapidminer/example/table/ViewAttribute.java b/src/main/java/com/rapidminer/example/table/ViewAttribute.java new file mode 100644 index 000000000..76fa1ea0a --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/ViewAttribute.java @@ -0,0 +1,165 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.example.table; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.MinMaxStatistics; +import com.rapidminer.example.NominalStatistics; +import com.rapidminer.example.NumericalStatistics; +import com.rapidminer.example.UnknownStatistics; +import com.rapidminer.example.WeightedNumericalStatistics; +import com.rapidminer.operator.ViewModel; +import com.rapidminer.tools.Ontology; + + +/** + * A view attribute is based on a ViewModel (Preprocessing Model) and applies the model on the fly. + * + * @author Sebastian Land + */ +public class ViewAttribute extends AbstractAttribute { + + private static final long serialVersionUID = -4075558616549596028L; + + private NominalMapping mapping; + + private boolean isNominal; + + private boolean isNumerical; + + private boolean isDateTime; + + private ViewModel model; + + private Attribute parent; + + protected ViewAttribute(ViewAttribute other) { + super(other); + if (other.mapping != null) { + this.mapping = (NominalMapping) other.mapping.clone(); + } + this.isNominal = other.isNominal; + this.isNumerical = other.isNumerical; + this.isDateTime = other.isDateTime(); + this.model = other.model; + if (other.parent != null) { + this.parent = (Attribute) other.parent.clone(); + } + } + + public ViewAttribute(ViewModel model, Attribute parent, String name, int valueType, NominalMapping mapping) { + super(name, valueType); + this.model = model; + this.mapping = mapping; + this.isNominal = mapping != null && Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NOMINAL); + this.isNumerical = Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.NUMERICAL); + this.isDateTime = Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.DATE_TIME) + || Ontology.ATTRIBUTE_VALUE_TYPE.isA(valueType, Ontology.DATE); + + this.parent = parent; + if (isNominal) { + registerStatistics(new NominalStatistics()); + registerStatistics(new UnknownStatistics()); + } else { + registerStatistics(new NumericalStatistics()); + registerStatistics(new WeightedNumericalStatistics()); + registerStatistics(new MinMaxStatistics()); + registerStatistics(new UnknownStatistics()); + } + } + + @Override + public double getValue(DataRow row) { + return model.getValue(this, row.get(parent)); + } + + @Override + public Object clone() { + return new ViewAttribute(this); + } + + @Override + public String getAsString(double value, int numberOfDigits, boolean quoteNominal) { + if (isNominal) { + if (Double.isNaN(value)) { + return "?"; + } else { + try { + String result = mapping.mapIndex((int) value); + if (quoteNominal) { + result = result.replaceAll("\"", "\\\\\""); + result = "\"" + result + "\""; + } + return result; + } catch (Throwable e) { + return "?"; + } + } + } else { + if (Double.isNaN(value)) { + return "?"; + } else { + switch (numberOfDigits) { + case NumericalAttribute.UNLIMITED_NUMBER_OF_DIGITS: + return Double.toString(value); + case NumericalAttribute.DEFAULT_NUMBER_OF_DIGITS: + return com.rapidminer.tools.Tools.formatIntegerIfPossible(value, -1); + default: + return com.rapidminer.tools.Tools.formatIntegerIfPossible(value, numberOfDigits); + } + } + } + + } + + @Override + public NominalMapping getMapping() { + return mapping; + } + + @Override + public boolean isNominal() { + return isNominal; + } + + @Override + public boolean isNumerical() { + return isNumerical; + } + + @Override + public void setMapping(NominalMapping nominalMapping) { + mapping = nominalMapping; + } + + @Override + public int getTableIndex() { + // return Attribute.VIEW_ATTRIBUTE_INDEX; + // TODO: is this correct? without parent index, this might lead to problems, + // e.g. for discretizations of the label inside of an AttributeSubsetPreprocessing + // (index of label is then -1) + return parent.getTableIndex(); + } + + @Override + public boolean isDateTime() { + // TODO Auto-generated method stub + return false; + } +} diff --git a/src/main/java/com/rapidminer/example/table/package.html b/src/main/java/com/rapidminer/example/table/package.html new file mode 100644 index 000000000..dea183db0 --- /dev/null +++ b/src/main/java/com/rapidminer/example/table/package.html @@ -0,0 +1,15 @@ + + + + + + + + +The available example table implementations (data sources). Please note that +an example set never contain any data. Several views can be stacked what we +call multi-layer data view concept. In this package you can find all classes +to define the sources for these views. + + + diff --git a/src/main/java/com/rapidminer/generator/AbsoluteValueGenerator.java b/src/main/java/com/rapidminer/generator/AbsoluteValueGenerator.java new file mode 100644 index 000000000..686220891 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/AbsoluteValueGenerator.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * This class has one numerical input attribute and one output attribute. Calculates the absolute + * value of the input attribute. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class AbsoluteValueGenerator extends SingularNumericalGenerator { + + public AbsoluteValueGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new AbsoluteValueGenerator(); + } + + @Override + public double calculateValue(double value) { + return Math.abs(value); + } + + @Override + public void setFunction(String name) { + if (!name.equals("abs")) { + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.AbsoluteValueGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + } + + @Override + public String getFunction() { + return "abs"; + } +} diff --git a/src/main/java/com/rapidminer/generator/AlgebraicOrGenerator.java b/src/main/java/com/rapidminer/generator/AlgebraicOrGenerator.java new file mode 100644 index 000000000..8a25ebab5 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/AlgebraicOrGenerator.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.tools.Ontology; + + +/** + * This class has two numerical input attributes and one output attribute. The result will be the + * algebraic or (s-norm) of the input attributes. + * + * @author Ingo Mierswa + */ +public class AlgebraicOrGenerator extends BinaryNumericalGenerator { + + public AlgebraicOrGenerator() {} + + @Override + public Attribute[] getOutputAttributes(ExampleTable input) { + Attribute a1 = getArgument(0); + Attribute a2 = getArgument(1); + Attribute ao = AttributeFactory.createAttribute(Ontology.NUMERICAL, Ontology.SINGLE_VALUE, + getFunction() + "(" + a1.getConstruction() + "," + a2.getConstruction() + ")"); + return new Attribute[] { ao }; + } + + @Override + public boolean isSelfApplicable() { + return false; + } + + @Override + public boolean isCommutative() { + return true; + } + + @Override + public FeatureGenerator newInstance() { + return new AlgebraicOrGenerator(); + } + + @Override + public double calculateValue(double value1, double value2) { + return (value1 + value2) - (value1 * value2); + } + + @Override + public void setFunction(String name) {} + + @Override + public String getFunction() { + return "algOr"; + } +} diff --git a/src/main/java/com/rapidminer/generator/AttributePeak.java b/src/main/java/com/rapidminer/generator/AttributePeak.java new file mode 100644 index 000000000..03fa4c610 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/AttributePeak.java @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.example.Attribute; + + +/** + * Helper class for attributes, their frequencies, and their evidences. + * + * @author Ingo Mierswa + */ +public class AttributePeak implements Comparable { + + private Attribute attribute; + + private double frequency; + + private double evidence; + + public AttributePeak(Attribute attribute, double frequency, double evidence) { + this.attribute = attribute; + this.frequency = frequency; + this.evidence = evidence; + } + + public Attribute getAttribute() { + return attribute; + } + + public double getFrequency() { + return frequency; + } + + public double getEvidence() { + return evidence; + } + + @Override + public int compareTo(AttributePeak p) { + return (-1) * Double.compare(this.evidence, p.evidence); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof AttributePeak)) { + return false; + } else { + AttributePeak peak = (AttributePeak) o; + return (this.attribute.equals(peak.attribute)) && (this.frequency == peak.frequency); + } + } + + @Override + public int hashCode() { + return this.attribute.hashCode() ^ Double.valueOf(this.frequency).hashCode(); + } +} diff --git a/src/main/java/com/rapidminer/generator/AverageGenerator.java b/src/main/java/com/rapidminer/generator/AverageGenerator.java new file mode 100644 index 000000000..674e4ddef --- /dev/null +++ b/src/main/java/com/rapidminer/generator/AverageGenerator.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.tools.Ontology; + + +/** + * This class has two numerical input attributes and one output attribute. The result will be the + * average of the input attributes. + * + * @author Ingo Mierswa + */ +public class AverageGenerator extends BinaryNumericalGenerator { + + public AverageGenerator() {} + + @Override + public Attribute[] getOutputAttributes(ExampleTable input) { + Attribute a1 = getArgument(0); + Attribute a2 = getArgument(1); + Attribute ao = AttributeFactory.createAttribute(Ontology.NUMERICAL, Ontology.SINGLE_VALUE, + getFunction() + "(" + a1.getConstruction() + "," + a2.getConstruction() + ")"); + return new Attribute[] { ao }; + } + + @Override + public boolean isSelfApplicable() { + return false; + } + + @Override + public boolean isCommutative() { + return true; + } + + @Override + public FeatureGenerator newInstance() { + return new AverageGenerator(); + } + + @Override + public double calculateValue(double value1, double value2) { + return (value1 + value2) / 2.0d; + } + + @Override + public void setFunction(String name) {} + + @Override + public String getFunction() { + return "avg"; + } +} diff --git a/src/main/java/com/rapidminer/generator/BasicArithmeticOperationGenerator.java b/src/main/java/com/rapidminer/generator/BasicArithmeticOperationGenerator.java new file mode 100644 index 000000000..afab09b78 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/BasicArithmeticOperationGenerator.java @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * This class is a very simple implementation of a FeatureGenerator. It has two numerical input + * attributes and one output attribute. Depending on the mode specified in the constructor the + * result will be the sum, difference, product or quotient. The four modes are numered from 0 to 3 + * int this order. + * + * @author Simon Fischer, Ingo Mierswa 15:35:40 ingomierswa Exp $ + */ +public class BasicArithmeticOperationGenerator extends BinaryNumericalGenerator { + + public static final int SUM = 0; + + public static final int DIFFERENCE = 1; + + public static final int PRODUCT = 2; + + public static final int QUOTIENT = 3; + + private static final String[] FUNCTION_NAMES = { "+", "-", "*", "/" }; + + private int mode; + + public BasicArithmeticOperationGenerator(int mode) { + this.mode = mode; + } + + public BasicArithmeticOperationGenerator() {} + + @Override + public boolean isSelfApplicable() { + return mode == PRODUCT; + } + + @Override + public boolean isCommutative() { + return ((mode == PRODUCT) || (mode == SUM)); + } + + @Override + public FeatureGenerator newInstance() { + return new BasicArithmeticOperationGenerator(mode); + } + + @Override + public double calculateValue(double o1, double o2) { + double r = 0.0d; + switch (mode) { + case SUM: + r = o1 + o2; + break; + case DIFFERENCE: + r = o1 - o2; + break; + case PRODUCT: + r = o1 * o2; + break; + case QUOTIENT: + r = o1 / o2; + break; + } + return r; + } + + @Override + public void setFunction(String name) { + for (int i = 0; i < FUNCTION_NAMES.length; i++) { + if (FUNCTION_NAMES[i].equals(name)) { + this.mode = i; + return; + } + } + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, + "com.rapidminer.generator.BasicArithmeticOperationGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + + @Override + public String getFunction() { + return FUNCTION_NAMES[mode]; + } + + @Override + public boolean equals(Object o) { + return (super.equals(o) && (this.mode == ((BasicArithmeticOperationGenerator) o).mode)); + } + + @Override + public int hashCode() { + return super.hashCode() ^ Integer.valueOf(mode).hashCode(); + } +} diff --git a/src/main/java/com/rapidminer/generator/BinaryNumericalGenerator.java b/src/main/java/com/rapidminer/generator/BinaryNumericalGenerator.java new file mode 100644 index 000000000..5b88c24b4 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/BinaryNumericalGenerator.java @@ -0,0 +1,207 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Ontology; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + + +/** + * Objects of this generator class have two numerical input attributes and one output attribute. + * + * @author Ingo Mierswa + */ +public abstract class BinaryNumericalGenerator extends FeatureGenerator { + + private static final Attribute[] INPUT_ATTR = { AttributeFactory.createAttribute(Ontology.NUMERICAL), + AttributeFactory.createAttribute(Ontology.NUMERICAL) }; + + public abstract double calculateValue(double value1, double value2); + + /** Must return true if this generator is commutative. */ + public abstract boolean isCommutative(); + + /** Must return true if this generator is self applicable. */ + public abstract boolean isSelfApplicable(); + + @Override + public Attribute[] getInputAttributes() { + return INPUT_ATTR; + } + + @Override + public Attribute[] getOutputAttributes(ExampleTable input) { + Attribute a1 = getArgument(0); + Attribute a2 = getArgument(1); + String construction1 = a1.getConstruction(); + if (!construction1.equals(a1.getName())) { + if (!construction1.startsWith("(") && !construction1.endsWith(")")) { + construction1 = "(" + construction1 + ")"; + } + } + String construction2 = a2.getConstruction(); + if (!construction2.equals(a2.getName())) { + if (!construction2.startsWith("(") && !construction2.endsWith(")")) { + construction2 = "(" + construction2 + ")"; + } + } + Attribute ao = AttributeFactory.createAttribute(Ontology.REAL, Ontology.SINGLE_VALUE, "(" + construction1 + " " + + getFunction() + " " + construction2 + ")"); + return new Attribute[] { ao }; + } + + /** + * Returns all compatible input attribute arrays for this generator from the given example set + * as list. + */ + @Override + public List getInputCandidates(ExampleSet exampleSet, String[] functions) { + List result = new ArrayList(); + if (getSelectionMode() == SELECTION_MODE_ALL) { + for (Attribute first : exampleSet.getAttributes()) { + if (!checkCompatibility(first, INPUT_ATTR[0], functions)) { + continue; + } + for (Attribute second : exampleSet.getAttributes()) { + if (checkCompatibility(second, INPUT_ATTR[1], functions)) { + result.add(new Attribute[] { first, second }); + } + } + } + } else { + if (isCommutative() && isSelfApplicable()) { + int firstCounter = 0; + for (Attribute first : exampleSet.getAttributes()) { + if (checkCompatibility(first, INPUT_ATTR[0], functions)) { + int secondCounter = 0; + for (Attribute second : exampleSet.getAttributes()) { + if (secondCounter >= firstCounter) { + if (checkCompatibility(second, INPUT_ATTR[1], functions)) { + result.add(new Attribute[] { first, second }); + } + } + secondCounter++; + } + } + firstCounter++; + } + } else if (isCommutative() && !isSelfApplicable()) { + int firstCounter = 0; + for (Attribute first : exampleSet.getAttributes()) { + if (checkCompatibility(first, INPUT_ATTR[0], functions)) { + int secondCounter = 0; + for (Attribute second : exampleSet.getAttributes()) { + if (secondCounter > firstCounter) { + if (checkCompatibility(second, INPUT_ATTR[1], functions)) { + result.add(new Attribute[] { first, second }); + } + } + secondCounter++; + } + } + firstCounter++; + } + } else if (!isCommutative() && isSelfApplicable()) { + for (Attribute first : exampleSet.getAttributes()) { + if (!checkCompatibility(first, INPUT_ATTR[0], functions)) { + continue; + } + for (Attribute second : exampleSet.getAttributes()) { + if (checkCompatibility(second, INPUT_ATTR[1], functions)) { + result.add(new Attribute[] { first, second }); + } + } + } + } else if (!isCommutative() && !isSelfApplicable()) { + int firstCounter = 0; + for (Attribute first : exampleSet.getAttributes()) { + if (checkCompatibility(first, INPUT_ATTR[0], functions)) { + int secondCounter = 0; + for (Attribute second : exampleSet.getAttributes()) { + if (firstCounter != secondCounter) { + if (checkCompatibility(second, INPUT_ATTR[1], functions)) { + result.add(new Attribute[] { first, second }); + } + } + secondCounter++; + } + } + firstCounter++; + } + } + } + return result; + } + + @Override + public void generate(DataRow data) throws GenerationException { + try { + Attribute a0 = getArgument(0); + Attribute a1 = getArgument(1); + double o1 = data.get(a0); + double o2 = data.get(a1); + double r = calculateValue(o1, o2); + + if (Double.isInfinite(r)) { + // LogService.getGlobal().log(getFunction() + ": Infinite value generated.", + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.generator.BinaryNumericalGenerator.infinite_value_generated", getFunction()); + } + if (Double.isNaN(r)) { + // LogService.getGlobal().log(getFunction() + ": NaN generated.", + // LogService.WARNING); + LogService.getRoot().log(Level.WARNING, "com.rapidminer.generator.BinaryNumericalGenerator.nan_generated", + getFunction()); + } + + if (resultAttributes[0] != null) { + data.set(resultAttributes[0], r); + } + } catch (ArrayIndexOutOfBoundsException ex) { + throw new GenerationException("a1:" + getArgument(0) + " a2: " + getArgument(1), ex); + } + } + + @Override + public String toString() { + String s = "binary function ("; + if ((resultAttributes != null) && (resultAttributes.length > 0) && (resultAttributes[0] != null)) { + s += resultAttributes[0].getName() + ":="; + } + if (argumentsSet()) { + s += getArgument(0).getName() + " "; + } + s += getFunction(); + if (argumentsSet()) { + s += " " + getArgument(1).getName(); + } + s += ")"; + return s; + } +} diff --git a/src/main/java/com/rapidminer/generator/ConstantGenerator.java b/src/main/java/com/rapidminer/generator/ConstantGenerator.java new file mode 100644 index 000000000..edf7745a9 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/ConstantGenerator.java @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.tools.Ontology; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Generates a constant attribute. The format is "const[value]()" for the + * {@link com.rapidminer.operator.features.construction.FeatureGenerationOperator} operator. + * + * @author Ingo Mierswa Exp $ + */ +public class ConstantGenerator extends FeatureGenerator { + + public static final String FUNCTION_NAME = "const"; + + private double constant = 1.0d; + + private String constantString = "1"; + + public ConstantGenerator() {} + + public ConstantGenerator(double constant) { + this.constant = constant; + this.constantString = constant + ""; + } + + @Override + public void setArguments(Attribute[] args) { + + } + + @Override + public FeatureGenerator newInstance() { + return new ConstantGenerator(); + } + + @Override + public String getFunction() { + return FUNCTION_NAME + "(" + constantString + ")"; + } + + @Override + public void setFunction(String functionName) { + int leftIndex = functionName.indexOf("("); + int rightIndex = functionName.indexOf(")"); + if ((leftIndex != -1) && (rightIndex != -1)) { + this.constantString = functionName.substring(leftIndex + 1, rightIndex); + this.constant = Double.parseDouble(constantString); + } + } + + @Override + public Attribute[] getInputAttributes() { + return new Attribute[0]; + } + + @Override + public Attribute[] getOutputAttributes(ExampleTable input) { + Attribute ao = AttributeFactory.createAttribute(Ontology.NUMERICAL, Ontology.SINGLE_VALUE, getFunction()); // + + // "()"); + return new Attribute[] { ao }; + } + + /** + * Returns all compatible input attribute arrays for this generator from the given example set + * as list. + */ + @Override + public List getInputCandidates(ExampleSet exampleSet, String[] functions) { + return new ArrayList(); + } + + @Override + public void generate(DataRow data) throws GenerationException { + try { + if (resultAttributes[0] != null) { + data.set(resultAttributes[0], constant); + } + } catch (ArrayIndexOutOfBoundsException ex) { + throw new GenerationException("a:" + getArgument(0), ex); + } + } + + @Override + public String toString() { + return getFunction(); + } +} diff --git a/src/main/java/com/rapidminer/generator/ExponentialFunctionGenerator.java b/src/main/java/com/rapidminer/generator/ExponentialFunctionGenerator.java new file mode 100644 index 000000000..6fcfa57e4 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/ExponentialFunctionGenerator.java @@ -0,0 +1,97 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * This class has one numerical input attribute and one output attribute. Depending on the mode + * specified in the constructor the result will be the exponential or the logarithm function of the + * input attribute. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class ExponentialFunctionGenerator extends SingularNumericalGenerator { + + public static final int EXP = 0; + + public static final int LOG = 1; + + private static final String[] FUNCTION_NAMES = { "exp", "log" }; + + private int mode; + + public ExponentialFunctionGenerator(int mode) { + this.mode = mode; + } + + public ExponentialFunctionGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new ExponentialFunctionGenerator(mode); + } + + @Override + public double calculateValue(double value) { + double r = 0; + switch (mode) { + case EXP: + r = Math.exp(value); + break; + case LOG: + r = Math.log(value); + break; + } + return r; + } + + @Override + public void setFunction(String name) { + for (int i = 0; i < FUNCTION_NAMES.length; i++) { + if (FUNCTION_NAMES[i].equals(name)) { + this.mode = i; + return; + } + } + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, + "com.rapidminer.generator.ExponentialFunctionGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + + @Override + public String getFunction() { + return FUNCTION_NAMES[mode]; + } + + @Override + public boolean equals(Object o) { + return (super.equals(o) && (this.mode == ((ExponentialFunctionGenerator) o).mode)); + } + + @Override + public int hashCode() { + return super.hashCode() ^ Integer.valueOf(mode).hashCode(); + } +} diff --git a/src/main/java/com/rapidminer/generator/FeatureGenerator.java b/src/main/java/com/rapidminer/generator/FeatureGenerator.java new file mode 100644 index 000000000..3def20dde --- /dev/null +++ b/src/main/java/com/rapidminer/generator/FeatureGenerator.java @@ -0,0 +1,407 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Tools; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.DataRowReader; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.RandomGenerator; + + +/** + * Abstract superclass of all attribute generators. Implementing classes have to implement the + * generate(Example), method and specify the input and output attributes by the appropriate + * methods so that the using algorithms can use them correctly. + * + * @author Simon Fischer, Ingo Mierswa Exp $ + */ +public abstract class FeatureGenerator { + + private static final String[] FUNCTION_NAMES = { "+", "-", "*", "/", "1/", "sin", "cos", "tan", "atan", "exp", "log", + "min", "max", "floor", "ceil", "round", "sqrt", "abs", "sgn", "pow" }; + + /** The classes which corresponds to FUNCTION_NAMES. */ + private static final Class[] GENERATOR_CLASSES = { BasicArithmeticOperationGenerator.class, + BasicArithmeticOperationGenerator.class, BasicArithmeticOperationGenerator.class, + BasicArithmeticOperationGenerator.class, ReciprocalValueGenerator.class, TrigonometricFunctionGenerator.class, + TrigonometricFunctionGenerator.class, TrigonometricFunctionGenerator.class, + TrigonometricFunctionGenerator.class, ExponentialFunctionGenerator.class, ExponentialFunctionGenerator.class, + MinMaxGenerator.class, MinMaxGenerator.class, FloorCeilGenerator.class, FloorCeilGenerator.class, + FloorCeilGenerator.class, SquareRootGenerator.class, AbsoluteValueGenerator.class, SignumGenerator.class, + PowerGenerator.class }; + + /** Maps function names to generators. */ + private static Map generatorMap; + + static { + generatorMap = new HashMap<>(); + for (int i = 0; i < FUNCTION_NAMES.length; i++) { + generatorMap.put(FUNCTION_NAMES[i], GENERATOR_CLASSES[i]); + } + } + + /** Indicates a non-restrictive generator selection mode. */ + public static final int SELECTION_MODE_ALL = 0; + + /** Indicates a restrictive generator selection mode. */ + public static final int SELECTION_MODE_RESTRICTIVE = 1; + + /** + * Indicates the selection mode. One of SELECTION_MODE_ALL and SELECTION_MODE_RESTRICTIVE. + */ + private static int selectionMode = SELECTION_MODE_ALL; + + /** The attributes of the function(s) calculated by this FeatureGenerator. */ + protected Attribute[] resultAttributes; + + /** + * The argument attributes on which to operate with respect to the example tables attribute + * array. + */ + private Attribute[] arguments = null; + + /** The example table to work on. */ + private ExampleTable exampleTable; + + // ------------------------------ The abstract methods + // ------------------------------ + + /** + * Generates the new attribute values for the example e and returns the new attribute values as + * doubles. e.getAttribute(getArgument(i)) is the correct way to access argument + * i. If the according attribute's type is VALUE_SERIES, the end index can be determined + * by i_end = getExampleTable().getBlockEndIndex(getArgument(i)). Thus all values of + * the series can be accessed using indices i through i_end. + */ + public abstract void generate(DataRow data) throws GenerationException; + + /** + * Returns an array of Attributes where the length is the arity of the generator, [i] + * is the attribute type of the i-th argument. + */ + public abstract Attribute[] getInputAttributes(); + + /** Returns the generated attributes types. */ + public abstract Attribute[] getOutputAttributes(ExampleTable input); + + /** + * Subclasses must implement this method so that a new instance of this generator class is + * returned. The arguments and the example table will not be cloned and thus be null. This kind + * of clone is needed as generating algorithms must be able to clone generators form their pool + * without changing the arguments already set for the others. + */ + public abstract FeatureGenerator newInstance(); + + /** + * Sets the function name. This method is only useful if subclasses can generate more than one + * function. (like the BasicArithmeticOperationGenerator). + */ + public abstract void setFunction(String name); + + /** + * Sets the function name. This method is only useful if subclasses can generate more than one + * function. (like the BasicArithmeticOperationGenerator). + */ + public abstract String getFunction(); + + /** + * Returns all compatible input attribute arrays for this generator from the given example set + * as list. Features with a depth greater than maxDepth or which contains one of the given + * functions should not be used as input candidates. Subclasses must consider if the generator + * is self-applicable or commutative. A maxDepth of -1 means that no maximal depth should be + * considered. + */ + public abstract List getInputCandidates(ExampleSet exampleSet, String[] functions); + + // -------------------------------------------------------------------------------- + + protected boolean checkCompatibility(Attribute attribute, Attribute compatible, String[] functions) { + if (Tools.compatible(attribute, compatible)) { + for (int f = 0; f < functions.length; f++) { + if (attribute.getConstruction().indexOf(functions[f]) != -1) { + return false; + } + } + return true; + } else { + return false; + } + } + + protected void setExampleTable(ExampleTable et) { + this.exampleTable = et; + } + + /** Gets the example table the examples are from. */ + protected ExampleTable getExampleTable() { + return exampleTable; + } + + /** + * Sets the arguments (indices) used in future generate(...) calls and has to be called + * prior to any generate(...) calls. The caller of this method has to take care that: + *
      + *
    • args.length == getInputAttributes().length, i.e. that the arity is correct. + *
    • The types of the example attributes match the types specified by + * getInputAttributes(). + *
    • The true attribute indices are used (as used by the example set's example table) + *
    + */ + public void setArguments(Attribute[] args) { + arguments = args; + } + + /** + * returns true, if the arguments have already been set, and false otherwise. + */ + public boolean argumentsSet() { + return getInputAttributes().length == 0 || arguments != null; + } + + /** + * Returns the i-th selected argument (the true index as used in the example set's example + * table). + */ + public Attribute getArgument(int i) { + return arguments[i]; + } + + /** + * Checks if the arguments are compatible with the attributes specified by getInputAttributes(). + */ + private boolean argumentsOk(ExampleTable input) { + Attribute[] inputA = getInputAttributes(); + for (int i = 0; i < inputA.length; i++) { + if (!Tools.compatible(arguments[i], inputA[i])) { + return false; + } + } + return true; + } + + // -------------------------------------------------------------------------------- + + /** Creates a new FeatureGenerator for a given function name. */ + public static FeatureGenerator createGeneratorForFunction(String functionName) { + if (functionName == null) { + return null; + } + Class genClass = generatorMap.get(functionName); + if (genClass == null) { + if (functionName.startsWith(ConstantGenerator.FUNCTION_NAME)) { + FeatureGenerator gen = new ConstantGenerator(); + gen.setFunction(functionName); + return gen; + } else { + return null; + } + } else { + try { + FeatureGenerator gen = (FeatureGenerator) genClass.newInstance(); + gen.setFunction(functionName); + return gen; + } catch (Exception e) { + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.FeatureGenerator.instantiating_error", + genClass.getName()); + return null; + } + } + } + + // -------------------------------------------------------------------------------- + + /** + * Randomly selects a generator from the generator list. The probability of a generator to be + * selected is proportional to its number of attribute combinations as delivered by + * {@link #getInputCandidates(ExampleSet, String[])} method. Returns null if no generators are + * applicable. + * + * @param generators + * List of {@link FeatureGenerator}s + */ + public static FeatureGenerator selectGenerator(ExampleSet exampleSet, List generators, String[] functions, + RandomGenerator random) { + int combinationSum = 0; + Iterator i = generators.iterator(); + double[] probs = new double[generators.size()]; + int k = 0; + while (i.hasNext()) { + FeatureGenerator generator = (FeatureGenerator) i.next(); + // probs[k] = + // generator.getNumberOfApplicableGenerations(exampleSet); + probs[k] = generator.getInputCandidates(exampleSet, functions).size(); + combinationSum += probs[k]; + k++; + } + if (combinationSum == 0) { + return null; + } else { + for (k = 0; k < probs.length; k++) { + probs[k] /= combinationSum; + } + + int index = random.randomIndex(probs); + FeatureGenerator selected = (FeatureGenerator) generators.get(index); + return selected; + } + } + + // -------------------------------------------------------------------------------- + + /** + * Generates all new attributes and updates the ExampleTable. Returns a list of Attributes for + * the newly generated attributes. + * + * @param exampleTable + * the source example table + * @param generatorList + * List of FeatureGenerators + * @return A list of Attributes + */ + public static List generateAll(ExampleTable exampleTable, Collection generatorList) + throws GenerationException { + LogService.getRoot().log(Level.FINE, "com.rapidminer.generator.FeatureGenerator.starting_feature_generation", + generatorList.size()); + + Iterator gi = generatorList.iterator(); + while (gi.hasNext()) { + gi.next().setExampleTable(exampleTable); + } + + // for performance reasons convert the list to an array + FeatureGenerator[] generators = new FeatureGenerator[generatorList.size()]; + generatorList.toArray(generators); + + List newAttributeList = newAttributes(generators, exampleTable); + // add the attributes to the example table and ensure length of the + // DataRows + exampleTable.addAttributes(newAttributeList); + LogService.getRoot().log(Level.FINE, "com.rapidminer.generator.FeatureGenerator.generator_list", generatorList); + LogService.getRoot().log(Level.FINE, + "com.rapidminer.generator.FeatureGenerator.input_has_feature_count_and_example_count", + new Object[] { exampleTable.getAttributeCount(), exampleTable.size() }); + + // generate the attribute values: + DataRowReader reader = exampleTable.getDataRowReader(); + while (reader.hasNext()) { + DataRow dataRow = reader.next(); + + for (int j = 0; j < generators.length; j++) { + generators[j].generate(dataRow); + } + } + + LogService.getRoot().log(Level.FINE, "com.rapidminer.generator.FeatureGenerator.finished_feature_generation"); + LogService.getRoot().log(Level.FINE, + "com.rapidminer.generator.FeatureGenerator.generated_set_has_feature_count_and_example_count", + new Object[] { exampleTable.getAttributeCount(), exampleTable.size() }); + + return newAttributeList; + } + + /** + * Returns a list of new Attributes that are generated by the given generators. + */ + private static List newAttributes(FeatureGenerator[] generators, ExampleTable exampleTable) { + List newAttributeList = new LinkedList<>(); + + // add the attributes to the example table + for (int i = 0; i < generators.length; i++) { + Attribute outputAttribute[] = generators[i].getOutputAttributes(exampleTable); + generators[i].resultAttributes = new Attribute[outputAttribute.length]; + + for (int j = 0; j < outputAttribute.length; j++) { + newAttributeList.add(outputAttribute[j]); + generators[i].resultAttributes[j] = outputAttribute[j]; + } + + // check the arguments + if (!generators[i].argumentsSet()) { + throw new RuntimeException("Catastrophic error: arguments not set for " + generators[i] + "!"); + } + if (!generators[i].argumentsOk(exampleTable)) { + LogService.getRoot().log(Level.WARNING, "com.rapidminer.generator.FeatureGenerator.wrong_argument_types", + generators[i]); + } + } + return newAttributeList; + } + + public static int getSelectionMode() { + return selectionMode; + } + + public static void setSelectionMode(int mode) { + selectionMode = mode; + } + + @Override + public String toString() { + return "FeatureGenerator (" + getClass().getName() + ")"; + } + + /** + * A FeatureGenerator equals another FeatureGenerator if its class is equal and its arguments + * are equal and its function names are equal. + */ + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (!this.getClass().equals(o.getClass())) { + return false; + } + FeatureGenerator fg = (FeatureGenerator) o; + if (!this.getFunction().equals(fg.getFunction())) { + return false; + } + if (this.arguments.length != fg.arguments.length) { + return false; + } + for (int i = 0; i < arguments.length; i++) { + if (!this.arguments[i].equals(fg.arguments[i])) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + int hashCode = getFunction().hashCode(); + if (this.arguments != null) { + hashCode ^= Arrays.hashCode(this.arguments); + } + return hashCode; + } +} diff --git a/src/main/java/com/rapidminer/generator/FloorCeilGenerator.java b/src/main/java/com/rapidminer/generator/FloorCeilGenerator.java new file mode 100644 index 000000000..97781ad40 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/FloorCeilGenerator.java @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * This class has one numerical input attribute and one output attribute. Depending on the mode + * specified in the constructor the result will be the floor or the ceil function of the input + * attribute. + * + * @author Ingo Mierswa Exp $ + */ +public class FloorCeilGenerator extends SingularNumericalGenerator { + + public static final int FLOOR = 0; + + public static final int CEIL = 1; + + public static final int ROUND = 2; + + private static final String[] FUNCTION_NAMES = { "floor", "ceil", "round" }; + + private int mode; + + public FloorCeilGenerator(int mode) { + this.mode = mode; + } + + public FloorCeilGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new FloorCeilGenerator(mode); + } + + @Override + public double calculateValue(double value) { + double r = 0; + switch (mode) { + case FLOOR: + r = Math.floor(value); + break; + case CEIL: + r = Math.ceil(value); + break; + case ROUND: + r = Math.round(value); + break; + } + return r; + } + + @Override + public void setFunction(String name) { + for (int i = 0; i < FUNCTION_NAMES.length; i++) { + if (FUNCTION_NAMES[i].equals(name)) { + this.mode = i; + return; + } + } + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.FloorCeilGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + + @Override + public String getFunction() { + return FUNCTION_NAMES[mode]; + } + + @Override + public boolean equals(Object o) { + return (super.equals(o) && (this.mode == ((FloorCeilGenerator) o).mode)); + } + + @Override + public int hashCode() { + return super.hashCode() ^ Integer.valueOf(mode).hashCode(); + } +} diff --git a/src/main/java/com/rapidminer/generator/GenerationException.java b/src/main/java/com/rapidminer/generator/GenerationException.java new file mode 100644 index 000000000..529128f9f --- /dev/null +++ b/src/main/java/com/rapidminer/generator/GenerationException.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.operator.OperatorException; + + +/** + * This exception will be thrown if an error occurs during the generation of new features. + * + * @author Ingo Mierswa, Simon Fischer Exp $ + */ +public class GenerationException extends OperatorException { + + private static final long serialVersionUID = -2760374156089530715L; + + public GenerationException(String str) { + super(str); + } + + public GenerationException(String str, Exception e) { + super(str, e); + } + +} diff --git a/src/main/java/com/rapidminer/generator/MinMaxGenerator.java b/src/main/java/com/rapidminer/generator/MinMaxGenerator.java new file mode 100644 index 000000000..c52545726 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/MinMaxGenerator.java @@ -0,0 +1,118 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Ontology; + +import java.util.logging.Level; + + +/** + * This class has two numerical input attributes and one output attribute. Depending on the mode + * specified in the constructor the result will be the minimum or maximum of the input attributes. + * + * @author Ingo Mierswa + */ +public class MinMaxGenerator extends BinaryNumericalGenerator { + + public static final int MIN = 0; + + public static final int MAX = 1; + + private static final String[] FUNCTION_NAMES = { "min", "max" }; + + private int mode; + + public MinMaxGenerator(int mode) { + this.mode = mode; + } + + public MinMaxGenerator() {} + + @Override + public Attribute[] getOutputAttributes(ExampleTable input) { + Attribute a1 = getArgument(0); + Attribute a2 = getArgument(1); + Attribute ao = AttributeFactory.createAttribute(Ontology.NUMERICAL, Ontology.SINGLE_VALUE, + getFunction() + "(" + a1.getConstruction() + "," + a2.getConstruction() + ")"); + return new Attribute[] { ao }; + } + + @Override + public boolean isSelfApplicable() { + return false; + } + + @Override + public boolean isCommutative() { + return true; + } + + @Override + public FeatureGenerator newInstance() { + return new MinMaxGenerator(mode); + } + + @Override + public double calculateValue(double value1, double value2) { + double r = 0; + switch (mode) { + case MIN: + r = Math.min(value1, value2); + break; + case MAX: + r = Math.max(value1, value2); + break; + } + return r; + } + + @Override + public void setFunction(String name) { + for (int i = 0; i < FUNCTION_NAMES.length; i++) { + if (FUNCTION_NAMES[i].equals(name)) { + this.mode = i; + return; + } + } + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.MinMaxGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + + @Override + public String getFunction() { + return FUNCTION_NAMES[mode]; + } + + @Override + public boolean equals(Object o) { + return (super.equals(o) && (this.mode == ((MinMaxGenerator) o).mode)); + } + + @Override + public int hashCode() { + return super.hashCode() ^ Integer.valueOf(mode).hashCode(); + } +} diff --git a/src/main/java/com/rapidminer/generator/PowerGenerator.java b/src/main/java/com/rapidminer/generator/PowerGenerator.java new file mode 100644 index 000000000..9ad9df53b --- /dev/null +++ b/src/main/java/com/rapidminer/generator/PowerGenerator.java @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * This class has two numerical input attributes and one output attribute. Calculates the power of + * the input attribute to the second. + * + * @author Ingo Mierswa + */ +public class PowerGenerator extends BinaryNumericalGenerator { + + public PowerGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new PowerGenerator(); + } + + @Override + public boolean isCommutative() { + return false; + } + + @Override + public boolean isSelfApplicable() { + return true; + } + + @Override + public double calculateValue(double value1, double value2) { + return Math.pow(value1, value2); + } + + @Override + public void setFunction(String name) { + if (!name.equals("^")) { + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.PowerGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + } + + @Override + public String getFunction() { + return "^"; + } +} diff --git a/src/main/java/com/rapidminer/generator/ReciprocalValueGenerator.java b/src/main/java/com/rapidminer/generator/ReciprocalValueGenerator.java new file mode 100644 index 000000000..a78f20067 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/ReciprocalValueGenerator.java @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import java.util.logging.Level; + +import com.rapidminer.tools.LogService; + + +/** + * Creates the reciprocal value of all input attributes. If the generator is bounded, the values are + * bounded by the biggest and smallest possible values. + * + * @author Simon Fischer, Ingo Mierswa ingomierswa Exp $ + */ +public class ReciprocalValueGenerator extends SingularNumericalGenerator { + + public static final String FUNCTION_NAMES[] = { "1/" }; + + public ReciprocalValueGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new ReciprocalValueGenerator(); + } + + @Override + public double calculateValue(double value) { + return 1.0d / value; + } + + @Override + public void setFunction(String name) { + for (int i = 0; i < FUNCTION_NAMES.length; i++) { + if (FUNCTION_NAMES[i].equals(name)) { + return; + } + } + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.ReciprocalValueGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + + @Override + public String getFunction() { + return FUNCTION_NAMES[0]; + } +} diff --git a/src/main/java/com/rapidminer/generator/SignumGenerator.java b/src/main/java/com/rapidminer/generator/SignumGenerator.java new file mode 100644 index 000000000..519f57641 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/SignumGenerator.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * This class has one numerical input attribute and one output attribute. Calculates the signum of + * the input attribute, i.e. -1 for values smaller than 0, 0 for zero, and 1 for values larger than + * zero. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class SignumGenerator extends SingularNumericalGenerator { + + public SignumGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new SignumGenerator(); + } + + @Override + public double calculateValue(double value) { + return Math.signum(value); + } + + @Override + public void setFunction(String name) { + if (!name.equals("sgn")) { + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.SignumGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + } + + @Override + public String getFunction() { + return "sgn"; + } +} diff --git a/src/main/java/com/rapidminer/generator/SingularNumericalGenerator.java b/src/main/java/com/rapidminer/generator/SingularNumericalGenerator.java new file mode 100644 index 000000000..ce8f3fc5e --- /dev/null +++ b/src/main/java/com/rapidminer/generator/SingularNumericalGenerator.java @@ -0,0 +1,123 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.table.AttributeFactory; +import com.rapidminer.example.table.DataRow; +import com.rapidminer.example.table.ExampleTable; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Ontology; + + +/** + * Generators of this class will have one numerical input attribute and one output attribute. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public abstract class SingularNumericalGenerator extends FeatureGenerator { + + private static final Attribute[] INPUT_ATTR = { AttributeFactory.createAttribute(Ontology.NUMERICAL) }; + + private boolean performLogging = true; + + public SingularNumericalGenerator() {} + + /** + * Subclasses have to implement this method to calculate the function result. + */ + public abstract double calculateValue(double value); + + @Override + public Attribute[] getInputAttributes() { + return INPUT_ATTR; + } + + @Override + public Attribute[] getOutputAttributes(ExampleTable input) { + Attribute a1 = getArgument(0); + Attribute ao = AttributeFactory.createAttribute(Ontology.NUMERICAL, Ontology.SINGLE_VALUE, + getFunction() + "(" + a1.getConstruction() + ")"); + return new Attribute[] { ao }; + } + + /** + * Returns all compatible input attribute arrays for this generator from the given example set + * as list. + */ + @Override + public List getInputCandidates(ExampleSet exampleSet, String[] functions) { + List result = new ArrayList<>(); + for (Attribute attribute : exampleSet.getAttributes()) { + if (checkCompatibility(attribute, INPUT_ATTR[0], functions)) { + result.add(new Attribute[] { attribute }); + } + } + return result; + } + + @Override + public void generate(DataRow data) throws GenerationException { + try { + Attribute a = getArgument(0); + double value = data.get(a); + double r = calculateValue(value); + + if (performLogging) { + if (Double.isNaN(r)) { + performLogging = false; + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.generator.SingularNumericalGenerator.nan_generated", getFunction()); + } else if (Double.isInfinite(r)) { + performLogging = false; + LogService.getRoot().log(Level.WARNING, + "com.rapidminer.generator.SingularNumericalGenerator.infinite_value_generated", getFunction()); + r = Double.NaN; + } + } else if (Double.isInfinite(r)) { + r = Double.NaN; + } + + if (resultAttributes[0] != null) { + data.set(resultAttributes[0], r); + } + } catch (ArrayIndexOutOfBoundsException ex) { + throw new GenerationException("a:" + getArgument(0), ex); + } + } + + @Override + public String toString() { + String s = "singular function "; + if (resultAttributes != null && resultAttributes.length > 0 && resultAttributes[0] != null) { + s += resultAttributes[0].getName() + ":="; + } + s += getFunction() + "("; + if (argumentsSet()) { + s += getArgument(0).getName(); + } + s += ")"; + return s; + } +} diff --git a/src/main/java/com/rapidminer/generator/SinusFactory.java b/src/main/java/com/rapidminer/generator/SinusFactory.java new file mode 100644 index 000000000..6a14a700f --- /dev/null +++ b/src/main/java/com/rapidminer/generator/SinusFactory.java @@ -0,0 +1,224 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.example.Attribute; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.example.Statistics; +import com.rapidminer.operator.OperatorException; +import com.rapidminer.tools.math.BinaryPeakFinder; +import com.rapidminer.tools.math.Complex; +import com.rapidminer.tools.math.FastFourierTransform; +import com.rapidminer.tools.math.Peak; +import com.rapidminer.tools.math.PeakFinder; +import com.rapidminer.tools.math.SpectrumFilter; +import com.rapidminer.tools.math.WindowFunction; + +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + + +/** + * Factory class to produce new attributes based on the fourier synthesis of the label mapped on an + * attribute dimension. + * + * @author Ingo Mierswa + */ +public class SinusFactory { + + /** Indicates the min evidence factor. */ + private static final double MIN_EVIDENCE = 0.2d; + + public static final String[] ADAPTION_TYPES = { "uniformly", "uniformly_without_nu", "gaussian" }; + + public static final int UNIFORMLY = 0; + + public static final int UNIFORMLY_WITHOUT_NU = 1; + + public static final int GAUSSIAN = 2; + + /** + * Generates this number of peaks in a range of epsilon * frequency. Necessary + * because the FT does not deliver the correct frequency (aliasing, leakage) in all cases. In + * later releases this should be replaced by a gradient search or a evolutionary search for the + * correct value. + */ + private int attributesPerPeak = 3; + + /** + * Generates this peaksPerPeak peaks in the range of + * epsilon * frequency. Necessary because the FT does not deliver the correct + * frequency (aliasing, leakage) in all cases. In later releases this should be replaced by a + * gradient search or a evolutionary search for the correct value. + */ + private double epsilon = 0.1; + + /** Indicates the type of frequency adaption. */ + private int adaptionType = UNIFORMLY; + + /** + * The maximal number of generated attributes for each possible attribute. Corresponds to the + * highest peaks in the frequency spectrum of the label in the source attribute's space. + */ + private int maxPeaks = 5; + + /** The fast fourier transformation calculator. */ + private FastFourierTransform fft = null; + + /** + * The spectrum filter type which should be applied on the spectrum after the fourier + * transformation. + */ + private SpectrumFilter filter = null; + + /** The algorithm to find the peaks in the frequency spectrum. */ + private PeakFinder peakFinder = null; + + /** + * Creates a new sinus factory which creates maxPeaks new peaks. Uses + * Blackman-Harris window function and no spectrum filter as default. The adaption type is + * gaussian with an epsilon of 0.1. The factory produces three attributes for each highest peak + * as default. + */ + public SinusFactory(int maxPeaks) { + this.maxPeaks = maxPeaks; + this.fft = new FastFourierTransform(WindowFunction.BLACKMAN_HARRIS); + this.filter = new SpectrumFilter(SpectrumFilter.NONE); + this.peakFinder = new BinaryPeakFinder(); + } + + public void setAdaptionType(int type) { + this.adaptionType = type; + } + + public void setEpsilon(double epsilon) { + this.epsilon = epsilon; + } + + /** Must be bigger than 2! */ + public void setAttributePerPeak(int attributesPerPeak) { + this.attributesPerPeak = attributesPerPeak; + } + + /** + * Calculates the fourier transformation from the first attribute on the second and delivers the + * maxPeaks highest peaks. Returns a list with the highest attribute peaks. + */ + public List getAttributePeaks(ExampleSet exampleSet, Attribute first, Attribute second) + throws OperatorException { + exampleSet.recalculateAllAttributeStatistics(); + Complex[] result = fft.getFourierTransform(exampleSet, first, second); + Peak[] spectrum = filter.filter(result, exampleSet.size()); + double average = 0.0d; + for (int k = 0; k < spectrum.length; k++) { + average += spectrum[k].getMagnitude(); + } + average /= spectrum.length; + List peaks = peakFinder.getPeaks(spectrum); + Collections.sort(peaks); + + // remember highest peaks + double inputDeviation = Math.sqrt(exampleSet.getStatistics(second, Statistics.VARIANCE)) + / (exampleSet.getStatistics(second, Statistics.MAXIMUM) - exampleSet.getStatistics(second, + Statistics.MINIMUM)); + Iterator p = peaks.iterator(); + double maxEvidence = Double.NaN; + List attributes = new LinkedList(); + for (int k = 0; k < maxPeaks; k++) { + if (p.hasNext()) { + Peak peak = (Peak) p.next(); + double evidence = (peak.getMagnitude() / average) * (1.0d / inputDeviation); + if (Double.isNaN(maxEvidence)) { + maxEvidence = evidence; + } + if (evidence > (MIN_EVIDENCE * maxEvidence)) { + attributes.add(new AttributePeak(second, peak.getIndex(), evidence)); + } + } + } + return attributes; + } + + /** + * Generates a new sinus function attribute for all given attribute peaks. Since the frequency + * cannot be calculated exactly (leakage, aliasing), several new attribute may be added for each + * peak. These additional attributes are randomly chosen (uniformly in epsilon range, uniformly + * without nu, gaussian with epsilon as standard deviation) + */ + public void generateSinusFunctions(ExampleSet exampleSet, List attributes, Random random) + throws GenerationException { + if (attributes.size() > 0) { + Collections.sort(attributes); + double totalMaxEvidence = attributes.get(0).getEvidence(); + + Iterator a = attributes.iterator(); + while (a.hasNext()) { + AttributePeak ae = a.next(); + if (ae.getEvidence() > MIN_EVIDENCE * totalMaxEvidence) { + for (int i = 0; i < attributesPerPeak; i++) { + double frequency = ae.getFrequency(); + switch (adaptionType) { + case UNIFORMLY: + if (attributesPerPeak != 1) { + frequency = (double) i / (double) (attributesPerPeak - 1) * 2.0d * epsilon * frequency + + (frequency - epsilon * frequency); + } + break; + case UNIFORMLY_WITHOUT_NU: + if (attributesPerPeak != 1) { + frequency = (double) i / (double) (attributesPerPeak - 1) * 2.0d * epsilon + + (frequency - epsilon); + } + break; + case GAUSSIAN: + frequency = random.nextGaussian() * epsilon + frequency; + break; + } + + // frequency constant + List frequencyResult = generateAttribute(exampleSet, new ConstantGenerator(frequency)); + + // scaling with frequency + FeatureGenerator scale = new BasicArithmeticOperationGenerator( + BasicArithmeticOperationGenerator.PRODUCT); + scale.setArguments(new Attribute[] { (Attribute) frequencyResult.get(0), ae.getAttribute() }); + List scaleResult = generateAttribute(exampleSet, scale); + + // calc sin + FeatureGenerator sin = new TrigonometricFunctionGenerator(TrigonometricFunctionGenerator.SINUS); + sin.setArguments(new Attribute[] { (Attribute) scaleResult.get(0) }); + List sinResult = generateAttribute(exampleSet, sin); + for (Attribute attribute : sinResult) { + exampleSet.getAttributes().addRegular(attribute); + } + } + } + } + } + } + + private List generateAttribute(ExampleSet exampleSet, FeatureGenerator generator) throws GenerationException { + List generators = new LinkedList(); + generators.add(generator); + return FeatureGenerator.generateAll(exampleSet.getExampleTable(), generators); + } +} diff --git a/src/main/java/com/rapidminer/generator/SquareRootGenerator.java b/src/main/java/com/rapidminer/generator/SquareRootGenerator.java new file mode 100644 index 000000000..91a2b8991 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/SquareRootGenerator.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import com.rapidminer.tools.LogService; + +import java.util.logging.Level; + + +/** + * This class has one numerical input attribute and one output attribute. Calculates the value of + * the square root of the input attribute. + * + * @author Ingo Mierswa Exp $ + */ +public class SquareRootGenerator extends SingularNumericalGenerator { + + public SquareRootGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new SquareRootGenerator(); + } + + @Override + public double calculateValue(double value) { + return Math.sqrt(value); + } + + @Override + public void setFunction(String name) { + if (!name.equals("sqrt")) { + // LogService.getGlobal().log("Illegal function name '" + name + "' for " + + // getClass().getName() + ".", LogService.ERROR); + LogService.getRoot().log(Level.SEVERE, "com.rapidminer.generator.SquareRootGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + } + + @Override + public String getFunction() { + return "sqrt"; + } +} diff --git a/src/main/java/com/rapidminer/generator/TrigonometricFunctionGenerator.java b/src/main/java/com/rapidminer/generator/TrigonometricFunctionGenerator.java new file mode 100644 index 000000000..389afbe9d --- /dev/null +++ b/src/main/java/com/rapidminer/generator/TrigonometricFunctionGenerator.java @@ -0,0 +1,105 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.generator; + +import java.util.logging.Level; + +import com.rapidminer.tools.LogService; + + +/** + * This class has one numerical input attribute and one output attribute. Depending on the mode + * specified in the constructor the result will be the sinus, cosinus, tangens, arc sinus, arc + * cosinus, or arc tangens. + * + * @author Ingo Mierswa ingomierswa Exp $ + */ +public class TrigonometricFunctionGenerator extends SingularNumericalGenerator { + + public static final int SINUS = 0; + + public static final int COSINUS = 1; + + public static final int TANGENS = 2; + + public static final int ARC_TANGENS = 3; + + private static final String[] FUNCTION_NAMES = { "sin", "cos", "tan", "atan" }; + + private int mode = SINUS; + + public TrigonometricFunctionGenerator(int mode) { + this.mode = mode; + } + + public TrigonometricFunctionGenerator() {} + + @Override + public FeatureGenerator newInstance() { + return new TrigonometricFunctionGenerator(mode); + } + + @Override + public double calculateValue(double value) { + double r = 0; + switch (mode) { + case SINUS: + r = Math.sin(value); + break; + case COSINUS: + r = Math.cos(value); + break; + case TANGENS: + r = Math.tan(value); + break; + case ARC_TANGENS: + r = Math.atan(value); + break; + } + return r; + } + + @Override + public void setFunction(String name) { + for (int i = 0; i < FUNCTION_NAMES.length; i++) { + if (FUNCTION_NAMES[i].equals(name)) { + this.mode = i; + return; + } + } + LogService.getRoot().log(Level.SEVERE, + "com.rapidminer.generator.TrigonometricFunctionGenerator.illegal_function_name", + new Object[] { name, getClass().getName() }); + } + + @Override + public String getFunction() { + return FUNCTION_NAMES[mode]; + } + + @Override + public boolean equals(Object o) { + return super.equals(o) && this.mode == ((TrigonometricFunctionGenerator) o).mode; + } + + @Override + public int hashCode() { + return super.hashCode() ^ Integer.valueOf(mode).hashCode(); + } +} diff --git a/src/main/java/com/rapidminer/generator/package.html b/src/main/java/com/rapidminer/generator/package.html new file mode 100644 index 000000000..8ffaa91c8 --- /dev/null +++ b/src/main/java/com/rapidminer/generator/package.html @@ -0,0 +1,12 @@ + + + + + + + + +Provides feature generators. These can create new attributes from old ones. + + + diff --git a/src/main/java/com/rapidminer/gui/ApplicationFrame.java b/src/main/java/com/rapidminer/gui/ApplicationFrame.java new file mode 100644 index 000000000..e25cc8f31 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/ApplicationFrame.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import javax.swing.JFrame; + +import com.rapidminer.gui.tools.StatusBar; + + +/** + * This is a singelton for getting access to the main frame of an application. + * + * @author Simon Fischer + */ +public abstract class ApplicationFrame extends JFrame { + + private static final long serialVersionUID = -4888325793866511406L; + + private static ApplicationFrame applicationFrame = null; + + // The status bar of the application, usually displayed at the bottom + // of the frame. + private final StatusBar statusBar = new StatusBar(); + + public ApplicationFrame(String title) { + super(title); + if (applicationFrame != null) { + throw new RuntimeException("Can only have one application frame."); + } + applicationFrame = this; + } + + /** + * Returns the status bar of the application. + * + * @return status bar + */ + public StatusBar getStatusBar() { + return statusBar; + } + + public static ApplicationFrame getApplicationFrame() { + return applicationFrame; + } +} diff --git a/src/main/java/com/rapidminer/gui/ApplicationPerspectives.java b/src/main/java/com/rapidminer/gui/ApplicationPerspectives.java new file mode 100644 index 000000000..d7e573d94 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/ApplicationPerspectives.java @@ -0,0 +1,141 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.util.logging.Level; + +import javax.swing.JMenu; +import javax.swing.JToolBar; + +import com.rapidminer.tools.LogService; +import com.vlsolutions.swing.docking.Dockable; +import com.vlsolutions.swing.docking.DockingContext; + + +/** + * Collection of {@link Perspective}s that can be applied, saved, created. + * + * @author Simon Fischer + * @deprecated Since 7.0.0. Use {@link PerspectiveController} instead. + */ +@Deprecated +public abstract class ApplicationPerspectives { + + protected final PerspectiveController perspectiveController; + + public ApplicationPerspectives(final PerspectiveController perspectiveController) { + this.perspectiveController = perspectiveController; + } + + public ApplicationPerspectives(final DockingContext context) { + perspectiveController = new PerspectiveController(context); + } + + public void showPerspective(final Perspective perspective) { + perspectiveController.showPerspective(perspective); + } + + public JMenu getWorkspaceMenu() { + LogService.getRoot().log(Level.WARNING, + "The access of the WorkspaceMenu deprecated. Use the PerspectiveController instead."); + return new JMenu(); + } + + public JToolBar getWorkspaceToolBar() { + LogService.getRoot().log(Level.WARNING, + "The access of the WorkspaceToolBar is deprecated. Use the PerspectiveController instead."); + return new JToolBar(); + } + + /** + * Checks if the given string is valid as name of a new perspective. + * + * @param name + * @return validity + */ + public boolean isValidName(final String name) { + return perspectiveController.getModel().isValidName(name); + } + + /** + * + * @throws IllegalArgumentException + * if name is already used + */ + public Perspective addPerspective(final String name, final boolean userDefined) { + return perspectiveController.getModel().addPerspective(name, userDefined); + } + + /** Saves all perspectives to the users config directory. */ + public void saveAll() { + perspectiveController.saveAll(); + } + + /** Loads all perspectives from the users config directory. */ + public void loadAll() { + perspectiveController.loadAll(); + } + + public Perspective getCurrentPerspective() { + return perspectiveController.getModel().getSelectedPerspective(); + } + + /** Switches to the given perspective, storing the current one. */ + public void showPerspective(final String name) { + perspectiveController.showPerspective(name); + } + + /** + * Creates a user-defined perspectives, and possibly switches to this new perspective + * immediately. The new perspective will be a copy of the current one. + */ + public Perspective createUserPerspective(final String name, final boolean show) { + return perspectiveController.createUserPerspective(name, show); + } + + /** Shows the tab as a child of the given dockable in all perspectives. */ + public void showTabInAllPerspectives(final Dockable dockable, final Dockable parent) { + perspectiveController.showTabInAllPerspectives(dockable, parent); + } + + public void removeFromAllPerspectives(final Dockable dockable) { + perspectiveController.removeFromAllPerspectives(dockable); + } + + protected abstract void makePredefined(); + + protected abstract void restoreDefault(String perspectiveName); + + protected Perspective getPerspective(final String name) { + return perspectiveController.getModel().getPerspective(name); + } + + public void addPerspectiveChangeListener(final PerspectiveChangeListener listener) { + perspectiveController.getModel().addPerspectiveChangeListener(listener); + } + + public boolean removePerspectiveChangeListener(final PerspectiveChangeListener listener) { + return perspectiveController.getModel().removePerspectiveChangeListener(listener); + } + + public void notifyChangeListener() { + perspectiveController.getModel().notifyChangeListener(); + } + +} diff --git a/src/main/java/com/rapidminer/gui/ConditionalAction.java b/src/main/java/com/rapidminer/gui/ConditionalAction.java new file mode 100644 index 000000000..7a6dc1f3b --- /dev/null +++ b/src/main/java/com/rapidminer/gui/ConditionalAction.java @@ -0,0 +1,180 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.lang.ref.WeakReference; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.AbstractAction; +import javax.swing.Icon; +import javax.swing.SwingUtilities; + + +/** + * An action that must be enabled/disabled depending on certain conditions. These conditions can be + * mandatory, disallowed, or irrelevant. All ConditionalActions created are added to a collection + * and there status is automatically checked if the condition premises might have changed. + * + * @author Ingo Mierswa, Simon Fischer + */ +public abstract class ConditionalAction extends AbstractAction { + + /** + * + */ + private static final long serialVersionUID = -3581066203343247846L; + + private static final List> ALL_ACTIONS = new LinkedList>(); + + /* The possible states. */ + public static final int DISALLOWED = -1; + + public static final int DONT_CARE = 0; + + public static final int MANDATORY = 1; + + /* + * The possible conditions. TODO: Make enum + */ + public static final int OPERATOR_SELECTED = 0; + + public static final int OPERATOR_CHAIN_SELECTED = 1; + + public static final int ROOT_SELECTED = 2; + + public static final int SIBLINGS_EXIST = 3; + + public static final int PROCESS_STOPPED = 4; + + public static final int PROCESS_PAUSED = 5; + + public static final int PROCESS_RUNNING = 6; + + public static final int PARENT_ENABLED = 7; + + /** TODO: Unused */ + public static final int EXECUTION_UNIT_SELECTED = 8; + + public static final int EDIT_IN_PROGRESS = 9; + + public static final int PROCESS_IS_ON_REMOTE_REPOSITORY = 10; + + public static final int PROCESS_SAVED = 11; + + public static final int PROCESS_RENDERER_IS_VISIBLE = 12; + + public static final int PROCESS_RENDERER_HAS_UNDO_STEPS = 13; + + public static final int PROCESS_RENDERER_HAS_REDO_STEPS = 14; + + public static final int NUMBER_OF_CONDITIONS = 15; + + private final int[] conditions = new int[NUMBER_OF_CONDITIONS]; + + private boolean isDisabledDueToFocusLost; + + public ConditionalAction(String name) { + this(name, null); + } + + public ConditionalAction(String name, Icon icon) { + super(name, icon); + conditions[EDIT_IN_PROGRESS] = DISALLOWED; + if (SwingUtilities.isEventDispatchThread()) { + ALL_ACTIONS.add(new WeakReference(this)); + } else { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + ALL_ACTIONS.add(new WeakReference(ConditionalAction.this)); + } + }); + } + } + + /** + * @param index + * one out of OPERATOR_SELECTED, OPERATOR_CHAIN_SELECTED, ROOT_SELECTED, + * CLIPBOARD_FILLED, and PROCESS_RUNNING + * @param condition + * one out of DISALLOWED, DONT_CARE, and MANDATORY + */ + public void setCondition(int index, int condition) { + conditions[index] = condition; + } + + /** Updates all actions. */ + public static void updateAll(boolean[] states) { + Iterator> i = ALL_ACTIONS.iterator(); + while (i.hasNext()) { + WeakReference ref = i.next(); + ConditionalAction c = ref.get(); + if (c == null) { + i.remove(); + } else { + c.update(states); + } + } + } + + /** + * Updates an action given the set of states that can be true or false. States refer to + * OPERATOR_SELECTED... An action is enabled iff for all states the condition is MANDATORY and + * state is true or DISALLOWED and state is false. If for all states the condition is DONT_CARE, + * the enabling status of the action is not touched. + */ + protected void update(boolean[] state) { + // if this action is disabled due to a focus loss never change its enabled state here + if (isDisabledDueToFocusLost) { + return; + } + + boolean ok = true; + boolean ignore = true; + for (int i = 0; i < conditions.length; i++) { + if (conditions[i] != DONT_CARE) { + ignore = false; + if (((conditions[i] == MANDATORY) && (state[i] == false)) + || ((conditions[i] == DISALLOWED) && (state[i] == true))) { + ok = false; + break; + } + } + } + if (!ignore) { + setEnabled(ok); + } + } + + public boolean isDisabledDueToFocusLost() { + return isDisabledDueToFocusLost; + } + + /** + * If set to true, will not enable itself to condition changes. + * + * @param isDisabledDueToFocusLost + */ + public void setDisabledDueToFocusLost(boolean isDisabledDueToFocusLost) { + this.isDisabledDueToFocusLost = isDisabledDueToFocusLost; + } +} diff --git a/src/main/java/com/rapidminer/gui/DockableMenu.java b/src/main/java/com/rapidminer/gui/DockableMenu.java new file mode 100644 index 000000000..03eb7dee0 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/DockableMenu.java @@ -0,0 +1,163 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; + +import com.rapidminer.gui.processeditor.ProcessLogTab; +import com.rapidminer.gui.processeditor.results.ResultDisplay; +import com.rapidminer.gui.processeditor.results.ResultTab; +import com.rapidminer.gui.tools.ResourceDockKey; +import com.rapidminer.gui.tools.ResourceMenu; +import com.rapidminer.tools.SystemInfoUtilities; +import com.rapidminer.tools.SystemInfoUtilities.OperatingSystem; +import com.vlsolutions.swing.docking.DockKey; +import com.vlsolutions.swing.docking.DockableState; +import com.vlsolutions.swing.docking.DockingContext; +import com.vlsolutions.swing.docking.DummyDockable; + + +/** + * + * @author Simon Fischer + */ +public class DockableMenu extends ResourceMenu { + + private static final long serialVersionUID = -5602297374075268751L; + + private static final List HIDE_IN_DOCKABLE_MENU_PREFIX_REGISTRY = new LinkedList<>(); + + /** + * Here you can register prefixes that will be used to test if a {@link DockableState} start + * with the provided prefix and thus won't be shown in the created {@link DockableMenu}. + * + * @param prefix + * the prefix of {@link DockableState} {@link DockKey}s to hide + */ + public static void registerHideInDockableMenuPrefix(String prefix) { + HIDE_IN_DOCKABLE_MENU_PREFIX_REGISTRY.add(prefix); + } + + static { + registerHideInDockableMenuPrefix(ResultTab.DOCKKEY_PREFIX); + registerHideInDockableMenuPrefix(ProcessLogTab.DOCKKEY_PREFIX); + } + + // private DockingDesktop dockingDesktop; + private final DockingContext dockingContext; + + public DockableMenu(DockingContext dockingContext) { + super("show_view"); + this.dockingContext = dockingContext; + addMenuListener(new MenuListener() { + + @Override + public void menuCanceled(MenuEvent e) {} + + @Override + public void menuDeselected(MenuEvent e) {} + + @Override + public void menuSelected(MenuEvent e) { + fill(); + } + }); + } + + private void fill() { + removeAll(); + DockableState[] dockables = dockingContext.getDesktopList().get(0).getDockables(); + List sorted = new LinkedList<>(); + sorted.addAll(Arrays.asList(dockables)); + Collections.sort(sorted, new Comparator() { + + @Override + public int compare(DockableState o1, DockableState o2) { + return o1.getDockable().getDockKey().getName().compareTo(o2.getDockable().getDockKey().getName()); + } + }); + for (final DockableState state : sorted) { + if (state.getDockable() instanceof DummyDockable) { + continue; + } + DockKey dockKey = state.getDockable().getDockKey(); + boolean cont = false; + for (String prefix : HIDE_IN_DOCKABLE_MENU_PREFIX_REGISTRY) { + if (dockKey.getKey().startsWith(prefix)) { + cont = true; + break; + } + } + if (cont) { + continue; + } + String description = null; + if (dockKey instanceof ResourceDockKey) { + description = ((ResourceDockKey) dockKey).getShortDescription(); + } + description = description != null ? description : ""; + String text = dockKey.getName(); + if (SystemInfoUtilities.getOperatingSystem() != OperatingSystem.OSX) { + // OS X cannot use html in menus so only do it for other OS + text = "

    " + dockKey.getName() + "
    " + description + "

    "; + } + JCheckBoxMenuItem item = new JCheckBoxMenuItem(text, dockKey.getIcon()); + + item.setSelected(!state.isClosed()); + item.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + if (state.isClosed()) { + dockingContext.getDesktopList().get(0).addDockable(state.getDockable()); + } else { + dockingContext.getDesktopList().get(0).close(state.getDockable()); + } + } + + }); + + // special handling for results overview dockable in Results perspective + // this dockable is not allowed to be closed so we disable this item while in said + // perspective + if (RapidMinerGUI.getMainFrame().getPerspectiveController().getModel().getSelectedPerspective().getName() + .equals(PerspectiveModel.RESULT) + && ResultDisplay.RESULT_DOCK_KEY.equals(state.getDockable().getDockKey().getKey())) { + item.setEnabled(false); + } + + add(item); + } + + } + + public DockingContext getDockingContext() { + return dockingContext; + } +} diff --git a/src/main/java/com/rapidminer/gui/DummyObjectVisualizer.java b/src/main/java/com/rapidminer/gui/DummyObjectVisualizer.java new file mode 100644 index 000000000..d377ec6ab --- /dev/null +++ b/src/main/java/com/rapidminer/gui/DummyObjectVisualizer.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import com.rapidminer.ObjectVisualizer; +import com.rapidminer.gui.tools.SwingTools; + + +/** + * A dummy visualizer, capable of visualizing anything, but actually doing nothing. + * + * @author Michael Wurst, Ingo Mierswa + */ +public class DummyObjectVisualizer implements ObjectVisualizer { + + @Override + public void startVisualization(Object objId) { + SwingTools.showVerySimpleErrorMessage("no_visual_for_obj", objId); + } + + @Override + public void stopVisualization(Object objId) {} + + @Override + public String getTitle(Object objId) { + return objId.toString(); + } + + @Override + public boolean isCapableToVisualize(Object id) { + return true; + } + + @Override + public String getDetailData(Object id, String fieldName) { + return null; + } + + @Override + public String[] getFieldNames(Object id) { + return new String[0]; + } +} diff --git a/src/main/java/com/rapidminer/gui/EditorCellRenderer.java b/src/main/java/com/rapidminer/gui/EditorCellRenderer.java new file mode 100644 index 000000000..5a8412df6 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/EditorCellRenderer.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.awt.Component; + +import javax.swing.JTable; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; + + +/** + * A TableCellRenderer that renders the cell by using a TableCellEditor, i.e. the same component is + * shown during editing and rendering. + * + * @author Ingo Mierswa, Simon Fischer Exp $ + */ +public class EditorCellRenderer implements TableCellRenderer { + + private TableCellEditor editor; + + public EditorCellRenderer(TableCellEditor editor) { + this.editor = editor; + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, + int row, int column) { + return editor.getTableCellEditorComponent(table, value, isSelected, row, column); + } + +} diff --git a/src/main/java/com/rapidminer/gui/ExampleVisualizer.java b/src/main/java/com/rapidminer/gui/ExampleVisualizer.java new file mode 100644 index 000000000..be1d58919 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/ExampleVisualizer.java @@ -0,0 +1,196 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.awt.Dimension; +import java.util.Date; +import java.util.Iterator; + +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; + +import com.rapidminer.ObjectVisualizer; +import com.rapidminer.example.Attribute; +import com.rapidminer.example.Example; +import com.rapidminer.example.ExampleSet; +import com.rapidminer.gui.properties.PropertyPanel; +import com.rapidminer.gui.tools.ExtendedJScrollPane; +import com.rapidminer.gui.tools.ExtendedJTable; +import com.rapidminer.gui.tools.dialogs.ButtonDialog; +import com.rapidminer.gui.tools.dialogs.ButtonDialog.ButtonDialogBuilder; +import com.rapidminer.gui.tools.dialogs.ButtonDialog.ButtonDialogBuilder.DefaultButtons; +import com.rapidminer.tools.Ontology; +import com.rapidminer.tools.Tools; + + +/** + * A visualizer which shows the attribute values of an example. This is the most simple visualizer + * which should work in all cases. + * + * @author Ingo Mierswa, Tobias Malbrecht + */ +public class ExampleVisualizer implements ObjectVisualizer { + + private final ExampleSet exampleSet; + + private final Attribute idAttribute; + + private boolean isExampleSetRemapped = false; + + public ExampleVisualizer(ExampleSet exampleSet) { + this.exampleSet = exampleSet; + this.idAttribute = exampleSet.getAttributes().getId(); + } + + @Override + public void startVisualization(final Object objId) { + remapIds(); + + double idValue = Double.NaN; + if (idAttribute.isNominal()) { + idValue = objId instanceof String ? idAttribute.getMapping().mapString((String) objId) : (Double) objId; + } else { + idValue = objId instanceof String ? Double.parseDouble((String) objId) : (Double) objId; + } + Example example = exampleSet.getExampleFromId(idValue); + JComponent main; + if (example != null) { + main = makeMainVisualizationComponent(example); + } else { + main = new JLabel("No information available for object '" + objId + "'."); + } + + ButtonDialogBuilder builder = new ButtonDialogBuilder("example_visualizer_dialog"); + JDialog dialog = builder.setI18nArguments(objId).setContent(main, ButtonDialog.NARROW) + .setButtons(DefaultButtons.CLOSE_BUTTON).build(); + dialog.setVisible(true); + } + + private String getFormattedValue(Example example, Attribute attribute) { + double value = example.getValue(attribute); + if (Double.isNaN(value)) { + return "?"; + } + if (attribute.isNominal()) { + return attribute.getMapping().mapIndex((int) value); + } else { + switch (attribute.getValueType()) { + case Ontology.INTEGER: + return Tools.formatIntegerIfPossible(value); + case Ontology.REAL: + return Tools.formatNumber(value); + case Ontology.NUMERICAL: + return Tools.formatNumber(value); + case Ontology.DATE: + return Tools.formatDate(new Date((long) value)); + case Ontology.TIME: + return Tools.formatTime(new Date((long) value)); + case Ontology.DATE_TIME: + return Tools.formatDateTime(new Date((long) value)); + } + } + ; + return ""; + } + + protected JComponent makeMainVisualizationComponent(Example example) { + JComponent main; + String[] columnNames = new String[] { "Attribute", "Value" }; + String[][] data = new String[exampleSet.getAttributes().allSize()][2]; + Iterator a = exampleSet.getAttributes().allAttributes(); + int counter = 0; + while (a.hasNext()) { + Attribute attribute = a.next(); + data[counter][0] = attribute.getName(); + data[counter][1] = getFormattedValue(example, attribute); + counter++; + } + ExtendedJTable table = new ExtendedJTable(); + table.setDefaultEditor(Object.class, null); + TableModel tableModel = new DefaultTableModel(data, columnNames); + table.setRowHighlighting(true); + table.setRowHeight(PropertyPanel.VALUE_CELL_EDITOR_HEIGHT); + table.setModel(tableModel); + main = new ExtendedJScrollPane(table); + main.setBorder(null); + int tableHeight = (int) (table.getPreferredSize().getHeight() + + table.getTableHeader().getPreferredSize().getHeight() + 5); // 5 for border + if (tableHeight < main.getPreferredSize().getHeight()) { + main.setPreferredSize(new Dimension((int) main.getPreferredSize().getWidth(), tableHeight)); + } + return main; + }; + + @Override + public String getDetailData(Object objId, String fieldName) { + remapIds(); + double idValue = Double.NaN; + + if (idAttribute.isNominal()) { + idValue = objId instanceof String ? idAttribute.getMapping().mapString((String) objId) : (Double) objId; + } else { + idValue = objId instanceof String ? Double.parseDouble((String) objId) : (Double) objId; + } + + Example example = exampleSet.getExampleFromId(idValue); + + Attribute attribute = exampleSet.getAttributes().get(fieldName); + if (attribute != null) { + return example.getValueAsString(attribute); + } else { + return null; + } + } + + @Override + public String[] getFieldNames(Object id) { + return com.rapidminer.example.Tools.getAllAttributeNames(exampleSet); + } + + /** Does nothing. */ + @Override + public void stopVisualization(Object objId) {} + + @Override + public String getTitle(Object objId) { + return objId instanceof String ? (String) objId : ((Double) objId).toString(); + } + + @Override + public boolean isCapableToVisualize(Object id) { + remapIds(); + if (idAttribute.isNominal()) { + double idValue = id instanceof String ? idAttribute.getMapping().mapString((String) id) : (Double) id; + return exampleSet.getExampleFromId(idValue) != null; + } else { + double idValue = id instanceof String ? Double.parseDouble((String) id) : (Double) id; + return exampleSet.getExampleFromId(idValue) != null; + } + } + + private void remapIds() { + if (!isExampleSetRemapped) { + this.exampleSet.remapIds(); + this.isExampleSetRemapped = true; + } + } +} diff --git a/src/main/java/com/rapidminer/gui/GUIInputHandler.java b/src/main/java/com/rapidminer/gui/GUIInputHandler.java new file mode 100644 index 000000000..1f134fffb --- /dev/null +++ b/src/main/java/com/rapidminer/gui/GUIInputHandler.java @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import com.rapidminer.InputHandler; + +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; + +import javax.swing.JDialog; +import javax.swing.JOptionPane; +import javax.swing.JPasswordField; +import javax.swing.SwingUtilities; + + +/** + * An input handler using a JOptionPane. + * + * @author Simon Fischer, Ingo Mierswa + */ +public class GUIInputHandler implements InputHandler { + + @Override + public String inputPassword(String messageText) { + final JPasswordField passwordField = new JPasswordField(); + JOptionPane jop = new JOptionPane(new Object[] { messageText, passwordField }, JOptionPane.QUESTION_MESSAGE, + JOptionPane.OK_CANCEL_OPTION); + JDialog dialog = jop.createDialog("Auhtentication required"); + dialog.addComponentListener(new ComponentAdapter() { + + @Override + public void componentShown(ComponentEvent e) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + passwordField.requestFocusInWindow(); + passwordField.requestFocus(); + } + }); + } + }); + dialog.setVisible(true); + int result = (Integer) jop.getValue(); + if (result == JOptionPane.OK_OPTION) { + return new String(passwordField.getPassword()); + } else { + return null; + } + } +} diff --git a/src/main/java/com/rapidminer/gui/GeneralProcessListener.java b/src/main/java/com/rapidminer/gui/GeneralProcessListener.java new file mode 100644 index 000000000..c5287af06 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/GeneralProcessListener.java @@ -0,0 +1,81 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import com.rapidminer.Process; +import com.rapidminer.ProcessListener; +import com.rapidminer.RapidMiner; +import com.rapidminer.gui.processeditor.ProcessEditor; +import com.rapidminer.operator.Operator; + +import java.util.List; + + +/** + * This listener must be created after the GUI is set up. It will then register automatically with + * every newly created or opened process. + * + * @author Simon Fischer + * + */ +public abstract class GeneralProcessListener implements ProcessListener { + + private Process process; + + public GeneralProcessListener(MainFrame mainFrame) { + register(mainFrame); + } + + public GeneralProcessListener() { + this(null); + } + + private void register(MainFrame mainFrame) { + if (!RapidMiner.getExecutionMode().isHeadless()) { + final ProcessEditor processEditor = new ProcessEditor() { + + @Override + public void processChanged(Process process) { + if (GeneralProcessListener.this.process != null) { + GeneralProcessListener.this.process.getRootOperator().removeProcessListener( + GeneralProcessListener.this); + } + GeneralProcessListener.this.process = process; + if (GeneralProcessListener.this.process != null) { + GeneralProcessListener.this.process.getRootOperator() + .addProcessListener(GeneralProcessListener.this); + } + } + + @Override + public void processUpdated(Process process) {} + + @Override + public void setSelection(List selection) {} + + }; + if (mainFrame == null) { + RapidMinerGUI.getMainFrame().addProcessEditor(processEditor); + } else { + mainFrame.addProcessEditor(processEditor); + } + } + } + +} diff --git a/src/main/java/com/rapidminer/gui/MainFrame.java b/src/main/java/com/rapidminer/gui/MainFrame.java new file mode 100644 index 000000000..1661ed422 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/MainFrame.java @@ -0,0 +1,1849 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JToolBar; +import javax.swing.SwingUtilities; +import javax.swing.Timer; +import javax.swing.event.EventListenerList; + +import com.rapidminer.BreakpointListener; +import com.rapidminer.Process; +import com.rapidminer.ProcessLocation; +import com.rapidminer.ProcessStorageListener; +import com.rapidminer.RapidMiner; +import com.rapidminer.RapidMiner.ExitMode; +import com.rapidminer.core.io.data.source.DataSourceFactoryRegistry; +import com.rapidminer.core.license.ProductConstraintManager; +import com.rapidminer.gui.actions.AboutAction; +import com.rapidminer.gui.actions.Actions; +import com.rapidminer.gui.actions.AutoWireAction; +import com.rapidminer.gui.actions.ExitAction; +import com.rapidminer.gui.actions.ExportProcessAction; +import com.rapidminer.gui.actions.ImportDataAction; +import com.rapidminer.gui.actions.ImportProcessAction; +import com.rapidminer.gui.actions.NewPerspectiveAction; +import com.rapidminer.gui.actions.PauseAction; +import com.rapidminer.gui.actions.PropagateRealMetaDataAction; +import com.rapidminer.gui.actions.RedoAction; +import com.rapidminer.gui.actions.RunAction; +import com.rapidminer.gui.actions.SaveAction; +import com.rapidminer.gui.actions.SaveAsAction; +import com.rapidminer.gui.actions.SettingsAction; +import com.rapidminer.gui.actions.StopAction; +import com.rapidminer.gui.actions.ToggleAction; +import com.rapidminer.gui.actions.UndoAction; +import com.rapidminer.gui.actions.ValidateAutomaticallyAction; +import com.rapidminer.gui.actions.ValidateProcessAction; +import com.rapidminer.gui.actions.export.ShowPrintAndExportDialogAction; +import com.rapidminer.gui.actions.startup.NewAction; +import com.rapidminer.gui.actions.startup.OpenAction; +import com.rapidminer.gui.dialog.UnknownParametersInfoDialog; +import com.rapidminer.gui.flow.ErrorTable; +import com.rapidminer.gui.flow.ProcessPanel; +import com.rapidminer.gui.flow.ProcessUndoManager; +import com.rapidminer.gui.flow.processrendering.annotations.model.WorkflowAnnotation; +import com.rapidminer.gui.flow.processrendering.event.ProcessRendererAnnotationEvent; +import com.rapidminer.gui.flow.processrendering.event.ProcessRendererEventListener; +import com.rapidminer.gui.flow.processrendering.event.ProcessRendererModelEvent; +import com.rapidminer.gui.flow.processrendering.event.ProcessRendererOperatorEvent; +import com.rapidminer.gui.flow.processrendering.event.ProcessRendererOperatorEvent.OperatorEvent; +import com.rapidminer.gui.flow.processrendering.model.ProcessRendererModel; +import com.rapidminer.gui.license.LicenseTools; +import com.rapidminer.gui.look.Colors; +import com.rapidminer.gui.operatortree.OperatorTree; +import com.rapidminer.gui.operatortree.OperatorTreePanel; +import com.rapidminer.gui.operatortree.actions.CutCopyPasteDeleteAction; +import com.rapidminer.gui.operatortree.actions.ToggleBreakpointItem; +import com.rapidminer.gui.osx.OSXAdapter; +import com.rapidminer.gui.osx.OSXQuitListener; +import com.rapidminer.gui.processeditor.ExtendedProcessEditor; +import com.rapidminer.gui.processeditor.MacroViewer; +import com.rapidminer.gui.processeditor.NewOperatorEditor; +import com.rapidminer.gui.processeditor.ProcessContextProcessEditor; +import com.rapidminer.gui.processeditor.ProcessEditor; +import com.rapidminer.gui.processeditor.XMLEditor; +import com.rapidminer.gui.processeditor.results.ResultDisplay; +import com.rapidminer.gui.processeditor.results.ResultDisplayTools; +import com.rapidminer.gui.properties.OperatorPropertyPanel; +import com.rapidminer.gui.security.PasswordManager; +import com.rapidminer.gui.tools.ProcessGUITools; +import com.rapidminer.gui.tools.ProgressThread; +import com.rapidminer.gui.tools.ResourceAction; +import com.rapidminer.gui.tools.ResourceMenu; +import com.rapidminer.gui.tools.ResultWarningPreventionRegistry; +import com.rapidminer.gui.tools.SwingTools; +import com.rapidminer.gui.tools.SystemMonitor; +import com.rapidminer.gui.tools.bubble.BubbleWindow; +import com.rapidminer.gui.tools.dialogs.ConfirmDialog; +import com.rapidminer.gui.tools.dialogs.DecisionRememberingConfirmDialog; +import com.rapidminer.gui.tools.dialogs.wizards.dataimport.DataImportWizardFactory; +import com.rapidminer.gui.tools.dialogs.wizards.dataimport.DataImportWizardRegistry; +import com.rapidminer.gui.tools.ioobjectcache.IOObjectCacheViewer; +import com.rapidminer.gui.tools.logging.LogViewer; +import com.rapidminer.operator.IOContainer; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorChain; +import com.rapidminer.operator.UnknownParameterInformation; +import com.rapidminer.operator.ports.Port; +import com.rapidminer.parameter.ParameterType; +import com.rapidminer.repository.RepositoryLocation; +import com.rapidminer.repository.gui.RepositoryBrowser; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Observable; +import com.rapidminer.tools.Observer; +import com.rapidminer.tools.ParameterService; +import com.rapidminer.tools.ProcessTools; +import com.rapidminer.tools.SystemInfoUtilities; +import com.rapidminer.tools.SystemInfoUtilities.OperatingSystem; +import com.rapidminer.tools.config.ConfigurationManager; +import com.rapidminer.tools.config.gui.ConfigurableDialog; +import com.rapidminer.tools.container.Pair; +import com.rapidminer.tutorial.Tutorial; +import com.rapidminer.tutorial.gui.TutorialBrowser; +import com.rapidminer.tutorial.gui.TutorialSelector; +import com.vlsolutions.swing.docking.DockGroup; +import com.vlsolutions.swing.docking.Dockable; +import com.vlsolutions.swing.docking.DockingContext; +import com.vlsolutions.swing.docking.DockingDesktop; +import com.vlsolutions.swing.toolbars.ToolBarContainer; + + +/** + * The main component class of the RapidMiner GUI. The class holds a lot of Actions that can be used + * for the tool bar and for the menu bar. MainFrame has methods for handling the process (saving, + * opening, creating new). It keeps track of the state of the process and enables/disables buttons. + * It must be notified whenever the process changes and propagates this event to its children. Most + * of the code is enclosed within the Actions. + * + * @author Ingo Mierswa, Simon Fischer, Sebastian Land, Marius Helf + */ +public class MainFrame extends ApplicationFrame implements WindowListener { + + private static final long serialVersionUID = 1L; + + /** The property name for "The pixel size of each plot in matrix plots." */ + public static final String PROPERTY_RAPIDMINER_GUI_PLOTTER_MATRIXPLOT_SIZE = "rapidminer.gui.plotter.matrixplot.size"; + + /** + * The property name for "The maximum number of rows used for a plotter, using only a + * sample of this size if more rows are available." + */ + public static final String PROPERTY_RAPIDMINER_GUI_PLOTTER_ROWS_MAXIMUM = "rapidminer.gui.plotter.rows.maximum"; + + /** + * The property name for the " The maximum number of examples in a data set for which + * default plotter settings will be generated." + */ + public static final String PROPERTY_RAPIDMINER_GUI_PLOTTER_DEFAULT_MAXIMUM = "rapidminer.gui.plotter.default.maximum"; + + /** + * The property name for "Limit number of displayed classes plotter legends. -1 for no + * limit." + */ + public static final String PROPERTY_RAPIDMINER_GUI_PLOTTER_LEGEND_CLASSLIMIT = "rapidminer.gui.plotter.legend.classlimit"; + + /** The property name for "The color for minimum values of the plotter legend." */ + public static final String PROPERTY_RAPIDMINER_GUI_PLOTTER_LEGEND_MINCOLOR = "rapidminer.gui.plotter.legend.mincolor"; + + /** The property name for "The color for maximum values of the plotter legend." */ + public static final String PROPERTY_RAPIDMINER_GUI_PLOTTER_LEGEND_MAXCOLOR = "rapidminer.gui.plotter.legend.maxcolor"; + + /** + * The property name for "Limit number of displayed classes for colorized plots. -1 for no + * limit." + */ + public static final String PROPERTY_RAPIDMINER_GUI_PLOTTER_COLORS_CLASSLIMIT = "rapidminer.gui.plotter.colors.classlimit"; + + /** The property name for "Maximum number of states in the undo list." */ + public static final String PROPERTY_RAPIDMINER_GUI_UNDOLIST_SIZE = "rapidminer.gui.undolist.size"; + + /** + * The property name for "Maximum number of examples to use for the attribute editor. -1 + * for no limit." + */ + public static final String PROPERTY_RAPIDMINER_GUI_ATTRIBUTEEDITOR_ROWLIMIT = "rapidminer.gui.attributeeditor.rowlimit"; + + /** The property name for "Beep on process success?" */ + public static final String PROPERTY_RAPIDMINER_GUI_BEEP_SUCCESS = "rapidminer.gui.beep.success"; + + /** The property name for "Beep on error?" */ + public static final String PROPERTY_RAPIDMINER_GUI_BEEP_ERROR = "rapidminer.gui.beep.error"; + + /** The property name for "Beep when breakpoint reached?" */ + public static final String PROPERTY_RAPIDMINER_GUI_BEEP_BREAKPOINT = "rapidminer.gui.beep.breakpoint"; + + /** + * The property name for "Limit number of displayed rows in the message viewer. -1 for no + * limit." + */ + public static final String PROPERTY_RAPIDMINER_GUI_MESSAGEVIEWER_ROWLIMIT = "rapidminer.gui.messageviewer.rowlimit"; + + /** The property name for "Shows process info screen after loading?" */ + public static final String PROPERTY_RAPIDMINER_GUI_PROCESSINFO_SHOW = "rapidminer.gui.processinfo.show"; + + public static final String PROPERTY_RAPIDMINER_GUI_SAVE_BEFORE_RUN = "rapidminer.gui.save_before_run"; + + public static final String PROPERTY_RAPIDMINER_GUI_SAVE_ON_PROCESS_CREATION = "rapidminer.gui.save_on_process_creation"; + + /** + * The property determining whether or not to switch to result view when results are produced. + */ + public static final String PROPERTY_RAPIDMINER_GUI_AUTO_SWITCH_TO_RESULTVIEW = "rapidminer.gui.auto_switch_to_resultview"; + + /** Log level of the LoggingViewer. */ + public static final String PROPERTY_RAPIDMINER_GUI_LOG_LEVEL = "rapidminer.gui.log_level"; + + private static final int MAX_LOCATION_TITLE_LENGTH = 150; + + private static final String getFrameTitle() { + return "RapidMiner Studio " + + LicenseTools.translateProductEdition(ProductConstraintManager.INSTANCE.getActiveLicense()) + " " + + RapidMiner.getLongVersion(); + } + + // -------------------------------------------------------------------------------- + + public static final int EDIT_MODE = 0; + public static final int RESULTS_MODE = 1; + + private final EventListenerList processEditors = new EventListenerList(); + + public final transient Action AUTO_WIRE = new AutoWireAction(this); + + public final transient Action NEW_ACTION = new NewAction(); + public final transient Action OPEN_ACTION = new OpenAction(); + public final transient SaveAction SAVE_ACTION = new SaveAction(); + public final transient Action SAVE_AS_ACTION = new SaveAsAction(); + public final transient ToggleAction PROPAGATE_REAL_METADATA_ACTION = new PropagateRealMetaDataAction(this); + + private final transient Action importDataAction = new ImportDataAction(); + public final transient Action IMPORT_PROCESS_ACTION = new ImportProcessAction(); + public final transient Action EXPORT_PROCESS_ACTION = new ExportProcessAction(); + + // ---------- Export as Image/Print actions ----------------- + public final transient Action EXPORT_ACTION = new ShowPrintAndExportDialogAction(false); + + public final transient Action EXIT_ACTION = new ExitAction(this); + + public final transient RunAction RUN_ACTION = new RunAction(this); + public final transient Action PAUSE_ACTION = new PauseAction(this); + public final transient Action STOP_ACTION = new StopAction(this); + public final transient Action VALIDATE_ACTION = new ValidateProcessAction(this); + public final transient ToggleAction VALIDATE_AUTOMATICALLY_ACTION = new ValidateAutomaticallyAction(); + + private transient JButton runRemoteToolbarButton; + + public final transient Action NEW_PERSPECTIVE_ACTION = new NewPerspectiveAction(this); + public final transient Action SETTINGS_ACTION = new SettingsAction(); + public final transient Action UNDO_ACTION = new UndoAction(this); + public final transient Action REDO_ACTION = new RedoAction(this); + public final transient Action MANAGE_CONFIGURABLES_ACTION = new ResourceAction(true, "manage_configurables") { + + private static final long serialVersionUID = 1L; + + @Override + public void actionPerformed(final ActionEvent e) { + ConfigurableDialog dialog = new ConfigurableDialog(process); + dialog.setVisible(true); + } + }; + + // -------------------------------------------------------------------------------- + + // DOCKING + + public static final DockGroup DOCK_GROUP_ROOT = new DockGroup("root"); + public static final DockGroup DOCK_GROUP_RESULTS = new DockGroup("results"); + + private final LinkedList storageListeners = new LinkedList<>(); + private final DockingContext dockingContext = new DockingContext(); + private final DockingDesktop dockingDesktop = new DockingDesktop("mainDesktop", dockingContext); + + private final Actions actions = new Actions(this); + + private final ResultDisplay resultDisplay = ResultDisplayTools.makeResultDisplay(); + private final LogViewer logViewer = new LogViewer(this); + private final IOObjectCacheViewer ioobjectCacheViewer = new IOObjectCacheViewer(RapidMiner.getGlobalIOObjectCache()); + private final SystemMonitor systemMonitor = new SystemMonitor(); + + private final OperatorDocumentationBrowser operatorDocumentationBrowser = new OperatorDocumentationBrowser(); + private final OperatorTreePanel operatorTree = new OperatorTreePanel(this); + private final ErrorTable errorTable = new ErrorTable(this); + private final OperatorPropertyPanel propertyPanel = new OperatorPropertyPanel(this); + private final XMLEditor xmlEditor = new XMLEditor(this); + private final ProcessContextProcessEditor processContextEditor = new ProcessContextProcessEditor(); + private final ProcessPanel processPanel = new ProcessPanel(this); + private final NewOperatorEditor newOperatorEditor = new NewOperatorEditor( + processPanel.getProcessRenderer().getDragListener()); + private final RepositoryBrowser repositoryBrowser = new RepositoryBrowser( + processPanel.getProcessRenderer().getDragListener()); + private final MacroViewer macroViewer = new MacroViewer(); + + private final PerspectiveController perspectiveController = new PerspectiveController(dockingContext); + private final TutorialSelector tutorialSelector = new TutorialSelector(this, perspectiveController.getModel()); + private final TutorialBrowser tutorialBrowser = new TutorialBrowser(tutorialSelector); + + /** + * @deprecated use {@link #perspectiveController} instead + */ + @Deprecated + private final Perspectives perspectives = new Perspectives(perspectiveController); + + private boolean changed = false; + private int undoIndex; + + /** the bubble which displays a warning that no result ports are connected */ + private BubbleWindow noResultConnectionBubble; + /** the bubble which displays a warning that a port must receive input but is not connected */ + private BubbleWindow missingInputBubble; + /** + * the bubble which displays a warning that a parameter must be set as he has no default value + */ + private BubbleWindow missingParameterBubble; + + private final JMenuBar menuBar; + + private final MainToolBar toolBar; + + private final JMenu fileMenu; + + private final JMenu editMenu; + + private final JMenu processMenu; + + private final JMenu settingsMenu; + + private final JMenu connectionsMenu; + + private final JMenu viewMenu; + + private final JMenu helpMenu; + + private final JMenu extensionsMenu; + + private DockableMenu dockableMenu; + + private final JMenu recentFilesMenu = new ResourceMenu("recent_files"); + + private final ProcessUndoManager undoManager = new ProcessUndoManager(); + + /** XML representation of the process at last validation. */ + private String lastProcessXML; + /** the OperatorChain which was last viewed */ + private OperatorChain lastProcessDisplayedOperatorChain; + + private Insets menuBarInsets = new Insets(0, 0, 0, 5); + + /** + * The host name of the system. Might be empty (no host name will be shown) and will be + * initialized in the first call of {@link #setTitle()}. + */ + private String hostname = null; + + private transient Process process = null; + private transient ProcessThread processThread; + + private final MetaDataUpdateQueue metaDataUpdateQueue = new MetaDataUpdateQueue(this); + + @Deprecated + private transient final DataImportWizardRegistry importWizardRegistry = new DataImportWizardRegistry() { + + private final List factories = new ArrayList<>(); + + @Override + public void register(DataImportWizardFactory factory) { + if (factory == null) { + throw new IllegalArgumentException("factory must not be null"); + } + synchronized (factories) { + factories.add(factory); + } + } + + @Override + public List getFactories() { + synchronized (factories) { + return new ArrayList<>(factories); + } + } + }; + + // -------------------------------------------------------------------------------- + // LISTENERS And OBSERVERS + + private final PerspectiveChangeListener perspectiveChangeListener = new PerspectiveChangeListener() { + + @Override + public void perspectiveChangedTo(Perspective perspective) { + // check all ConditionalActions on perspective switch + getActions().enableActions(); + + // try to request focus for the process renderer so actions are enabled after + // perspective switch and + // ProcessRenderer is visible + if (getProcessPanel().getProcessRenderer().isShowing()) { + getProcessPanel().getProcessRenderer().requestFocusInWindow(); + } + } + }; + + private long lastUpdate = 0; + private final Timer updateTimer = new Timer(500, new ActionListener() { + + @Override + public void actionPerformed(final ActionEvent e) { + updateProcessNow(); + } + }) { + + private static final long serialVersionUID = 1L; + + { + setRepeats(false); + } + }; + + public void addViewSwitchToUndo() { + fireProcessViewChanged(); + String xmlWithoutGUIInformation = process.getRootOperator().getXML(true, false); + if (lastProcessDisplayedOperatorChain != null + && processPanel.getProcessRenderer().getModel().getDisplayedChain() != null + && !processPanel.getProcessRenderer().getModel().getDisplayedChain().getName() + .equals(lastProcessDisplayedOperatorChain.getName())) { + addToUndoList(xmlWithoutGUIInformation, true); + } + lastProcessXML = xmlWithoutGUIInformation; + lastProcessDisplayedOperatorChain = processPanel.getProcessRenderer().getModel().getDisplayedChain(); + } + + private void updateProcessNow() { + lastUpdate = System.currentTimeMillis(); + String xmlWithoutGUIInformation = process.getRootOperator().getXML(true, false); + if (!xmlWithoutGUIInformation.equals(lastProcessXML)) { + addToUndoList(xmlWithoutGUIInformation, false); + validateProcess(false); + } + processPanel.getProcessRenderer().repaint(); + lastProcessXML = xmlWithoutGUIInformation; + lastProcessDisplayedOperatorChain = processPanel.getProcessRenderer().getModel().getDisplayedChain(); + } + + public void validateProcess(final boolean force) { + if (force || process.getProcessState() != Process.PROCESS_STATE_RUNNING) { + metaDataUpdateQueue.validate(process, force); + } + fireProcessUpdated(); + } + + public boolean isProcessRendererFocused() { + return processPanel.getProcessRenderer().hasFocus(); + } + + private transient final Observer processObserver = new Observer() { + + @Override + public void update(final Observable observable, final Process arg) { + // if (process.getProcessState() == Process.PROCESS_STATE_RUNNING) { + // return; + // } + if (System.currentTimeMillis() - lastUpdate > 500) { + updateProcessNow(); + } else { + if (process.getProcessState() == Process.PROCESS_STATE_RUNNING) { + if (!updateTimer.isRunning()) { + updateTimer.start(); + } + } else { + updateProcessNow(); + } + } + } + }; + + private transient final BreakpointListener breakpointListener = new BreakpointListener() { + + @Override + public void breakpointReached(final Process process, final Operator operator, final IOContainer ioContainer, + final int location) { + if (process.equals(MainFrame.this.process)) { + RUN_ACTION.setState(process.getProcessState()); + ProcessThread.beep("breakpoint"); + MainFrame.this.toFront(); + resultDisplay.showData(ioContainer, + "Breakpoint in " + operator.getName() + ", application " + operator.getApplyCount()); + } + } + + /** Since the mainframe triggers the resume itself this method does nothing. */ + @Override + public void resume() { + RUN_ACTION.setState(process.getProcessState()); + } + }; + + private JToolBar buttonToolbar; + + // -------------------------------------------------------------------------------- + + /** Creates a new main frame containing the RapidMiner GUI. */ + public MainFrame() { + super(getFrameTitle()); + + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(this); + if (SystemInfoUtilities.getOperatingSystem() == OperatingSystem.OSX) { + // load dock icon from resources and adapt UI via OSXAdapter class + try { + OSXQuitListener quitListener = new OSXQuitListener() { + + @Override + public void quit() { + RapidMiner.quit(ExitMode.NORMAL); + } + }; + OSXAdapter.adaptUI(this, SETTINGS_ACTION, new AboutAction(this), quitListener); + } catch (Throwable t) { + // catch everything - in case the OSX adapter is called without being on a OS X + // system + // or the Java classes have been removed from OS X JRE it will just log an error + // instead of breaking the program start-up + LogService.getRoot().log(Level.WARNING, "com.rapidminer.gui.MainFrame.could_not_adapt_OSX_look_and_feel", t); + } + } + + addProcessEditor(actions); + addProcessEditor(xmlEditor); + addProcessEditor(propertyPanel); + addProcessEditor(operatorTree); + addProcessEditor(operatorDocumentationBrowser); + addProcessEditor(processPanel); + addProcessEditor(errorTable); + addProcessEditor(processContextEditor); + addProcessEditor(getStatusBar()); + addProcessEditor(resultDisplay); + addProcessEditor(macroViewer); + + SwingTools.setFrameIcon(this); + + // load perspectives now because otherwise the WSDesktop class does not know the nodes and + // won't restore the user customized perspective + perspectiveController.loadAll(); + + dockingContext.addDesktop(dockingDesktop); + dockingDesktop.registerDockable(repositoryBrowser); + dockingDesktop.registerDockable(operatorTree); + dockingDesktop.registerDockable(propertyPanel); + dockingDesktop.registerDockable(processPanel); + dockingDesktop.registerDockable(xmlEditor); + dockingDesktop.registerDockable(newOperatorEditor); + dockingDesktop.registerDockable(errorTable); + dockingDesktop.registerDockable(resultDisplay); + dockingDesktop.registerDockable(logViewer); + dockingDesktop.registerDockable(ioobjectCacheViewer); + dockingDesktop.registerDockable(systemMonitor); + dockingDesktop.registerDockable(operatorDocumentationBrowser); + dockingDesktop.registerDockable(processContextEditor); + dockingDesktop.registerDockable(processPanel.getProcessRenderer().getOverviewPanel()); + dockingDesktop.registerDockable(macroViewer); + dockingDesktop.registerDockable(tutorialBrowser); + + // Test + + ToolBarContainer toolBarContainer = ToolBarContainer.createDefaultContainer(true, true, true, true); + toolBarContainer.setBorder(BorderFactory.createEmptyBorder(6, 3, 0, 3)); + toolBarContainer.setOpaque(true); + toolBarContainer.setBackground(Colors.WINDOW_BACKGROUND); + getContentPane().add(toolBarContainer, BorderLayout.CENTER); + toolBarContainer.add(dockingDesktop, BorderLayout.CENTER); + + systemMonitor.startMonitorThread(); + resultDisplay.getDockKey().setCloseEnabled(false); + resultDisplay.getDockKey().setAutoHideEnabled(false); + resultDisplay.init(this); + + // menu bar + menuBar = new JMenuBar(); + setJMenuBar(menuBar); + + fileMenu = new ResourceMenu("file"); + fileMenu.setMargin(menuBarInsets); + fileMenu.add(NEW_ACTION); + fileMenu.add(OPEN_ACTION); + updateRecentFileList(); + fileMenu.add(recentFilesMenu); + fileMenu.addSeparator(); + fileMenu.add(SAVE_ACTION); + fileMenu.add(SAVE_AS_ACTION); + fileMenu.addSeparator(); + fileMenu.add(importDataAction); + fileMenu.add(IMPORT_PROCESS_ACTION); + fileMenu.add(EXPORT_PROCESS_ACTION); + menuBar.add(fileMenu); + + // edit menu + ((ResourceAction) actions.INFO_OPERATOR_ACTION).addToActionMap(JComponent.WHEN_FOCUSED, true, true, null, + getProcessPanel().getProcessRenderer(), getOperatorTree()); + ((ResourceAction) actions.TOGGLE_ACTIVATION_ITEM).addToActionMap(JComponent.WHEN_FOCUSED, true, true, null, + getProcessPanel().getProcessRenderer(), getOperatorTree()); + ((ResourceAction) actions.RENAME_OPERATOR_ACTION).addToActionMap(JComponent.WHEN_FOCUSED, true, true, null, + getProcessPanel().getProcessRenderer(), getOperatorTree()); + // not added for ProcessRenderer because there the DELETE_SELECTED_CONNECTION action is + // active + ((ResourceAction) actions.DELETE_OPERATOR_ACTION).addToActionMap(JComponent.WHEN_FOCUSED, true, true, null, + getOperatorTree()); + ((ResourceAction) actions.TOGGLE_ALL_BREAKPOINTS).addToActionMap(JComponent.WHEN_FOCUSED, true, true, null, + getProcessPanel().getProcessRenderer(), getOperatorTree()); + editMenu = new ResourceMenu("edit"); + editMenu.setMargin(menuBarInsets); + editMenu.add(UNDO_ACTION); + editMenu.add(REDO_ACTION); + editMenu.addSeparator(); + editMenu.add(actions.INFO_OPERATOR_ACTION); + editMenu.add(actions.TOGGLE_ACTIVATION_ITEM.createMenuItem()); + editMenu.add(actions.RENAME_OPERATOR_ACTION); + editMenu.addSeparator(); + editMenu.add(CutCopyPasteDeleteAction.CUT_ACTION); + editMenu.add(CutCopyPasteDeleteAction.COPY_ACTION); + editMenu.add(CutCopyPasteDeleteAction.PASTE_ACTION); + editMenu.add(CutCopyPasteDeleteAction.DELETE_ACTION); + editMenu.addSeparator(); + for (ToggleBreakpointItem item : actions.TOGGLE_BREAKPOINT) { + editMenu.add(item.createMenuItem()); + } + editMenu.add(actions.TOGGLE_ALL_BREAKPOINTS.createMenuItem()); + // editMenu.add(actions.MAKE_DIRTY_ACTION); + menuBar.add(editMenu); + + // process menu + processMenu = new ResourceMenu("process"); + processMenu.setMargin(menuBarInsets); + processMenu.add(RUN_ACTION); + processMenu.add(PAUSE_ACTION); + processMenu.add(STOP_ACTION); + processMenu.addSeparator(); + processMenu.add(PROPAGATE_REAL_METADATA_ACTION.createMenuItem()); + processMenu.add(VALIDATE_ACTION); + processMenu.add(VALIDATE_AUTOMATICALLY_ACTION.createMenuItem()); + processMenu.addSeparator(); + + processMenu.add(AUTO_WIRE); + processMenu.add(processPanel.getFlowVisualizer().ALTER_EXECUTION_ORDER.createMenuItem()); + JMenu layoutMenu = new ResourceMenu("process_layout"); + layoutMenu.add(processPanel.getProcessRenderer().getArrangeOperatorsAction()); + layoutMenu.add(processPanel.getProcessRenderer().getAutoFitAction()); + processMenu.add(layoutMenu); + menuBar.add(processMenu); + + // view menu + viewMenu = new ResourceMenu("view"); + viewMenu.setMargin(menuBarInsets); + viewMenu.add(new PerspectiveMenu(perspectiveController)); + viewMenu.add(NEW_PERSPECTIVE_ACTION); + viewMenu.add(dockableMenu = new DockableMenu(dockingContext)); + viewMenu.add(perspectiveController.getRestoreDefaultAction()); + menuBar.add(viewMenu); + + // create settings menu (will be added in finishInitialization()) + settingsMenu = new ResourceMenu("settings"); + settingsMenu.setMargin(menuBarInsets); + + // connections menu + connectionsMenu = new ResourceMenu("connections"); + connectionsMenu.setMargin(menuBarInsets); + menuBar.add(connectionsMenu); + + // help menu + helpMenu = new ResourceMenu("help"); + + // extensions menu + extensionsMenu = new ResourceMenu("extensions"); + extensionsMenu.setMargin(menuBarInsets); + + // main tool bar + toolBar = new MainToolBar(this); + + getStatusBar().setBackground(Colors.WINDOW_BACKGROUND); + getContentPane().add(toolBar, BorderLayout.NORTH); + getContentPane().add(getStatusBar(), BorderLayout.SOUTH); + getStatusBar().startClockThread(); + + // listen for selection changes in the ProcessRendererView and notify all registered process + // editors + processPanel.getProcessRenderer().getModel().registerEventListener(new ProcessRendererEventListener() { + + @Override + public void modelChanged(ProcessRendererModelEvent e) { + // ignore + } + + @Override + public void operatorsChanged(ProcessRendererOperatorEvent e, Collection operators) { + if (e.getEventType() == OperatorEvent.SELECTED_OPERATORS_CHANGED) { + for (ProcessEditor editor : processEditors.getListeners(ProcessEditor.class)) { + editor.setSelection(new LinkedList(operators)); + } + for (ExtendedProcessEditor editor : processEditors.getListeners(ExtendedProcessEditor.class)) { + editor.setSelection(new LinkedList(operators)); + } + } + } + + @Override + public void annotationsChanged(ProcessRendererAnnotationEvent e, Collection annotations) { + // ignore + } + }); + + setProcess(new Process(), true); + selectOperator(process.getRootOperator()); + addToUndoList(); + + perspectiveController.getModel().addPerspectiveChangeListener(perspectiveChangeListener); + pack(); + metaDataUpdateQueue.start(); + } + + /** + * Finishes the MainFrame initialization. Should be called after all extension have been + * initialized. + */ + public void finishInitialization() { + + // Configurators (if they exist) + if (!ConfigurationManager.getInstance().isEmpty()) { + connectionsMenu.addSeparator(); + connectionsMenu.add(MANAGE_CONFIGURABLES_ACTION); + } + + // add export and exit as last file menu actions + fileMenu.addSeparator(); + fileMenu.add(EXPORT_ACTION); + fileMenu.addSeparator(); + fileMenu.add(EXIT_ACTION); + + // Password Manager + settingsMenu.add(PasswordManager.OPEN_WINDOW); + if (SystemInfoUtilities.getOperatingSystem() != OperatingSystem.OSX || !OSXAdapter.isAdapted()) { + settingsMenu.add(SETTINGS_ACTION); + } + + // add settings menu as second last menu or third last if there are entries in the help menu + menuBar.add(settingsMenu); + + // add extensions menu as last menu or second last if there are entries in the help + // menu + menuBar.add(extensionsMenu); + + // Add Help menu as last entry if it is not empty + if (helpMenu.getItemCount() > 0) { + helpMenu.setMargin(menuBarInsets); + menuBar.add(helpMenu); + } + } + + public OperatorPropertyPanel getPropertyPanel() { + return propertyPanel; + } + + /** + * Returns a registry for {@link DataImportWizardFactory} instances. The factories are used to + * populate menus such as the main import menu. + * + * @return the registry + * @deprecated Use {@link DataSourceFactoryRegistry} instead. Registering a + * {@link DataImportWizardRegistry} will not have an effect anymore. + */ + @Deprecated + public DataImportWizardRegistry getDataImportWizardRegistry() { + return importWizardRegistry; + } + + public LogViewer getLogViewer() { + return logViewer; + } + + public NewOperatorEditor getNewOperatorEditor() { + return newOperatorEditor; + } + + public OperatorTree getOperatorTree() { + return operatorTree.getOperatorTree(); + } + + public Actions getActions() { + return actions; + } + + public ResultDisplay getResultDisplay() { + return resultDisplay; + } + + /** + * @return the toolbar button for running processes on the Server + */ + public JButton getRunRemoteToolbarButton() { + return runRemoteToolbarButton; + } + + public int getProcessState() { + if (process == null) { + return Process.PROCESS_STATE_UNKNOWN; + } else { + return process.getProcessState(); + } + } + + /** + * @deprecated Use {@link #getProcess()} instead + */ + @Deprecated + public final Process getExperiment() { + return getProcess(); + } + + public final Process getProcess() { + return this.process; + } + + // ==================================================== + // M A I N A C T I O N S + // =================================================== + + /** + * Creates a new process. If there are unsaved changes, the user will be asked to save their + * work. + */ + public void newProcess() { + newProcess(true); + } + + /** + * Creates a new process. Depending on the given parameter, the user will or will not be asked + * to save unsaved changes. + * + * @param checkforUnsavedWork + * Iff {@code true} the user is asked to save their unsaved work (if any), otherwise + * unsaved work is discarded without warning. + */ + public void newProcess(final boolean checkforUnsavedWork) { + // ask for confirmation before stopping the currently running process and opening a new one! + if (getProcessState() == Process.PROCESS_STATE_RUNNING || getProcessState() == Process.PROCESS_STATE_PAUSED) { + if (SwingTools.showConfirmDialog("close_running_process", + ConfirmDialog.YES_NO_OPTION) == ConfirmDialog.NO_OPTION) { + return; + } + } + + ProgressThread newProcessThread = new ProgressThread("new_process") { + + @Override + public void run() { + // Invoking close() will ask the user to save their work if there are unsaved + // changes. This method can be skipped if it is already clear that changes should be + // discarded. + boolean resetProcess = checkforUnsavedWork ? close(false) : true; + if (resetProcess) { + // process changed -> clear undo history + resetUndo(); + + stopProcess(); + changed = false; + setProcess(new Process(), true); + addToUndoList(); + if (!"false" + .equals(ParameterService.getParameterValue(PROPERTY_RAPIDMINER_GUI_SAVE_ON_PROCESS_CREATION))) { + SaveAction.saveAsync(getProcess()); + } + // always have save action enabled. If process is not yet associated with + // location SaveAs will be used + SAVE_ACTION.setEnabled(true); + } + } + }; + newProcessThread.setIndeterminate(true); + newProcessThread.setCancelable(false); + newProcessThread.start(); + } + + /** + * Runs or resumes the current process. If the process is started, checks for potential errors + * first and prevents execution unless the user has disabled the pre-run check. + */ + public void runProcess() { + runProcess(true); + } + + /** + * Runs or resumes the current process. + * + * @param precheckBeforeExecution + * if {@code true} and the process is started, checks for potential errors first and + * prevents execution unless the user has disabled the pre-run check + */ + public void runProcess(boolean precheckBeforeExecution) { + if (getProcessState() == Process.PROCESS_STATE_STOPPED) { + // Run + if (isChanged() || getProcess().getProcessLocation() == null) { + if (DecisionRememberingConfirmDialog.confirmAction("save_before_run", + PROPERTY_RAPIDMINER_GUI_SAVE_BEFORE_RUN)) { + SaveAction.saveAsync(getProcess()); + } + } + + // don't run process if showstoppers are present + // this only returns true if the user did not disable the strict process check in the + // preferences + if (precheckBeforeExecution && doesProcessContainShowstoppers()) { + return; + } + + processThread = new ProcessThread(MainFrame.this.process); + try { + processThread.start(); + } catch (Exception t) { + SwingTools.showSimpleErrorMessage("cannot_start_process", t); + } + } else { + process.resume(); + } + } + + /** + * Can be used to stop the currently running process. Please note that the ProcessThread will + * still be running in the background until the current operator is finished. + */ + public void stopProcess() { + if (getProcessState() != Process.PROCESS_STATE_STOPPED) { + getProcess().getLogger().info("Process stopped. Completing current operator."); + getStatusBar().setSpecialText("Process stopped. Completing current operator."); + if (processThread != null) { + if (processThread.isAlive()) { + processThread.setPriority(Thread.MIN_PRIORITY); + processThread.stopProcess(); + } + } + } + } + + public void pauseProcess() { + if (getProcessState() == Process.PROCESS_STATE_RUNNING) { + getProcess().getLogger().info("Process paused. Completing current operator."); + getStatusBar().setSpecialText("Process paused. Completing current operator."); + if (processThread != null) { + processThread.pauseProcess(); + } + } + } + + /** Will be invoked from the process thread after the process was successfully ended. */ + void processEnded(final Process process, final IOContainer results) { + if (process.equals(MainFrame.this.process)) { + if (results != null) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + MainFrame.this.toFront(); + } + }); + } + } + if (process.equals(MainFrame.this.process)) { + if (results != null) { + resultDisplay.showData(results, "Process results"); + } + } + } + + /** + * Sets a new process and registers the MainFrame listener. Please note that this method does + * not invoke {@link #processChanged()}. Do so if necessary. + * + * @deprecated Use {@link #setProcess(Process, boolean)} instead + */ + @Deprecated + public void setExperiment(final Process process) { + setProcess(process, true); + } + + /** + * Sets a new process and registers the MainFrame's listeners. + */ + public void setProcess(final Process process, final boolean newProcess) { + setProcess(process, newProcess, false); + } + + /** + * Sets a new process and registers the MainFrame's listeners. + */ + public void setProcess(final Process process, final boolean newProcess, final boolean addToUndoList) { + boolean firstProcess = this.process == null; + if (this.process != null) { + // this.process.getRootOperator().removeObserver(processObserver); + this.process.removeObserver(processObserver); + } + + if (getProcessState() != Process.PROCESS_STATE_STOPPED) { + if (processThread != null) { + processThread.stopProcess(); + } + } + + if (process != null) { + // process.getRootOperator().addObserver(processObserver, true); + process.addObserver(processObserver, true); + + synchronized (process) { + this.process = process; + this.processThread = new ProcessThread(this.process); + this.process.addBreakpointListener(breakpointListener); + if (addToUndoList) { + addToUndoList(process.getRootOperator().getXML(true, false), false); + } + fireProcessChanged(); + processPanel.getProcessRenderer().getModel().setDisplayedChain(this.getProcess().getRootOperator()); + processPanel.getProcessRenderer().getModel().fireDisplayedChainChanged(); + selectOperator(this.process.getRootOperator()); + if (VALIDATE_AUTOMATICALLY_ACTION.isSelected()) { + validateProcess(false); + } + } + } + if (newProcess && !firstProcess) { + // VLDocking appears to get nervous when applying two perspectives while the + // window is not yet visible. So to avoid that we set design and then welcome + // during startup, avoid applying design if this is the first process we create. + perspectiveController.showPerspective(PerspectiveModel.DESIGN); + } + setTitle(); + getStatusBar().clearSpecialText(); + } + + /** + * Must be called when the process changed (such that is different from the process before). + * Enables the correct actions if the process can be saved to disk. + * + * @deprecated this method is no longer necessary (and does nothing) since the MainFrame + * observes the process using an Observer pattern. See {@link #processObserver}. + */ + @Deprecated + public void processChanged() {} + + /** Returns true if the process has changed since the last save. */ + public boolean isChanged() { + return changed; + } + + private boolean addToUndoList() { + return addToUndoList(null, false); + } + + /** + * Adds the current state of the process to the undo list. + * + * Note: This method must not be exposed by making it public. It may confuse the MainFrame such + * that it can no longer determine correctly whether validation is possible. + * + * @return true if process really differs. + */ + private boolean addToUndoList(String currentStateXML, final boolean viewSwitch) { + String lastStateXML = null; + if (undoManager.getNumberOfUndos() != 0) { + lastStateXML = undoManager.getXml(undoIndex); + } + + if (currentStateXML == null) { + currentStateXML = this.process.getRootOperator().getXML(true); + } + if (currentStateXML != null) { + // mark as changed only if the XML has changed + if (lastStateXML == null || !lastStateXML.equals(currentStateXML) || viewSwitch) { + if (undoIndex < undoManager.getNumberOfUndos() - 1) { + while (undoManager.getNumberOfUndos() > undoIndex + 1) { + undoManager.removeLast(); + } + } + undoManager.add(currentStateXML, getProcessPanel().getProcessRenderer().getModel().getDisplayedChain(), + getFirstSelectedOperator()); + String maxSizeProperty = ParameterService.getParameterValue(PROPERTY_RAPIDMINER_GUI_UNDOLIST_SIZE); + int maxSize = 20; + try { + if (maxSizeProperty != null) { + maxSize = Integer.parseInt(maxSizeProperty); + } + } catch (NumberFormatException e) { + LogService.getRoot().warning("com.rapidminer.gui.main_frame_warning"); + } + while (undoManager.getNumberOfUndos() > maxSize) { + undoManager.removeFirst(); + } + undoIndex = undoManager.getNumberOfUndos() - 1; + enableUndoAction(); + + boolean oldChangedValue = MainFrame.this.changed; + // mark as changed only if the XML has changed + if (currentStateXML.equals(lastStateXML)) { + return false; + } + + MainFrame.this.changed = lastStateXML != null; + + if (!oldChangedValue) { + setTitle(); + } + if (MainFrame.this.process.getProcessLocation() != null) { + MainFrame.this.SAVE_ACTION.setEnabled(true); + } + return true; + } else { + return false; + } + } else { + return false; + } + } + + public void undo() { + if (undoIndex > 0) { + undoIndex--; + setProcessIntoStateAt(undoIndex, true); + } + enableUndoAction(); + } + + public void redo() { + if (undoIndex < undoManager.getNumberOfUndos()) { + undoIndex++; + setProcessIntoStateAt(undoIndex, false); + } + enableUndoAction(); + } + + private void enableUndoAction() { + if (undoIndex > 0) { + UNDO_ACTION.setEnabled(true); + } else { + UNDO_ACTION.setEnabled(false); + } + if (undoIndex < undoManager.getNumberOfUndos() - 1) { + REDO_ACTION.setEnabled(true); + } else { + REDO_ACTION.setEnabled(false); + } + } + + /** + * Returns true if the current process has undo steps available. + * + * @return + */ + public boolean hasUndoSteps() { + return undoIndex > 0; + } + + /** + * Returns true if the current process has redo steps available. + * + * @return + */ + public boolean hasRedoSteps() { + return undoIndex < undoManager.getNumberOfUndos() - 1; + } + + private void setProcessIntoStateAt(final int undoIndex, final boolean undo) { + String stateXML = undoManager.getXml(undoIndex); + OperatorChain shownOperatorChain = null; + if (undo) { + shownOperatorChain = undoManager.getOperatorChain(undoIndex); + } else { + shownOperatorChain = undoManager.getOperatorChain(undoIndex); + } + Operator selectedOperator = undoManager.getSelectedOperator(undoIndex); + try { + synchronized (process) { + String oldXml = process.getRootOperator().getXML(true); + Process process = new Process(stateXML, this.process); + // this.process.setupFromXML(stateXML); + setProcess(process, false); + // cannot use method processChanged() because this would add the + // old state to the undo stack! + if (!stateXML.equals(oldXml)) { + this.changed = true; + setTitle(); + if (this.process.getProcessLocation() != null) { + this.SAVE_ACTION.setEnabled(true); + } + } + + // restore selected operator + if (selectedOperator != null) { + Operator restoredOperator = getProcess().getOperator(selectedOperator.getName()); + if (restoredOperator != null) { + selectOperator(restoredOperator); + } + } + + // restore process panel view on correct subprocess on undo + if (shownOperatorChain != null) { + OperatorChain restoredOperatorChain = (OperatorChain) getProcess() + .getOperator(shownOperatorChain.getName()); + processPanel.getProcessRenderer().getModel().setDisplayedChain(restoredOperatorChain); + processPanel.getProcessRenderer().getModel().fireDisplayedChainChanged(); + } + } + } catch (Exception e) { + SwingTools.showSimpleErrorMessage("while_changing_process", e); + } + + lastProcessDisplayedOperatorChain = getProcessPanel().getProcessRenderer().getModel().getDisplayedChain(); + lastProcessXML = process.getRootOperator().getXML(true, false); + } + + /** + * Sets the window title (RapidMiner + filename + an asterisk if process was modified. + */ + public void setTitle() { + if (hostname == null) { + try { + hostname = " @ " + InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + hostname = ""; + } + } + + if (this.process != null) { + ProcessLocation loc = process.getProcessLocation(); + if (loc != null) { + String locString = loc.toString(); + // location string exceeding arbitrary number will be cut into repository name + + // /.../ + process name + if (locString.length() > MAX_LOCATION_TITLE_LENGTH) { + locString = RepositoryLocation.REPOSITORY_PREFIX + process.getRepositoryLocation().getRepositoryName() + + RepositoryLocation.SEPARATOR + "..." + RepositoryLocation.SEPARATOR + loc.getShortName(); + } + setTitle(locString + (changed ? "*" : "") + " \u2013 " + getFrameTitle() + hostname); + } else { + setTitle(" \u2013 " + getFrameTitle() + hostname); + } + } else { + setTitle(getFrameTitle() + hostname); + } + } + + // //////////////////// File menu actions //////////////////// + + /** + * Closes the current process + * + * @param askForConfirmation + * if true, will prompt the user if he really wants to close the current + * process + * @return + */ + public boolean close(final boolean askForConfirmation) { + if (changed) { + ProcessLocation loc = process.getProcessLocation(); + String locName; + if (loc != null) { + locName = loc.getShortName(); + } else { + locName = "unnamed"; + } + switch (SwingTools.showConfirmDialog("save", ConfirmDialog.YES_NO_CANCEL_OPTION, locName)) { + case ConfirmDialog.YES_OPTION: + SaveAction.save(getProcess()); + + // it may happen that save() does not actually save the process, because the + // user hits cancel in the + // saveAs dialog or an error occurs. In this case the process won't be marked as + // unchanged. Thus, + // we return the process changed status. + return !isChanged(); + case ConfirmDialog.NO_OPTION: + // ask for confirmation before stopping the currently running process (if + // askForConfirmation=true) + if (askForConfirmation) { + if (RapidMinerGUI.getMainFrame().getProcessState() == Process.PROCESS_STATE_RUNNING + || RapidMinerGUI.getMainFrame().getProcessState() == Process.PROCESS_STATE_PAUSED) { + if (SwingTools.showConfirmDialog("close_running_process", + ConfirmDialog.YES_NO_OPTION) == ConfirmDialog.NO_OPTION) { + return false; + } + } + } + if (getProcessState() != Process.PROCESS_STATE_STOPPED) { + synchronized (processThread) { + processThread.stopProcess(); + } + } + return true; + default: // cancel + return false; + } + } else { + return true; + } + } + + public boolean close() { + return close(true); + } + + public void setOpenedProcess(final Process process, final boolean showInfo, final String sourceName) { + // process changed -> clear undo history + resetUndo(); + + setProcess(process, true); + + if (process.getImportMessage() != null && process.getImportMessage().contains("error")) { + SwingTools.showLongMessage("import_message", process.getImportMessage()); + } + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + SAVE_ACTION.setEnabled(false); + } + }); + + List unknownParameters = null; + synchronized (process) { + RapidMinerGUI.useProcessFile(MainFrame.this.process); + unknownParameters = process.getUnknownParameters(); + } + + addToUndoList(); + updateRecentFileList(); + changed = false; + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + SAVE_ACTION.setEnabled(false); + setTitle(); + } + }); + + // show unsupported parameters info? + if (unknownParameters != null && unknownParameters.size() > 0) { + final UnknownParametersInfoDialog unknownParametersInfoDialog = new UnknownParametersInfoDialog(MainFrame.this, + unknownParameters); + if (SwingUtilities.isEventDispatchThread()) { + unknownParametersInfoDialog.setVisible(true); + } else { + try { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + unknownParametersInfoDialog.setVisible(true); + } + }); + } catch (Exception e) { + LogService.getRoot().log(Level.WARNING, "Error opening the unknown parameter dialog: " + e, e); + } + } + } + fireProcessLoaded(); + } + + private void resetUndo() { + undoIndex = 0; + undoManager.reset(); + enableUndoAction(); + } + + public void exit(final boolean relaunch) { + if (changed) { + ProcessLocation loc = process.getProcessLocation(); + String locName; + if (loc != null) { + locName = loc.getShortName(); + } else { + locName = "unnamed"; + } + switch (SwingTools.showConfirmDialog("save", ConfirmDialog.YES_NO_CANCEL_OPTION, locName)) { + case ConfirmDialog.YES_OPTION: + SaveAction.save(process); + if (changed) { + return; + } + break; + case ConfirmDialog.NO_OPTION: + break; + case ConfirmDialog.CANCEL_OPTION: + default: + return; + } + } else { + if (!relaunch) { // in this case we have already confirmed + // ask for special confirmation before exiting RapidMiner while a process is + // running! + if (getProcessState() == Process.PROCESS_STATE_RUNNING + || getProcessState() == Process.PROCESS_STATE_PAUSED) { + if (SwingTools.showConfirmDialog("exit_despite_running_process", + ConfirmDialog.YES_NO_OPTION) == ConfirmDialog.NO_OPTION) { + return; + } + } else { + int answer = ConfirmDialog.showConfirmDialog(ApplicationFrame.getApplicationFrame(), "exit", + ConfirmDialog.YES_NO_OPTION, RapidMinerGUI.PROPERTY_CONFIRM_EXIT, ConfirmDialog.YES_OPTION); + if (answer != ConfirmDialog.YES_OPTION) { + return; + } + } + } + } + stopProcess(); + dispose(); + RapidMiner.quit(relaunch ? RapidMiner.ExitMode.RELAUNCH : RapidMiner.ExitMode.NORMAL); + } + + /** Updates the list of recently used files. */ + public void updateRecentFileList() { + recentFilesMenu.removeAll(); + List recentFiles = RapidMinerGUI.getRecentFiles(); + int j = 1; + for (final ProcessLocation recentLocation : recentFiles) { + JMenuItem menuItem = new JMenuItem(j + " " + recentLocation.toMenuString()); + menuItem.setMnemonic('0' + j); + menuItem.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(final ActionEvent e) { + if (RapidMinerGUI.getMainFrame().close()) { + com.rapidminer.gui.actions.OpenAction.open(recentLocation, true); + } + } + }); + recentFilesMenu.add(menuItem); + j++; + } + } + + /** + * Update the elements of the main tool bar. + */ + public void updateToolbar() { + toolBar.update(); + } + + @Override + public void windowOpened(final WindowEvent e) {} + + @Override + public void windowClosing(final WindowEvent e) { + exit(false); + } + + @Override + public void windowClosed(final WindowEvent e) {} + + @Override + public void windowIconified(final WindowEvent e) {} + + @Override + public void windowDeiconified(final WindowEvent e) {} + + @Override + public void windowActivated(final WindowEvent e) {} + + @Override + public void windowDeactivated(final WindowEvent e) {} + + /** + * This methods provide plugins the possibility to modify the menus + */ + public void removeMenu(final int index) { + menuBar.remove(menuBar.getMenu(index)); + } + + public void removeMenuItem(final int menuIndex, final int itemIndex) { + menuBar.getMenu(menuIndex).remove(itemIndex); + } + + public void addMenuItem(final int menuIndex, final int itemIndex, final JMenuItem item) { + menuBar.getMenu(menuIndex).add(item, itemIndex); + } + + public void addMenu(int menuIndex, final JMenu menu) { + menu.setMargin(menuBarInsets); + if (menuIndex < -1 || menuIndex >= menuBar.getComponentCount()) { + menuIndex = -1; + } + menuBar.add(menu, menuIndex); + } + + public void addMenuSeparator(final int menuIndex) { + menuBar.getMenu(menuIndex).addSeparator(); + } + + // / LISTENERS + + public List getSelectedOperators() { + return processPanel.getProcessRenderer().getModel().getSelectedOperators(); + } + + public Operator getFirstSelectedOperator() { + return processPanel.getProcessRenderer().getModel().getSelectedOperators().isEmpty() ? null + : processPanel.getProcessRenderer().getModel().getSelectedOperators().get(0); + } + + /** + * @deprecated use {@link #addExtendedProcessEditor(ExtendedProcessEditor)} instead. + */ + @Deprecated + public void addProcessEditor(final ProcessEditor p) { + processEditors.add(ProcessEditor.class, p); + } + + /** + * Adds the given {@link ExtendedProcessEditor} listener. + * + * @param p + */ + public void addExtendedProcessEditor(final ExtendedProcessEditor p) { + processEditors.add(ExtendedProcessEditor.class, p); + } + + /** + * @deprecated use {@link #removeExtendedProcessEditor(ExtendedProcessEditor)} instead. + */ + @Deprecated + public void removeProcessEditor(final ProcessEditor p) { + processEditors.remove(ProcessEditor.class, p); + } + + /** + * Removes the given {@link ExtendedProcessEditor} listener. + * + * @param p + */ + public void removeExtendedProcessEditor(final ExtendedProcessEditor p) { + processEditors.remove(ExtendedProcessEditor.class, p); + } + + public void addProcessStorageListener(final ProcessStorageListener listener) { + storageListeners.add(listener); + } + + public void removeProcessStorageListener(final ProcessStorageListener listener) { + storageListeners.remove(listener); + } + + public void selectOperator(Operator currentlySelected) { + if (currentlySelected == null) { + currentlySelected = process.getRootOperator(); + } + selectOperators(Collections.singletonList(currentlySelected)); + } + + public void selectOperators(List currentlySelected) { + if (currentlySelected == null) { + currentlySelected = Collections. singletonList(process.getRootOperator()); + } + for (Operator op : currentlySelected) { + Process selectedProcess = op.getProcess(); + if (selectedProcess == null || selectedProcess != process) { + SwingTools.showVerySimpleErrorMessage("op_deleted", op.getName()); + return; + } + } + + ProcessRendererModel model = processPanel.getProcessRenderer().getModel(); + model.clearOperatorSelection(); + model.addOperatorsToSelection(currentlySelected); + model.fireOperatorSelectionChanged(currentlySelected); + } + + public void fireProcessUpdated() { + for (ProcessEditor editor : processEditors.getListeners(ProcessEditor.class)) { + editor.processUpdated(process); + } + for (ExtendedProcessEditor editor : processEditors.getListeners(ExtendedProcessEditor.class)) { + editor.processUpdated(process); + } + } + + /** + * Fire this when the process view has changed, e.g. when the user enters/leaves a subprocess in + * the process design panel. + */ + private void fireProcessViewChanged() { + for (ExtendedProcessEditor editor : processEditors.getListeners(ExtendedProcessEditor.class)) { + editor.processViewChanged(process); + } + } + + private void fireProcessChanged() { + for (ProcessEditor editor : processEditors.getListeners(ProcessEditor.class)) { + editor.processChanged(process); + } + for (ExtendedProcessEditor editor : processEditors.getListeners(ExtendedProcessEditor.class)) { + editor.processChanged(process); + } + } + + private void fireProcessLoaded() { + LinkedList list = new LinkedList<>(storageListeners); + for (ProcessStorageListener l : list) { + l.opened(process); + } + } + + private void fireProcessStored() { + LinkedList list = new LinkedList<>(storageListeners); + for (ProcessStorageListener l : list) { + l.stored(process); + } + } + + public DockingDesktop getDockingDesktop() { + return dockingDesktop; + } + + /** + * @deprecated use {@link #getPerspectiveController()} instead + */ + @Deprecated + public Perspectives getPerspectives() { + return perspectives; + } + + public PerspectiveController getPerspectiveController() { + return perspectiveController; + } + + public void handleBrokenProxessXML(final ProcessLocation location, final String xml, final Exception e) { + SwingTools.showSimpleErrorMessage("while_loading", e, location.toString(), e.getMessage()); + Process process = new Process(); + process.setProcessLocation(location); + setProcess(process, true); + perspectiveController.showPerspective(PerspectiveModel.DESIGN); + xmlEditor.setText(xml); + } + + public OperatorDocumentationBrowser getOperatorDocViewer() { + return operatorDocumentationBrowser; + } + + public ProcessPanel getProcessPanel() { + return processPanel; + } + + public void registerDockable(final Dockable dockable) { + dockingDesktop.registerDockable(dockable); + } + + public void processHasBeenSaved() { + SAVE_ACTION.setEnabled(false); + changed = false; + setTitle(); + updateRecentFileList(); + fireProcessStored(); + } + + public ProcessContextProcessEditor getProcessContextEditor() { + return processContextEditor; + } + + public RepositoryBrowser getRepositoryBrowser() { + return repositoryBrowser; + } + + public Component getXMLEditor() { + return xmlEditor; + } + + /** + * This returns the file menu to change menu entries + */ + public JMenu getFileMenu() { + return fileMenu; + } + + /** + * This returns the connections menu to change menu entries + */ + public JMenu getConnectionsMenu() { + return connectionsMenu; + } + + /** + * This returns the settings menu to change menu entries. + * + * @deprecated the tools menu was split into multiple menus. Use {@link #getConnectionsMenu()} + * or {@link #getSettingsMenu()} instead + */ + @Deprecated + public JMenu getToolsMenu() { + return settingsMenu; + } + + /** + * This returns the settings menu to change menu entries + * + * @return the settings menu + */ + public JMenu getSettingsMenu() { + return settingsMenu; + } + + /** + * This returns the edit menu to change menu entries + */ + public JMenu getEditMenu() { + return editMenu; + } + + /** + * This returns the process menu to change menu entries + */ + + public JMenu getProcessMenu() { + return processMenu; + } + + /** + * This returns the help menu to change menu entries + */ + public JMenu getHelpMenu() { + return helpMenu; + } + + /** + * This returns the extensions menu to change menu entries + * + * @since 7.0.0 + */ + public JMenu getExtensionsMenu() { + return extensionsMenu; + } + + public DockableMenu getDockableMenu() { + return dockableMenu; + } + + /** + * + * @return the toolbar containing e.g. process run buttons + */ + public JToolBar getButtonToolbar() { + return buttonToolbar; + } + + /** + * The {@link TutorialSelector} holds the selected {@link Tutorial}. + * + * @return the registered tutorial selector + * @since 7.0.0 + */ + public TutorialSelector getTutorialSelector() { + return tutorialSelector; + } + + /** + * Checks the current process for potential problems. If a problem is deemed big enough (e.g. an + * operator that requires input but is not connected), returns {@code true}. If no showstoppers + * are found, returns {@code false}. This method also alerts the user about the problems so + * after it returns, nothing else needs to be done. + * + * @return {@code true} if the process contains a problem which should prevent process + * execution; {@code false} otherwise + */ + private boolean doesProcessContainShowstoppers() { + // if any operator has a mandatory parameter with no value and no default value. As it + // cannot predict execution behavior (e.g. Branch operators), this may turn up problems + // which would not occur during process execution + Pair missingParamPair = ProcessTools.getOperatorWithoutMandatoryParameter(process); + if (missingParamPair != null) { + // if there is already one of these, kill + if (missingParameterBubble != null) { + missingParameterBubble.killBubble(true); + } + + missingParameterBubble = ProcessGUITools.displayPrecheckMissingMandatoryParameterWarning( + missingParamPair.getFirst(), missingParamPair.getSecond()); + return true; + } + + // if any port needs data but is not connected. As it cannot predict execution behavior + // (e.g. Branch operators), this may turn up problems which would not occur during + // process execution + Port missingInputPort = ProcessTools.getPortWithoutMandatoryConnection(process); + if (missingInputPort != null) { + // if there is already one of these, kill + if (missingInputBubble != null) { + missingInputBubble.killBubble(true); + } + + missingInputBubble = ProcessGUITools.displayPrecheckInputPortDisconnectedWarning(missingInputPort); + return true; + } + + // if there is already one of these, kill + if (noResultConnectionBubble != null) { + noResultConnectionBubble.killBubble(true); + } + + // if the process has no connected result ports and the last executed + // process root child operator does not prevent a warning bubble we need + // to notify the user that no output port is connected + boolean isWarnOnNoResultProcess = Boolean + .parseBoolean(ParameterService.getParameterValue(RapidMinerGUI.PROPERTY_SHOW_NO_RESULT_WARNING)); + if (isWarnOnNoResultProcess) { + boolean connectedResultPort = ProcessTools.isProcessConnectedToResultPort(process); + Operator lastExecutedProcessRootChild = ProcessTools.getLastExecutedRootChild(process); + if (!connectedResultPort && lastExecutedProcessRootChild != null + && !ResultWarningPreventionRegistry.isResultWarningSuppressed(lastExecutedProcessRootChild)) { + noResultConnectionBubble = ProcessGUITools.displayPrecheckNoResultPortInformation(process); + return true; + } + } + + // no showstopper + return false; + } +} diff --git a/src/main/java/com/rapidminer/gui/MainToolBar.java b/src/main/java/com/rapidminer/gui/MainToolBar.java new file mode 100644 index 000000000..667bb79c8 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/MainToolBar.java @@ -0,0 +1,321 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JPanel; + +import com.rapidminer.gui.actions.AboutAction; +import com.rapidminer.gui.actions.BrowseAction; +import com.rapidminer.gui.actions.RedoAction; +import com.rapidminer.gui.actions.UndoAction; +import com.rapidminer.gui.actions.WorkspaceAction; +import com.rapidminer.gui.actions.startup.TutorialAction; +import com.rapidminer.gui.look.Colors; +import com.rapidminer.gui.osx.OSXAdapter; +import com.rapidminer.gui.tools.ResourceActionAdapter; +import com.rapidminer.gui.tools.ResourceLabel; +import com.rapidminer.gui.tools.components.DropDownPopupButton.DropDownPopupButtonBuilder; +import com.rapidminer.gui.tools.components.composite.PerspectiveToggleGroup; +import com.rapidminer.gui.tools.components.composite.SplitButton; +import com.rapidminer.tools.I18N; +import com.rapidminer.tools.Observable; +import com.rapidminer.tools.Observer; +import com.rapidminer.tools.SystemInfoUtilities; +import com.rapidminer.tools.SystemInfoUtilities.OperatingSystem; + + +/** + * Main tool bar of RapidMiner Studio. The tool bar consist of three columns. Action buttons such as + * the save or run button are shown on the left, the perspective navigation is shown in the middle, + * and additional resources are displayed on the right. + * + * @author Michael Knopf + * @see MainFrame + * @since 7.0.0 + */ +public class MainToolBar extends JPanel { + + private static final Dimension PERSPECTIVES_SIZE = new Dimension(120, 32); + + private static final long serialVersionUID = 1L; + + /** Split button containing all run actions. */ + private SplitButton runActions; + + /** Panel which contains the perspective group and a label */ + private JPanel perspectivesPanel; + + /** Panel which contains the resource button */ + private JPanel resourcesPanel; + + /** Displays the available perspectives */ + private PerspectiveToggleGroup perspectivesGroup; + + /** Maps the perspective name to the corresponding action */ + private Map perspectiveActionMap = new HashMap<>(); + + /** The cached name of the current perspective */ + private String perspectiveName; + + /** + * Creates a new tool bar instance. The new instance only contains build-in actions and + * perspectives. To display element registered by an extension, the {@link #update()} method + * must be invoked (after the extension is fully initialized). + * + * @param mainframe + * the mainframe that uses this tool bar + */ + public MainToolBar(final MainFrame mainframe) { + // use default look and feel background + setOpaque(true); + setBackground(Colors.WINDOW_BACKGROUND); + setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Colors.TAB_BORDER)); + + // The three columns are implemented via a grid-bag layout. The idea is that both the left + // and the right column have the same weight and are both set to grow (fill) horizontally to + // ensure an equal column whenever possible. As a consequence, the middle column (which is + // not set to grow) is automatically aligned to the center of the tool bar. + // + // To make this work it is necessary that both the left and the right panel have the same + // preferred width. + setLayout(new GridBagLayout()); + + GridBagConstraints constrainst = new GridBagConstraints(); + + // left column + constrainst.gridx = 0; + constrainst.weightx = 1; + constrainst.fill = GridBagConstraints.HORIZONTAL; + + // action button panel + JPanel actionsPanel; + { + FlowLayout actionsLayout = new FlowLayout(FlowLayout.LEFT); + actionsLayout.setVgap(0); + actionsPanel = new JPanel(actionsLayout); + actionsPanel.setOpaque(false); + + JButton newButton = new JButton(mainframe.NEW_ACTION); + newButton.setHideActionText(true); + actionsPanel.add(newButton); + + JButton openButton = new JButton(mainframe.OPEN_ACTION); + openButton.setHideActionText(true); + actionsPanel.add(openButton); + + SplitButton saveButtons = new SplitButton(mainframe.SAVE_ACTION, mainframe.SAVE_AS_ACTION); + saveButtons.SetHideActionText(true); + actionsPanel.add(saveButtons); + + actionsPanel.add(Box.createRigidArea(new Dimension(10, 0))); + + JButton undoButton = new JButton(new UndoAction(mainframe)); + undoButton.setHideActionText(true); + actionsPanel.add(undoButton); + + JButton redoButton = new JButton(new RedoAction(mainframe)); + redoButton.setHideActionText(true); + actionsPanel.add(redoButton); + + actionsPanel.add(Box.createRigidArea(new Dimension(10, 0))); + + runActions = new SplitButton(mainframe.RUN_ACTION); + runActions.SetHideActionText(true); + actionsPanel.add(runActions); + + JButton stopButton = new JButton(mainframe.STOP_ACTION); + stopButton.setHideActionText(true); + actionsPanel.add(stopButton); + + add(actionsPanel, constrainst); + } + + // middle column + constrainst.gridx += 1; + constrainst.weightx = 0; + constrainst.fill = GridBagConstraints.NONE; + + // perspectives panel + { + FlowLayout perspectiveLayout = new FlowLayout(FlowLayout.LEFT); + perspectiveLayout.setVgap(0); + + perspectivesPanel = new JPanel(perspectiveLayout); + perspectivesPanel.setOpaque(false); + ResourceLabel viewPerspectiveLabel = new ResourceLabel("workspace_views"); + viewPerspectiveLabel.setForeground(Color.GRAY); + perspectivesPanel.add(viewPerspectiveLabel); + + final PerspectiveController perspectiveController = mainframe.getPerspectiveController(); + PerspectiveModel perspectiveModel = perspectiveController.getModel(); + perspectiveModel.addObserver(new Observer>() { + + @Override + public void update(Observable> observable, List perspectives) { + updatePerspectivePanel(perspectiveController, perspectives); + Action perspectiveAction = perspectiveActionMap.get(perspectiveName); + if (perspectiveAction != null) { + perspectivesGroup.setSelected(perspectiveAction); + } + } + }, true); + perspectiveModel.addPerspectiveChangeListener(new PerspectiveChangeListener() { + + @Override + public void perspectiveChangedTo(Perspective perspective) { + perspectiveName = perspective.getName(); + Action perspectiveAction = perspectiveActionMap.get(perspectiveName); + if (perspectiveAction != null) { + perspectivesGroup.setSelected(perspectiveAction); + } + + } + }); + + updatePerspectivePanel(perspectiveController, perspectiveController.getModel().getAllPerspectives()); + + add(perspectivesPanel, constrainst); + } + + // right column + constrainst.gridx += 1; + constrainst.weightx = 1; + constrainst.fill = GridBagConstraints.HORIZONTAL; + + { + resourcesPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + resourcesPanel.setOpaque(false); + resourcesPanel.setPreferredSize(actionsPanel.getPreferredSize()); + + resourcesPanel.add(createResourcesButton()); + + add(resourcesPanel, constrainst); + } + + } + + /** + * @return a dropdown button with a menu containing a links to the tutorial, the online + * documentation, the forum, the support and the about box + */ + private Component createResourcesButton() { + DropDownPopupButtonBuilder builder = new DropDownPopupButtonBuilder(); + builder.with(new ResourceActionAdapter("toolbar_resources")); + + builder.add(new TutorialAction()); + + builder.add(new BrowseAction("toolbar_resources.documentation", + URI.create("http://redirects.rapidminer.com/app/studio/6/documentation"))); + builder.add(new BrowseAction("toolbar_resources.help_forum", + URI.create("http://redirects.rapidminer.com/app/studio/6/forum"))); + builder.add(new BrowseAction("toolbar_resources.support", + URI.create("http://redirects.rapidminer.com/app/studio/6/support/"))); + + // put "About RapidMiner Studio" action as last action if not on ox + if (SystemInfoUtilities.getOperatingSystem() != OperatingSystem.OSX || !OSXAdapter.isAdapted()) { + builder.addSeparator(); + builder.add(new AboutAction(RapidMinerGUI.getMainFrame())); + } + return builder.build(); + } + + public void update() { + List factories = RunActionRegistry.INSTANCE.getFacories(); + for (int i = 0; i < factories.size(); i++) { + runActions.getPopupMenu().addSeparator(); + for (MenuItemFactory.MenuEntry entry : factories.get(i).create()) { + if (entry.isAction()) { + runActions.getPopupMenu().add(entry.getAction()); + } else if (entry.isMenu()) { + runActions.getPopupMenu().add(entry.getMenu()); + } else if (entry.isComponent()) { + runActions.getPopupMenu().add(entry.getComponent()); + } + } + } + } + + /** + * Updates the {@link #perspectivesGroup} in regard to the perspective controller and the given + * perspectives. + * + * @param perspectiveController + * the controller which should be used + * @param perspectives + * all available perspectives + */ + private void updatePerspectivePanel(final PerspectiveController perspectiveController, + Collection perspectives) { + if (perspectivesGroup != null) { + perspectivesPanel.remove(perspectivesGroup); + } + perspectiveActionMap.clear(); + List primaryActionList = new ArrayList<>(); + List secondaryActionList = new ArrayList<>(); + for (Perspective p : perspectives) { + String name = p.getName(); + Action action = new WorkspaceAction(perspectiveController, p, name); + action.putValue(Action.LARGE_ICON_KEY, null); + action.putValue(Action.SMALL_ICON, null); + if (p.isUserDefined()) { + action.putValue(Action.ACTION_COMMAND_KEY, "perspective-" + name); + action.putValue(Action.NAME, name); + action.putValue(Action.SHORT_DESCRIPTION, + I18N.getMessage(I18N.getGUIBundle(), "gui.action.workspace_user.tip", name)); + } + if (!p.isUserDefined()) { + primaryActionList.add(action); + } else { + secondaryActionList.add(action); + } + perspectiveActionMap.put(p.getName(), action); + } + + if (primaryActionList.size() > 1) { + perspectivesGroup = new PerspectiveToggleGroup(perspectiveController, PERSPECTIVES_SIZE, + primaryActionList.toArray(new Action[primaryActionList.size()])); + } + if (perspectivesGroup != null && secondaryActionList.size() > 0) { + perspectivesGroup.addSeconderyActions(secondaryActionList.toArray(new Action[secondaryActionList.size()])); + } + if (perspectivesGroup != null) { + perspectivesPanel.add(perspectivesGroup); + perspectivesPanel.validate(); + perspectivesPanel.repaint(); + } + } + +} diff --git a/src/main/java/com/rapidminer/gui/MenuItemFactory.java b/src/main/java/com/rapidminer/gui/MenuItemFactory.java new file mode 100644 index 000000000..377daa6fa --- /dev/null +++ b/src/main/java/com/rapidminer/gui/MenuItemFactory.java @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.util.List; + +import javax.swing.Action; +import javax.swing.JComponent; +import javax.swing.JMenu; + + +/** + * Factory that creates a list of menu items. Wraps an {@link Action} (simple item), a {@link JMenu} + * (sub-menu), or an arbitrary {@link JComponent} (custom entries). + * + * @author Michael Knopf + * @since 7.0.0 + */ +public interface MenuItemFactory { + + /** + * Wrapper for a single menu entry. + */ + static final class MenuEntry { + + private final Action action; + private final JComponent component; + private final JMenu menu; + + /** + * Creates a wrapper for a single item. + * + * @param action + * the action of the menu item + */ + public MenuEntry(Action action) { + this.action = action; + this.component = null; + this.menu = null; + } + + /** + * Creates a wrapper for both {@link JMenu}s and general {@link JComponent}s. + * + * @param component + * the sub-menu or custom component + */ + public MenuEntry(JComponent component) { + this.action = null; + if (component instanceof JMenu) { + this.component = null; + this.menu = (JMenu) component; + } else { + this.component = component; + this.menu = null; + } + } + + public boolean isMenu() { + return menu != null; + } + + public boolean isAction() { + return action != null; + } + + public boolean isComponent() { + return component != null; + } + + public Action getAction() { + if (action == null) { + throw new UnsupportedOperationException(); + } + return action; + } + + public JMenu getMenu() { + if (menu == null) { + throw new UnsupportedOperationException(); + } + return menu; + } + + public JComponent getComponent() { + if (component == null) { + throw new UnsupportedOperationException(); + } + return component; + } + + } + + /** + * @return The list of menu entries, may be empty but must not be {@code null}. + */ + public List create(); + +} diff --git a/src/main/java/com/rapidminer/gui/MetaDataUpdateQueue.java b/src/main/java/com/rapidminer/gui/MetaDataUpdateQueue.java new file mode 100644 index 000000000..b3927d162 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/MetaDataUpdateQueue.java @@ -0,0 +1,98 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import com.rapidminer.Process; +import com.rapidminer.gui.tools.ProgressThread; +import com.rapidminer.gui.tools.UpdateQueue; +import com.rapidminer.tools.I18N; +import com.rapidminer.tools.LogService; + +import java.lang.reflect.InvocationTargetException; +import java.util.logging.Level; + +import javax.swing.SwingUtilities; + + +/** + * This queue updates the meta data on any update received from a process. + * + * @author Simon Fischer + * + */ +public class MetaDataUpdateQueue extends UpdateQueue { + + private final MainFrame mainFrame; + + public MetaDataUpdateQueue(MainFrame mainFrame) { + super("MetaDataValidation"); + this.mainFrame = mainFrame; + this.setPriority(MIN_PRIORITY); + } + + /** + * Enqueues a tasks to validate the given process. + * + * @param force + * if false, process will be validated only if validate automatically is selected. + */ + public void validate(final Process process, final boolean force) { + execute(new Runnable() { + + @Override + public void run() { + new ProgressThread("validate_process") { + + @Override + public void run() { + getProgressListener().setTotal(100); + getProgressListener().setCompleted(10); + if (force || mainFrame.VALIDATE_AUTOMATICALLY_ACTION.isSelected()) { + process.getRootOperator().checkAll(); + } else { + process.getRootOperator().checkAllExcludingMetaData(); + } + getProgressListener().setCompleted(90); + try { + SwingUtilities.invokeAndWait(new Runnable() { + + @Override + public void run() { + mainFrame.fireProcessUpdated(); + } + }); + } catch (InterruptedException e) { + } catch (InvocationTargetException e) { + // LogService.getRoot().log(Level.WARNING, + // "While updating process editors: "+e, e); + LogService.getRoot().log( + Level.WARNING, + I18N.getMessage(LogService.getRoot().getResourceBundle(), + "com.rapidminer.gui.MetaDataUpdateQueue.error_while_updating", e), e); + + } + getProgressListener().setCompleted(100); + getProgressListener().complete(); + } + }.startAndWait(); + } + }); + } + +} diff --git a/src/main/java/com/rapidminer/gui/OperatorDocLoader.java b/src/main/java/com/rapidminer/gui/OperatorDocLoader.java new file mode 100644 index 000000000..aed9e4150 --- /dev/null +++ b/src/main/java/com/rapidminer/gui/OperatorDocLoader.java @@ -0,0 +1,689 @@ +/** + * Copyright (C) 2001-2016 by RapidMiner and the contributors + * + * Complete list of developers available at our web site: + * + * http://rapidminer.com + * + * 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 http://www.gnu.org/licenses/. + */ +package com.rapidminer.gui; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.HashMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.apache.commons.lang.StringUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import com.rapidminer.gui.tools.SwingTools; +import com.rapidminer.operator.Operator; +import com.rapidminer.operator.OperatorCreationException; +import com.rapidminer.operator.OperatorDescription; +import com.rapidminer.operator.ports.Port; +import com.rapidminer.operator.ports.Ports; +import com.rapidminer.parameter.ParameterType; +import com.rapidminer.parameter.Parameters; +import com.rapidminer.parameter.conditions.ParameterCondition; +import com.rapidminer.tools.I18N; +import com.rapidminer.tools.LogService; +import com.rapidminer.tools.Tools; +import com.rapidminer.tools.WebServiceTools; +import com.rapidminer.tools.documentation.ExampleProcess; +import com.rapidminer.tools.xml.XHTMLEntityResolver; + + +/** + * This class loads the operator's descriptions either live from the internet wiki or from the + * resources. The latter requires that a custom Bot which gets all operator description sites from + * the MediaWiki was executed during build time. Those html files retrieved there for an operator + * must have been parsed and saved in the resources folder in "doc/namespace/operatorname". If the + * user does not have an internet connection all operators are loaded from this resource. If the + * user does have an internet connection the operators are loaded directly from the RapidWiki site. + * The operator description is shown in the RapidMiner Help Window. + * + * @author Miguel Buescher, Sebastian Land + * + */ +public class OperatorDocLoader { + + // private static final String HOST_NAME = "http://www.rapid-i.com"; + private static final String WIKI_PREFIX_FOR_IMAGES = "http://www.rapid-i.com";; + private static final String WIKI_PREFIX_FOR_OPERATORS = "http://rapid-i.com/wiki/index.php?title="; + + private static final Logger logger = Logger.getLogger(OperatorDocLoader.class.getName()); + private static String CORRECT_HTML_STRING_DIRTY = ""; + private static String ERROR_TEXT_FOR_WIKI; + private static String ERROR_TEXT_FOR_LOCAL; + + private static final String RESOURCE_SUB_DIR = "com/rapidminer/resources/doc"; + + private static HashMap OPERATOR_CACHE_MAP = new HashMap(); + + static { + // TODO: Transfer this to resource + ERROR_TEXT_FOR_WIKI = "
    Could not retrieve documentation of selected operator from wiki.
    "; + ERROR_TEXT_FOR_LOCAL = "
    Selected Operator not documented locally. Try online version.
    "; + + } + + /** + * This is the method for loading an operator's documentation within the program. + */ + public static String loadOperatorDocumentation(final boolean online, final boolean activateCache, + final OperatorDescription dirtyOpDesc) { + String toShowText; + OperatorDescription opDesc = dirtyOpDesc; + if (opDesc == null) { + // TODO: Eliminate this case + toShowText = ERROR_TEXT_FOR_WIKI; + } else { + if (activateCache && OPERATOR_CACHE_MAP.containsKey(opDesc)) { + return OPERATOR_CACHE_MAP.get(opDesc); + } else { + try { + if (online) { + toShowText = loadSelectedOperatorDocuFromWiki(opDesc); + } else { + toShowText = loadSelectedOperatorDocuLocally(opDesc); + } + } catch (Exception e) { + SwingTools.showFinalErrorMessage("rapid_doc_bot_importer_showInBrowser", e, true, + new Object[] { e.getMessage() }); + toShowText = ERROR_TEXT_FOR_WIKI; + } + if (activateCache && StringUtils.isNotBlank(toShowText) && StringUtils.isNotEmpty(toShowText)) { + OPERATOR_CACHE_MAP.put(opDesc, toShowText); + } + } + } + return toShowText; + } + + public static void clearOperatorCache() { + OPERATOR_CACHE_MAP.clear(); + } + + public static boolean hasCache(OperatorDescription opDesc) { + return OPERATOR_CACHE_MAP.containsKey(opDesc); + } + + private static String customizeHTMLStringDirty(String HTMLString, OperatorDescription opDesc) { + + HTMLString = HTMLString + .replaceFirst( + "\\<[^\\>]*>", + ""); + + // customize operator-name + + StringBuilder newHtml = new StringBuilder(512); + newHtml.append("

    "); + newHtml.append(opDesc.getName()); + + newHtml.append("
    "); + newHtml.append(opDesc.getProviderName()); + + newHtml.append("

    "); + + HTMLString = HTMLString.replaceFirst("]*>", ""); + HTMLString = HTMLString.replaceFirst(CORRECT_HTML_STRING_DIRTY, newHtml.toString()); + + // customize all headlines + HTMLString = HTMLString.replaceAll("

    ", "

    "); + HTMLString = HTMLString.replaceAll("

    ", ""); + + // replace all painted circles by icons + HTMLString = HTMLString.replaceAll("