From: asmodai Date: Wed, 18 Jul 2007 05:21:54 +0000 (+0000) Subject: Merged revisions 984-1044 via svnmerge. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=1845a1af58a27ee275b8c790f17777d4456d7716;p=OpenSRF.git Merged revisions 984-1044 via svnmerge. git-svn-id: svn://svn.open-ils.org/OpenSRF/branches/autotools@1045 9efc2488-bf62-4759-914b-345cdb29e865 --- diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..6235a64 --- /dev/null +++ b/COPYING @@ -0,0 +1,17 @@ + Copyright (C) 2005-2007, Georgia Public Library Service and others + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..113c29b --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,340 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey 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 General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/bin/osrf_ctl.sh b/bin/osrf_ctl.sh index 374385d..8958204 100755 --- a/bin/osrf_ctl.sh +++ b/bin/osrf_ctl.sh @@ -119,9 +119,9 @@ function stop_router { function start_perl { do_action "start" $PID_OSRF_PERL "OpenSRF Perl"; perl -MOpenSRF::System="$OPT_CONFIG" -e 'OpenSRF::System->bootstrap()' & - pid=$!; + sleep 3; + pid=$(ps ax | grep "OpenSRF System" | grep -v grep | grep -v "System-C"| awk '{print $1}') echo $pid > $PID_OSRF_PERL; - sleep 5; return 0; } diff --git a/doc/dokuwiki-doc-stubber.pl b/doc/dokuwiki-doc-stubber.pl index fcdd03d..0182745 100755 --- a/doc/dokuwiki-doc-stubber.pl +++ b/doc/dokuwiki-doc-stubber.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -w -use OpenSRF::System qw(/pines/conf/bootstrap.conf); +use OpenSRF::System qw(/openils/conf/opensrf_core.xml); use Getopt::Long $| = 1; diff --git a/examples/bootstrap.conf.example b/examples/bootstrap.conf.example deleted file mode 100644 index ce445f7..0000000 --- a/examples/bootstrap.conf.example +++ /dev/null @@ -1,44 +0,0 @@ -# ---------------------------------------------------------- -# bootstrap config file -# ---------------------------------------------------------- -[bootstrap] - -# location of the opensrf.xml config file -settings_config = /path/to/opensrf.xml - -# log files directory -log_dir = /path/to/log - -## Log file is either a file name or syslog: -#logfile = osrfysys.log -logfile = syslog:local0 - -# defines the syslog facility for the activity log -#actlog = activity.log -actlog = syslog:local1 - -# log level -debug = ERROR -#debug = INFO -#debug = DEBUG -#debug = INTERNAL - -# the jabber login of the router (changing this will likely cause problems) -router_name = router - -# all jabber domains we want our app to connect to -list:domains = router1.domain.com, router2.domain.com - -# jabber login -username = jabber_username - -# jabber password -passwd = jabber_password - -# if port is non-numeric (e.g. /tmp/mysock.sock) then we will attempt to -# connect to the specified string as a unix socket file -# This works with Chop Chop jabber only (opensrf custom jabber server) -port = 5222 - -# -------------------------------------- - diff --git a/examples/fieldmapper2perl.xsl b/examples/fieldmapper2perl.xsl index 4d3a8a5..8ef601e 100644 --- a/examples/fieldmapper2perl.xsl +++ b/examples/fieldmapper2perl.xsl @@ -13,7 +13,7 @@ package Fieldmapper; -use JSON; +use OpenSRF::Utils::JSON; use Data::Dumper; use base 'OpenSRF::Application'; diff --git a/examples/math_bench.pl b/examples/math_bench.pl index c3a504c..f83e0fc 100755 --- a/examples/math_bench.pl +++ b/examples/math_bench.pl @@ -13,7 +13,7 @@ my $count = $ARGV[0]; print "usage: $0 \n" and exit unless $count; # * connect to the Jabber network -OpenSRF::System->bootstrap_client( config_file => "/openils/conf/bootstrap.conf" ); +OpenSRF::System->bootstrap_client( config_file => "/openils/conf/opensrf_core.xml" ); $log->set_service('math_bench'); # * create a new application session for the opensrf.math service diff --git a/examples/multisession-test.pl b/examples/multisession-test.pl index bb75a46..21c0c99 100755 --- a/examples/multisession-test.pl +++ b/examples/multisession-test.pl @@ -4,7 +4,7 @@ use OpenSRF::System; use OpenILS::Application::AppUtils; use OpenILS::Event; use OpenSRF::EX qw/:try/; -use JSON; +use OpenSRF::Utils::JSON; use Data::Dumper; use OpenILS::Utils::Fieldmapper; use Digest::MD5 qw/md5_hex/; @@ -12,7 +12,6 @@ use OpenSRF::Utils qw/:daemon/; use OpenSRF::MultiSession; use OpenSRF::AppSession; use Time::HiRes qw/time/; -use JSON; my $config = shift; @@ -37,7 +36,7 @@ $mses->success_handler( sub { my $ses = shift; my $req = shift; - print $req->{params}->[0] . "\t: " . JSON->perl2JSON($req->{response}->[0]->content)."\n"; + print $req->{params}->[0] . "\t: " . OpenSRF::Utils::JSON->perl2JSON($req->{response}->[0]->content)."\n"; } ); @@ -45,7 +44,7 @@ $mses->failure_handler( sub { my $ses = shift; my $req = shift; - warn "record $req->{params}->[0] failed: ".JSON->perl2JSON($req->{response}); + warn "record $req->{params}->[0] failed: " . OpenSRF::Utils::JSON->perl2JSON($req->{response}); } ); diff --git a/examples/opensrf.xml.example b/examples/opensrf.xml.example index 437570a..fa2bc44 100644 --- a/examples/opensrf.xml.example +++ b/examples/opensrf.xml.example @@ -1,208 +1,207 @@ - + + + - Any valid XML may be added to the block and server components will have - acces to it. + + - --> + + /path/to/log - - - + + /path/to/sock - - /path/to/log + + /path/to/pid - - /path/to/sock + + /path/to/conf + - - /path/to/pid + + prefork - - /path/to/conf + + + + + - + + 127.0.0.1:10101 - - prefork + - - + + 86400 - - - - - 127.0.0.1:10101 - - - 86400 - - - - - - - - - - - 1 - - - 1 - - - perl - - - OpenSRF::Application::Persist - - - 97 - - - - - - opensrf.persist_unix.sock - - - opensrf.persist_unix.pid - - - 1000 - - - opensrf.persist_unix.log - - - 5 - - - 25 - - - 2 - - - 5 - - - - - - - - /path/to/dbfile/persist.db - - - - - - 3 - 1 - perl - OpenSRF::Application::Demo::Math - 97 - - opensrf.math_unix.sock - opensrf.math_unix.pid - 1000 - opensrf.math_unix.log - 5 - 15 - 2 - 5 - - - - - 3 - 1 - perl - OpenSRF::Application::Demo::MathDB - 99 - - 1000 - opensrf.dbmath_unix.log - opensrf.dbmath_unix.sock - opensrf.dbmath_unix.pid - 5 - 15 - 2 5 - - - - - 1 - 0 - perl - OpenSRF::Application::Settings - 17 - - opensrf.settings_unix.sock - opoensrf.settings_unix.pid - 1000 - opensrf.settings_unix.log - 5 - 15 - 3 - 5 - - - - - - - - - - - - - - - - opensrf.persist - opensrf.settings - opensrf.math - opensrf.dbmath - - - - - - /different/path/to/dbfile/persist.db - - - - - - - + + + + + + + + + + 1 + + + 1 + + + perl + + + OpenSRF::Application::Persist + + + 97 + + + + + + opensrf.persist_unix.sock + + + opensrf.persist_unix.pid + + + 1000 + + + opensrf.persist_unix.log + + + 5 + + + 25 + + + 2 + + + 5 + + + + + + + + /path/to/dbfile/persist.db + + + + + + 3 + 1 + perl + OpenSRF::Application::Demo::Math + 97 + + opensrf.math_unix.sock + opensrf.math_unix.pid + 1000 + opensrf.math_unix.log + 5 + 15 + 2 + 5 + + + + + 3 + 1 + perl + OpenSRF::Application::Demo::MathDB + 99 + + 1000 + opensrf.dbmath_unix.log + opensrf.dbmath_unix.sock + opensrf.dbmath_unix.pid + 5 + 15 + 2 + 5 + + + + + 1 + 0 + perl + OpenSRF::Application::Settings + 17 + + opensrf.settings_unix.sock + opoensrf.settings_unix.pid + 1000 + opensrf.settings_unix.log + 5 + 15 + 3 + 5 + + + + + + + + + + + + + opensrf.persist + opensrf.settings + opensrf.math + opensrf.dbmath + + + + + + + + /different/path/to/dbfile/persist.db + + + + + + + + diff --git a/examples/opensrf_core.xml.example b/examples/opensrf_core.xml.example index 708d4a6..d24121d 100644 --- a/examples/opensrf_core.xml.example +++ b/examples/opensrf_core.xml.example @@ -1,143 +1,141 @@ - - + - - - - - router - - - - localhost - - - - - localhost - + + - client - mypass - 5222 + + + router + + - - /openils/var/log/osrfsys.log + + localhost + + + + + + localhost - + + client + mypass + 5222 - + + /openils/var/log/osrfsys.log - - 3 + + + + + 3 /openils/conf/opensrf.xml + - - - localhost - 5222 + + - - 5269 - secret + + localhost + 5222 - 10.0.0.3 - 3 - /openils/var/log/osrfsys.log - + + 5269 + secret + 10.0.0.3 + 3 + /openils/var/log/osrfsys.log + - - + + - - true - - - router - - - - localhost - - - - - opensrf.math - open-ils.cat - open-ils.search - open-ils.circ - open-ils.actor - open-ils.auth - - - - - mylogin - mypassword - 5222 - - /openils/var/log/gateway.log - 3 - - - - - - - - - - 0 - - - - localhost - - localhost - - - - - localhost - 5222 - - + router + + + + localhost + + + + + opensrf.math + open-ils.cat + open-ils.search + open-ils.circ + open-ils.actor + open-ils.auth + + + + mylogin + mypassword + 5222 + /openils/var/log/gateway.log + 3 + + + + + + + + + 0 + + + + + localhost + + + localhost + + + + + + + localhost + 5222 + + - router + router + mypassword - mypassword + + + router + 10 + 5 - - - router + + /openils/var/log/router.log + 3 - 10 - 5 - - - /openils/var/log/router.log - 3 - - + - + diff --git a/examples/srfsh.xml.example b/examples/srfsh.xml.example index 5bc1e2d..e88ae6b 100644 --- a/examples/srfsh.xml.example +++ b/examples/srfsh.xml.example @@ -1,12 +1,13 @@ - + + - router - - 127.0.0.1 - - myusername - mypassword - 5222 - /path/to/log/srfsh.log - 4 + router + + 127.0.0.1 + + myusername + mypassword + 5222 + /path/to/log/srfsh.log + 4 diff --git a/include/objson/json_parser.h b/include/objson/json_parser.h index ede5d91..a1f785b 100644 --- a/include/objson/json_parser.h +++ b/include/objson/json_parser.h @@ -23,6 +23,7 @@ GNU General Public License for more details. #define JSON_PARSER_H #include +#include #include #include @@ -77,9 +78,6 @@ int json_eat_comment(char* string, unsigned long* index, char** class_hint, int /* prints a useful error message to stderr. always returns -1 */ int json_handle_error(char* string, unsigned long* index, char* err_msg); -/* returns true if c is 0-9 */ -int is_number(char c); - int json_parse_json_null(char* string, unsigned long* index, jsonObject* obj, int current_strlen); diff --git a/include/opensrf/socket_bundle.h b/include/opensrf/socket_bundle.h index f290cdc..555a211 100644 --- a/include/opensrf/socket_bundle.h +++ b/include/opensrf/socket_bundle.h @@ -67,19 +67,19 @@ void socket_manager_free(socket_manager* mgr); /* creates a new server socket node and adds it to the socket set. returns socket id on success. -1 on failure. socket_type is one of INET or UNIX */ -int socket_open_tcp_server(socket_manager*, int port, char* listen_ip ); +int socket_open_tcp_server(socket_manager*, int port, const char* listen_ip ); int socket_open_unix_server(socket_manager* mgr, char* path); -int socket_open_udp_server( socket_manager* mgr, int port, char* listen_ip ); +int socket_open_udp_server( socket_manager* mgr, int port, const char* listen_ip ); /* creates a client TCP socket and adds it to the socket set. returns 0 on success. -1 on failure. */ -int socket_open_tcp_client(socket_manager*, int port, char* dest_addr); +int socket_open_tcp_client(socket_manager*, int port, const char* dest_addr); /* creates a client UNIX socket and adds it to the socket set. returns 0 on success. -1 on failure. */ -int socket_open_unix_client(socket_manager*, char* sock_path); +int socket_open_unix_client(socket_manager*, const char* sock_path); int socket_open_udp_client( socket_manager* mgr, int port, char* dest_addr); diff --git a/src/Makefile b/src/Makefile index 0cf5657..14823ab 100644 --- a/src/Makefile +++ b/src/Makefile @@ -86,7 +86,6 @@ opensrf-install: objson-install cp -r ../include/opensrf $(INCLUDEDIR) cp libopensrf/opensrf $(BINDIR)/opensrf-c make -C c-apps install - cp ../examples/bootstrap.conf.example $(ETCDIR) cp ../bin/osrf_ctl.sh $(BINDIR) cp ../examples/opensrf.xml.example $(ETCDIR) cp ../examples/opensrf_core.xml.example $(ETCDIR) diff --git a/src/jserver/osrf_chat.c b/src/jserver/osrf_chat.c index 2585719..9a20bd6 100644 --- a/src/jserver/osrf_chat.c +++ b/src/jserver/osrf_chat.c @@ -19,7 +19,10 @@ GNU General Public License for more details. #include static int osrfChatXMLErrorOcurred = 0; -static int osrfChatClientSentDisconnect = 0; + +/* This is used by code in osrfChatPushData, but that code is + currently commented out. Uncomment the next line if needed. */ +//static int osrfChatClientSentDisconnect = 0; /* shorter version of strcmp */ static int eq(const char* a, const char* b) { return (a && b && !strcmp(a,b)); } @@ -613,7 +616,7 @@ int osrfChatHandleConnected( osrfChatNode* node, const char* name, const xmlChar if(eq(name,"message")) { /* drop the old message and start with a new one */ - xmlNodePtr root = xmlNewNode(NULL, name); + xmlNodePtr root = xmlNewNode(NULL, BAD_CAST name); xmlAddAttrs(root, atts); xmlNodePtr oldRoot = xmlDocSetRootElement(node->msgDoc, root); free(node->to); @@ -628,7 +631,7 @@ int osrfChatHandleConnected( osrfChatNode* node, const char* name, const xmlChar } else { /* all non "message" nodes are simply added to the message */ - xmlNodePtr nodep = xmlNewNode(NULL, name); + xmlNodePtr nodep = xmlNewNode(NULL, BAD_CAST name); xmlAddAttrs(nodep, atts); xmlAddChild(xmlDocGetRootElement(node->msgDoc), nodep); } diff --git a/src/libopensrf/opensrf.c b/src/libopensrf/opensrf.c index 5532f73..3b6f6fd 100644 --- a/src/libopensrf/opensrf.c +++ b/src/libopensrf/opensrf.c @@ -9,9 +9,6 @@ int main( int argc, char* argv[] ) { return 1; } - fprintf(stderr, "Loading OpenSRF host %s with bootstrap config %s " - "and config context %s\n", argv[1], argv[2], argv[3] ); - /* these must be strdup'ed because init_proc_title / set_proc_title are evil and overwrite the argv memory */ char* host = strdup( argv[1] ); diff --git a/src/libopensrf/osrf_prefork.c b/src/libopensrf/osrf_prefork.c index 01a97cc..36b203c 100644 --- a/src/libopensrf/osrf_prefork.c +++ b/src/libopensrf/osrf_prefork.c @@ -69,14 +69,14 @@ int osrf_prefork_run(char* appname) { prefork_simple* forker = prefork_simple_init( osrfSystemGetTransportClient(), maxr, minc, maxc); - forker->appname = strdup(appname); - forker->keepalive = kalive; - if(forker == NULL) { osrfLogError( OSRF_LOG_MARK, "osrf_prefork_run() failed to create prefork_simple object"); return -1; } + forker->appname = strdup(appname); + forker->keepalive = kalive; + prefork_launch_children(forker); osrf_prefork_register_routers(appname); diff --git a/src/libopensrf/osrf_system.c b/src/libopensrf/osrf_system.c index c378b7b..e5596dd 100644 --- a/src/libopensrf/osrf_system.c +++ b/src/libopensrf/osrf_system.c @@ -79,7 +79,12 @@ int osrfSystemBootstrap( char* hostname, char* configfile, char* contextNode ) { hostname, configfile ); return -1; } - + + /** daemonize me **/ + /* background and let our children do their thing */ + /* NOTE: This has been moved from below the 'if (apps)' block below ... move it back if things go crazy */ + daemonize(); + jsonObject* apps = osrf_settings_host_value_object("/activeapps/appname"); osrfStringArray* arr = osrfNewStringArray(8); @@ -122,7 +127,7 @@ int osrfSystemBootstrap( char* hostname, char* configfile, char* contextNode ) { } else { - fprintf(stderr, " * Running application %s\n", appname); + osrfLogError( OSRF_LOG_MARK, " * Running application %s\n", appname); if( osrfAppRegisterApplication( appname, libfile ) == 0 ) osrf_prefork_run(appname); @@ -131,27 +136,22 @@ int osrfSystemBootstrap( char* hostname, char* configfile, char* contextNode ) { } } // language == c } + } // should we do something if there are no apps? does the wait(NULL) below do that for us? + + while(1) { + errno = 0; + pid_t pid = wait(NULL); + if(-1 == pid) { + if(errno == ECHILD) + osrfLogError(OSRF_LOG_MARK, "We have no more live services... exiting"); + else + osrfLogError(OSRF_LOG_MARK, "Exiting top-level system loop with error: %s", strerror(errno)); + break; + } else { + osrfLogError(OSRF_LOG_MARK, "We lost a top-level service process with PID %ld", pid); + } } - /** daemonize me **/ - - /* background and let our children do their thing */ - daemonize(); - while(1) { - errno = 0; - pid_t pid = wait(NULL); - if(-1 == pid) { - if(errno == ECHILD) - osrfLogError(OSRF_LOG_MARK, "We have no more live services... exiting"); - else - osrfLogError(OSRF_LOG_MARK, "Exiting top-level system loop with error: %s", strerror(errno)); - break; - } else { - osrfLogError(OSRF_LOG_MARK, "We lost a top-level service process with PID %ld", pid); - } - } - - return 0; } diff --git a/src/libopensrf/socket_bundle.c b/src/libopensrf/socket_bundle.c index 6196410..6dc91b0 100644 --- a/src/libopensrf/socket_bundle.c +++ b/src/libopensrf/socket_bundle.c @@ -77,7 +77,7 @@ static socket_node* _socket_add_node(socket_manager* mgr, /* creates a new server socket node and adds it to the socket set. returns new socket fd on success. -1 on failure. socket_type is one of INET or UNIX */ -int socket_open_tcp_server(socket_manager* mgr, int port, char* listen_ip) { +int socket_open_tcp_server(socket_manager* mgr, int port, const char* listen_ip) { if( mgr == NULL ) { osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): NULL mgr"); @@ -98,7 +98,13 @@ int socket_open_tcp_server(socket_manager* mgr, int port, char* listen_ip) { server_addr.sin_family = AF_INET; if(listen_ip != NULL) { - server_addr.sin_addr.s_addr = inet_addr(listen_ip); + struct in_addr addr; + if( inet_aton( listen_ip, &addr ) ) + server_addr.sin_addr.s_addr = addr.s_addr; + else { + osrfLogError( OSRF_LOG_MARK, "Listener address is invalid: %s", listen_ip ); + return -1; + } } else { server_addr.sin_addr.s_addr = htonl(INADDR_ANY); } @@ -175,7 +181,7 @@ int socket_open_unix_server(socket_manager* mgr, char* path) { int socket_open_udp_server( - socket_manager* mgr, int port, char* listen_ip ) { + socket_manager* mgr, int port, const char* listen_ip ) { int sockfd; struct sockaddr_in server_addr; @@ -188,8 +194,15 @@ int socket_open_udp_server( server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); - if(listen_ip) server_addr.sin_addr.s_addr = inet_addr(listen_ip); - else server_addr.sin_addr.s_addr = htonl(INADDR_ANY); + if(listen_ip) { + struct in_addr addr; + if( inet_aton( listen_ip, &addr ) ) + server_addr.sin_addr.s_addr = addr.s_addr; + else { + osrfLogError( OSRF_LOG_MARK, "UDP listener address is invalid: %s", listen_ip ); + return -1; + } + } else server_addr.sin_addr.s_addr = htonl(INADDR_ANY); errno = 0; if( (bind (sockfd, (struct sockaddr *) &server_addr,sizeof(server_addr))) ) { @@ -203,7 +216,7 @@ int socket_open_udp_server( } -int socket_open_tcp_client(socket_manager* mgr, int port, char* dest_addr) { +int socket_open_tcp_client(socket_manager* mgr, int port, const char* dest_addr) { struct sockaddr_in remoteAddr, localAddr; struct hostent *hptr; @@ -318,7 +331,7 @@ int socket_open_udp_client( } -int socket_open_unix_client(socket_manager* mgr, char* sock_path) { +int socket_open_unix_client(socket_manager* mgr, const char* sock_path) { int sock_fd, len; struct sockaddr_un usock; diff --git a/src/libopensrf/transport_message.c b/src/libopensrf/transport_message.c index 5c6862b..6488115 100644 --- a/src/libopensrf/transport_message.c +++ b/src/libopensrf/transport_message.c @@ -95,7 +95,7 @@ transport_message* new_message_from_xml( const char* msg_xml ) { xmlFree(router_class); } if(broadcast) { - if(strcmp(broadcast,"0") ) + if(strcmp((char*) broadcast,"0") ) new_msg->broadcast = 1; xmlFree(broadcast); } @@ -211,9 +211,9 @@ int message_free( transport_message* msg ){ // --------------------------------------------------------------------------------- char* message_to_xml( const transport_message* msg ) { - int bufsize; + //int bufsize; //xmlChar* xmlbuf; - char* encoded_body; + //char* encoded_body; xmlNodePtr message_node; xmlNodePtr body_node; diff --git a/src/libopensrf/transport_session.c b/src/libopensrf/transport_session.c index 43483f0..4fb0290 100644 --- a/src/libopensrf/transport_session.c +++ b/src/libopensrf/transport_session.c @@ -332,7 +332,7 @@ void startElementHandler( if( ! ses ) { return; } - if( strcmp( name, "message" ) == 0 ) { + if( strcmp( (char*) name, "message" ) == 0 ) { ses->state_machine->in_message = 1; buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) ); buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) ); @@ -350,37 +350,37 @@ void startElementHandler( if( ses->state_machine->in_message ) { - if( strcmp( name, "body" ) == 0 ) { + if( strcmp( (char*) name, "body" ) == 0 ) { ses->state_machine->in_message_body = 1; return; } - if( strcmp( name, "subject" ) == 0 ) { + if( strcmp( (char*) name, "subject" ) == 0 ) { ses->state_machine->in_subject = 1; return; } - if( strcmp( name, "thread" ) == 0 ) { + if( strcmp( (char*) name, "thread" ) == 0 ) { ses->state_machine->in_thread = 1; return; } } - if( strcmp( name, "presence" ) == 0 ) { + if( strcmp( (char*) name, "presence" ) == 0 ) { ses->state_machine->in_presence = 1; buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) ); buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) ); return; } - if( strcmp( name, "status" ) == 0 ) { + if( strcmp( (char*) name, "status" ) == 0 ) { ses->state_machine->in_status = 1; return; } - if( strcmp( name, "stream:error" ) == 0 ) { + if( strcmp( (char*) name, "stream:error" ) == 0 ) { ses->state_machine->in_error = 1; ses->state_machine->connected = 0; osrfLogWarning( OSRF_LOG_MARK, "Received message from Jabber server" ); @@ -389,21 +389,21 @@ void startElementHandler( /* first server response from a connect attempt */ - if( strcmp( name, "stream:stream" ) == 0 ) { + if( strcmp( (char*) name, "stream:stream" ) == 0 ) { if( ses->state_machine->connecting == CONNECTING_1 ) { ses->state_machine->connecting = CONNECTING_2; buffer_add( ses->session_id, get_xml_attr(atts, "id") ); } } - if( strcmp( name, "handshake" ) == 0 ) { + if( strcmp( (char*) name, "handshake" ) == 0 ) { ses->state_machine->connected = 1; ses->state_machine->connecting = 0; return; } - if( strcmp( name, "error" ) == 0 ) { + if( strcmp( (char*) name, "error" ) == 0 ) { ses->state_machine->in_message_error = 1; buffer_add( ses->message_error_type, get_xml_attr( atts, "type" ) ); ses->message_error_code = atoi( get_xml_attr( atts, "code" ) ); @@ -412,7 +412,7 @@ void startElementHandler( return; } - if( strcmp( name, "iq" ) == 0 ) { + if( strcmp( (char*) name, "iq" ) == 0 ) { ses->state_machine->in_iq = 1; if( strcmp( get_xml_attr(atts, "type"), "result") == 0 @@ -433,7 +433,7 @@ char* get_xml_attr( const xmlChar** atts, char* attr_name ) { int i; if (atts != NULL) { for(i = 0;(atts[i] != NULL);i++) { - if( strcmp( atts[i++], attr_name ) == 0 ) { + if( strcmp( (char*) atts[i++], attr_name ) == 0 ) { if( atts[i] != NULL ) { return (char*) atts[i]; } @@ -451,7 +451,7 @@ void endElementHandler( void *session, const xmlChar *name) { transport_session* ses = (transport_session*) session; if( ! ses ) { return; } - if( strcmp( name, "message" ) == 0 ) { + if( strcmp( (char*) name, "message" ) == 0 ) { /* pass off the message info the callback */ @@ -489,22 +489,22 @@ void endElementHandler( void *session, const xmlChar *name) { return; } - if( strcmp( name, "body" ) == 0 ) { + if( strcmp( (char*) name, "body" ) == 0 ) { ses->state_machine->in_message_body = 0; return; } - if( strcmp( name, "subject" ) == 0 ) { + if( strcmp( (char*) name, "subject" ) == 0 ) { ses->state_machine->in_subject = 0; return; } - if( strcmp( name, "thread" ) == 0 ) { + if( strcmp( (char*) name, "thread" ) == 0 ) { ses->state_machine->in_thread = 0; return; } - if( strcmp( name, "iq" ) == 0 ) { + if( strcmp( (char*) name, "iq" ) == 0 ) { ses->state_machine->in_iq = 0; if( ses->message_error_code > 0 ) { osrfLogWarning( OSRF_LOG_MARK, "Error in IQ packet: code %d", ses->message_error_code ); @@ -514,7 +514,7 @@ void endElementHandler( void *session, const xmlChar *name) { return; } - if( strcmp( name, "presence" ) == 0 ) { + if( strcmp( (char*) name, "presence" ) == 0 ) { ses->state_machine->in_presence = 0; /* if( ses->presence_callback ) { @@ -525,17 +525,17 @@ void endElementHandler( void *session, const xmlChar *name) { return; } - if( strcmp( name, "status" ) == 0 ) { + if( strcmp( (char*) name, "status" ) == 0 ) { ses->state_machine->in_status = 0; return; } - if( strcmp( name, "error" ) == 0 ) { + if( strcmp( (char*) name, "error" ) == 0 ) { ses->state_machine->in_message_error = 0; return; } - if( strcmp( name, "error:error" ) == 0 ) { + if( strcmp( (char*) name, "error:error" ) == 0 ) { ses->state_machine->in_error = 0; return; } diff --git a/src/libopensrf/utils.c b/src/libopensrf/utils.c index 07ed9a2..908145b 100644 --- a/src/libopensrf/utils.c +++ b/src/libopensrf/utils.c @@ -13,12 +13,13 @@ GNU General Public License for more details. */ #include +#include #include inline void* safe_malloc( int size ) { void* ptr = (void*) malloc( size ); if( ptr == NULL ) { - perror("safe_malloc(): Out of Memory" ); + osrfLogError( OSRF_LOG_MARK, "Out of Memory" ); exit(99); } memset( ptr, 0, size ); @@ -189,7 +190,7 @@ int buffer_add(growing_buffer* gb, char* data) { } if( gb->size > BUFFER_MAX_SIZE ) { - fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE ); + osrfLogError( OSRF_LOG_MARK, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE ); buffer_free( gb ); return 0; } @@ -366,20 +367,34 @@ char* uescape( const char* string, int size, int full_escape ) { } -// A function to turn a process into a daemon and set it's process name in ps/top +// A function to turn a process into a daemon int daemonize() { - int f = fork(); + pid_t f = fork(); if (f == -1) { - perror("Failed to fork!"); + osrfLogError( OSRF_LOG_MARK, "Failed to fork!" ); return -1; } else if (f == 0) { // We're in the child now... + + // Change directories. Otherwise whatever directory + // we're in couldn't be deleted until the program + // terminated -- possibly causing some inconvenience. + chdir( "/" ); + + /* create new session */ setsid(); + + // Now that we're no longer attached to a terminal, + // we don't want any traffic on the standard streams + freopen( "/dev/null", "r", stdin ); + freopen( "/dev/null", "w", stdout ); + freopen( "/dev/null", "w", stderr ); + return 0; } else { // We're in the parent... - exit(0); + _exit(0); } } @@ -406,10 +421,7 @@ char* file_to_string(const char* filename) { FILE* file = fopen(filename, "r"); if(!file) { - int l = strlen(filename) + 64; - char b[l]; - snprintf(b,l,"Unable to open file [%s] in file_to_string()", filename); - perror(b); + osrfLogError( OSRF_LOG_MARK, "Unable to open file [%s]", filename ); return NULL; } diff --git a/src/libopensrf/xml_utils.c b/src/libopensrf/xml_utils.c index e3ef206..ec9e5c3 100644 --- a/src/libopensrf/xml_utils.c +++ b/src/libopensrf/xml_utils.c @@ -97,7 +97,7 @@ char* xmlSaxAttr( const xmlChar** atts, char* name ) { if( atts && name ) { int i; for(i = 0; (atts[i] != NULL); i++) { - if(!strcmp(atts[i], name)) { + if(!strcmp((char*) atts[i], name)) { if(atts[++i]) return (char*) atts[i]; } } diff --git a/src/objson/json_parser.c b/src/objson/json_parser.c index 8313872..18cd2a8 100644 --- a/src/objson/json_parser.c +++ b/src/objson/json_parser.c @@ -127,7 +127,7 @@ int _json_parse_string(char* string, unsigned long* index, jsonObject* obj, int break; default: - if(is_number(c) || c == '.' || c == '-') { /* are we a number? */ + if(isdigit(c) || c == '.' || c == '-') { /* are we a number? */ status = json_parse_json_number(string, index, obj, current_strlen); if(status) return status; break; @@ -225,7 +225,7 @@ int json_parse_json_number(char* string, unsigned long* index, jsonObject* obj, while(*index < current_strlen) { - if(is_number(c)) { + if(isdigit(c)) { buffer_add_char(buf, c); } @@ -503,18 +503,18 @@ int json_parse_json_string(char* string, unsigned long* index, jsonObject* obj, if (ucs_char < 0x80) { utf_out[0] = ucs_char; - buffer_add(buf, utf_out); + buffer_add(buf, (char*) utf_out); } else if (ucs_char < 0x800) { utf_out[0] = 0xc0 | (ucs_char >> 6); utf_out[1] = 0x80 | (ucs_char & 0x3f); - buffer_add(buf, utf_out); + buffer_add(buf, (char*) utf_out); } else { utf_out[0] = 0xe0 | (ucs_char >> 12); utf_out[1] = 0x80 | ((ucs_char >> 6) & 0x3f); utf_out[2] = 0x80 | (ucs_char & 0x3f); - buffer_add(buf, utf_out); + buffer_add(buf, (char*) utf_out); } /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ @@ -692,23 +692,6 @@ int json_eat_comment(char* string, unsigned long* index, char** buffer, int pars return 0; } -int is_number(char c) { - switch(c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return 1; - } - return 0; -} - int json_handle_error(char* string, unsigned long* index, char* err_msg) { char buf[60]; diff --git a/src/perlmods/JSON.pm b/src/perlmods/JSON.pm deleted file mode 100644 index 2128f96..0000000 --- a/src/perlmods/JSON.pm +++ /dev/null @@ -1,827 +0,0 @@ - -package JSON::number; -sub new { - my $class = shift; - my $x = shift || $class; - return bless \$x => __PACKAGE__; -} - -use overload ( '""' => \&toString ); - -sub toString { defined($_[1]) ? ${$_[1]} : ${$_[0]} } - -package JSON::bool::true; -sub new { return bless {} => __PACKAGE__ } -use overload ( '""' => \&toString ); -use overload ( 'bool' => sub { 1 } ); -use overload ( '0+' => sub { 1 } ); - -sub toString { 'true' } - -package JSON::bool::false; -sub new { return bless {} => __PACKAGE__ } -use overload ( '""' => \&toString ); -use overload ( 'bool' => sub { 0 } ); -use overload ( '0+' => sub { 0 } ); - -sub toString { 'false' } - -package JSON; -use Unicode::Normalize; -use vars qw/%_class_map/; - -sub register_class_hint { - my $class = shift; - my %args = @_; - - $_class_map{hints}{$args{hint}} = \%args; - $_class_map{classes}{$args{name}} = \%args; -} - -sub _JSON_regex { - my $string = shift; - - $string =~ s/^\s* ( - { | # start object - \[ | # start array - -?\d+\.?\d* | # number literal - "(?:(?:\\[\"])|[^\"])*" | # string literal - (?:\/\*.+?\*\/) | # C comment - true | # bool true - false | # bool false - null | # undef() - : | # object key-value sep - , | # list sep - \] | # array end - } # object end - ) - \s*//sox; - return ($string,$1); -} - -sub lookup_class { - my $self = shift; - my $hint = shift; - return $_class_map{hints}{$hint}{name} -} - -sub lookup_hint { - my $self = shift; - my $class = shift; - return $_class_map{classes}{$class}{hint} -} - -sub _json_hint_to_class { - my $type = shift; - my $hint = shift; - - return $_class_map{hints}{$hint}{name} if (exists $_class_map{hints}{$hint}); - - $type = 'hash' if ($type eq '}'); - $type = 'array' if ($type eq ']'); - - JSON->register_class_hint(name => $hint, hint => $hint, type => $type); - - return $hint; -} - -sub JSON2perl { - my $class = shift; - local $_ = shift; - - s/(? _json_hint_to_class("$1", "$2")) /sog; - - my $re = qr/((?(?<=\\)"|[^"])*(? /sog; - - # Do numbers... - #s/\b(-?\d+\.?\d*)\b/ JSON::number::new($1) /sog; - - # Change javascript stuff to perl... - s/null/ undef /sog; - s/true/ bless( {}, "JSON::bool::true") /sog; - s/false/ bless( {}, "JSON::bool::false") /sog; - - my $ret; - return eval '$ret = '.$_; -} - -my $_json_index; -sub ___JSON2perl { - my $class = shift; - my $data = shift; - - $data = [ split //, $data ]; - - $_json_index = 0; - - return _json_parse_data($data); -} - -sub _eat_WS { - my $data = shift; - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } -} - -sub _json_parse_data { - my $data = shift; - - my $out; - - #warn "parse_data"; - - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - - my $class = ''; - - my $c = $$data[$_json_index]; - - if ($c eq '/') { - $_json_index++; - $class = _json_parse_comment($data); - - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - $c = $$data[$_json_index]; - } - - if ($c eq '"') { - $_json_index++; - my $val = ''; - - my $seen_slash = 0; - my $done = 0; - while (!$done) { - my $c = $$data[$_json_index]; - #warn "c is $c"; - - if ($c eq '\\') { - if ($seen_slash) { - $val .= '\\'; - $seen_slash = 0; - } else { - $seen_slash = 1; - } - } elsif ($c eq '"') { - if ($seen_slash) { - $val .= '"'; - $seen_slash = 0; - } else { - $done = 1; - } - } elsif ($c eq 't') { - if ($seen_slash) { - $val .= "\t"; - $seen_slash = 0; - } else { - $val .= 't'; - } - } elsif ($c eq 'b') { - if ($seen_slash) { - $val .= "\b"; - $seen_slash = 0; - } else { - $val .= 'b'; - } - } elsif ($c eq 'f') { - if ($seen_slash) { - $val .= "\f"; - $seen_slash = 0; - } else { - $val .= 'f'; - } - } elsif ($c eq 'r') { - if ($seen_slash) { - $val .= "\r"; - $seen_slash = 0; - } else { - $val .= 'r'; - } - } elsif ($c eq 'n') { - if ($seen_slash) { - $val .= "\n"; - $seen_slash = 0; - } else { - $val .= 'n'; - } - } elsif ($c eq 'u') { - if ($seen_slash) { - $_json_index++; - $val .= chr(hex(join('',$$data[$_json_index .. $_json_index + 3]))); - $_json_index += 3; - $seen_slash = 0; - } else { - $val .= 'u'; - } - } else { - $val .= $c; - } - $_json_index++; - - #warn "string is $val"; - } - - $out = $val; - - #$out = _json_parse_string($data); - } elsif ($c eq '[') { - $_json_index++; - $out = []; - - my $in_parse = 0; - my $done = 0; - while(!$done) { - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - - if ($$data[$_json_index] eq ']') { - $done = 1; - $_json_index++; - last; - } - - if ($in_parse) { - if ($$data[$_json_index] ne ',') { - #warn "_json_parse_array: bad data, leaving array parser"; - last; - } - $_json_index++; - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - } - - my $item = _json_parse_data($data); - - push @$out, $item; - $in_parse++; - } - - #$out = _json_parse_array($data); - } elsif ($c eq '{') { - $_json_index++; - $out = {}; - - my $in_parse = 0; - my $done = 0; - while(!$done) { - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - - if ($$data[$_json_index] eq '}') { - $done = 1; - $_json_index++; - last; - } - - if ($in_parse) { - if ($$data[$_json_index] ne ',') { - #warn "_json_parse_object: bad data, leaving object parser"; - last; - } - $_json_index++; - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - } - - my ($key,$value); - $key = _json_parse_data($data); - - #warn "object key is $key"; - - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - - if ($$data[$_json_index] ne ':') { - #warn "_json_parse_object: bad data, leaving object parser"; - last; - } - $_json_index++; - $value = _json_parse_data($data); - - $out->{$key} = $value; - $in_parse++; - } - #$out = _json_parse_object($data); - } elsif (lc($c) eq 'n') { - if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'null') { - $_json_index += 4; - } else { - warn "CRAP! bad null parsing..."; - } - $out = undef; - #$out = _json_parse_null($data); - } elsif (lc($c) eq 't' or lc($c) eq 'f') { - if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'true') { - $out = 1; - $_json_index += 4; - } elsif (lc(join('',$$data[$_json_index .. $_json_index + 4])) eq 'false') { - $out = 0; - $_json_index += 5; - } else { - #warn "CRAP! bad bool parsing..."; - $out = undef; - } - #$out = _json_parse_bool($data); - } elsif ($c =~ /\d+/o or $c eq '.' or $c eq '-') { - my $val; - while ($$data[$_json_index] =~ /[-\.0-9]+/io) { - $val .= $$data[$_json_index]; - $_json_index++; - } - $out = 0+$val; - #$out = _json_parse_number($data); - } - - if ($class) { - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - my $c = $$data[$_json_index]; - - if ($c eq '/') { - $_json_index++; - _json_parse_comment($data) - } - - bless( $out => lookup_class($class) ); - } - - $out; -} - -sub _json_parse_null { - my $data = shift; - - #warn "parse_null"; - - if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'null') { - $_json_index += 4; - } else { - #warn "CRAP! bad null parsing..."; - } - return undef; -} - -sub _json_parse_bool { - my $data = shift; - - my $out; - - #warn "parse_bool"; - - if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'true') { - $out = 1; - $_json_index += 4; - } elsif (lc(join('',$$data[$_json_index .. $_json_index + 4])) eq 'false') { - $out = 0; - $_json_index += 5; - } else { - #warn "CRAP! bad bool parsing..."; - $out = undef; - } - return $out; -} - -sub _json_parse_number { - my $data = shift; - - #warn "parse_number"; - - my $val; - while ($$data[$_json_index] =~ /[-\.0-9]+/io) { - $val .= $$data[$_json_index]; - $_json_index++; - } - - return 0+$val; -} - -sub _json_parse_object { - my $data = shift; - - #warn "parse_object"; - - my $out = {}; - - my $in_parse = 0; - my $done = 0; - while(!$done) { - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - - if ($$data[$_json_index] eq '}') { - $done = 1; - $_json_index++; - last; - } - - if ($in_parse) { - if ($$data[$_json_index] ne ',') { - #warn "_json_parse_object: bad data, leaving object parser"; - last; - } - $_json_index++; - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - } - - my ($key,$value); - $key = _json_parse_data($data); - - #warn "object key is $key"; - - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - - if ($$data[$_json_index] ne ':') { - #warn "_json_parse_object: bad data, leaving object parser"; - last; - } - $_json_index++; - $value = _json_parse_data($data); - - $out->{$key} = $value; - $in_parse++; - } - - return $out; -} - -sub _json_parse_array { - my $data = shift; - - #warn "parse_array"; - - my $out = []; - - my $in_parse = 0; - my $done = 0; - while(!$done) { - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - - if ($$data[$_json_index] eq ']') { - $done = 1; - $_json_index++; - last; - } - - if ($in_parse) { - if ($$data[$_json_index] ne ',') { - #warn "_json_parse_array: bad data, leaving array parser"; - last; - } - $_json_index++; - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - } - - my $item = _json_parse_data($data); - - push @$out, $item; - $in_parse++; - } - - return $out; -} - - -sub _json_parse_string { - my $data = shift; - - #warn "parse_string"; - - my $val = ''; - - my $seen_slash = 0; - my $done = 0; - while (!$done) { - my $c = $$data[$_json_index]; - #warn "c is $c"; - - if ($c eq '\\') { - if ($seen_slash) { - $val .= '\\'; - $seen_slash = 0; - } else { - $seen_slash = 1; - } - } elsif ($c eq '"') { - if ($seen_slash) { - $val .= '"'; - $seen_slash = 0; - } else { - $done = 1; - } - } elsif ($c eq 't') { - if ($seen_slash) { - $val .= "\t"; - $seen_slash = 0; - } else { - $val .= 't'; - } - } elsif ($c eq 'b') { - if ($seen_slash) { - $val .= "\b"; - $seen_slash = 0; - } else { - $val .= 'b'; - } - } elsif ($c eq 'f') { - if ($seen_slash) { - $val .= "\f"; - $seen_slash = 0; - } else { - $val .= 'f'; - } - } elsif ($c eq 'r') { - if ($seen_slash) { - $val .= "\r"; - $seen_slash = 0; - } else { - $val .= 'r'; - } - } elsif ($c eq 'n') { - if ($seen_slash) { - $val .= "\n"; - $seen_slash = 0; - } else { - $val .= 'n'; - } - } elsif ($c eq 'u') { - if ($seen_slash) { - $_json_index++; - $val .= chr(hex(join('',$$data[$_json_index .. $_json_index + 3]))); - $_json_index += 3; - $seen_slash = 0; - } else { - $val .= 'u'; - } - } else { - $val .= $c; - } - $_json_index++; - - #warn "string is $val"; - } - - return $val; -} - -sub _json_parse_comment { - my $data = shift; - - #warn "parse_comment"; - - if ($$data[$_json_index] eq '/') { - $_json_index++; - while (!($$data[$_json_index] eq "\n")) { $_json_index++ } - $_json_index++; - return undef; - } - - my $class = ''; - - if (join('',$$data[$_json_index .. $_json_index + 2]) eq '*--') { - $_json_index += 3; - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - if ($$data[$_json_index] eq 'S') { - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - while ($$data[$_json_index] !~ /[-\s]+/o) { - $class .= $$data[$_json_index]; - $_json_index++; - } - while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } - } - } - - while ($$data[$_json_index] ne '/') { $_json_index++ }; - $_json_index++; - - return $class; -} - -sub old_JSON2perl { - my ($class, $json) = @_; - - if (!defined($json)) { - return undef; - } - - $json =~ s/(? '; - next; - } elsif ($element eq 'true') { - $output .= 'bless( {}, "JSON::bool::true")'; - next; - } elsif ($element eq 'false') { - $output .= 'bless( {}, "JSON::bool::false")'; - next; - } - - $output .= $element; - } - - return eval $output; -} - -sub perl2JSON { - my ($class, $perl, $strict) = @_; - - my $output = ''; - if (!defined($perl)) { - $output = '' if $strict; - $output = 'null' unless $strict; - } elsif (ref($perl) and ref($perl) =~ /^JSON/) { - $output .= $perl; - } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) { - $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}.'--*/'; - if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') { - my %hash = %$perl; - $output .= perl2JSON(undef,\%hash, $strict); - } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') { - my @array = @$perl; - $output .= perl2JSON(undef,\@array, $strict); - } - $output .= '/*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/'; - } elsif (ref($perl) and ref($perl) =~ /HASH/) { - $output .= '{'; - my $c = 0; - for my $key (sort keys %$perl) { - my $outkey = NFC($key); - $output .= ',' if ($c); - - $outkey =~ s{\\}{\\\\}sgo; - $outkey =~ s/"/\\"/sgo; - $outkey =~ s/\t/\\t/sgo; - $outkey =~ s/\f/\\f/sgo; - $outkey =~ s/\r/\\r/sgo; - $outkey =~ s/\n/\\n/sgo; - $outkey =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe; - - $output .= '"'.$outkey.'":'. perl2JSON(undef,$$perl{$key}, $strict); - $c++; - } - $output .= '}'; - } elsif (ref($perl) and ref($perl) =~ /ARRAY/) { - $output .= '['; - my $c = 0; - for my $part (@$perl) { - $output .= ',' if ($c); - - $output .= perl2JSON(undef,$part, $strict); - $c++; - } - $output .= ']'; - } elsif (ref($perl) and ref($perl) =~ /CODE/) { - $output .= perl2JSON(undef,$perl->(), $strict); - } elsif (ref($perl) and ("$perl" =~ /^([^=]+)=(\w+)/o)) { - my $type = $2; - my $name = $1; - JSON->register_class_hint(name => $name, hint => $name, type => lc($type)); - $output .= perl2JSON(undef,$perl, $strict); - } else { - $perl = NFC($perl); - $perl =~ s{\\}{\\\\}sgo; - $perl =~ s/"/\\"/sgo; - $perl =~ s/\t/\\t/sgo; - $perl =~ s/\f/\\f/sgo; - $perl =~ s/\r/\\r/sgo; - $perl =~ s/\n/\\n/sgo; - $perl =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe; - if (length($perl) < 10 and $perl =~ /^(?:\+|-)?\d*\.?\d+$/o and $perl !~ /^(?:\+|-)?0\d+/o ) { - $output = $perl; - } else { - $output = '"'.$perl.'"'; - } - } - - return $output; -} - -my $depth = 0; -sub perl2prettyJSON { - my ($class, $perl, $nospace) = @_; - $perl ||= $class; - - my $output = ''; - if (!defined($perl)) { - $output = " "x$depth unless($nospace); - $output .= 'null'; - } elsif (ref($perl) and ref($perl) =~ /^JSON/) { - $output = " "x$depth unless($nospace); - $output .= $perl; - } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) { - $depth++; - $output .= "\n"; - $output .= " "x$depth; - $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}."--*/ "; - if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') { - my %hash = %$perl; - $output .= perl2prettyJSON(\%hash,undef,1); - } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') { - my @array = @$perl; - $output .= perl2prettyJSON(\@array,undef,1); - } - $output .= ' /*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/'; - $depth--; - } elsif (ref($perl) and ref($perl) =~ /HASH/) { - $output .= " "x$depth unless ($nospace); - $output .= "{\n"; - my $c = 0; - $depth++; - for my $key (sort keys %$perl) { - $output .= ",\n" if ($c); - $output .= " "x$depth; - $output .= perl2prettyJSON($key)." : ".perl2prettyJSON($$perl{$key}, undef, 1); - $c++; - } - $depth--; - $output .= "\n"; - $output .= " "x$depth; - $output .= '}'; - } elsif (ref($perl) and ref($perl) =~ /ARRAY/) { - $output .= " "x$depth unless ($nospace); - $output .= "[\n"; - my $c = 0; - $depth++; - for my $part (@$perl) { - $output .= ",\n" if ($c); - $output .= " "x$depth; - $output .= perl2prettyJSON($part); - $c++; - } - $depth--; - $output .= "\n"; - $output .= " "x$depth; - $output .= "]"; - } elsif (ref($perl) and ref($perl) =~ /CODE/) { - $output .= perl2prettyJSON(undef,$perl->(), $nospace); - } elsif (ref($perl) and "$perl" =~ /^([^=]+)=(\w{4,5})\(0x/) { - my $type = $2; - my $name = $1; - register_class_hint(undef, name => $name, hint => $name, type => lc($type)); - $output .= perl2prettyJSON(undef,$perl); - } else { - $perl = NFC($perl); - $perl =~ s/\\/\\\\/sgo; - $perl =~ s/"/\\"/sgo; - $perl =~ s/\t/\\t/sgo; - $perl =~ s/\f/\\f/sgo; - $perl =~ s/\r/\\r/sgo; - $perl =~ s/\n/\\n/sgo; - $perl =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe; - $output .= " "x$depth unless($nospace); - if (length($perl) < 10 and $perl =~ /^(?:\+|-)?\d*\.?\d+$/o and $perl !~ /^(?:\+|-)?0\d+/o ) { - $output = $perl; - } else { - $output = '"'.$perl.'"'; - } - } - - return $output; -} - -1; diff --git a/src/perlmods/OpenSRF/AppSession.pm b/src/perlmods/OpenSRF/AppSession.pm index 6c32af1..9b2017a 100644 --- a/src/perlmods/OpenSRF/AppSession.pm +++ b/src/perlmods/OpenSRF/AppSession.pm @@ -1,10 +1,9 @@ package OpenSRF::AppSession; -use OpenSRF::DOM; -#use OpenSRF::DOM::Element::userAuth; use OpenSRF::DomainObject::oilsMessage; use OpenSRF::DomainObject::oilsMethod; use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::Transport::PeerHandle; +use OpenSRF::Utils::JSON; use OpenSRF::Utils::Logger qw(:level); use OpenSRF::Utils::SettingsClient; use OpenSRF::Utils::Config; @@ -531,7 +530,7 @@ sub send { } } - my $json = JSON->perl2JSON(\@doc); + my $json = OpenSRF::Utils::JSON->perl2JSON(\@doc); $logger->internal("AppSession sending doc: $json"); $self->{peer_handle}->send( diff --git a/src/perlmods/OpenSRF/Application.pm b/src/perlmods/OpenSRF/Application.pm index 0b3f9b7..71e62a4 100644 --- a/src/perlmods/OpenSRF/Application.pm +++ b/src/perlmods/OpenSRF/Application.pm @@ -10,7 +10,7 @@ use Data::Dumper; use Time::HiRes qw/time/; use OpenSRF::EX qw/:try/; use Carp; -use JSON; +use OpenSRF::Utils::JSON; #use OpenSRF::UnixServer; # to get the server class from UnixServer::App sub DESTROY{}; @@ -148,7 +148,7 @@ sub handler { for my $p (0 .. scalar(@{ $sig->{params} }) - 1 ) { my $s = $sig->{params}->[$p]; my $a = $args[$p]; - if ($s->{class} && JSON->lookup_hint(ref $a) ne $s->{class}) { + if ($s->{class} && OpenSRF::Utils::JSON->lookup_hint(ref $a) ne $s->{class}) { die "Incorrect param class at position $p : should be a '$$s{class}'"; } elsif ($s->{type}) { if (lc($s->{type}) eq 'object' && $a !~ /HASH/o) { @@ -225,7 +225,7 @@ sub handler { for my $p (0 .. scalar(@{ $sig->{params} }) - 1 ) { my $s = $sig->{params}->[$p]; my $a = $args[$p]; - if ($s->{class} && JSON->lookup_hint(ref $a) ne $s->{class}) { + if ($s->{class} && OpenSRF::Utils::JSON->lookup_hint(ref $a) ne $s->{class}) { die "Incorrect param class at position $p : should be a '$$s{class}'"; } elsif ($s->{type}) { if (lc($s->{type}) eq 'object' && $a !~ /HASH/o) { @@ -393,7 +393,7 @@ sub register_method { ($args{object_hint} = $args{package}) =~ s/::/_/go; } - JSON->register_class_hint( name => $args{package}, hint => $args{object_hint}, type => "hash" ); + OpenSRF::Utils::JSON->register_class_hint( name => $args{package}, hint => $args{object_hint}, type => "hash" ); $_METHODS[$args{api_level}]{$args{api_name}} = bless \%args => $app; diff --git a/src/perlmods/OpenSRF/Application/Demo/Math.pm b/src/perlmods/OpenSRF/Application/Demo/Math.pm index eed993a..1bc99ef 100644 --- a/src/perlmods/OpenSRF/Application/Demo/Math.pm +++ b/src/perlmods/OpenSRF/Application/Demo/Math.pm @@ -3,7 +3,6 @@ use base qw/OpenSRF::Application/; use OpenSRF::Application; use OpenSRF::Utils::Logger qw/:level/; use OpenSRF::DomainObject::oilsResponse; -#use OpenSRF::DomainObject::oilsPrimitive; use OpenSRF::EX qw/:try/; use strict; use warnings; diff --git a/src/perlmods/OpenSRF/Application/Demo/MathDB.pm b/src/perlmods/OpenSRF/Application/Demo/MathDB.pm index eb90345..6cdc78c 100644 --- a/src/perlmods/OpenSRF/Application/Demo/MathDB.pm +++ b/src/perlmods/OpenSRF/Application/Demo/MathDB.pm @@ -1,9 +1,8 @@ package OpenSRF::Application::Demo::MathDB; -use JSON; +use OpenSRF::Utils::JSON; use base qw/OpenSRF::Application/; use OpenSRF::Application; use OpenSRF::DomainObject::oilsResponse qw/:status/; -#use OpenSRF::DomainObject::oilsPrimitive; use OpenSRF::Utils::Logger qw/:level/; use strict; use warnings; @@ -20,7 +19,7 @@ sub add_1 { my $n1 = shift; my $n2 = shift; my $a = $n1 + $n2; - return JSON::number->new($a); + return OpenSRF::Utils::JSON::number->new($a); } __PACKAGE__->register_method( method => 'sub_1', api_name => 'dbmath.sub' ); @@ -31,7 +30,7 @@ sub sub_1 { my $n1 = shift; my $n2 = shift; my $a = $n1 - $n2; - return JSON::number->new($a); + return OpenSRF::Utils::JSON::number->new($a); } __PACKAGE__->register_method( method => 'mult_1', api_name => 'dbmath.mult' ); @@ -42,7 +41,7 @@ sub mult_1 { my $n1 = shift; my $n2 = shift; my $a = $n1 * $n2; - return JSON::number->new($a); + return OpenSRF::Utils::JSON::number->new($a); } __PACKAGE__->register_method( method => 'div_1', api_name => 'dbmath.div' ); @@ -53,7 +52,7 @@ sub div_1 { my $n1 = shift; my $n2 = shift; my $a = $n1 / $n2; - return JSON::number->new($a); + return OpenSRF::Utils::JSON::number->new($a); } 1; diff --git a/src/perlmods/OpenSRF/Application/Persist.pm b/src/perlmods/OpenSRF/Application/Persist.pm index 1099dba..b8b291f 100644 --- a/src/perlmods/OpenSRF/Application/Persist.pm +++ b/src/perlmods/OpenSRF/Application/Persist.pm @@ -6,7 +6,7 @@ use OpenSRF::Utils::SettingsClient; use OpenSRF::EX qw/:try/; use OpenSRF::Utils qw/:common/; use OpenSRF::Utils::Logger; -use JSON; +use OpenSRF::Utils::JSON; use DBI; use vars qw/$dbh $log $default_expire_time/; @@ -227,7 +227,7 @@ sub add_item { $dbh->do('DELETE FROM storage WHERE name_id = ?;', {}, $name_id); } - $dbh->do('INSERT INTO storage (name_id,value) VALUES (?,?);', {}, $name_id, JSON->perl2JSON($value)); + $dbh->do('INSERT INTO storage (name_id,value) VALUES (?,?);', {}, $name_id, OpenSRF::Utils::JSON->perl2JSON($value)); _flush_by_name($name); @@ -344,7 +344,7 @@ sub pop_queue { _flush_by_name($name); - return JSON->JSON2perl( $value->[1] ); + return OpenSRF::Utils::JSON->JSON2perl( $value->[1] ); } catch Error with { #my $e = shift; #return $e; @@ -377,7 +377,7 @@ sub peek_slot { my $values = $dbh->selectall_arrayref("SELECT value FROM storage WHERE name_id = ? ORDER BY id $order;", {}, $name_id); - $client->respond( JSON->JSON2perl( $_->[0] ) ) for (@$values); + $client->respond( OpenSRF::Utils::JSON->JSON2perl( $_->[0] ) ) for (@$values); _flush_by_name($name); return undef; @@ -407,7 +407,7 @@ sub store_size { my $value = $dbh->selectcol_arrayref('SELECT SUM(LENGTH(value)) FROM storage WHERE name_id = ?;', {}, $name_id); - return JSON->JSON2perl( $value->[0] ); + return OpenSRF::Utils::JSON->JSON2perl( $value->[0] ); } __PACKAGE__->register_method( api_name => 'opensrf.persist.queue.size', @@ -436,7 +436,7 @@ sub store_depth { my $value = $dbh->selectcol_arrayref('SELECT COUNT(*) FROM storage WHERE name_id = ?;', {}, $name_id); - return JSON->JSON2perl( $value->[0] ); + return OpenSRF::Utils::JSON->JSON2perl( $value->[0] ); } __PACKAGE__->register_method( api_name => 'opensrf.persist.queue.length', @@ -465,7 +465,7 @@ sub shift_stack { _flush_by_name($name); - return JSON->JSON2perl( $value->[1] ); + return OpenSRF::Utils::JSON->JSON2perl( $value->[1] ); } catch Error with { my $e = shift; return undef; @@ -498,7 +498,7 @@ sub get_object { _flush_by_name($name); - return JSON->JSON2perl( $value->[1] ); + return OpenSRF::Utils::JSON->JSON2perl( $value->[1] ); } catch Error with { return undef; }; diff --git a/src/perlmods/OpenSRF/DOM.pm b/src/perlmods/OpenSRF/DOM.pm deleted file mode 100644 index 8ddb095..0000000 --- a/src/perlmods/OpenSRF/DOM.pm +++ /dev/null @@ -1,289 +0,0 @@ -use XML::LibXML; -use OpenSRF::Utils::Logger qw(:level); - -package XML::LibXML::Element; -use OpenSRF::EX; - -sub AUTOLOAD { - my $self = shift; - (my $name = $AUTOLOAD) =~ s/.*://; # strip fully-qualified portion - - ### Check for recursion - my $calling_method = (caller(1))[3]; - my @info = caller(1); - - if( @info ) { - if ($info[0] =~ /AUTOLOAD/) { @info = caller(2); } - } - unless( @info ) { @info = caller(); } - if( $calling_method and $calling_method eq "XML::LibXML::Element::AUTOLOAD" ) { - throw OpenSRF::EX::PANIC ( "RECURSION! Caller [ @info ] | Object [ ".ref($self)." ]\n ** Trying to call $name", ERROR ); - } - ### Check for recursion - - #OpenSRF::Utils::Logger->debug( "Autoloading method for DOM: $AUTOLOAD on ".$self->toString, INTERNAL ); - - my $new_node = OpenSRF::DOM::upcast($self); - OpenSRF::Utils::Logger->debug( "Autoloaded to: ".ref($new_node), INTERNAL ); - - return $new_node->$name(@_); -} - - - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM; -use base qw/XML::LibXML OpenSRF/; - -our %_NAMESPACE_MAP = ( - 'http://open-ils.org/xml/namespaces/oils_v1' => 'oils', -); - -our $_one_true_parser; - -sub new { - my $self = shift; - return $_one_true_parser if (defined $_one_true_parser); - $_one_true_parser = $self->SUPER::new(@_); - $_one_true_parser->keep_blanks(0); - $XML::LibXML::skipXMLDeclaration = 0; - return $_one_true_parser = $self->SUPER::new(@_); -} - -sub createDocument { - my $self = shift; - - # DOM API: createDocument(namespaceURI, qualifiedName, doctype?) - my $doc = XML::LibXML::Document->new("1.0", "UTF-8"); - my $el = $doc->createElement('root'); - - $el->setNamespace('http://open-ils.org/xml/namespaces/oils_v1', 'oils', 1); - $doc->setDocumentElement($el); - - return $doc; -} - -my %_loaded_classes; -sub upcast { - my $node = shift; - return undef unless $node; - - my ($ns,$tag) = split ':' => $node->nodeName; - - return $node unless ($ns eq 'oils'); - - my $class = "OpenSRF::DOM::Element::$tag"; - unless (exists $_loaded_classes{$class}) { - $class->use; - $_loaded_classes{$class} = 1; - } - if ($@) { - OpenSRF::Utils::Logger->error("Couldn't use $class! $@"); - } - - #OpenSRF::Utils::Logger->debug("Upcasting ".$node->toString." to $class", INTERNAL); - - return bless $node => $class; -} - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Node; -use base 'XML::LibXML::Node'; - -sub new { - my $class = shift; - return bless $class->SUPER::new(@_) => $class; -} - -sub childNodes { - my $self = shift; - my @children = $self->_childNodes(); - return wantarray ? @children : OpenSRF::DOM::NodeList->new( @children ); -} - -sub attributes { - my $self = shift; - my @attr = $self->_attributes(); - return wantarray ? @attr : OpenSRF::DOM::NamedNodeMap->new( @attr ); -} - -sub findnodes { - my ($node, $xpath) = @_; - my @nodes = $node->_findnodes($xpath); - if (wantarray) { - return @nodes; - } else { - return OpenSRF::DOM::NodeList->new(@nodes); - } -} - - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::NamedNodeMap; -use base 'XML::LibXML::NamedNodeMap'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::NodeList; -use base 'XML::LibXML::NodeList'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Element; -use base 'XML::LibXML::Element'; - -sub new { - my $class = shift; - - # magically create the element (tag) name, or build a blank element - (my $name = $class) =~ s/^OpenSRF::DOM::Element:://; - if ($name) { - $name = "oils:$name"; - } else { - undef $name; - } - - my $self = $class->SUPER::new($name); - - my %attrs = @_; - for my $aname (keys %attrs) { - $self->setAttribute($aname, $attrs{$aname}); - } - - return $self; -} - -sub getElementsByTagName { - my ( $node , $name ) = @_; - my $xpath = "descendant::$name"; - my @nodes = $node->_findnodes($xpath); - return wantarray ? @nodes : OpenSRF::DOM::NodeList->new(@nodes); -} - -sub getElementsByTagNameNS { - my ( $node, $nsURI, $name ) = @_; - my $xpath = "descendant::*[local-name()='$name' and namespace-uri()='$nsURI']"; - my @nodes = $node->_findnodes($xpath); - return wantarray ? @nodes : OpenSRF::DOM::NodeList->new(@nodes); -} - -sub getElementsByLocalName { - my ( $node,$name ) = @_; - my $xpath = "descendant::*[local-name()='$name']"; - my @nodes = $node->_findnodes($xpath); - return wantarray ? @nodes : OpenSRF::DOM::NodeList->new(@nodes); -} - -sub getChildrenByLocalName { - my ( $node,$name ) = @_; - my $xpath = "./*[local-name()='$name']"; - my @nodes = $node->_findnodes($xpath); - return @nodes; -} - -sub getChildrenByTagName { - my ( $node, $name ) = @_; - my @nodes = grep { $_->nodeName eq $name } $node->childNodes(); - return @nodes; -} - -sub getChildrenByTagNameNS { - my ( $node, $nsURI, $name ) = @_; - my $xpath = "*[local-name()='$name' and namespace-uri()='$nsURI']"; - my @nodes = $node->_findnodes($xpath); - return @nodes; -} - -sub appendWellBalancedChunk { - my ( $self, $chunk ) = @_; - - my $local_parser = OpenSRF::DOM->new(); - my $frag = $local_parser->parse_xml_chunk( $chunk ); - - $self->appendChild( $frag ); -} - -package OpenSRF::DOM::Element::root; -use base 'OpenSRF::DOM::Element'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Text; -use base 'XML::LibXML::Text'; - - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Comment; -use base 'XML::LibXML::Comment'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::CDATASection; -use base 'XML::LibXML::CDATASection'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Document; -use base 'XML::LibXML::Document'; - -sub empty { - my $self = shift; - return undef unless (ref($self)); - $self->documentElement->removeChild($_) for $self->documentElement->childNodes; - return $self; -} - -sub new { - my $class = shift; - return bless $class->SUPER::new(@_) => $class; -} - -sub getElementsByTagName { - my ( $doc , $name ) = @_; - my $xpath = "descendant-or-self::node()/$name"; - my @nodes = $doc->_findnodes($xpath); - return wantarray ? @nodes : OpenSRF::DOM::NodeList->new(@nodes); -} - -sub getElementsByTagNameNS { - my ( $doc, $nsURI, $name ) = @_; - my $xpath = "descendant-or-self::*[local-name()='$name' and namespace-uri()='$nsURI']"; - my @nodes = $doc->_findnodes($xpath); - return wantarray ? @nodes : OpenSRF::DOM::NodeList->new(@nodes); -} - -sub getElementsByLocalName { - my ( $doc,$name ) = @_; - my $xpath = "descendant-or-self::*[local-name()='$name']"; - my @nodes = $doc->_findnodes($xpath); - return wantarray ? @nodes : OpenSRF::DOM::NodeList->new(@nodes); -} - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::DocumentFragment; -use base 'XML::LibXML::DocumentFragment'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Attr; -use base 'XML::LibXML::Attr'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Dtd; -use base 'XML::LibXML::Dtd'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::PI; -use base 'XML::LibXML::PI'; - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Namespace; -use base 'XML::LibXML::Namespace'; - -sub isEqualNode { - my ( $self, $ref ) = @_; - if ( $ref->isa("XML::LibXML::Namespace") ) { - return $self->_isEqual($ref); - } - return 0; -} - -#-------------------------------------------------------------------------------- -package OpenSRF::DOM::Schema; -use base 'XML::LibXML::Schema'; - -1; diff --git a/src/perlmods/OpenSRF/DOM/Element/domainObject.pm b/src/perlmods/OpenSRF/DOM/Element/domainObject.pm deleted file mode 100644 index 4b98512..0000000 --- a/src/perlmods/OpenSRF/DOM/Element/domainObject.pm +++ /dev/null @@ -1,118 +0,0 @@ -package OpenSRF::DOM::Element::domainObject; -use strict; use warnings; -use base 'OpenSRF::DOM::Element'; -use OpenSRF::DOM; -use OpenSRF::DOM::Element::domainObjectAttr; -use OpenSRF::Utils::Logger qw(:level); -use OpenSRF::EX qw(:try); -use Carp; -#use OpenSRF::DomainObject::oilsPrimitive; -#use OpenSRF::DomainObject::oilsResponse; -use vars qw($AUTOLOAD); - -sub AUTOLOAD { - my $self = shift; - (my $name = $AUTOLOAD) =~ s/.*://; # strip fully-qualified portion - - return class($self) if ($name eq 'class'); - if ($self->can($name)) { - return $self->$name(@_); - } - - if (1) { - ### Check for recursion - my $calling_method = (caller(1))[3]; - my @info = caller(1); - - if( @info ) { - if ($info[0] =~ /AUTOLOAD/) { @info = caller(2); } - } - unless( @info ) { @info = caller(); } - - if( $calling_method and $calling_method eq "OpenSRF::DOM::Element::domainObject::AUTOLOAD" ) { - warn Carp::cluck; - throw OpenSRF::EX::PANIC ( "RECURSION! Caller [ @info[0..2] ] | Object [ ".ref($self)." ]\n ** Trying to call $name", ERROR ); - } - ### Check for recursion - } - - my @args = @_; - my $meth = class($self).'::'.$name; - - try { - return $self->$meth(@args); - } catch Error with { - my $e = shift; - if( $e ) { - OpenSRF::Utils::Logger->error( $@ . $e); - } else { - OpenSRF::Utils::Logger->error( $@ ); - } - die $@; - }; - - - my $node = OpenSRF::DOM::Element::domainObject::upcast($self); - OpenSRF::Utils::Logger->debug( "Autoloaded to: ".ref($node), INTERNAL ); - - return $node->$name(@_); -} - -sub downcast { - my $obj = shift; - return bless $obj => 'XML::LibXML::Element'; -} - -sub upcast { - my $self = shift; - return bless $self => class($self); -} - -sub new { - my $class = shift; - my $type = shift; - my $obj = $class->SUPER::new( name => $type ); - while (@_) { - my ($attr,$val) = (shift,shift); - last unless ($attr and $val); - $obj->addAttr( $attr, $val ); - #$obj->appendChild( OpenSRF::DOM::Element::domainObjectAttr->new($attr, $val) ); - } - return $obj; -} - -sub class { - my $self = shift; - return 'OpenSRF::DomainObject::'.$self->getAttribute('name'); -} - -sub base_type { - my $self = shift; - return $self->getAttribute('name'); -} - -sub addAttr { - my $self = shift; - $self->appendChild( $_ ) for OpenSRF::DOM::Element::domainObjectAttr->new(@_); - return $self; -} - -sub attrNode { - my $self = shift; - my $type = shift; - return (grep { $_->getAttribute('name') eq $type } $self->getChildrenByTagName("oils:domainObjectAttr"))[0]; -} - -sub attrHash { - my $self = shift; - my %attrs = map { ( $_->getAttribute('name') => $_->getAttribute('value') ) } $self->getChildrenByTagName('oils:domainObjectAttr'); - - return \%attrs; -} - -sub attrValue { - my $self = shift; - return $self->attrHash->{shift}; -} - -1; diff --git a/src/perlmods/OpenSRF/DOM/Element/domainObjectAttr.pm b/src/perlmods/OpenSRF/DOM/Element/domainObjectAttr.pm deleted file mode 100644 index fbdc28e..0000000 --- a/src/perlmods/OpenSRF/DOM/Element/domainObjectAttr.pm +++ /dev/null @@ -1,15 +0,0 @@ -package OpenSRF::DOM::Element::domainObjectAttr; -use base 'OpenSRF::DOM::Element'; - -sub new { - my $class = shift; - my @nodes; - while (@_) { - my ($name,$val) = (shift,shift); - push @nodes, $class->SUPER::new(name => $name, value => $val); - } - return @nodes if (wantarray); - return $nodes[0]; -} - -1; diff --git a/src/perlmods/OpenSRF/DOM/Element/domainObjectCollection.pm b/src/perlmods/OpenSRF/DOM/Element/domainObjectCollection.pm deleted file mode 100644 index 264c435..0000000 --- a/src/perlmods/OpenSRF/DOM/Element/domainObjectCollection.pm +++ /dev/null @@ -1,116 +0,0 @@ -package OpenSRF::DOM::Element::domainObjectCollection; -use base 'OpenSRF::DOM::Element'; -use OpenSRF::DOM::Element::domainObjectAttr; -use OpenSRF::EX; - -sub AUTOLOAD { - my $self = CORE::shift; - (my $name = $AUTOLOAD) =~ s/.*://; # strip fully-qualified portion - - return class($self) if ($name eq 'class'); - - my @args = @_; - my $meth = class($self).'::'.$name; - - ### Check for recursion - my $calling_method = (caller(1))[3]; - my @info = caller(1); - - if( @info ) { - if ($info[0] =~ /AUTOLOAD/) { @info = caller(2); } - } - unless( @info ) { @info = caller(); } - if( $calling_method and $calling_method eq "OpenSRF::DOM::Element::domainObjectCollection::AUTOLOAD" ) { - throw OpenSRF::EX::PANIC ( "RECURSION! Caller [ @info ] | Object [ ".ref($self)." ]\n ** Trying to call $name", ERROR ); - } - ### Check for recursion - - try { - return $self->$meth(@args);; - } catch Error with { - my $e = shift; - OpenSRF::Utils::Logger->error( $@ . $e); - die $@; - }; - - return upcast($self)->$name(@_); -} - -sub downcast { - my $obj = CORE::shift; - return bless $obj => 'XML::LibXML::Element'; -} - -sub upcast { - my $self = CORE::shift; - return bless $self => class($self); -} - -sub new { - my $class = CORE::shift; - my $type = CORE::shift; - my $obj = $class->SUPER::new( name => $type ); - while ( my $val = shift) { - throw OpenSRF::EX::NotADomainObject - if (ref $val and $val->nodeName !~ /^oils:domainObject/o); - $obj->appendChild( $val ); - } - return $obj; -} - -sub class { - my $self = shift; - return 'OpenSRF::DomainObjectCollection::'.$self->getAttribute('name'); -} - -sub base_type { - my $self = shift; - return $self->getAttribute('name'); -} - -sub pop { - my $self = CORE::shift; - return $self->removeChild( $self->lastChild )->upcast; -} - -sub push { - my $self = CORE::shift; - my @args = @_; - for my $node (@args) { - #throw OpenSRF::EX::NotADomainObject ( "$_ must be a oils:domainOjbect*, it's a ".$_->nodeName ) - # unless ($_->nodeName =~ /^oils:domainObject/o); - - unless ($node->nodeName =~ /^oils:domainObject/o) { - $node = OpenSRF::DomainObject::oilsScalar->new($node); - } - - $self->appendChild( $node ); - } -} - -sub shift { - my $self = CORE::shift; - return $self->removeChild( $self->firstChild )->upcast; -} - -sub unshift { - my $self = CORE::shift; - my @args = @_; - for (reverse @args) { - throw OpenSRF::EX::NotADomainObject - unless ($_->nodeName =~ /^oils:domainObject/o); - $self->insertBefore( $_, $self->firstChild ); - } -} - -sub first { - my $self = CORE::shift; - return $self->firstChild->upcast; -} - -sub list { - my $self = CORE::shift; - return map {(bless($_ => 'OpenSRF::DomainObject::'.$_->getAttribute('name')))} $self->childNodes; -} - -1; diff --git a/src/perlmods/OpenSRF/DOM/Element/params.pm b/src/perlmods/OpenSRF/DOM/Element/params.pm deleted file mode 100644 index ee3755a..0000000 --- a/src/perlmods/OpenSRF/DOM/Element/params.pm +++ /dev/null @@ -1,4 +0,0 @@ -package OpenSRF::DOM::Element::params; -use base 'OpenSRF::DOM::Element'; - -1; diff --git a/src/perlmods/OpenSRF/DomainObject.pm b/src/perlmods/OpenSRF/DomainObject.pm deleted file mode 100644 index 4dc4258..0000000 --- a/src/perlmods/OpenSRF/DomainObject.pm +++ /dev/null @@ -1,85 +0,0 @@ -package OpenSRF::DomainObject; -use base 'OpenSRF::DOM::Element::domainObject'; -use OpenSRF::DOM; -use OpenSRF::Utils::Logger qw(:level); -use OpenSRF::DomainObject::oilsPrimitive; -my $logger = "OpenSRF::Utils::Logger"; - -=head1 NAME - -OpenSRF::DomainObject - -=head1 SYNOPSIS - -OpenSRF::DomainObject is an abstract base class. It -should not be used directly. See C -for details. - -=cut - -my $tmp_doc; - -sub object_castor { - my $self = shift; - my $node = shift; - - return unless (defined $node); - - if (ref($node) eq 'HASH') { - return new OpenSRF::DomainObject::oilsHash (%$node); - } elsif (ref($node) eq 'ARRAY') { - return new OpenSRF::DomainObject::oilsArray (@$node); - } - - return $node; -} - -sub native_castor { - my $self = shift; - my $node = shift; - - return unless (defined $node); - - if ($node->nodeType == 3) { - return $node->nodeValue; - } elsif ($node->nodeName =~ /domainObject/o) { - return $node->tie_me if ($node->class->can('tie_me')); - } - return $node; -} - -sub new { - my $class = shift; - $class = ref($class) || $class; - - (my $type = $class) =~ s/^.+://o; - - $tmp_doc ||= OpenSRF::DOM->createDocument; - my $dO = OpenSRF::DOM::Element::domainObject->new( $type, @_ ); - - $tmp_doc->documentElement->appendChild($dO); - - return $dO; -} - -sub _attr_get_set { - my $self = shift; - my $part = shift; - - my $node = $self->attrNode($part); - - if (defined(my $new_value = shift)) { - if (defined $node) { - my $old_val = $node->getAttribute( "value" ); - $node->setAttribute(value => $new_value); - return $old_val; - } else { - $self->addAttr( $part => $new_value ); - return $new_value; - } - } elsif ( $node ) { - return $node->getAttribute( "value" ); - } -} - -1; diff --git a/src/perlmods/OpenSRF/DomainObject/oilsMessage.pm b/src/perlmods/OpenSRF/DomainObject/oilsMessage.pm index 56fa9d3..1374e28 100644 --- a/src/perlmods/OpenSRF/DomainObject/oilsMessage.pm +++ b/src/perlmods/OpenSRF/DomainObject/oilsMessage.pm @@ -1,18 +1,18 @@ package OpenSRF::DomainObject::oilsMessage; -use JSON; +use OpenSRF::Utils::JSON; use OpenSRF::AppSession; use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::Utils::Logger qw/:level/; use warnings; use strict; use OpenSRF::EX qw/:try/; -JSON->register_class_hint(hint => 'osrfMessage', name => 'OpenSRF::DomainObject::oilsMessage', type => 'hash'); +OpenSRF::Utils::JSON->register_class_hint(hint => 'osrfMessage', name => 'OpenSRF::DomainObject::oilsMessage', type => 'hash'); sub toString { my $self = shift; my $pretty = shift; - return JSON->perl2prettyJSON($self) if ($pretty); - return JSON->perl2JSON($self); + return OpenSRF::Utils::JSON->perl2prettyJSON($self) if ($pretty); + return OpenSRF::Utils::JSON->perl2JSON($self); } sub new { diff --git a/src/perlmods/OpenSRF/DomainObject/oilsMethod.pm b/src/perlmods/OpenSRF/DomainObject/oilsMethod.pm index 6c81902..f83727b 100644 --- a/src/perlmods/OpenSRF/DomainObject/oilsMethod.pm +++ b/src/perlmods/OpenSRF/DomainObject/oilsMethod.pm @@ -1,13 +1,13 @@ package OpenSRF::DomainObject::oilsMethod; -use JSON; -JSON->register_class_hint(hint => 'osrfMethod', name => 'OpenSRF::DomainObject::oilsMethod', type => 'hash'); +use OpenSRF::Utils::JSON; +OpenSRF::Utils::JSON->register_class_hint(hint => 'osrfMethod', name => 'OpenSRF::DomainObject::oilsMethod', type => 'hash'); sub toString { my $self = shift; my $pretty = shift; - return JSON->perl2prettyJSON($self) if ($pretty); - return JSON->perl2JSON($self); + return OpenSRF::Utils::JSON->perl2prettyJSON($self) if ($pretty); + return OpenSRF::Utils::JSON->perl2JSON($self); } sub new { diff --git a/src/perlmods/OpenSRF/DomainObject/oilsMultiSearch.pm b/src/perlmods/OpenSRF/DomainObject/oilsMultiSearch.pm deleted file mode 100644 index fda4523..0000000 --- a/src/perlmods/OpenSRF/DomainObject/oilsMultiSearch.pm +++ /dev/null @@ -1,186 +0,0 @@ -package OpenSRF::DomainObjectCollection::oilsMultiSearch; -use OpenSRF::DomainObjectCollection; -use OpenSRF::DomainObject::oilsPrimitive; -use OpenSRF::DomainObject::oilsSearch; -use OpenSRF::DOM::Element::searchCriteria; -use OpenSRF::DOM::Element::searchCriterium; -use base 'OpenSRF::DomainObjectCollection::oilsHash'; - -sub new { - my $class = shift; - my %args = @_; - - $class = ref($class) || $class; - - my $self = $class->SUPER::new; - - tie my %hash, 'OpenSRF::DomainObjectCollection::oilsHash', $self; - - $self->set( bind_count => 1 ); - $self->set( searches => new OpenSRF::DomainObjectCollection::oilsHash ); - $self->set( relators => new OpenSRF::DomainObjectCollection::oilsArray ); - $self->set( fields => new OpenSRF::DomainObjectCollection::oilsArray ); - $self->set( group_by => new OpenSRF::DomainObjectCollection::oilsArray ); - $self->set( order_by => new OpenSRF::DomainObjectCollection::oilsArray ); - - return $self; -} - -sub add_subsearch { - my $self = shift; - my $alias = shift; - my $search = shift; - my $relator = shift; - - $search = OpenSRF::DomainObject::oilsSearch->new($search) if (ref($search) eq 'ARRAY'); - - $self->searches->set( $alias => $search ); - - if ($self->searches->size > 1) { - throw OpenSRF::EX::InvalidArg ('You need to pass a relator searchCriterium') - unless (defined $relator); - } - - $relator = OpenSRF::DOM::Element::searchCriterium->new( @$relator ) - if (ref($relator) eq 'ARRAY'); - - $self->relators->push( $relator ) if (defined $relator); - - return $self; -} - -sub relators { - return $_[0]->_accessor('relators'); -} - -sub searches { - return $_[0]->_accessor('searches'); -} - -sub fields { - my $self = shift; - my @parts = @_; - if (@parts) { - $self->set( fields => OpenSRF::DomainObjectCollection::oilsArray->new(@_) ); - } - return $self->_accessor('fields')->list; -} - -sub format { - $_[0]->set( format => $_[1] ) if (defined $_[1]); - return $_[0]->_accessor('format'); -} - -sub limit { - $_[0]->set( limit => $_[1] ) if (defined $_[1]); - return $_[0]->_accessor('limit'); -} - -sub offset { - $_[0]->set( offset => $_[1] ) if (defined $_[1]); - return $_[0]->_accessor('offset'); -} - -sub chunk_key { - $_[0]->set( chunk_key => $_[1] ) if (defined $_[1]); - return $_[0]->_accessor('chunk_key'); -} - -sub order_by { - my $self = shift; - my @parts = @_; - if (@parts) { - $self->set( order_by => OpenSRF::DomainObjectCollection::oilsArray->new(@_) ); - } - return $self->_accessor('order_by')->list; -} - -sub group_by { - my $self = shift; - my @parts = @_; - if (@parts) { - $self->set( group_by => OpenSRF::DomainObjectCollection::oilsArray->new(@_) ); - } - return $self->_accessor('group_by')->list; -} - -sub SQL_select_list { - my $self = shift; - - if (my $sql = $self->_accessor('sql_select_list')) { - return $sql; - } - - $self->set( sql_select_list => 'SELECT '.join(', ', $self->fields) ) if defined($self->fields); - return $self->_accessor('sql_select_list'); -} - -sub SQL_group_by { - my $self = shift; - - if (my $sql = $self->_accessor('sql_group_by')) { - return $sql; - } - - $self->set( sql_group_by => 'GROUP BY '.join(', ', $self->group_by) ) if defined($self->group_by); - return $self->_accessor('sql_group_by'); -} - -sub SQL_order_by { - my $self = shift; - - if (my $sql = $self->_accessor('sql_order_by')) { - return $sql; - } - - $self->set( sql_order_by => 'ORDER BY '.join(', ', $self->order_by) ) if defined($self->order_by); - return $self->_accessor('sql_order_by'); -} - -sub SQL_offset { - my $self = shift; - - if (my $sql = $self->_accessor('sql_offset')) { - return $sql; - } - - $self->set( sql_offset => 'OFFSET '.$self->offset ) if defined($self->offset); - return $self->_accessor('sql_offset'); -} - -sub SQL_limit { - my $self = shift; - - if (my $sql = $self->_accessor('sql_limit')) { - return $sql; - } - - $self->set( sql_limit => 'LIMIT '.$self->limit ) if defined($self->limit); - return $self->_accessor('sql_limit'); -} - -sub toSQL { - my $self = shift; - - my $SQL = $self->SQL_select_list.' FROM '; - - my @subselects; - for my $search ( $self->searches->keys ) { - push @subselects, '('.$self->searches->_accessor($search)->toSQL.') '.$search; - } - $SQL .= join(', ', @subselects).' WHERE '; - - my @relators; - for my $rel ( $self->relators->list ) { - push @relators, $rel->value->toSQL( no_quote => 1 ); - } - $SQL .= join(' AND ', @relators).' '; - $SQL .= join ' ', ($self->SQL_group_by, $self->SQL_order_by, $self->SQL_limit, $self->SQL_offset); - - return $SQL; -} - -#this is just to allow DomainObject to "upcast" nicely -package OpenSRF::DomainObject::oilsMultiSearch; -use base OpenSRF::DomainObjectCollection::oilsMultiSearch; -1; diff --git a/src/perlmods/OpenSRF/DomainObject/oilsPrimitive.pm b/src/perlmods/OpenSRF/DomainObject/oilsPrimitive.pm deleted file mode 100644 index bf9507a..0000000 --- a/src/perlmods/OpenSRF/DomainObject/oilsPrimitive.pm +++ /dev/null @@ -1,623 +0,0 @@ -package OpenSRF::DomainObject::oilsScalar; -use base 'OpenSRF::DomainObject'; -use OpenSRF::DomainObject; - -=head1 NAME - -OpenSRF::DomainObject::oilsScalar - -=head1 SYNOPSIS - - use OpenSRF::DomainObject::oilsScalar; - - my $text = OpenSRF::DomainObject::oilsScalar->new( 'a string or number' ); - $text->value( 'replacement value' ); - print "$text"; # stringify - - ... - - $text->value( 1 ); - if( $text ) { # boolify - - ... - - $text->value( rand() * 1000 ); - print 10 + $text; # numify - - Or, using the TIE interface: - - my $scalar; - my $real_object = tie($scalar, 'OpenSRF::DomainObject::oilsScalar', "a string to store..."); - - $scalar = "a new string"; - print $scalar . "\n"; - print $real_object->toString . "\n"; - -=head1 METHODS - -=head2 OpenSRF::DomainObject::oilsScalar->value( [$new_value] ) - -=over 4 - -Sets or gets the value of the scalar. As above, this can be specified -as a build attribute as well as added to a prebuilt oilsScalar object. - -=back - -=cut - -use overload '""' => sub { return ''.$_[0]->value }; -use overload '0+' => sub { return int($_[0]->value) }; -use overload '<=>' => sub { return int($_[0]->value) <=> $_[1] }; -use overload 'bool' => sub { return 1 if ($_[0]->value); return 0 }; - -sub new { - my $class = shift; - $class = ref($class) || $class; - - my $value = shift; - - return $value - if ( defined $value and - ref $value and $value->can('base_type') and - UNIVERSAL::isa($value->class, __PACKAGE__) and - !scalar(@_) - ); - - my $self = $class->SUPER::new; - - if (ref($value) and ref($value) eq 'SCALAR') { - $self->value($$value); - tie( $$value, ref($self->upcast), $self); - } else { - $self->value($value) if (defined $value); - } - - return $self; -} - -sub TIESCALAR { - return CORE::shift()->new(@_); -} - -sub value { - my $self = shift; - my $value = shift; - - if ( defined $value ) { - $self->removeChild($_) for ($self->childNodes); - if (ref($value) && $value->isa('XML::LibXML::Node')) { - #throw OpenSRF::EX::NotADomainObject - # unless ($value->nodeName =~ /^oils:domainObject/o); - $self->appendChild($value); - } elsif (defined $value) { - $self->appendText( ''.$value ); - } - - return $value - } else { - $value = $self->firstChild; - if ($value) { - if ($value->nodeType == 3) { - return $value->textContent; - } else { - return $value; - } - } - return undef; - } -} - -sub FETCH { $_[0]->value } -sub STORE { $_[0]->value($_[1]) } - -package OpenSRF::DomainObject::oilsPair; -use base 'OpenSRF::DomainObject::oilsScalar'; - -=head1 NAME - -OpenSRF::DomainObject::oilsPair - -=head1 SYNOPSIS - - use OpenSRF::DomainObject::oilsPair; - - my $pair = OpenSRF::DomainObject::oilsPair->new( 'key_for_pair' => 'a string or number' ); - - $pair->key( 'replacement key' ); - $pair->value( 'replacement value' ); - - print "$pair"; # stringify 'value' - - ... - - $pair->value( 1 ); - - if( $pair ) { # boolify - - ... - - $pair->value( rand() * 1000 ); - - print 10 + $pair; # numify 'value' - -=head1 ABSTRACT - -This class impliments a "named pair" object. This is the basis for -hash-type domain objects. - -=head1 METHODS - -=head2 OpenSRF::DomainObject::oilsPair->value( [$new_value] ) - -=over 4 - -Sets or gets the value of the pair. As above, this can be specified -as a build attribute as well as added to a prebuilt oilsPair object. - -=back - -=head2 OpenSRF::DomainObject::oilsPair->key( [$new_key] ) - -=over 4 - -Sets or gets the key of the pair. As above, this can be specified -as a build attribute as well as added to a prebuilt oilsPair object. -This must be a perlish scalar; any string or number that is valid as the -attribute on an XML node will work. - -=back - -=cut - -use overload '""' => sub { return ''.$_[0]->value }; -use overload '0+' => sub { return int($_[0]->value) }; -use overload 'bool' => sub { return 1 if ($_[0]->value); return 0 }; - -sub new { - my $class = shift; - my ($key, $value) = @_; - - my $self = $class->SUPER::new($value); - $self->setAttribute( key => $key); - - return $self; -} - -sub key { - my $self = shift; - my $key = shift; - - $self->setAttribute( key => $key) if ($key); - return $self->getAttribute( 'key' ); -} - -package OpenSRF::DomainObjectCollection::oilsArray; -use base qw/OpenSRF::DomainObjectCollection Tie::Array/; -use OpenSRF::DomainObjectCollection; - -=head1 NAME - -OpenSRF::DomainObjectCollection::oilsArray - -=head1 SYNOPSIS - - use OpenSRF::DomainObject::oilsPrimitive; - - my $collection = OpenSRF::DomainObjectCollection::oilsArray->new( $domain_object, $another_domain_object, ...); - - $collection->push( 'appended value' ); - $collection->unshift( 'prepended vaule' ); - my $first = $collection->shift; - my $last = $collection->pop; - - ... - - my @values = $collection->list; - - Or, using the TIE interface: - - my @array; - my $real_object = tie(@array, 'OpenSRF::DomainObjectCollection::oilsArray', $domain, $objects, 'to', $store); - - or to tie an existing $collection object - - my @array; - tie(@array, 'OpenSRF::DomainObjectCollection::oilsArray', $collection); - - or even.... - - my @array; - tie(@array, ref($collection), $collection); - - - $array[2] = $DomainObject; # replaces 'to' (which is now an OpenSRF::DomainObject::oilsScalar) above - delete( $array[3] ); # removes '$store' above. - my $size = scalar( @array ); - - print $real_object->toString; - -=head1 ABSTRACT - -This package impliments array-like domain objects. A full tie interface -is also provided. If elements are passed in as strings (or numbers) they -are turned into oilsScalar objects. Any simple scalar or Domain Object may -be stored in the array. - -=head1 METHODS - -=head2 OpenSRF::DomainObjectCollection::oilsArray->list() - -=over 4 - -Returns the array of 'OpenSRF::DomainObject's that this collection contains. - -=back - -=cut - -sub tie_me { - my $class = shift; - $class = ref($class) || $class; - my $node = shift; - my @array; - tie @array, $class, $node; - return \@array; -} - -# an existing DomainObjectCollection::oilsArray can now be tied -sub TIEARRAY { - return CORE::shift()->new(@_); -} - -sub new { - my $class = CORE::shift; - $class = ref($class) || $class; - - my $first = CORE::shift; - - return $first - if ( defined $first and - ref $first and $first->can('base_type') and - UNIVERSAL::isa($first->class, __PACKAGE__) and - !scalar(@_) - ); - - my $self = $class->SUPER::new; - - my @args = @_; - if (ref($first) and ref($first) eq 'ARRAY') { - push @args, @$first; - tie( @$first, ref($self->upcast), $self); - } else { - unshift @args, $first if (defined $first); - } - - $self->STORE($self->FETCHSIZE, $_) for (@args); - return $self; -} - -sub STORE { - my $self = CORE::shift; - my ($index, $value) = @_; - - $value = OpenSRF::DomainObject::oilsScalar->new($value) - unless ( ref $value and $value->nodeName =~ /^oils:domainObject/o ); - - $self->_expand($index) unless ($self->EXISTS($index)); - - ($self->childNodes)[$index]->replaceNode( $value ); - - return $value->upcast; -} - -sub push { - my $self = CORE::shift; - my @values = @_; - $self->STORE($self->FETCHSIZE, $_) for (@values); -} - -sub pop { - my $self = CORE::shift; - my $node = $self->SUPER::pop; - if ($node) { - if ($node->base_type eq 'oilsScalar') { - return $node->value; - } - return $node->upcast; - } -} - -sub unshift { - my $self = CORE::shift; - my @values = @_; - $self->insertBefore($self->firstChild, $_ ) for (reverse @values); -} - -sub shift { - my $self = CORE::shift; - my $node = $self->SUPER::shift; - if ($node) { - if ($node->base_type eq 'oilsScalar') { - return $node->value; - } - return $node->upcast; - } -} - -sub FETCH { - my $self = CORE::shift; - my $index = CORE::shift; - my $node = ($self->childNodes)[$index]->upcast; - if ($node) { - if ($node->base_type eq 'oilsScalar') { - return $node->value; - } - return $node->upcast; - } -} - -sub size { - my $self = CORE::shift; - scalar($self->FETCHSIZE) -} - -sub FETCHSIZE { - my $self = CORE::shift; - my @a = $self->childNodes; - return scalar(@a); -} - -sub _expand { - my $self = CORE::shift; - my $count = CORE::shift; - my $size = $self->FETCHSIZE; - for ($size..$count) { - $self->SUPER::push( new OpenSRF::DomainObject::oilsScalar ); - } -} - -sub STORESIZE { - my $self = CORE::shift; - my $count = CORE::shift; - my $size = $self->FETCHSIZE - 1; - - if (defined $count and $count != $size) { - if ($size < $count) { - $self->_expand($count); - $size = $self->FETCHSIZE - 1; - } else { - while ($size > $count) { - $self->SUPER::pop; - $size = $self->FETCHSIZE - 1; - } - } - } - - return $size -} - -sub EXISTS { - my $self = CORE::shift; - my $index = CORE::shift; - return $self->FETCHSIZE > abs($index) ? 1 : 0; -} - -sub CLEAR { - my $self = CORE::shift; - $self->STORESIZE(0); - return $self; -} - -sub DELETE { - my $self = CORE::shift; - my $index = CORE::shift; - return $self->removeChild( ($self->childNodes)[$index] ); -} - -package OpenSRF::DomainObjectCollection::oilsHash; -use base qw/OpenSRF::DomainObjectCollection Tie::Hash/; - -=head1 NAME - -OpenSRF::DomainObjectCollection::oilsHash - -=head1 SYNOPSIS - - use OpenSRF::DomainObject::oilsPrimitive; - - my $collection = OpenSRF::DomainObjectCollection::oilsHash->new( key1 => $domain_object, key2 => $another_domain_object, ...); - - $collection->set( key =>'value' ); - my $value = $collection->find( $key ); - my $dead_value = $collection->remove( $key ); - my @keys = $collection->keys; - my @values = $collection->values; - - Or, using the TIE interface: - - my %hash; - my $real_object = tie(%hash, 'OpenSRF::DomainObjectCollection::oilsHash', domain => $objects, to => $store); - - or to tie an existing $collection object - - my %hash; - tie(%hash, 'OpenSRF::DomainObjectCollection::oilsHash', $collection); - - or even.... - - my %hash; - tie(%hash, ref($collection), $collection); - - or perhaps ... - - my $content = $session->recv->content; # eh? EH?!?! - tie(my %hash, ref($content), $content); - - $hash{domain} = $DomainObject; # replaces value for key 'domain' above - delete( $hash{to} ); # removes 'to => $store' above. - for my $key ( keys %hash ) { - ... do stuff ... - } - - print $real_object->toString; - -=head1 ABSTRACT - -This package impliments hash-like domain objects. A full tie interface -is also provided. If elements are passed in as strings (or numbers) they -are turned into oilsScalar objects. Any simple scalar or Domain Object may -be stored in the hash. - -=back - -=cut - -sub tie_me { - my $class = shift; - $class = ref($class) || $class; - my $node = shift; - my %hash; - tie %hash, $class, $node; - return %hash; -} - - -sub keys { - my $self = shift; - return map { $_->key } $self->childNodes; -} - -sub values { - my $self = shift; - return map { $_->value } $self->childNodes; -} - -# an existing DomainObjectCollection::oilsHash can now be tied -sub TIEHASH { - return shift()->new(@_); -} - -sub new { - my $class = shift; - $class = ref($class) || $class; - my $first = shift; - - return $first - if ( defined $first and - ref $first and $first->can('base_type') and - UNIVERSAL::isa($first->class, __PACKAGE__) and - !scalar(@_) - ); - - my $self = $class->SUPER::new; - - my @args = @_; - if (ref($first) and ref($first) eq 'HASH') { - push @args, %$first; - tie( %$first, ref($self->upcast), $self); - } else { - unshift @args, $first if (defined $first); - } - - my %arg_hash = @args; - while ( my ($key, $value) = each(%arg_hash) ) { - $self->STORE($key => $value); - } - return $self; -} - -sub STORE { - shift()->set(@_); -} - -sub set { - my $self = shift; - my ($key, $value) = @_; - - my $node = $self->find_node($key); - - return $node->value( $value ) if (defined $node); - return $self->appendChild( OpenSRF::DomainObject::oilsPair->new($key => $value) ); -} - -sub _accessor { - my $self = shift; - my $key = shift; - my $node = find_node($self, $key); - return $node->value if ($node); -} - -sub find_node { - my $self = shift; - my $key = shift; - return ($self->findnodes("oils:domainObject[\@name=\"oilsPair\" and \@key=\"$key\"]", $self))[0]; -} - -sub find { - my $self = shift; - my $key = shift; - my $node = $self->find_node($key); - my $value = $node->value if (defined $node); - return $value; -} - -sub size { - my $self = CORE::shift; - my @a = $self->childNodes; - return scalar(@a); -} - -sub FETCH { - my $self = shift; - my $key = shift; - return $self->find($key); -} - -sub EXISTS { - my $self = shift; - my $key = shift; - return $self->find_node($key); -} - -sub CLEAR { - my $self = shift; - $self->removeChild for ($self->childNodes); - return $self; -} - -sub DELETE { - shift()->remove(@_); -} - -sub remove { - my $self = shift; - my $key = shift; - return $self->removeChild( $self->find_node($key) ); -} - -sub FIRSTKEY { - my $self = shift; - return $self->firstChild->key; -} - -sub NEXTKEY { - my $self = shift; - my $key = shift; - my ($prev_node) = $self->find_node($key); - my $last_node = $self->lastChild; - - if ($last_node and $last_node->key eq $prev_node->key) { - return undef; - } else { - return $prev_node->nextSibling->key; - } -} - -package OpenSRF::DomainObject::oilsHash; -use base qw/OpenSRF::DomainObjectCollection::oilsHash/; - -package OpenSRF::DomainObject::oilsArray; -use base qw/OpenSRF::DomainObjectCollection::oilsArray/; - -1; diff --git a/src/perlmods/OpenSRF/DomainObject/oilsResponse.pm b/src/perlmods/OpenSRF/DomainObject/oilsResponse.pm index 673516b..bcaf96f 100644 --- a/src/perlmods/OpenSRF/DomainObject/oilsResponse.pm +++ b/src/perlmods/OpenSRF/DomainObject/oilsResponse.pm @@ -1,11 +1,11 @@ package OpenSRF::DomainObject::oilsResponse; use vars qw/@EXPORT_OK %EXPORT_TAGS/; use Exporter; -use JSON; +use OpenSRF::Utils::JSON; use base qw/Exporter/; use OpenSRF::Utils::Logger qw/:level/; -JSON->register_class_hint( hint => 'osrfResponse', name => 'OpenSRF::DomainObject::oilsResponse', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfResponse', name => 'OpenSRF::DomainObject::oilsResponse', type => 'hash' ); BEGIN { @EXPORT_OK = qw/STATUS_CONTINUE STATUS_OK STATUS_ACCEPTED @@ -74,8 +74,8 @@ my $log = 'OpenSRF::Utils::Logger'; sub toString { my $self = shift; my $pretty = shift; - return JSON->perl2prettyJSON($self) if ($pretty); - return JSON->perl2JSON($self); + return OpenSRF::Utils::JSON->perl2prettyJSON($self) if ($pretty); + return OpenSRF::Utils::JSON->perl2JSON($self); } sub new { @@ -106,16 +106,13 @@ sub statusCode { return $self->{statusCode}; } - #------------------------------------------------------------------------------- - - package OpenSRF::DomainObject::oilsStatus; use OpenSRF::DomainObject::oilsResponse qw/:status/; use base 'OpenSRF::DomainObject::oilsResponse'; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfStatus', name => 'OpenSRF::DomainObject::oilsStatus', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfStatus', name => 'OpenSRF::DomainObject::oilsStatus', type => 'hash' ); =head1 NAME @@ -142,11 +139,13 @@ sets the default B to C and B to C. $status = 'Status'; $statusCode = STATUS_OK; +#------------------------------------------------------------------------------- + package OpenSRF::DomainObject::oilsConnectStatus; use OpenSRF::DomainObject::oilsResponse qw/:status/; use base 'OpenSRF::DomainObject::oilsStatus'; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfConnectStatus', name => 'OpenSRF::DomainObject::oilsConnectStatus', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfConnectStatus', name => 'OpenSRF::DomainObject::oilsConnectStatus', type => 'hash' ); =head1 NAME @@ -177,14 +176,13 @@ B $status = 'Connection Successful'; $statusCode = STATUS_OK; - - +#------------------------------------------------------------------------------- package OpenSRF::DomainObject::oilsContinueStatus; use OpenSRF::DomainObject::oilsResponse qw/:status/; use base 'OpenSRF::DomainObject::oilsStatus'; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfContinueStatus', name => 'OpenSRF::DomainObject::oilsContinueStatus', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfContinueStatus', name => 'OpenSRF::DomainObject::oilsContinueStatus', type => 'hash' ); =head1 NAME @@ -216,18 +214,13 @@ $statusCode = STATUS_CONTINUE; 1; - - #------------------------------------------------------------------------------- - - package OpenSRF::DomainObject::oilsResult; use OpenSRF::DomainObject::oilsResponse qw/:status/; -use OpenSRF::DomainObject::oilsPrimitive; use base 'OpenSRF::DomainObject::oilsResponse'; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfResult', name => 'OpenSRF::DomainObject::oilsResult', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfResult', name => 'OpenSRF::DomainObject::oilsResult', type => 'hash' ); $status = 'OK'; @@ -284,19 +277,15 @@ B 1; - - #------------------------------------------------------------------------------- - - package OpenSRF::DomainObject::oilsException; use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::EX; use base qw/OpenSRF::EX OpenSRF::DomainObject::oilsResponse/; use vars qw/$status $statusCode/; use Error; -JSON->register_class_hint( hint => 'osrfException', name => 'OpenSRF::DomainObject::oilsException', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfException', name => 'OpenSRF::DomainObject::oilsException', type => 'hash' ); sub message { my $self = shift; @@ -334,12 +323,14 @@ sets the default B to C and B to Cregister_class_hint( hint => 'osrfConnectException', name => 'OpenSRF::DomainObject::oilsConnectException', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfConnectException', name => 'OpenSRF::DomainObject::oilsConnectException', type => 'hash' ); =head1 NAME @@ -371,11 +362,13 @@ B $status = 'Connect Request Failed'; $statusCode = STATUS_FORBIDDEN; +#------------------------------------------------------------------------------- + package OpenSRF::DomainObject::oilsMethodException; use OpenSRF::DomainObject::oilsResponse qw/:status/; use base 'OpenSRF::DomainObject::oilsException'; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfMethodException', name => 'OpenSRF::DomainObject::oilsMethodException', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfMethodException', name => 'OpenSRF::DomainObject::oilsMethodException', type => 'hash' ); =head1 NAME @@ -414,40 +407,40 @@ package OpenSRF::DomainObject::oilsServerError; use OpenSRF::DomainObject::oilsResponse qw/:status/; use base 'OpenSRF::DomainObject::oilsException'; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfServerError', name => 'OpenSRF::DomainObject::oilsServerError', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfServerError', name => 'OpenSRF::DomainObject::oilsServerError', type => 'hash' ); $status = 'Internal Server Error'; $statusCode = STATUS_INTERNALSERVERERROR; # ------------------------------------------- - - - - package OpenSRF::DomainObject::oilsBrokenSession; use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::EX; use base qw/OpenSRF::DomainObject::oilsException OpenSRF::EX::ERROR/; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfBrokenSession', name => 'OpenSRF::DomainObject::oilsBrokenSession', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfBrokenSession', name => 'OpenSRF::DomainObject::oilsBrokenSession', type => 'hash' ); $status = "Request on Disconnected Session"; $statusCode = STATUS_EXPFAILED; +#------------------------------------------------------------------------------- + package OpenSRF::DomainObject::oilsXMLParseError; use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::EX; use base qw/OpenSRF::DomainObject::oilsException OpenSRF::EX::ERROR/; use vars qw/$status $statusCode/; -JSON->register_class_hint( hint => 'osrfXMLParseError', name => 'OpenSRF::DomainObject::oilsXMLParseError', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfXMLParseError', name => 'OpenSRF::DomainObject::oilsXMLParseError', type => 'hash' ); $status = "XML Parse Error"; $statusCode = STATUS_EXPFAILED; +#------------------------------------------------------------------------------- + package OpenSRF::DomainObject::oilsAuthException; use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::EX; use base qw/OpenSRF::DomainObject::oilsException OpenSRF::EX::ERROR/; -JSON->register_class_hint( hint => 'osrfAuthException', name => 'OpenSRF::DomainObject::oilsAuthException', type => 'hash' ); +OpenSRF::Utils::JSON->register_class_hint( hint => 'osrfAuthException', name => 'OpenSRF::DomainObject::oilsAuthException', type => 'hash' ); use vars qw/$status $statusCode/; $status = "Authentication Failure"; $statusCode = STATUS_FORBIDDEN; diff --git a/src/perlmods/OpenSRF/DomainObject/oilsSearch.pm b/src/perlmods/OpenSRF/DomainObject/oilsSearch.pm deleted file mode 100644 index b2e23e4..0000000 --- a/src/perlmods/OpenSRF/DomainObject/oilsSearch.pm +++ /dev/null @@ -1,106 +0,0 @@ -package OpenSRF::DomainObject::oilsSearch; -use OpenSRF::DomainObject; -use OpenSRF::DomainObject::oilsPrimitive; -use OpenSRF::DOM::Element::searchCriteria; -use base 'OpenSRF::DomainObject'; - -sub new { - my $class = shift; - $class = ref($class) || $class; - - unshift @_, 'table' if (@_ == 1); - my %args = @_; - - my $self = $class->SUPER::new; - - for my $part ( keys %args ) { - if ($part ne 'criteria') { - $self->$part( $args{$part} ); - next; - } - $self->criteria( OpenSRF::DOM::Element::searchCriteria->new( @{$args{$part}} ) ); - } - return $self; -} - -sub format { - my $self = shift; - return $self->_attr_get_set( format => shift ); -} - -sub table { - my $self = shift; - return $self->_attr_get_set( table => shift ); -} - -sub fields { - my $self = shift; - my $new_fields_ref = shift; - - my ($old_fields) = $self->getChildrenByTagName("oils:domainObjectCollection"); - - if ($new_fields_ref) { - my $do = OpenSRF::DomainObjectCollection::oilsArray->new( @$new_fields_ref ); - if (defined $old_fields) { - $old_fields->replaceNode($do); - } else { - $self->appendChild($do); - return $do->list; - } - } - - return $old_fields->list if ($old_fields); -} - -sub limit { - my $self = shift; - return $self->_attr_get_set( limit => shift ); -} - -sub offset { - my $self = shift; - return $self->_attr_get_set( offset => shift ); -} - -sub group_by { - my $self = shift; - return $self->_attr_get_set( group_by => shift ); -} - -sub criteria { - my $self = shift; - my $new_crit = shift; - - if (@_) { - unshift @_, $new_crit; - $new_crit = OpenSRF::DOM::Element::searchCriteria->new(@_); - } - - my ($old_crit) = $self->getChildrenByTagName("oils:searchCriteria"); - - if (defined $new_crit) { - if (defined $old_crit) { - $old_crit->replaceNode($new_crit); - } else { - $self->appendChild($new_crit); - return $new_crit; - } - } - - return $old_crit; -} - -sub toSQL { - my $self = shift; - - my $SQL = 'SELECT ' . join(',', $self->fields); - $SQL .= ' FROM ' . $self->table; - $SQL .= ' WHERE ' . $self->criteria->toSQL if ($self->criteria); - $SQL .= ' GROUP BY ' . $self->group_by if ($self->group_by); - $SQL .= ' LIMIT ' . $self->limit if ($self->limit); - $SQL .= ' OFFSET ' . $self->offset if ($self->offset); - - return $SQL; -} - -1; diff --git a/src/perlmods/OpenSRF/DomainObjectCollection.pm b/src/perlmods/OpenSRF/DomainObjectCollection.pm deleted file mode 100644 index 7049af7..0000000 --- a/src/perlmods/OpenSRF/DomainObjectCollection.pm +++ /dev/null @@ -1,35 +0,0 @@ -package OpenSRF::DomainObjectCollection; -use base 'OpenSRF::DOM::Element::domainObjectCollection'; -use OpenSRF::DOM; -use OpenSRF::Utils::Logger qw(:level); -my $logger = "OpenSRF::Utils::Logger"; - -=head1 NAME - -OpenSRF::DomainObjectCollection - -=head1 SYNOPSIS - -OpenSRF::DomainObjectCollection is an abstract base class. It -should not be used directly. See C -for details. - -=cut - -sub new { - my $class = shift; - $class = ref($class) || $class; - - my @args = shift; - - (my $type = $class) =~ s/^.+://o; - - my $doc = OpenSRF::DOM->createDocument; - my $dO = OpenSRF::DOM::Element::domainObjectCollection->new( $type, @args ); - - $doc->documentElement->appendChild($dO); - - return $dO; -} - -1; diff --git a/src/perlmods/OpenSRF/EX.pm b/src/perlmods/OpenSRF/EX.pm index 7b2cfb0..8aff411 100644 --- a/src/perlmods/OpenSRF/EX.pm +++ b/src/perlmods/OpenSRF/EX.pm @@ -179,34 +179,6 @@ Thrown where an argument to a method was invalid or not provided # ------------------------------------------------------------------- -package OpenSRF::EX::NotADomainObject; -use base 'OpenSRF::EX::ERROR'; -our $ex_msg_header = "Must be a Domain Object"; - -=head2 OpenSRF::EX::NotADomainObject - -Thrown where a OpenSRF::DomainObject::oilsScalar or -OpenSRF::DomainObject::oilsPair was passed a value that -is not a perl scalar or a OpenSRF::DomainObject. - -=cut - - -# ------------------------------------------------------------------- -package OpenSRF::EX::ArrayOutOfBounds; -use base 'OpenSRF::EX::ERROR'; -our $ex_msg_header = "Tied array access on a nonexistant index"; - -=head2 OpenSRF::EX::ArrayOutOfBounds - -Thrown where a TIEd array (OpenSRF::DomainObject::oilsArray) was accessed at -a nonexistant index - -=cut - - - -# ------------------------------------------------------------------- package OpenSRF::EX::Socket; use base 'OpenSRF::EX::ERROR'; our $ex_msg_header = "Socket Exception"; diff --git a/src/perlmods/OpenSRF/System.pm b/src/perlmods/OpenSRF/System.pm index cf3e840..ba86243 100644 --- a/src/perlmods/OpenSRF/System.pm +++ b/src/perlmods/OpenSRF/System.pm @@ -8,9 +8,8 @@ use OpenSRF::Transport; use OpenSRF::UnixServer; use OpenSRF::Utils; use OpenSRF::Utils::LogServer; -use OpenSRF::DOM; use OpenSRF::EX qw/:try/; -use POSIX ":sys_wait_h"; +use POSIX qw/setsid :sys_wait_h/; use OpenSRF::Utils::Config; use OpenSRF::Utils::SettingsParser; use OpenSRF::Utils::SettingsClient; @@ -111,7 +110,7 @@ sub load_bootstrap_config { OpenSRF::Utils::Config->load( config_file => $bootstrap_config_file ); - JSON->register_class_hint( name => "OpenSRF::Application", hint => "method", type => "hash" ); + OpenSRF::Utils::JSON->register_class_hint( name => "OpenSRF::Application", hint => "method", type => "hash" ); OpenSRF::Transport->message_envelope( "OpenSRF::Transport::SlimJabber::MessageWrapper" ); OpenSRF::Transport::PeerHandle->set_peer_client( "OpenSRF::Transport::SlimJabber::PeerConnection" ); @@ -127,7 +126,13 @@ sub bootstrap { my $bsconfig = OpenSRF::Utils::Config->current; # Start a process group and make me the captain - setpgrp( 0, 0 ); + exit if (OpenSRF::Utils::safe_fork()); + chdir('/'); + setsid(); + close STDIN; + close STDOUT; + close STDERR; + $0 = "OpenSRF System"; # ----------------------------------------------- diff --git a/src/perlmods/OpenSRF/Transport.pm b/src/perlmods/OpenSRF/Transport.pm index 4ee322c..9af9282 100644 --- a/src/perlmods/OpenSRF/Transport.pm +++ b/src/perlmods/OpenSRF/Transport.pm @@ -3,6 +3,7 @@ use strict; use warnings; use base 'OpenSRF'; use Time::HiRes qw/time/; use OpenSRF::AppSession; +use OpenSRF::Utils::JSON; use OpenSRF::Utils::Logger qw(:level); use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::EX qw/:try/; @@ -118,7 +119,7 @@ sub handler { # Create a document from the JSON contained within the message my $doc; - eval { $doc = JSON->JSON2perl($body); }; + eval { $doc = OpenSRF::Utils::JSON->JSON2perl($body); }; if( $@ ) { $logger->transport( "Received bogus JSON: $@", INFO ); diff --git a/src/perlmods/OpenSRF/UnixServer.pm b/src/perlmods/OpenSRF/UnixServer.pm index 120f73c..472bb44 100644 --- a/src/perlmods/OpenSRF/UnixServer.pm +++ b/src/perlmods/OpenSRF/UnixServer.pm @@ -10,7 +10,7 @@ use OpenSRF::DomainObject::oilsResponse qw/:status/; use OpenSRF::System; use OpenSRF::Utils::SettingsClient; use Time::HiRes qw(time); -use JSON; +use OpenSRF::Utils::JSON; use vars qw/@ISA $app/; use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); use Carp; @@ -208,7 +208,7 @@ sub configure_hook { my $imp = $client->config_value("apps", $app, "implementation"); OpenSRF::Application::server_class($app); OpenSRF::Application->application_implementation( $imp ); - JSON->register_class_hint( name => $imp, hint => $app, type => "hash" ); + OpenSRF::Utils::JSON->register_class_hint( name => $imp, hint => $app, type => "hash" ); OpenSRF::Application->application_implementation->initialize() if (OpenSRF::Application->application_implementation->can('initialize')); diff --git a/src/perlmods/OpenSRF/Utils/Cache.pm b/src/perlmods/OpenSRF/Utils/Cache.pm index ac430bd..635a2b3 100644 --- a/src/perlmods/OpenSRF/Utils/Cache.pm +++ b/src/perlmods/OpenSRF/Utils/Cache.pm @@ -6,7 +6,7 @@ use OpenSRF::Utils::Logger qw/:level/; use OpenSRF::Utils::Config; use OpenSRF::Utils::SettingsClient; use OpenSRF::EX qw(:try); -use JSON; +use OpenSRF::Utils::JSON; my $log = 'OpenSRF::Utils::Logger'; @@ -96,7 +96,7 @@ sub put_cache { my($self, $key, $value, $expiretime ) = @_; return undef unless( defined $key and defined $value ); - $value = JSON->perl2JSON($value); + $value = OpenSRF::Utils::JSON->perl2JSON($value); if($self->{persist}){ _load_methods(); } @@ -148,7 +148,7 @@ sub get_cache { my($self, $key ) = @_; my $val = $self->{memcache}->get( $key ); - return JSON->JSON2perl($val) if defined($val); + return OpenSRF::Utils::JSON->JSON2perl($val) if defined($val); if($self->{persist}){ _load_methods(); } @@ -162,7 +162,7 @@ sub get_cache { } else { $self->{memcache}->set( $key, $val, $max_persist_time); } - return JSON->JSON2perl($val); + return OpenSRF::Utils::JSON->JSON2perl($val); } } return undef; diff --git a/src/perlmods/OpenSRF/Utils/JSON.pm b/src/perlmods/OpenSRF/Utils/JSON.pm new file mode 100644 index 0000000..b417425 --- /dev/null +++ b/src/perlmods/OpenSRF/Utils/JSON.pm @@ -0,0 +1,827 @@ + +package OpenSRF::Utils::JSON::number; +sub new { + my $class = shift; + my $x = shift || $class; + return bless \$x => __PACKAGE__; +} + +use overload ( '""' => \&toString ); + +sub toString { defined($_[1]) ? ${$_[1]} : ${$_[0]} } + +package OpenSRF::Utils::JSON::bool::true; +sub new { return bless {} => __PACKAGE__ } +use overload ( '""' => \&toString ); +use overload ( 'bool' => sub { 1 } ); +use overload ( '0+' => sub { 1 } ); + +sub toString { 'true' } + +package OpenSRF::Utils::JSON::bool::false; +sub new { return bless {} => __PACKAGE__ } +use overload ( '""' => \&toString ); +use overload ( 'bool' => sub { 0 } ); +use overload ( '0+' => sub { 0 } ); + +sub toString { 'false' } + +package OpenSRF::Utils::JSON; +use Unicode::Normalize; +use vars qw/%_class_map/; + +sub register_class_hint { + my $class = shift; + my %args = @_; + + $_class_map{hints}{$args{hint}} = \%args; + $_class_map{classes}{$args{name}} = \%args; +} + +sub _JSON_regex { + my $string = shift; + + $string =~ s/^\s* ( + { | # start object + \[ | # start array + -?\d+\.?\d* | # number literal + "(?:(?:\\[\"])|[^\"])*" | # string literal + (?:\/\*.+?\*\/) | # C comment + true | # bool true + false | # bool false + null | # undef() + : | # object key-value sep + , | # list sep + \] | # array end + } # object end + ) + \s*//sox; + return ($string,$1); +} + +sub lookup_class { + my $self = shift; + my $hint = shift; + return $_class_map{hints}{$hint}{name} +} + +sub lookup_hint { + my $self = shift; + my $class = shift; + return $_class_map{classes}{$class}{hint} +} + +sub _json_hint_to_class { + my $type = shift; + my $hint = shift; + + return $_class_map{hints}{$hint}{name} if (exists $_class_map{hints}{$hint}); + + $type = 'hash' if ($type eq '}'); + $type = 'array' if ($type eq ']'); + + OpenSRF::Utils::JSON->register_class_hint(name => $hint, hint => $hint, type => $type); + + return $hint; +} + +sub JSON2perl { + my $class = shift; + local $_ = shift; + + s/(? _json_hint_to_class("$1", "$2")) /sog; + + my $re = qr/((?(?<=\\)"|[^"])*(? /sog; + + # Do numbers... + #s/\b(-?\d+\.?\d*)\b/ OpenSRF::Utils::JSON::number::new($1) /sog; + + # Change javascript stuff to perl... + s/null/ undef /sog; + s/true/ bless( {}, "OpenSRF::Utils::JSON::bool::true") /sog; + s/false/ bless( {}, "OpenSRF::Utils::JSON::bool::false") /sog; + + my $ret; + return eval '$ret = '.$_; +} + +my $_json_index; +sub ___JSON2perl { + my $class = shift; + my $data = shift; + + $data = [ split //, $data ]; + + $_json_index = 0; + + return _json_parse_data($data); +} + +sub _eat_WS { + my $data = shift; + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } +} + +sub _json_parse_data { + my $data = shift; + + my $out; + + #warn "parse_data"; + + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + + my $class = ''; + + my $c = $$data[$_json_index]; + + if ($c eq '/') { + $_json_index++; + $class = _json_parse_comment($data); + + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + $c = $$data[$_json_index]; + } + + if ($c eq '"') { + $_json_index++; + my $val = ''; + + my $seen_slash = 0; + my $done = 0; + while (!$done) { + my $c = $$data[$_json_index]; + #warn "c is $c"; + + if ($c eq '\\') { + if ($seen_slash) { + $val .= '\\'; + $seen_slash = 0; + } else { + $seen_slash = 1; + } + } elsif ($c eq '"') { + if ($seen_slash) { + $val .= '"'; + $seen_slash = 0; + } else { + $done = 1; + } + } elsif ($c eq 't') { + if ($seen_slash) { + $val .= "\t"; + $seen_slash = 0; + } else { + $val .= 't'; + } + } elsif ($c eq 'b') { + if ($seen_slash) { + $val .= "\b"; + $seen_slash = 0; + } else { + $val .= 'b'; + } + } elsif ($c eq 'f') { + if ($seen_slash) { + $val .= "\f"; + $seen_slash = 0; + } else { + $val .= 'f'; + } + } elsif ($c eq 'r') { + if ($seen_slash) { + $val .= "\r"; + $seen_slash = 0; + } else { + $val .= 'r'; + } + } elsif ($c eq 'n') { + if ($seen_slash) { + $val .= "\n"; + $seen_slash = 0; + } else { + $val .= 'n'; + } + } elsif ($c eq 'u') { + if ($seen_slash) { + $_json_index++; + $val .= chr(hex(join('',$$data[$_json_index .. $_json_index + 3]))); + $_json_index += 3; + $seen_slash = 0; + } else { + $val .= 'u'; + } + } else { + $val .= $c; + } + $_json_index++; + + #warn "string is $val"; + } + + $out = $val; + + #$out = _json_parse_string($data); + } elsif ($c eq '[') { + $_json_index++; + $out = []; + + my $in_parse = 0; + my $done = 0; + while(!$done) { + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + + if ($$data[$_json_index] eq ']') { + $done = 1; + $_json_index++; + last; + } + + if ($in_parse) { + if ($$data[$_json_index] ne ',') { + #warn "_json_parse_array: bad data, leaving array parser"; + last; + } + $_json_index++; + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + } + + my $item = _json_parse_data($data); + + push @$out, $item; + $in_parse++; + } + + #$out = _json_parse_array($data); + } elsif ($c eq '{') { + $_json_index++; + $out = {}; + + my $in_parse = 0; + my $done = 0; + while(!$done) { + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + + if ($$data[$_json_index] eq '}') { + $done = 1; + $_json_index++; + last; + } + + if ($in_parse) { + if ($$data[$_json_index] ne ',') { + #warn "_json_parse_object: bad data, leaving object parser"; + last; + } + $_json_index++; + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + } + + my ($key,$value); + $key = _json_parse_data($data); + + #warn "object key is $key"; + + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + + if ($$data[$_json_index] ne ':') { + #warn "_json_parse_object: bad data, leaving object parser"; + last; + } + $_json_index++; + $value = _json_parse_data($data); + + $out->{$key} = $value; + $in_parse++; + } + #$out = _json_parse_object($data); + } elsif (lc($c) eq 'n') { + if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'null') { + $_json_index += 4; + } else { + warn "CRAP! bad null parsing..."; + } + $out = undef; + #$out = _json_parse_null($data); + } elsif (lc($c) eq 't' or lc($c) eq 'f') { + if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'true') { + $out = 1; + $_json_index += 4; + } elsif (lc(join('',$$data[$_json_index .. $_json_index + 4])) eq 'false') { + $out = 0; + $_json_index += 5; + } else { + #warn "CRAP! bad bool parsing..."; + $out = undef; + } + #$out = _json_parse_bool($data); + } elsif ($c =~ /\d+/o or $c eq '.' or $c eq '-') { + my $val; + while ($$data[$_json_index] =~ /[-\.0-9]+/io) { + $val .= $$data[$_json_index]; + $_json_index++; + } + $out = 0+$val; + #$out = _json_parse_number($data); + } + + if ($class) { + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + my $c = $$data[$_json_index]; + + if ($c eq '/') { + $_json_index++; + _json_parse_comment($data) + } + + bless( $out => lookup_class($class) ); + } + + $out; +} + +sub _json_parse_null { + my $data = shift; + + #warn "parse_null"; + + if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'null') { + $_json_index += 4; + } else { + #warn "CRAP! bad null parsing..."; + } + return undef; +} + +sub _json_parse_bool { + my $data = shift; + + my $out; + + #warn "parse_bool"; + + if (lc(join('',$$data[$_json_index .. $_json_index + 3])) eq 'true') { + $out = 1; + $_json_index += 4; + } elsif (lc(join('',$$data[$_json_index .. $_json_index + 4])) eq 'false') { + $out = 0; + $_json_index += 5; + } else { + #warn "CRAP! bad bool parsing..."; + $out = undef; + } + return $out; +} + +sub _json_parse_number { + my $data = shift; + + #warn "parse_number"; + + my $val; + while ($$data[$_json_index] =~ /[-\.0-9]+/io) { + $val .= $$data[$_json_index]; + $_json_index++; + } + + return 0+$val; +} + +sub _json_parse_object { + my $data = shift; + + #warn "parse_object"; + + my $out = {}; + + my $in_parse = 0; + my $done = 0; + while(!$done) { + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + + if ($$data[$_json_index] eq '}') { + $done = 1; + $_json_index++; + last; + } + + if ($in_parse) { + if ($$data[$_json_index] ne ',') { + #warn "_json_parse_object: bad data, leaving object parser"; + last; + } + $_json_index++; + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + } + + my ($key,$value); + $key = _json_parse_data($data); + + #warn "object key is $key"; + + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + + if ($$data[$_json_index] ne ':') { + #warn "_json_parse_object: bad data, leaving object parser"; + last; + } + $_json_index++; + $value = _json_parse_data($data); + + $out->{$key} = $value; + $in_parse++; + } + + return $out; +} + +sub _json_parse_array { + my $data = shift; + + #warn "parse_array"; + + my $out = []; + + my $in_parse = 0; + my $done = 0; + while(!$done) { + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + + if ($$data[$_json_index] eq ']') { + $done = 1; + $_json_index++; + last; + } + + if ($in_parse) { + if ($$data[$_json_index] ne ',') { + #warn "_json_parse_array: bad data, leaving array parser"; + last; + } + $_json_index++; + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + } + + my $item = _json_parse_data($data); + + push @$out, $item; + $in_parse++; + } + + return $out; +} + + +sub _json_parse_string { + my $data = shift; + + #warn "parse_string"; + + my $val = ''; + + my $seen_slash = 0; + my $done = 0; + while (!$done) { + my $c = $$data[$_json_index]; + #warn "c is $c"; + + if ($c eq '\\') { + if ($seen_slash) { + $val .= '\\'; + $seen_slash = 0; + } else { + $seen_slash = 1; + } + } elsif ($c eq '"') { + if ($seen_slash) { + $val .= '"'; + $seen_slash = 0; + } else { + $done = 1; + } + } elsif ($c eq 't') { + if ($seen_slash) { + $val .= "\t"; + $seen_slash = 0; + } else { + $val .= 't'; + } + } elsif ($c eq 'b') { + if ($seen_slash) { + $val .= "\b"; + $seen_slash = 0; + } else { + $val .= 'b'; + } + } elsif ($c eq 'f') { + if ($seen_slash) { + $val .= "\f"; + $seen_slash = 0; + } else { + $val .= 'f'; + } + } elsif ($c eq 'r') { + if ($seen_slash) { + $val .= "\r"; + $seen_slash = 0; + } else { + $val .= 'r'; + } + } elsif ($c eq 'n') { + if ($seen_slash) { + $val .= "\n"; + $seen_slash = 0; + } else { + $val .= 'n'; + } + } elsif ($c eq 'u') { + if ($seen_slash) { + $_json_index++; + $val .= chr(hex(join('',$$data[$_json_index .. $_json_index + 3]))); + $_json_index += 3; + $seen_slash = 0; + } else { + $val .= 'u'; + } + } else { + $val .= $c; + } + $_json_index++; + + #warn "string is $val"; + } + + return $val; +} + +sub _json_parse_comment { + my $data = shift; + + #warn "parse_comment"; + + if ($$data[$_json_index] eq '/') { + $_json_index++; + while (!($$data[$_json_index] eq "\n")) { $_json_index++ } + $_json_index++; + return undef; + } + + my $class = ''; + + if (join('',$$data[$_json_index .. $_json_index + 2]) eq '*--') { + $_json_index += 3; + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + if ($$data[$_json_index] eq 'S') { + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + while ($$data[$_json_index] !~ /[-\s]+/o) { + $class .= $$data[$_json_index]; + $_json_index++; + } + while ($$data[$_json_index] =~ /\s+/o) { $_json_index++ } + } + } + + while ($$data[$_json_index] ne '/') { $_json_index++ }; + $_json_index++; + + return $class; +} + +sub old_JSON2perl { + my ($class, $json) = @_; + + if (!defined($json)) { + return undef; + } + + $json =~ s/(? '; + next; + } elsif ($element eq 'true') { + $output .= 'bless( {}, "OpenSRF::Utils::JSON::bool::true")'; + next; + } elsif ($element eq 'false') { + $output .= 'bless( {}, "OpenSRF::Utils::JSON::bool::false")'; + next; + } + + $output .= $element; + } + + return eval $output; +} + +sub perl2JSON { + my ($class, $perl, $strict) = @_; + + my $output = ''; + if (!defined($perl)) { + $output = '' if $strict; + $output = 'null' unless $strict; + } elsif (ref($perl) and ref($perl) =~ /^OpenSRF::Utils::JSON/) { + $output .= $perl; + } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) { + $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}.'--*/'; + if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') { + my %hash = %$perl; + $output .= perl2JSON(undef,\%hash, $strict); + } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') { + my @array = @$perl; + $output .= perl2JSON(undef,\@array, $strict); + } + $output .= '/*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/'; + } elsif (ref($perl) and ref($perl) =~ /HASH/) { + $output .= '{'; + my $c = 0; + for my $key (sort keys %$perl) { + my $outkey = NFC($key); + $output .= ',' if ($c); + + $outkey =~ s{\\}{\\\\}sgo; + $outkey =~ s/"/\\"/sgo; + $outkey =~ s/\t/\\t/sgo; + $outkey =~ s/\f/\\f/sgo; + $outkey =~ s/\r/\\r/sgo; + $outkey =~ s/\n/\\n/sgo; + $outkey =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe; + + $output .= '"'.$outkey.'":'. perl2JSON(undef,$$perl{$key}, $strict); + $c++; + } + $output .= '}'; + } elsif (ref($perl) and ref($perl) =~ /ARRAY/) { + $output .= '['; + my $c = 0; + for my $part (@$perl) { + $output .= ',' if ($c); + + $output .= perl2JSON(undef,$part, $strict); + $c++; + } + $output .= ']'; + } elsif (ref($perl) and ref($perl) =~ /CODE/) { + $output .= perl2JSON(undef,$perl->(), $strict); + } elsif (ref($perl) and ("$perl" =~ /^([^=]+)=(\w+)/o)) { + my $type = $2; + my $name = $1; + OpenSRF::Utils::JSON->register_class_hint(name => $name, hint => $name, type => lc($type)); + $output .= perl2JSON(undef,$perl, $strict); + } else { + $perl = NFC($perl); + $perl =~ s{\\}{\\\\}sgo; + $perl =~ s/"/\\"/sgo; + $perl =~ s/\t/\\t/sgo; + $perl =~ s/\f/\\f/sgo; + $perl =~ s/\r/\\r/sgo; + $perl =~ s/\n/\\n/sgo; + $perl =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe; + if (length($perl) < 10 and $perl =~ /^(?:\+|-)?\d*\.?\d+$/o and $perl !~ /^(?:\+|-)?0\d+/o ) { + $output = $perl; + } else { + $output = '"'.$perl.'"'; + } + } + + return $output; +} + +my $depth = 0; +sub perl2prettyJSON { + my ($class, $perl, $nospace) = @_; + $perl ||= $class; + + my $output = ''; + if (!defined($perl)) { + $output = " "x$depth unless($nospace); + $output .= 'null'; + } elsif (ref($perl) and ref($perl) =~ /^OpenSRF::Utils::JSON/) { + $output = " "x$depth unless($nospace); + $output .= $perl; + } elsif ( ref($perl) && exists($_class_map{classes}{ref($perl)}) ) { + $depth++; + $output .= "\n"; + $output .= " "x$depth; + $output .= '/*--S '.$_class_map{classes}{ref($perl)}{hint}."--*/ "; + if (lc($_class_map{classes}{ref($perl)}{type}) eq 'hash') { + my %hash = %$perl; + $output .= perl2prettyJSON(\%hash,undef,1); + } elsif (lc($_class_map{classes}{ref($perl)}{type}) eq 'array') { + my @array = @$perl; + $output .= perl2prettyJSON(\@array,undef,1); + } + $output .= ' /*--E '.$_class_map{classes}{ref($perl)}{hint}.'--*/'; + $depth--; + } elsif (ref($perl) and ref($perl) =~ /HASH/) { + $output .= " "x$depth unless ($nospace); + $output .= "{\n"; + my $c = 0; + $depth++; + for my $key (sort keys %$perl) { + $output .= ",\n" if ($c); + $output .= " "x$depth; + $output .= perl2prettyJSON($key)." : ".perl2prettyJSON($$perl{$key}, undef, 1); + $c++; + } + $depth--; + $output .= "\n"; + $output .= " "x$depth; + $output .= '}'; + } elsif (ref($perl) and ref($perl) =~ /ARRAY/) { + $output .= " "x$depth unless ($nospace); + $output .= "[\n"; + my $c = 0; + $depth++; + for my $part (@$perl) { + $output .= ",\n" if ($c); + $output .= " "x$depth; + $output .= perl2prettyJSON($part); + $c++; + } + $depth--; + $output .= "\n"; + $output .= " "x$depth; + $output .= "]"; + } elsif (ref($perl) and ref($perl) =~ /CODE/) { + $output .= perl2prettyJSON(undef,$perl->(), $nospace); + } elsif (ref($perl) and "$perl" =~ /^([^=]+)=(\w{4,5})\(0x/) { + my $type = $2; + my $name = $1; + register_class_hint(undef, name => $name, hint => $name, type => lc($type)); + $output .= perl2prettyJSON(undef,$perl); + } else { + $perl = NFC($perl); + $perl =~ s/\\/\\\\/sgo; + $perl =~ s/"/\\"/sgo; + $perl =~ s/\t/\\t/sgo; + $perl =~ s/\f/\\f/sgo; + $perl =~ s/\r/\\r/sgo; + $perl =~ s/\n/\\n/sgo; + $perl =~ s/([\x{0080}-\x{fffd}])/sprintf('\u%0.4x',ord($1))/sgoe; + $output .= " "x$depth unless($nospace); + if (length($perl) < 10 and $perl =~ /^(?:\+|-)?\d*\.?\d+$/o and $perl !~ /^(?:\+|-)?0\d+/o ) { + $output = $perl; + } else { + $output = '"'.$perl.'"'; + } + } + + return $output; +} + +1; diff --git a/src/perlmods/OpenSRF/Utils/Logger.pm b/src/perlmods/OpenSRF/Utils/Logger.pm index 138aa01..8734115 100644 --- a/src/perlmods/OpenSRF/Utils/Logger.pm +++ b/src/perlmods/OpenSRF/Utils/Logger.pm @@ -66,18 +66,12 @@ sub set_config { } $loglevel = $config->bootstrap->loglevel; - if($loglevel = 1){ $loglevel = ERROR(); } - elsif($loglevel = 2){ $loglevel = WARN(); } - elsif($loglevel = 3){ $loglevel = INFO(); } - elsif($loglevel = 4){ $loglevel = DEBUG(); } - elsif($loglevel = 5){ $loglevel = INTERNAL(); } - else{$loglevel= INFO(); } $logfile = $config->bootstrap->logfile; if($logfile =~ /^syslog/) { $syslog_enabled = 1; $logfile_enabled = 0; - $logfile =~ s/^syslog:?//; + $logfile = $config->bootstrap->syslog; $facility = $logfile; $logfile = undef; $facility = _fac_to_const($facility); @@ -85,16 +79,28 @@ sub set_config { } else { $logfile = "$logfile"; } - $actfile = $config->bootstrap->actlog; - if($actfile =~ /^syslog/) { - $act_syslog_enabled = 1; - $act_logfile_enabled = 0; - $actfile =~ s/^syslog:?//; - $actfac = $actfile || "local1"; - $actfile = undef; - $actfac = _fac_to_const($actfac); - } else { $actfile = "$actfile"; } + if($syslog_enabled) { + # -------------------------------------------------------------- + # if we're syslogging, see if we have a special syslog facility + # for activity logging. If not, use the syslog facility for + # standard logging + # -------------------------------------------------------------- + $act_syslog_enabled = 1; + $act_logfile_enabled = 0; + $actfac = $config->bootstrap->actlog || $config->bootstrap->syslog; + $actfac = _fac_to_const($actfac); + $actfile = undef; + } else { + # -------------------------------------------------------------- + # we're not syslogging, use any specified activity log file. + # Fall back to the standard log file otherwise + # -------------------------------------------------------------- + $act_syslog_enabled = 0; + $act_logfile_enabled = 1; + $actfile = $config->bootstrap->actlog || $config->bootstrap->logfile; + } + $isclient = (OpenSRF::Utils::Config->current->bootstrap->client =~ /^true$/iog) ? 1 : 0; } diff --git a/src/python/osrf/conf.py b/src/python/osrf/conf.py index 34e8df3..74f8bd9 100644 --- a/src/python/osrf/conf.py +++ b/src/python/osrf/conf.py @@ -16,33 +16,56 @@ from osrf.utils import * from osrf.ex import * +import re class osrfConfig(object): - """Loads and parses the bootstrap config file""" + """Loads and parses the bootstrap config file""" - config = None + config = None - def __init__(self, file=None): - self.file = file - self.data = {} + def __init__(self, file, context=None): + self.file = file + self.context = context + self.data = {} - def parseConfig(self,file=None): - self.data = osrfXMLFileToObject(file or self.file) - osrfConfig.config = self - - def getValue(self, key, idx=None): - val = osrfObjectFindPath(self.data, key, idx) - if not val: - raise osrfConfigException("Config value not found: " + key) - return val + #def parseConfig(self,file=None): + def parseConfig(self): + self.data = osrfXMLFileToObject(self.file) + osrfConfig.config = self + + def getValue(self, key, idx=None): + if self.context: + if re.search('/', key): + key = "%s/%s" % (self.context, key) + else: + key = "%s.%s" % (self.context, key) + + val = osrfObjectFindPath(self.data, key, idx) + if not val: + raise osrfConfigException("Config value not found: " + key) + return val def osrfConfigValue(key, idx=None): - """Returns a bootstrap config value. - - key -- A string representing the path to the value in the config object - e.g. "domains.domain", "username" - idx -- Optional array index if the searched value is an array member - """ - return osrfConfig.config.getValue(key, idx) - + """Returns a bootstrap config value. + + key -- A string representing the path to the value in the config object + e.g. "domains.domain", "username" + idx -- Optional array index if the searched value is an array member + """ + return osrfConfig.config.getValue(key, idx) + + +def osrfConfigValueNoEx(key, idx=None): + """ Returns a bootstrap config value without throwing an exception + if the item is not found. + + key -- A string representing the path to the value in the config object + e.g. "domains.domain", "username" + idx -- Optional array index if the searched value is an array member + """ + try: + return osrfConfig.config.getValue(key, idx) + except: + return None + diff --git a/src/python/osrf/gateway.py b/src/python/osrf/gateway.py index c9f9392..98c8686 100644 --- a/src/python/osrf/gateway.py +++ b/src/python/osrf/gateway.py @@ -21,7 +21,7 @@ class GatewayRequest: response =urllib2.urlopen(request) except urllib2.HTTPError, e: # log this? - sys.stderr.write('HTTPError: code=%d : %s' % (e.code, str(e))) + sys.stderr.write('%s => %s?%s\n' % (str(e), self.buildURL(), params)) raise e return self.handleResponse(response) @@ -77,6 +77,9 @@ class XMLGatewayParser(handler.ContentHandler): self.keyStack = [] self.posStack = [] # for tracking array-based hinted object indices + # true if we are parsing an element that may have character data + self.charsPending = 0 + def getResult(self): return self.result @@ -87,13 +90,20 @@ class XMLGatewayParser(handler.ContentHandler): return None def startElement(self, name, attrs): - - # XXX add support for serializable objects! + + if self.charsPending: + # we just read a 'string' or 'number' element that resulted + # in no text data. Appaned a None object + self.appendChild(None) if name == 'null': self.appendChild(None) return + if name == 'string' or name == 'number': + self.charsPending = True + return + if name == 'element': # this is an object item wrapper self.keyStack.append(self.__getAttr(attrs, 'key')) return @@ -157,6 +167,7 @@ class XMLGatewayParser(handler.ContentHandler): self.objStack.pop() def characters(self, chars): + self.charsPending = False self.appendChild(urllib.unquote_plus(chars)) diff --git a/src/python/osrf/json.py b/src/python/osrf/json.py index b6b3154..8845b92 100644 --- a/src/python/osrf/json.py +++ b/src/python/osrf/json.py @@ -6,7 +6,7 @@ class osrfJSONNetworkEncoder(simplejson.JSONEncoder): def default(self, obj): if isinstance(obj, osrfNetworkObject): return { - OSRF_JSON_CLASS_KEY: obj.getHint(), + OSRF_JSON_CLASS_KEY: obj.getRegistry().hint, OSRF_JSON_PAYLOAD_KEY: self.default(obj.getData()) } return obj diff --git a/src/python/osrf/log.py b/src/python/osrf/log.py index f0ef2ad..187a34d 100644 --- a/src/python/osrf/log.py +++ b/src/python/osrf/log.py @@ -22,9 +22,14 @@ def osrfInitLog(level, facility=None, file=None): """Initialize the logging subsystem.""" import syslog global loglevel - if facility: osrfInitSyslog(facility, level) + if facility: + osrfInitSyslog(facility, level) + syslog.syslog(syslog.LOG_DEBUG, "syslog initialized") + else: + if file: + sys.stderr.write("\n * file-based logging not implemented yet\n") + loglevel = level - syslog.syslog(LOG_DEBUG, "syslog initialized") # ----------------------------------------------------------------------- @@ -72,6 +77,8 @@ def __osrfLog(level, msg): def osrfInitSyslog(facility, level): """Connect to syslog and set the logmask based on the level provided.""" + import syslog + level = int(level) if facility == 'local0': facility = syslog.LOG_LOCAL0 @@ -82,13 +89,13 @@ def osrfInitSyslog(facility, level): if facility == 'local5': facility = syslog.LOG_LOCAL5 if facility == 'local6': facility = syslog.LOG_LOCAL6 # XXX add other facility maps if necessary - openlog(sys.argv[0], 0, facility) + syslog.openlog(sys.argv[0], 0, facility) # this is redundant... - mask = LOG_UPTO(syslog.LOG_ERR) - if level >= 1: mask |= LOG_MASK(syslog.LOG_WARNING) - if level >= 2: mask |= LOG_MASK(syslog.LOG_NOTICE) - if level >= 3: mask |= LOG_MASK(syslog.LOG_INFO) - if level >= 4: mask |= LOG_MASK(syslog.LOG_DEBUG) + mask = syslog.LOG_UPTO(syslog.LOG_ERR) + if level >= 1: mask |= syslog.LOG_MASK(syslog.LOG_WARNING) + if level >= 2: mask |= syslog.LOG_MASK(syslog.LOG_NOTICE) + if level >= 3: mask |= syslog.LOG_MASK(syslog.LOG_INFO) + if level >= 4: mask |= syslog.LOG_MASK(syslog.LOG_DEBUG) syslog.setlogmask(mask) diff --git a/src/python/osrf/net_obj.py b/src/python/osrf/net_obj.py index 792c613..8ae3b9b 100644 --- a/src/python/osrf/net_obj.py +++ b/src/python/osrf/net_obj.py @@ -13,7 +13,6 @@ def osrfNewObjectFromHint(hint): return obj except AttributeError: return osrfNetworkObject.__unknown() -#newFromHint = staticmethod(newFromHint) ''' Global object registry ''' @@ -76,9 +75,8 @@ def __osrfNetworkObjectInit(self, data={}): If this is an array, we pull data out of the data array (if there is any) and translate that into a hash internally ''' - self.__data = data - if len(data) > 0: + if isinstance(data, list) and len(data) > 0: reg = self.getRegistry() if reg.wireProtocol == 'array': self.__data = {} @@ -134,31 +132,47 @@ osrfNetworkRegisterHint('__unknown', [], 'hash') # Define the custom object parsing behavior # ------------------------------------------------------------------- def parseNetObject(obj): - hint = None - islist = False + try: + hint = obj[OSRF_JSON_CLASS_KEY] - obj = obj[OSRF_JSON_PAYLOAD_KEY] - except: pass - if isinstance(obj,list): - islist = True - for i in range(len(obj)): - obj[i] = parseNetObject(obj[i]) - else: - if isinstance(obj,dict): - for k,v in obj.iteritems(): - obj[k] = parseNetObject(v) + subObj = obj[OSRF_JSON_PAYLOAD_KEY] + reg = osrfNetworkRegistry.getRegistry(hint) + + obj = {} + + if reg.wireProtocol == 'array': + for i in range(len(reg.keys)): + if len(subObj) > i: + obj[reg.keys[i]] = parseNetObject(subObj[i]) + else: + obj[reg.keys[i]] = None + else: + for k in reg.keys: + obj[k] = parseNetObject(subObj.get(k)) - if hint: # Now, "bless" the object into an osrfNetworkObject estr = 'obj = osrfNetworkObject.%s(obj)' % hint try: exec(estr) - except AttributeError: + except e: # this object has not been registered, shove it into the default container obj = osrfNetworkObject.__unknown(obj) - return obj; + return obj + + except: pass + + # the current object does not have a class hint + if isinstance(obj, list): + for i in range(len(obj)): + obj[i] = parseNetObject(obj[i]) + + else: + if isinstance(obj, dict): + for k,v in obj.iteritems(): + obj[k] = parseNetObject(v) + return obj; def osrfObjectToXML(obj): diff --git a/src/python/osrf/ses.py b/src/python/osrf/ses.py index f1c6c38..462ae08 100644 --- a/src/python/osrf/ses.py +++ b/src/python/osrf/ses.py @@ -33,276 +33,276 @@ osrfNetworkRegisterHint('osrfMethodException', ['status', 'statusCode'], 'hash') class osrfSession(object): - """Abstract session superclass.""" + """Abstract session superclass.""" - def __init__(self): - # by default, we're connected to no one - self.state = OSRF_APP_SESSION_DISCONNECTED + def __init__(self): + # by default, we're connected to no one + self.state = OSRF_APP_SESSION_DISCONNECTED - def wait(self, timeout=120): - """Wait up to seconds for data to arrive on the network""" - osrfLogInternal("osrfSession.wait(%d)" % timeout) - handle = osrfGetNetworkHandle() - handle.recv(timeout) + def wait(self, timeout=120): + """Wait up to seconds for data to arrive on the network""" + osrfLogInternal("osrfSession.wait(%d)" % timeout) + handle = osrfGetNetworkHandle() + handle.recv(timeout) - def send(self, omessage): - """Sends an OpenSRF message""" - netMessage = osrfNetworkMessage( - to = self.remoteId, - body = osrfObjectToJSON([omessage]), - thread = self.thread ) + def send(self, omessage): + """Sends an OpenSRF message""" + netMessage = osrfNetworkMessage( + to = self.remoteId, + body = osrfObjectToJSON([omessage]), + thread = self.thread ) - handle = osrfGetNetworkHandle() - handle.send(netMessage) + handle = osrfGetNetworkHandle() + handle.send(netMessage) - def cleanup(self): - """Removes the session from the global session cache.""" - del osrfClientSession.sessionCache[self.thread] + def cleanup(self): + """Removes the session from the global session cache.""" + del osrfClientSession.sessionCache[self.thread] class osrfClientSession(osrfSession): - """Client session object. Use this to make server requests.""" - - def __init__(self, service): - - # call superclass constructor - osrfSession.__init__(self) - - # the remote service we want to make requests of - self.service = service - - # find the remote service handle @/ - domain = osrfConfigValue('domains.domain', 0) - router = osrfConfigValue('router_name') - self.remoteId = "%s@%s/%s" % (router, domain, service) - self.origRemoteId = self.remoteId - - # generate a random message thread - self.thread = "%s%s%s" % (os.getpid(), str(random.randint(100,100000)), str(time.time())) - - # how many requests this session has taken part in - self.nextId = 0 - - # cache of request objects - self.requests = {} - - # cache this session in the global session cache - osrfClientSession.sessionCache[self.thread] = self - - def resetRequestTimeout(self, rid): - req = self.findRequest(rid) - if req: - req.resetTimeout = True - - - def request2(self, method, arr): - """Creates a new request and sends the request to the server using a python array as the params.""" - return self.__request(method, arr) - - def request(self, method, *args): - """Creates a new request and sends the request to the server using a variable argument list as params""" - arr = list(args) - return self.__request(method, arr) - - def __request(self, method, arr): - """Builds the request object and sends it.""" - if self.state != OSRF_APP_SESSION_CONNECTED: - self.resetRemoteId() - - osrfLogDebug("Sending request %s -> %s " % (self.service, method)) - req = osrfRequest(self, self.nextId, method, arr) - self.requests[str(self.nextId)] = req - self.nextId += 1 - req.send() - return req - - - def connect(self, timeout=10): - """Connects to a remote service""" - - if self.state == OSRF_APP_SESSION_CONNECTED: - return True - self.state == OSRF_APP_SESSION_CONNECTING - - # construct and send a CONNECT message - self.send( - osrfNetworkObject.osrfMessage( - { 'threadTrace' : 0, - 'type' : OSRF_MESSAGE_TYPE_CONNECT - } - ) - ) - - while timeout >= 0 and not self.state == OSRF_APP_SESSION_CONNECTED: - start = time.time() - self.wait(timeout) - timeout -= time.time() - start - - if self.state != OSRF_APP_SESSION_CONNECTED: - raise osrfServiceException("Unable to connect to " + self.service) - - return True - - def disconnect(self): - """Disconnects from a remote service""" - - if self.state == OSRF_APP_SESSION_DISCONNECTED: - return True - - self.send( - osrfNetworkObject.osrfMessage( - { 'threadTrace' : 0, - 'type' : OSRF_MESSAGE_TYPE_DISCONNECT - } - ) - ) - - self.state = OSRF_APP_SESSION_DISCONNECTED - - - - - def setRemoteId(self, remoteid): - self.remoteId = remoteid - osrfLogInternal("Setting request remote ID to %s" % self.remoteId) - - def resetRemoteId(self): - """Recovers the original remote id""" - self.remoteId = self.origRemoteId - osrfLogInternal("Resetting remote ID to %s" % self.remoteId) - - def pushResponseQueue(self, message): - """Pushes the message payload onto the response queue - for the request associated with the message's ID.""" - osrfLogDebug("pushing %s" % message.payload()) - try: - self.findRequest(message.threadTrace()).pushResponse(message.payload()) - except Exception, e: - osrfLogWarn("pushing respond to non-existent request %s : %s" % (message.threadTrace(), e)) - - def findRequest(self, rid): - """Returns the original request matching this message's threadTrace.""" - try: - return self.requests[str(rid)] - except KeyError: - osrfLogDebug('findRequest(): non-existent request %s' % str(rid)) - return None + """Client session object. Use this to make server requests.""" + + def __init__(self, service): + + # call superclass constructor + osrfSession.__init__(self) + + # the remote service we want to make requests of + self.service = service + + # find the remote service handle @/ + domain = osrfConfigValue('domains.domain', 0) + router = osrfConfigValue('router_name') + self.remoteId = "%s@%s/%s" % (router, domain, service) + self.origRemoteId = self.remoteId + + # generate a random message thread + self.thread = "%s%s%s" % (os.getpid(), str(random.randint(100,100000)), str(time.time())) + + # how many requests this session has taken part in + self.nextId = 0 + + # cache of request objects + self.requests = {} + + # cache this session in the global session cache + osrfClientSession.sessionCache[self.thread] = self + + def resetRequestTimeout(self, rid): + req = self.findRequest(rid) + if req: + req.resetTimeout = True + + + def request2(self, method, arr): + """Creates a new request and sends the request to the server using a python array as the params.""" + return self.__request(method, arr) + + def request(self, method, *args): + """Creates a new request and sends the request to the server using a variable argument list as params""" + arr = list(args) + return self.__request(method, arr) + + def __request(self, method, arr): + """Builds the request object and sends it.""" + if self.state != OSRF_APP_SESSION_CONNECTED: + self.resetRemoteId() + + osrfLogDebug("Sending request %s -> %s " % (self.service, method)) + req = osrfRequest(self, self.nextId, method, arr) + self.requests[str(self.nextId)] = req + self.nextId += 1 + req.send() + return req + + + def connect(self, timeout=10): + """Connects to a remote service""" + + if self.state == OSRF_APP_SESSION_CONNECTED: + return True + self.state == OSRF_APP_SESSION_CONNECTING + + # construct and send a CONNECT message + self.send( + osrfNetworkObject.osrfMessage( + { 'threadTrace' : 0, + 'type' : OSRF_MESSAGE_TYPE_CONNECT + } + ) + ) + + while timeout >= 0 and not self.state == OSRF_APP_SESSION_CONNECTED: + start = time.time() + self.wait(timeout) + timeout -= time.time() - start + + if self.state != OSRF_APP_SESSION_CONNECTED: + raise osrfServiceException("Unable to connect to " + self.service) + + return True + + def disconnect(self): + """Disconnects from a remote service""" + + if self.state == OSRF_APP_SESSION_DISCONNECTED: + return True + + self.send( + osrfNetworkObject.osrfMessage( + { 'threadTrace' : 0, + 'type' : OSRF_MESSAGE_TYPE_DISCONNECT + } + ) + ) + + self.state = OSRF_APP_SESSION_DISCONNECTED + + + + + def setRemoteId(self, remoteid): + self.remoteId = remoteid + osrfLogInternal("Setting request remote ID to %s" % self.remoteId) + + def resetRemoteId(self): + """Recovers the original remote id""" + self.remoteId = self.origRemoteId + osrfLogInternal("Resetting remote ID to %s" % self.remoteId) + + def pushResponseQueue(self, message): + """Pushes the message payload onto the response queue + for the request associated with the message's ID.""" + osrfLogDebug("pushing %s" % message.payload()) + try: + self.findRequest(message.threadTrace()).pushResponse(message.payload()) + except Exception, e: + osrfLogWarn("pushing respond to non-existent request %s : %s" % (message.threadTrace(), e)) + + def findRequest(self, rid): + """Returns the original request matching this message's threadTrace.""" + try: + return self.requests[str(rid)] + except KeyError: + osrfLogDebug('findRequest(): non-existent request %s' % str(rid)) + return None osrfSession.sessionCache = {} def osrfFindSession(thread): - """Finds a session in the global cache.""" - try: - return osrfClientSession.sessionCache[thread] - except: return None + """Finds a session in the global cache.""" + try: + return osrfClientSession.sessionCache[thread] + except: return None class osrfRequest(object): - """Represents a single OpenSRF request. - A request is made and any resulting respones are - collected for the client.""" - - def __init__(self, session, id, method=None, params=[]): - - self.session = session # my session handle - self.id = id # my unique request ID - self.method = method # method name - self.params = params # my method params - self.queue = [] # response queue - self.resetTimeout = False # resets the recv timeout? - self.complete = False # has the server told us this request is done? - self.sendTime = 0 # local time the request was put on the wire - self.completeTime = 0 # time the server told us the request was completed - self.firstResponseTime = 0 # time it took for our first reponse to be received - - def send(self): - """Sends a request message""" - - # construct the method object message with params and method name - method = osrfNetworkObject.osrfMethod( { - 'method' : self.method, - 'params' : self.params - } ) - - # construct the osrf message with our method message embedded - message = osrfNetworkObject.osrfMessage( { - 'threadTrace' : self.id, - 'type' : OSRF_MESSAGE_TYPE_REQUEST, - 'payload' : method - } ) - - self.sendTime = time.time() - self.session.send(message) - - def recv(self, timeout=120): - """Waits up to seconds for a response to this request. - - If a message is received in time, the response message is returned. - Returns None otherwise.""" - - self.session.wait(0) - - origTimeout = timeout - while not self.complete and timeout >= 0 and len(self.queue) == 0: - s = time.time() - self.session.wait(timeout) - timeout -= time.time() - s - if self.resetTimeout: - self.resetTimeout = False - timeout = origTimeout - - now = time.time() - - # ----------------------------------------------------------------- - # log some statistics - if len(self.queue) > 0: - if not self.firstResponseTime: - self.firstResponseTime = now - osrfLogDebug("time elapsed before first response: %f" \ - % (self.firstResponseTime - self.sendTime)) - - if self.complete: - if not self.completeTime: - self.completeTime = now - osrfLogDebug("time elapsed before complete: %f" \ - % (self.completeTime - self.sendTime)) - # ----------------------------------------------------------------- - - - if len(self.queue) > 0: - # we have a reponse, return it - return self.queue.pop(0) - - return None - - def pushResponse(self, content): - """Pushes a method response onto this requests response queue.""" - self.queue.append(content) - - def cleanup(self): - """Cleans up request data from the cache. - - Do this when you are done with a request to prevent "leaked" cache memory.""" - del self.session.requests[str(self.id)] - - def setComplete(self): - """Sets me as complete. This means the server has sent a 'request complete' message""" - self.complete = True + """Represents a single OpenSRF request. + A request is made and any resulting respones are + collected for the client.""" + + def __init__(self, session, id, method=None, params=[]): + + self.session = session # my session handle + self.id = id # my unique request ID + self.method = method # method name + self.params = params # my method params + self.queue = [] # response queue + self.resetTimeout = False # resets the recv timeout? + self.complete = False # has the server told us this request is done? + self.sendTime = 0 # local time the request was put on the wire + self.completeTime = 0 # time the server told us the request was completed + self.firstResponseTime = 0 # time it took for our first reponse to be received + + def send(self): + """Sends a request message""" + + # construct the method object message with params and method name + method = osrfNetworkObject.osrfMethod( { + 'method' : self.method, + 'params' : self.params + } ) + + # construct the osrf message with our method message embedded + message = osrfNetworkObject.osrfMessage( { + 'threadTrace' : self.id, + 'type' : OSRF_MESSAGE_TYPE_REQUEST, + 'payload' : method + } ) + + self.sendTime = time.time() + self.session.send(message) + + def recv(self, timeout=120): + """Waits up to seconds for a response to this request. + + If a message is received in time, the response message is returned. + Returns None otherwise.""" + + self.session.wait(0) + + origTimeout = timeout + while not self.complete and timeout >= 0 and len(self.queue) == 0: + s = time.time() + self.session.wait(timeout) + timeout -= time.time() - s + if self.resetTimeout: + self.resetTimeout = False + timeout = origTimeout + + now = time.time() + + # ----------------------------------------------------------------- + # log some statistics + if len(self.queue) > 0: + if not self.firstResponseTime: + self.firstResponseTime = now + osrfLogDebug("time elapsed before first response: %f" \ + % (self.firstResponseTime - self.sendTime)) + + if self.complete: + if not self.completeTime: + self.completeTime = now + osrfLogDebug("time elapsed before complete: %f" \ + % (self.completeTime - self.sendTime)) + # ----------------------------------------------------------------- + + + if len(self.queue) > 0: + # we have a reponse, return it + return self.queue.pop(0) + + return None + + def pushResponse(self, content): + """Pushes a method response onto this requests response queue.""" + self.queue.append(content) + + def cleanup(self): + """Cleans up request data from the cache. + + Do this when you are done with a request to prevent "leaked" cache memory.""" + del self.session.requests[str(self.id)] + + def setComplete(self): + """Sets me as complete. This means the server has sent a 'request complete' message""" + self.complete = True class osrfServerSession(osrfSession): - """Implements a server-side session""" - pass + """Implements a server-side session""" + pass def osrfAtomicRequest(service, method, *args): - ses = osrfClientSession(service) - req = ses.request2('open-ils.cstore.direct.actor.user.retrieve', list(args)) # grab user with ID 1 - resp = req.recv() - data = resp.content() - req.cleanup() - ses.cleanup() - return data + ses = osrfClientSession(service) + req = ses.request2(method, list(args)) + resp = req.recv() + data = resp.content() + req.cleanup() + ses.cleanup() + return data diff --git a/src/python/osrf/system.py b/src/python/osrf/system.py index 4a978a5..bfc5463 100644 --- a/src/python/osrf/system.py +++ b/src/python/osrf/system.py @@ -13,7 +13,7 @@ # GNU General Public License for more details. # ----------------------------------------------------------------------- -from osrf.conf import osrfConfig, osrfConfigValue +from osrf.conf import osrfConfig, osrfConfigValue, osrfConfigValueNoEx from osrf.net import osrfNetwork, osrfSetNetworkHandle from osrf.stack import osrfPushStack from osrf.log import * @@ -21,28 +21,31 @@ from osrf.set import osrfLoadSettings import sys -def osrfConnect(configFile): - """ Connects to the opensrf network """ - - # parse the config file - configParser = osrfConfig(configFile) - configParser.parseConfig() - - # set up logging - osrfInitLog(osrfConfigValue('loglevel'), osrfConfigValue('syslog')) - - # connect to the opensrf network - network = osrfNetwork( - host=osrfConfigValue('domains.domain'), - port=osrfConfigValue('port'), - username=osrfConfigValue('username'), - password=osrfConfigValue('passwd')) - network.setRecvCallback(osrfPushStack) - osrfSetNetworkHandle(network) - network.connect() - - # load the domain-wide settings file - osrfLoadSettings(osrfConfigValue('domains.domain')) +def osrfConnect(configFile, configContext): + """ Connects to the opensrf network """ + + # parse the config file + configParser = osrfConfig(configFile, configContext) + configParser.parseConfig() + + # set up logging + osrfInitLog( + osrfConfigValue('loglevel'), + osrfConfigValueNoEx('syslog'), + osrfConfigValueNoEx('logfile')) + + # connect to the opensrf network + network = osrfNetwork( + host=osrfConfigValue('domains.domain'), + port=osrfConfigValue('port'), + username=osrfConfigValue('username'), + password=osrfConfigValue('passwd')) + network.setRecvCallback(osrfPushStack) + osrfSetNetworkHandle(network) + network.connect() + + # load the domain-wide settings file + osrfLoadSettings(osrfConfigValue('domains.domain')) diff --git a/src/python/osrf/utils.py b/src/python/osrf/utils.py index fe637f1..6b20675 100644 --- a/src/python/osrf/utils.py +++ b/src/python/osrf/utils.py @@ -3,14 +3,14 @@ import xml.dom.minidom, re def osrfXMLFileToObject(filename): """Turns the contents of an XML file into a Python object""" doc = xml.dom.minidom.parse(filename) - obj = osrfXMLNodeToObject(doc.childNodes[0]) + obj = osrfXMLNodeToObject(doc.documentElement) doc.unlink() return obj def osrfXMLStringToObject(string): """Turns an XML string into a Python object""" doc = xml.dom.minidom.parseString(string) - obj = osrfXMLNodeToObject(doc.childNodes[0]) + obj = osrfXMLNodeToObject(doc.documentElement) doc.unlink() return obj @@ -72,7 +72,7 @@ def osrfObjectFindPath(obj, path, idx=None): parts = [] - if re.compile('/').search(path): + if re.search('/', path): parts = path.split('/') else: parts = path.split('.') diff --git a/src/python/srfsh.py b/src/python/srfsh.py index 4742246..70a278e 100755 --- a/src/python/srfsh.py +++ b/src/python/srfsh.py @@ -214,9 +214,8 @@ def setup_readline(): def do_connect(): file = os.path.join(get_var('HOME'), ".srfsh.xml") - print_green("Connecting to opensrf...") - osrfConnect(file) + osrfConnect(file, 'srfsh') print_red('OK\n') def load_plugins(): diff --git a/src/router/osrf_router_main.c b/src/router/osrf_router_main.c index f3122cb..a789d98 100644 --- a/src/router/osrf_router_main.c +++ b/src/router/osrf_router_main.c @@ -35,12 +35,9 @@ int main( int argc, char* argv[] ) { int __setupRouter( char* config, char* context ) { - osrfLogInfo(OSRF_LOG_MARK, "Launching router with config " - "%s and config context %s", config, context ); osrfConfig* cfg = osrfConfigInit( config, context ); osrfConfigSetDefaultConfig(cfg); - char* server = osrfConfigGetValue(NULL, "/transport/server"); char* port = osrfConfigGetValue(NULL, "/transport/port"); char* username = osrfConfigGetValue(NULL, "/transport/username"); @@ -55,11 +52,6 @@ int __setupRouter( char* config, char* context ) { int llevel = 1; if(level) llevel = atoi(level); - /* - if(!log_init( llevel, log_file )) - fprintf(stderr, "Unable to init logging, going to stderr...\n" ); - */ - if(!log_file) { fprintf(stderr, "Log file needed\n"); return -1; } if(!strcmp(log_file, "syslog")) { diff --git a/src/srfsh/Makefile b/src/srfsh/Makefile index 163818e..9b04bd5 100644 --- a/src/srfsh/Makefile +++ b/src/srfsh/Makefile @@ -6,7 +6,7 @@ LDFLAGS += -DEXEC_DEFAULT all: srfsh srfsh: srfsh.o -srfsh.o: srfsh.c srfsh.h +srfsh.o: srfsh.c install: cp srfsh $(BINDIR) diff --git a/src/srfsh/srfsh.c b/src/srfsh/srfsh.c index 9887038..6c4cb54 100644 --- a/src/srfsh/srfsh.c +++ b/src/srfsh/srfsh.c @@ -1,9 +1,77 @@ -#include "srfsh.h" +#include +#include +#include +#include +#include +#include +#include +#include -int recv_timeout = 120; -int is_from_script = 0; -FILE* shell_writer = NULL; -FILE* shell_reader = NULL; +#include +#include + +#include + +#include +#include +#include + +#define SRFSH_PORT 5222 +#define COMMAND_BUFSIZE 4096 + + +/* shell prompt */ +static const char* prompt = "srfsh# "; + +static char* history_file = NULL; + +//static int child_dead = 0; + +static char* login_session = NULL; + +/* true if we're pretty printing json results */ +static int pretty_print = 1; +/* true if we're bypassing 'less' */ +static int raw_print = 0; + +/* our jabber connection */ +static transport_client* client = NULL; + +/* the last result we received */ +static osrf_message* last_result = NULL; + +/* functions */ +static int parse_request( char* request ); + +/* handles router requests */ +static int handle_router( char* words[] ); + +/* utility method for print time data */ +/* static int handle_time( char* words[] ); */ + +/* handles app level requests */ +static int handle_request( char* words[], int relay ); +static int handle_set( char* words[]); +static int handle_print( char* words[]); +static int send_request( char* server, + char* method, growing_buffer* buffer, int relay ); +static int parse_error( char* words[] ); +static int router_query_servers( const char* server ); +static int print_help( void ); + +//static int srfsh_client_connect(); +//static char* tabs(int count); +//static void sig_child_handler( int s ); +//static void sig_int_handler( int s ); + +static int load_history( void ); +static int handle_math( char* words[] ); +static int do_math( int count, int style ); +static int handle_introspect(char* words[]); +static int handle_login( char* words[]); + +static int recv_timeout = 120; +static int is_from_script = 0; int main( int argc, char* argv[] ) { @@ -50,32 +118,66 @@ int main( int argc, char* argv[] ) { client = osrf_system_get_transport_client(); - /* open the shell handle */ - shell_writer = popen( "bash", "w"); - //shell_reader = popen( "bash", "r"); - /* main process loop */ + int newline_needed = 1; /* used as boolean */ char* request; while((request=readline(prompt))) { - if( !strcasecmp(request, "exit") || !strcasecmp(request,"quit")) - break; + // Find first non-whitespace character + + char * cmd = request; + while( isspace( (unsigned char) *cmd ) ) + ++cmd; - char* req_copy = strdup(request); + // ignore comments and empty lines + + if( '\0' == *cmd || '#' == *cmd ) + continue; + + // Remove trailing whitespace. We know at this point that + // there is at least one non-whitespace character somewhere, + // or we would have already skipped this line. Hence we + // needn't check to make sure that we don't back up past + // the beginning. + + { + // The curly braces limit the scope of the end variable + + char * end = cmd + strlen(cmd) - 1; + while( isspace( (unsigned char) *end ) ) + --end; + end[1] = '\0'; + } + + if( !strcasecmp(cmd, "exit") || !strcasecmp(cmd, "quit")) + { + newline_needed = 0; + break; + } + + char* req_copy = strdup(cmd); parse_request( req_copy ); - if( request && strlen(request) > 1 ) { + if( request && *cmd ) { add_history(request); } free(request); free(req_copy); - fflush(shell_writer); fflush(stderr); fflush(stdout); } + if( newline_needed ) { + + // We left the readline loop after seeing an EOF, not after + // seeing "quit" or "exit". So we issue a newline in order + // to avoid leaving a dangling prompt. + + putchar( '\n' ); + } + if(history_file != NULL ) write_history(history_file); @@ -85,9 +187,11 @@ int main( int argc, char* argv[] ) { return 0; } -void sig_child_handler( int s ) { +/* +static void sig_child_handler( int s ) { child_dead = 1; } +*/ /* void sig_int_handler( int s ) { @@ -97,7 +201,7 @@ void sig_int_handler( int s ) { } */ -int load_history() { +static int load_history( void ) { char* home = getenv("HOME"); int l = strlen(home) + 24; @@ -115,54 +219,62 @@ int load_history() { } -int parse_error( char* words[] ) { +static int parse_error( char* words[] ) { if( ! words ) return 0; - - int i = 0; - char* current; - char buffer[256]; - memset(buffer, 0, 256); - while( (current=words[i++]) ) { - strcat(buffer, current); - strcat(buffer, " "); + growing_buffer * gbuf = buffer_init( 64 ); + buffer_add( gbuf, *words ); + while( *++words ) { + buffer_add( gbuf, " " ); + buffer_add( gbuf, *words ); } - if( ! buffer || strlen(buffer) < 1 ) - printf("\n"); - - fprintf( stderr, "???: %s\n", buffer ); + fprintf( stderr, "???: %s\n", gbuf->buf ); + buffer_free( gbuf ); + return 0; } -int parse_request( char* request ) { +static int parse_request( char* request ) { if( request == NULL ) return 0; + char* original_request = strdup( request ); + char* words[COMMAND_BUFSIZE]; + int ret_val = 0; int i = 0; - char* words[COMMAND_BUFSIZE]; - memset(words,0,COMMAND_BUFSIZE); - char* req = request; + + char* req = request; char* cur_tok = strtok( req, " " ); if( cur_tok == NULL ) + { + free( original_request ); return 0; + } + /* Load an array with pointers to */ + /* the tokens as defined by strtok() */ + while(cur_tok != NULL) { - words[i++] = cur_tok; - cur_tok = strtok( NULL, " " ); + if( i < COMMAND_BUFSIZE - 1 ) { + words[i++] = cur_tok; + cur_tok = strtok( NULL, " " ); + } else { + fprintf( stderr, "Too many tokens in command\n" ); + free( original_request ); + return 1; + } } - - // not sure why (strtok?), but this is necessary - memset( words + i, 0, COMMAND_BUFSIZE - i ); - + words[i] = NULL; + /* pass off to the top level command */ if( !strcmp(words[0],"router") ) ret_val = handle_router( words ); @@ -196,47 +308,50 @@ int parse_request( char* request ) { else if (!strcmp(words[0],"login")) ret_val = handle_login(words); - else if (words[0][0] == '!') - ret_val = handle_exec( words, 1 ); - - if(!ret_val) { - #ifdef EXEC_DEFAULT - return handle_exec( words, 0 ); - #else - return parse_error( words ); - #endif + else if (words[0][0] == '!') { + system( original_request + 1 ); + ret_val = 1; } + + free( original_request ); + + if(!ret_val) + return parse_error( words ); + else + return 1; +} - return 1; -} +static int handle_introspect(char* words[]) { + if( ! words[1] ) + return 0; -int handle_introspect(char* words[]) { + fprintf(stderr, "--> %s\n", words[1]); - if(words[1] && words[2]) { - fprintf(stderr, "--> %s\n", words[1]); - char buf[256]; - memset(buf,0,256); - sprintf( buf, "request %s opensrf.system.method %s", words[1], words[2] ); + // Build a command in a suitably-sized + // buffer and then parse it + + size_t len; + if( words[2] ) { + static const char text[] = "request %s opensrf.system.method %s"; + len = sizeof( text ) + strlen( words[1] ) + strlen( words[2] ); + char buf[len]; + sprintf( buf, text, words[1], words[2] ); return parse_request( buf ); } else { - - if(words[1]) { - fprintf(stderr, "--> %s\n", words[1]); - char buf[256]; - memset(buf,0,256); - sprintf( buf, "request %s opensrf.system.method.all", words[1] ); - return parse_request( buf ); - } - } + static const char text[] = "request %s opensrf.system.method.all"; + len = sizeof( text ) + strlen( words[1] ); + char buf[len]; + sprintf( buf, text, words[1] ); + return parse_request( buf ); - return 0; + } } -int handle_login( char* words[]) { +static int handle_login( char* words[]) { if( words[1] && words[2]) { @@ -317,7 +432,7 @@ int handle_login( char* words[]) { return 0; } -int handle_set( char* words[]) { +static int handle_set( char* words[]) { char* variable; if( (variable=words[1]) ) { @@ -358,7 +473,7 @@ int handle_set( char* words[]) { } -int handle_print( char* words[]) { +static int handle_print( char* words[]) { char* variable; if( (variable=words[1]) ) { @@ -381,7 +496,7 @@ int handle_print( char* words[]) { return 0; } -int handle_router( char* words[] ) { +static int handle_router( char* words[] ) { if(!client) return 1; @@ -405,79 +520,8 @@ int handle_router( char* words[] ) { } -/* if new shell, spawn a new child and subshell to do the work, - otherwise pipe the request to the currently open (piped) shell */ -int handle_exec(char* words[], int new_shell) { - - if(!words[0]) return 0; - - if( words[0] && words[0][0] == '!') { - int len = strlen(words[0]); - char command[len]; - memset(command,0,len); - - int i; /* chop out the ! */ - for( i=1; i!= len; i++) { - command[i-1] = words[0][i]; - } - - free(words[0]); - words[0] = strdup(command); - } - - if(new_shell) { - signal(SIGCHLD, sig_child_handler); - if(fork()) { - - waitpid(-1, 0, 0); - if(child_dead) { - signal(SIGCHLD,sig_child_handler); - child_dead = 0; - } - - } else { - execvp( words[0], words ); - exit(0); - } - - } else { - - - growing_buffer* b = buffer_init(64); - int i = 0; - while(words[i]) - buffer_fadd( b, "%s ", words[i++] ); - - buffer_add( b, "\n"); - - //int reader; - //int reader = dup2(STDOUT_FILENO, reader); - //int reader = dup(STDOUT_FILENO); - //close(STDOUT_FILENO); - - fprintf( shell_writer, b->buf ); - buffer_free(b); - - fflush(shell_writer); - usleep(1000); - - /* - char c[4096]; - bzero(c, 4096); - read( reader, c, 4095 ); - fprintf(stderr, "read %s", c); - dup2(reader, STDOUT_FILENO); - */ - - } - - - return 1; -} - - -int handle_request( char* words[], int relay ) { +static int handle_request( char* words[], int relay ) { if(!client) return 1; @@ -662,7 +706,7 @@ int send_request( char* server, } /* -int handle_time( char* words[] ) { +static int handle_time( char* words[] ) { if( ! words[1] ) { @@ -688,7 +732,7 @@ int handle_time( char* words[] ) { -int router_query_servers( char* router_server ) { +static int router_query_servers( const char* router_server ) { if( ! router_server || strlen(router_server) == 0 ) return 0; @@ -724,8 +768,8 @@ int router_query_servers( char* router_server ) { return 1; } - -int print_help() { + +static int print_help( void ) { printf( "---------------------------------------------------------------------------------\n" @@ -733,8 +777,10 @@ int print_help() { "---------------------------------------------------------------------------------\n" "help - Display this message\n" "! [args] - Forks and runs the given command in the shell\n" - "time - Prints the current time\n" + /* + "time - Prints the current time\n" "time - Formats seconds since epoch into readable format\n" + */ "set - set a srfsh variable (e.g. set pretty_print true )\n" "print - Displays the value of a srfsh variable\n" "---------------------------------------------------------------------------------\n" @@ -778,8 +824,8 @@ int print_help() { } - -char* tabs(int count) { +/* +static char* tabs(int count) { growing_buffer* buf = buffer_init(24); int i; for(i=0;i!=count;i++) @@ -789,15 +835,17 @@ char* tabs(int count) { buffer_free( buf ); return final; } +*/ + -int handle_math( char* words[] ) { +static int handle_math( char* words[] ) { if( words[1] ) return do_math( atoi(words[1]), 0 ); return 0; } -int do_math( int count, int style ) { +static int do_math( int count, int style ) { osrf_app_session* session = osrf_app_client_session_init( "opensrf.math" ); osrf_app_session_connect(session); diff --git a/src/srfsh/srfsh.h b/src/srfsh/srfsh.h deleted file mode 100644 index 6497231..0000000 --- a/src/srfsh/srfsh.h +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - - - - -#define SRFSH_PORT 5222 -#define COMMAND_BUFSIZE 4096 - - -/* shell prompt */ -char* prompt = "srfsh# "; - -char* history_file = NULL; - -int child_dead = 0; - -char* login_session = NULL; - -/* true if we're pretty printing json results */ -int pretty_print = 1; -/* true if we're bypassing 'less' */ -int raw_print = 0; - -/* our jabber connection */ -transport_client* client = NULL; - -/* the last result we received */ -osrf_message* last_result = NULL; - -/* functions */ -int parse_request( char* request ); - -/* handles router requests */ -int handle_router( char* words[] ); - -/* utility method for print time data */ -int handle_time( char* words[] ); - -/* handles app level requests */ -int handle_request( char* words[], int relay ); -int handle_exec(char* words[], int new_shell); -int handle_set( char* words[]); -int handle_print( char* words[]); -int send_request( char* server, - char* method, growing_buffer* buffer, int relay ); -int parse_error( char* words[] ); -int router_query_servers( char* server ); -int srfsh_client_connect(); -int print_help(); -char* tabs(int count); -void sig_child_handler( int s ); -void sig_int_handler( int s ); - -int load_history(); -int handle_math( char* words[] ); -int do_math( int count, int style ); -int handle_introspect(char* words[]); -int handle_login( char* words[]);