PageRenderTime 25ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/RPC/XML/Parser.pm

https://github.com/tokuhirom/rpc-xml
Perl | 326 lines | 165 code | 88 blank | 73 comment | 16 complexity | fb5f5dab364ae4cd03921c06c71a7ca2 MD5 | raw file
  1. ###############################################################################
  2. #
  3. # This file copyright (c) 2001-2010 Randy J. Ray, all rights reserved
  4. #
  5. # Copying and distribution are permitted under the terms of the Artistic
  6. # License 2.0 (http://www.opensource.org/licenses/artistic-license-2.0.php) or
  7. # the GNU LGPL (http://www.opensource.org/licenses/lgpl-2.1.php).
  8. #
  9. ###############################################################################
  10. #
  11. # Description: This is the RPC::XML::Parser class, an empty class that
  12. # acts as an interface for parser implementations that can
  13. # be created/returned by RPC::XML::ParserFactory.
  14. #
  15. # Functions: new
  16. # parse
  17. #
  18. # Global Consts: $VERSION
  19. #
  20. # Environment: None.
  21. #
  22. ###############################################################################
  23. package RPC::XML::Parser;
  24. use 5.006001;
  25. use strict;
  26. use warnings;
  27. use vars qw($VERSION);
  28. use subs qw(new parse);
  29. $VERSION = '1.22';
  30. $VERSION = eval $VERSION; ## no critic (ProhibitStringyEval)
  31. ###############################################################################
  32. #
  33. # Sub Name: new
  34. #
  35. # Description: Constructor. Dies, because this should be overridden.
  36. #
  37. # Per RT#50013: Now, when called specifically for this class,
  38. # quietly loads RPC::XML::ParserFactory and instantiates a
  39. # parser based on XML::Parser.
  40. #
  41. # Returns: undef
  42. #
  43. ###############################################################################
  44. sub new
  45. {
  46. my ($class, @args) = @_;
  47. if ($class eq 'RPC::XML::Parser')
  48. {
  49. # For sake of not breaking backwards-compatibility with projects like
  50. # Catalyst::Plugin::Server::XMLRPC, in this case quietly load the
  51. # RPC::XML::ParserFactory and return a factory-generated instance:
  52. require RPC::XML::ParserFactory;
  53. return RPC::XML::ParserFactory->new(class => 'xmlparser', @args);
  54. }
  55. die __PACKAGE__ . '::new: This method should have been overridden by ' .
  56. "the $class class\n";
  57. }
  58. ###############################################################################
  59. #
  60. # Sub Name: parse
  61. #
  62. # Description: Parse the requested string or stream, or return a
  63. # push-parser instance. In this case, it dies because the
  64. # sub-class should have overridden it.
  65. #
  66. # Returns: dies
  67. #
  68. ###############################################################################
  69. sub parse
  70. {
  71. my $class = shift;
  72. $class = ref($class) || $class;
  73. die __PACKAGE__ . '::parse: This method should have been overridden by ' .
  74. "the $class class\n";
  75. }
  76. ###############################################################################
  77. #
  78. # Sub Name: parse_more
  79. #
  80. # Description: When called on a push-parser instance (which may or may
  81. # not be the same class), parses additional content and
  82. # waits for more. In this case it dies because the sub-class
  83. # should have overridden it.
  84. #
  85. # Returns: dies
  86. #
  87. ###############################################################################
  88. sub parse_more
  89. {
  90. my $class = shift;
  91. $class = ref($class) || $class;
  92. die __PACKAGE__ . '::parse_more: This method should have been overridden' .
  93. " by the $class class\n";
  94. }
  95. ###############################################################################
  96. #
  97. # Sub Name: parse_done
  98. #
  99. # Description: When called on a push-parser instance (which may or may
  100. # not be the same class), finishes the parse process and
  101. # returns the result. In this case it dies because the
  102. # sub-class should have overridden it.
  103. #
  104. # Returns: dies
  105. #
  106. ###############################################################################
  107. sub parse_done
  108. {
  109. my $class = shift;
  110. $class = ref($class) || $class;
  111. die __PACKAGE__ . '::parse_done: This method should have been overridden' .
  112. " by the $class class\n";
  113. }
  114. 1;
  115. __END__
  116. =head1 NAME
  117. RPC::XML::Parser - Interface for parsers created by RPC::XML::ParserFactory
  118. =head1 SYNOPSIS
  119. This class is not instantiated directly; see L<RPC::XML::ParserFactory>.
  120. =head1 DESCRIPTION
  121. The B<RPC::XML::Parser> class encapsulates the interface for the parsing
  122. process. It is an empty class that is used in conjuntion with the
  123. B<RPC::XML::ParserFactory> class.
  124. All parser implementations that are intended to be returned by calls to
  125. RPC::XML::ParserFactory::new() should declare this as their parent class.
  126. =head1 SUBROUTINES/METHODS
  127. This class provides empty implementations for the following methods. A parser
  128. implementation must provide definitions for B<both> of these methods. If the
  129. versions from this class are triggered they will throw exceptions (C<die>).
  130. The descriptions below define the interface that implementations must
  131. adhere to.
  132. =over 4
  133. =item new([ARGS])
  134. Create a new instance of the class. Any extra data passed to the constructor
  135. is taken as key/value pairs (B<not> a hash reference) and attached to the
  136. object.
  137. The following parameters are currently recognized:
  138. =over 8
  139. =item base64_to_fh
  140. If passed with a true value, this tells the parser that incoming Base64 data
  141. is to be spooled to a filehandle opened onto an anonymous temporary file. The
  142. file itself is unlinked after opening, though the resulting B<RPC::XML::base64>
  143. object can use its C<to_file> method to save the data to a specific file at a
  144. later point. No checks on size are made; if this option is set, B<all> Base64
  145. data goes to filehandles.
  146. =item base64_temp_dir
  147. If this argument is passed, the value is taken as the directory under which
  148. the temporary files are created. This is so that the application is not locked
  149. in to the list of directories that B<File::Spec> defaults to with its
  150. C<tmpdir> method. If this is not passed, the previously-mentioned method is
  151. used to derive the directory in which to create the temporary files. Only
  152. relevant if B<base64_to_fh> is set.
  153. =back
  154. The C<base64*> parameters do not have to be implemented if the user has
  155. no plans to use the C<to_file> method of the B<RPC::XML::base64> data-class.
  156. As a special-case, to preserve backwards compatibility with pre-0.69 versions
  157. of this package, new() has special behavior when specifically called for the
  158. package B<RPC::XML::Parser>. When called for this package, the constructor
  159. quietly loads B<RPC::XML::ParserFactory> and uses it to construct and return
  160. an instance of a parser based on B<XML::Parser>.
  161. =item parse [ STRING | STREAM ]
  162. Parse the XML document specified in either a string or a stream. The stream
  163. may be any file descriptor, derivative of B<IO::Handle>, etc.
  164. The value returned must be one of the following:
  165. =over 4
  166. =item RPC::XML::request instance
  167. When passed a valid XML-RPC request message, the return value should be
  168. an instance of the B<RPC::XML::request> class.
  169. =item RPC::XML::response instance
  170. Likewise, when passed a valid XML-RPC response, the return value should be
  171. an instance of the B<RPC::XML::response> class.
  172. =item string containing an error message
  173. If the message does not conform to either a request or a response, or does
  174. not properly parse, the return value must be a string containing the error
  175. message.
  176. =item A non-blocking (push) parser instance
  177. If no arguments are passed in, the return value must be a parser object that
  178. implements push-parsing (non-blocking). It does not have to be of the same
  179. class as the original object, but it must support the remaining two methods
  180. =back
  181. =back
  182. The next two methods are only called on push-parser instances, and as such do
  183. not have to be implemented by the actual factory-compatible parser. It is
  184. enough if the non-blocking parser instance it returns from the no-argument call
  185. to parse() implements these:
  186. =over 4
  187. =item parse_more STRING
  188. Send a chunk of the current XML document to the parser for processing.
  189. =item parse_done
  190. Signal the end of parsing. The return value from this should be one of the
  191. same three possibilities that the direct use of parse() (above) returns:
  192. =over 4
  193. =item RPC::XML::request instance
  194. =item RPC::XML::response instance
  195. =item string containing an error message
  196. =back
  197. parse_done() may also signal an error by throwing an exception.
  198. =back
  199. =head1 DIAGNOSTICS
  200. Unless otherwises specified, routines return the object reference itself upon
  201. a successful operation, and an error string (which is not a blessed reference)
  202. upon error.
  203. =head1 BUGS
  204. Please report any bugs or feature requests to
  205. C<bug-rpc-xml at rt.cpan.org>, or through the web interface at
  206. L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=RPC-XML>. I will be
  207. notified, and then you'll automatically be notified of progress on
  208. your bug as I make changes.
  209. =head1 SUPPORT
  210. =over 4
  211. =item * RT: CPAN's request tracker
  212. L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=RPC-XML>
  213. =item * AnnoCPAN: Annotated CPAN documentation
  214. L<http://annocpan.org/dist/RPC-XML>
  215. =item * CPAN Ratings
  216. L<http://cpanratings.perl.org/d/RPC-XML>
  217. =item * Search CPAN
  218. L<http://search.cpan.org/dist/RPC-XML>
  219. =item * Source code on GitHub
  220. L<http://github.com/rjray/rpc-xml>
  221. =back
  222. =head1 LICENSE AND COPYRIGHT
  223. This file and the code within are copyright (c) 2010 by Randy J. Ray.
  224. Copying and distribution are permitted under the terms of the Artistic
  225. License 2.0 (L<http://www.opensource.org/licenses/artistic-license-2.0.php>) or
  226. the GNU LGPL 2.1 (L<http://www.opensource.org/licenses/lgpl-2.1.php>).
  227. =head1 CREDITS
  228. The B<XML-RPC> standard is Copyright (c) 1998-2001, UserLand Software, Inc.
  229. See <http://www.xmlrpc.com> for more information about the B<XML-RPC>
  230. specification.
  231. =head1 SEE ALSO
  232. L<RPC::XML>, L<RPC::XML::ParserFactory>, L<RPC::XML::Parser::XMLParser>
  233. =head1 AUTHOR
  234. Randy J. Ray <rjray@blackperl.com>
  235. =cut