#!/usr/bin/perl # Created on: 2013-04-21 10:43:25 # Create by: Ivan Wills # $Id$ # $Revision$, $HeadURL$, $Date$ # $Revision$, $Source$, $Date$ use strict; use warnings; use version; use Getopt::Long; use Pod::Usage; use Data::Dumper qw/Dumper/; use English qw/ -no_match_vars /; use FindBin qw/$Bin/; use Path::Tiny; use W3C::SOAP::WADL::Parser; use File::ShareDir qw/dist_dir/; use Template; our $VERSION = version->new('0.007'); my ($name) = $PROGRAM_NAME =~ m{^.*/(.*?)$}mxs; my %option = ( lib => 'lib', ns_module_map => {}, verbose => 0, man => 0, help => 0, VERSION => 0, ); if ( !@ARGV ) { pod2usage( -verbose => 1 ); } main(); exit 0; sub main { Getopt::Long::Configure('bundling'); GetOptions( \%option, 'ns_module_map|ns|namespace-map|n=s%', 'ns_module_map_file|map-file|f=s', 'module_base|module-base|b=s', 'lib|l=s', 'show|s', 'path|p=s', 'save|S', 'verbose|v+', 'man', 'help', 'VERSION!', ) or pod2usage(2); if ( $option{'VERSION'} ) { print "$name Version = $VERSION\n"; exit 1; } elsif ( $option{'man'} ) { pod2usage( -verbose => 2 ); } elsif ( $option{'help'} ) { pod2usage( -verbose => 1 ); } if ( $option{ns_module_map_file} && -f $option{ns_module_map_file} ) { $option{ns_module_map} ||= {}; my $file = path $option{ns_module_map_file}; for my $line ($file->slurp) { chomp $line; next if !$line; my ($ns, $mod) = split /=|,|\t/, $line, 2; $option{ns_module_map}{$ns} ||= $mod } } #warn Dumper $option{ns_module_map}, $option{ns_module_map_file}; $option{module_base} = 'Static::WADL' if $option{show} && !$option{module_base}; return show() if $option{show}; my $template = Template->new( INCLUDE_PATH => ($option{path} ? "$option{path}:" : '') . dist_dir('W3C-SOAP-WADL') . ':' . dist_dir('W3C-SOAP'), INTERPOLATE => 0, EVAL_PERL => 1, ); my ( $module, $wadl_file ) = @ARGV; if ( !$wadl_file ) { if ( !$option{module_base} ) { warn "You must specify a package name for your WADL!\n"; pod2usage( -verbose => 1 ); } $wadl_file = $module; $module = $option{module_base}; } # check that %map modules don't overlap with $option{ns_module_map} modules if (!$option{module_base} && !$option{ns_module_map}{$module}) { die "The module '$module' is mapped from both the WADL '$wadl_file'" . " and the XMLSchema '$option{ns_module_map}{$module}' namespaces" . " please use different modules!\n"; } my $wadl = W3C::SOAP::WADL::Parser->new( location => $wadl_file, template => $template, $module ? ( module => $module ) : (), %option, ); $wadl->write_modules; my $generated = $wadl->module; print "Generated WADL client $generated\n"; if ( $option{save} ) { my $file = $wadl_file; $file =~ s{[/:?&]}{_}g; my $fh = path("$file.wadl")->openw; print {$fh} $wadl->document->xml->toString(); for my $schema ($wadl->get_xsd->get_schemas) { next if ! $schema->location; my $file = $schema->location; $file =~ s{[/:?&]}{_}g; my $fh = path("$file.xsd")->openw; print {$fh} $schema->xml->toString(); } } return; } sub show { # do stuff here my %map = $option{module_base} ? ($option{module_base} => @ARGV) : @ARGV; for my $module (keys %map) { my $wadl = W3C::SOAP::WADL::Document->new( %option, file => $map{$module}, ); print $wadl->target_namespace, "\n"; print "Resources :\n"; for my $node (@{ $wadl->resources }) { print "\t", $node->path, "\n"; print "\tResource :\n"; for my $node (@{ $node->resource }) { print "\t\t", $node->path, ' (', $node->id, ")\n"; for my $method (@{ $node->method }) { print "\t\t\t", $method->name, ' (', $method->id, ")\n"; print "\t\t\t\tRequest:\n"; for my $param (@{ $method->request->param }) { print "\t\t\t\t\t", $param->name, "\n"; } for my $response (@{ $method->response }) { print "\t\t\t\tResponse (", $response->status, ")\n"; for my $param (@{ $response->param }) { print "\t\t\t\t\t\t", $param->name, "\n"; } eval { $response->representation }; eval { warn Dumper $response->representation->[0]->{_node}->toString }; print "\t\t\t\t\t\tReturns : ", $response->representation->[0]->media_type, "\n" if %{ $response->representation->[0] }; } } } } #print Dumper $wadl; } return; } __DATA__ =head1 NAME wadl-parser - Parses a WADL file to generate a REST client =head1 VERSION This documentation refers to wadl-parser version 0.007. =head1 SYNOPSIS wadl-parser [option] package wadl_file_or_url OPTIONS: -s --show Show some info about the passed WADL file -b --module-base[=]str Let the program auto generate package names with this value as the base of the module name. (Note packages names will be valid but not pretty) -n --namespace-map ns=package A mapping of XSD namespaces (ns) to perl package names, it is required when writing XSD files -f --map-file[=]file File that contains mappings of name -l --lib[=]dir Directory where generated modules should be writted, the default is ./lib -p --path[=]str Extra template toolkit directories if you want to override default templates. -S --save Save all downloaded WADLs & XSDs -v --verbose Show more detailed option --version Prints the version information --help Prints this help information --man Prints the full documentation for wadl-parser =head1 DESCRIPTION The L<wadl=parser> program generates static WADL clients that can be used by your own programs to talk to the WADL service. The L<wadl-parser> command can also (with the C<--show> flag) be used to give you a summary of what a WADL service provides. =head1 SUBROUTINES/METHODS =over 4 =back =head1 CONFIGURATION AND ENVIRONMENT =head1 DEPENDENCIES =head1 INCOMPATIBILITIES =head1 BUGS AND LIMITATIONS There are no known bugs in this module. Please report problems to Ivan Wills (ivan.wills@gmail.com). Patches are welcome. =head1 AUTHOR Ivan Wills - (ivan.wills@gmail.com) =head1 LICENSE AND COPYRIGHT Copyright (c) 2013 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW Australia 2077). All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L<perlartistic>. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =cut