mirror of https://github.com/apache/jclouds.git
Issue 36: converted to not have any java binding, and clarified to deal with enums and constraints
git-svn-id: http://jclouds.googlecode.com/svn/trunk@888 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
34698fb78a
commit
655b34dc9e
|
@ -54,15 +54,9 @@ use JSON;
|
||||||
|
|
||||||
my $refUrl = "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference";
|
my $refUrl = "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference";
|
||||||
|
|
||||||
# my $refUrl = "/tmp/scrape";
|
#my $refUrl = "/tmp/scrape";
|
||||||
|
|
||||||
my $appUrl = "${refUrl}/OperationList-query.html";
|
my $appUrl = "${refUrl}/OperationList-query.html";
|
||||||
my $global_package = "org.jclouds.aws.ec2";
|
|
||||||
my $commands_package = $global_package . ".commands";
|
|
||||||
my $response_package = $commands_package . ".response";
|
|
||||||
my $options_package = $commands_package . ".options";
|
|
||||||
my $domain_package = $global_package . ".domain";
|
|
||||||
my $xml_package = $global_package . ".xml";
|
|
||||||
|
|
||||||
my $domain = {};
|
my $domain = {};
|
||||||
|
|
||||||
|
@ -75,69 +69,17 @@ sub parse_file {
|
||||||
}
|
}
|
||||||
|
|
||||||
sub parse {
|
sub parse {
|
||||||
|
|
||||||
#return parse_file(shift);
|
#return parse_file(shift);
|
||||||
|
|
||||||
return parse_url(shift);
|
return parse_url(shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub parse_java_type {
|
sub get_subtypes {
|
||||||
$_ = shift;
|
$_ = shift;
|
||||||
s/xsd:string/String/;
|
if ( /^[A-Z]/ && $_ ne 'String' && $_ ne 'Integer' && $_ ne 'Boolean' ) {
|
||||||
s/xsd:boolean/Boolean/;
|
my $type = $_;
|
||||||
s/xsd:Int/Integer/;
|
$domain->{$type} = build_bean($type);
|
||||||
s/xsd:dateTime/DateTime/;
|
|
||||||
if (/Type/ || /Item/) {
|
|
||||||
my $awsType = $_;
|
|
||||||
my $javaType = get_java_name($awsType);
|
|
||||||
#if ( !/Response/ || /ResponseInfoType/ || $javaType =~ /Set/ ) {
|
|
||||||
$domain->{$awsType} = {
|
|
||||||
awsType => $awsType,
|
|
||||||
javaType => $javaType,
|
|
||||||
packageName => $domain_package,
|
|
||||||
className => $domain_package . "." . $javaType,
|
|
||||||
see => ["${refUrl}/ApiReference-ItemType-${awsType}.html"],
|
|
||||||
fields =>
|
|
||||||
build_fields("${refUrl}/ApiReference-ItemType-$awsType.html")
|
|
||||||
};
|
|
||||||
#}
|
|
||||||
$_ = $javaType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $_;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub get_java_name {
|
|
||||||
$_ = shift;
|
|
||||||
if (/sSetType/) {
|
|
||||||
s/sSetType//;
|
|
||||||
return "Set<$_>";
|
|
||||||
}
|
|
||||||
if (/sResponseInfoType/){
|
|
||||||
s/sResponseInfoType//;
|
|
||||||
return "Set<$_>";
|
|
||||||
}
|
|
||||||
if (/sSetItemType/) {
|
|
||||||
s/sSetItemType//;
|
|
||||||
}
|
|
||||||
if (/sResponseItemType/){
|
|
||||||
s/sResponseItemType//;
|
|
||||||
}
|
|
||||||
if (/sItemType/) {
|
|
||||||
s/sItemType//;
|
|
||||||
}
|
|
||||||
if (/sSet/) {
|
|
||||||
s/sSet//;
|
|
||||||
}
|
|
||||||
if (/Set/) {
|
|
||||||
s/Set//;
|
|
||||||
}
|
|
||||||
if (/Type/) {
|
|
||||||
s/Type//;
|
|
||||||
}
|
|
||||||
if (/Item/) {
|
|
||||||
s/Item//;
|
|
||||||
}
|
|
||||||
return $_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub parse_url {
|
sub parse_url {
|
||||||
|
@ -156,253 +98,220 @@ sub parse_url {
|
||||||
return $tree;
|
return $tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub build_commands {
|
sub build_queries {
|
||||||
my $tree = parse( $_[0] );
|
my $tree = parse( $_[0] );
|
||||||
my @out;
|
my @out;
|
||||||
foreach my $link (
|
foreach my $link (
|
||||||
( $tree->look_down( '_tag', 'div', 'class', 'itemizedlist' ) ) )
|
( $tree->look_down( '_tag', 'div', 'class', 'itemizedlist' ) ) )
|
||||||
{
|
{
|
||||||
my $package = $link->look_down( '_tag', 'b' );
|
my $category = $link->look_down( '_tag', 'b' )->as_text();
|
||||||
$_ = $package->as_text;
|
|
||||||
s/ //g;
|
|
||||||
my $packageName = lc();
|
|
||||||
my @commands;
|
|
||||||
|
|
||||||
|
my $queries;
|
||||||
foreach my $class ( $link->look_down( '_tag', 'a' ) ) {
|
foreach my $class ( $link->look_down( '_tag', 'a' ) ) {
|
||||||
my $awsType = $class->attr('title');
|
my $type = $class->attr('title');
|
||||||
my $command = {
|
my $query = build_query($type);
|
||||||
awsType => $awsType,
|
|
||||||
packageName => $commands_package . ".$packageName",
|
|
||||||
className => $commands_package . ".$packageName." . $awsType,
|
|
||||||
see => ["${refUrl}/ApiReference-query-${awsType}.html"],
|
|
||||||
response => {
|
|
||||||
javaType => $awsType . "Response",
|
|
||||||
awsType => $awsType . "Response",
|
|
||||||
packageName => $response_package . ".$packageName",
|
|
||||||
className => $response_package
|
|
||||||
. ".$packageName."
|
|
||||||
. $awsType
|
|
||||||
. "Response",
|
|
||||||
see => [
|
|
||||||
"${refUrl}/ApiReference-ItemType-${awsType}Response.html"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
options => {
|
|
||||||
javaType => $awsType . "Options",
|
|
||||||
awsType => $awsType . "Options",
|
|
||||||
packageName => $options_package . ".$packageName",
|
|
||||||
className => $options_package
|
|
||||||
. ".$packageName."
|
|
||||||
. $awsType
|
|
||||||
. "Options",
|
|
||||||
see => ["${refUrl}/ApiReference-ItemType-${awsType}.html"]
|
|
||||||
},
|
|
||||||
handler => {
|
|
||||||
awsType => $awsType . "Handler",
|
|
||||||
packageName => $xml_package . ".$packageName",
|
|
||||||
className => $xml_package
|
|
||||||
. ".$packageName."
|
|
||||||
. $awsType
|
|
||||||
. "Handler",
|
|
||||||
see => [
|
|
||||||
"${refUrl}/ApiReference-ItemType-${awsType}Response.html"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
$command = build_command($command);
|
|
||||||
|
|
||||||
# do not build options when there are none!
|
# add a domain object for the response type
|
||||||
if ( $#{ $$command{options}->{parameters} } == -1 ) {
|
$domain->{ $type . "Response" } =
|
||||||
$$command{options}->{javaType} =
|
build_bean( $type . "Response", "Response" );
|
||||||
"BaseEC2RequestOptions<EC2RequestOptions>";
|
|
||||||
$$command{options}->{packageName} = $options_package;
|
$query->{responseType} = $type . "Response";
|
||||||
$$command{options}->{className} = $options_package . "."
|
|
||||||
. "BaseEC2RequestOptions<EC2RequestOptions>";
|
$queries->{$type} = $query;
|
||||||
$$command{options}->{see} = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# clear parameters for commands who don't require them
|
|
||||||
if ( $#{ $$command{parameters} } == -1 ) {
|
|
||||||
delete $$command{parameters};
|
|
||||||
}
|
|
||||||
push @commands, $command;
|
|
||||||
}
|
|
||||||
push @out,
|
push @out,
|
||||||
{
|
{
|
||||||
name => $packageName,
|
name => $category,
|
||||||
commands => \@commands,
|
queries => $queries,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
$tree->eof;
|
$tree->eof;
|
||||||
$tree->delete;
|
$tree->delete;
|
||||||
foreach my $packageRef (@out) {
|
|
||||||
my @commands = @{ $packageRef->{commands} };
|
|
||||||
foreach my $command (@commands) {
|
|
||||||
my $fieldCount = scalar @{ $command->{response}->{fields} };
|
|
||||||
|
|
||||||
# convert to native java type
|
|
||||||
if ( $fieldCount == 1 ) {
|
|
||||||
$command->{response}->{javaType} =
|
|
||||||
${ $command->{response}->{fields} }[0]->{javaType};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return \@out;
|
return \@out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub build_app {
|
sub build_app {
|
||||||
my $url = shift;
|
my $url = shift;
|
||||||
my $packages = build_commands($url);
|
my $categories = build_queries($url);
|
||||||
while ( my ( $awsType, $classDef ) = each %$domain ) {
|
|
||||||
my $fieldCount = scalar @{ $classDef->{fields} };
|
|
||||||
if ( $fieldCount == 1 ) {
|
|
||||||
if ( $classDef->{fields}->[0]->{"name"} eq "item" ) {
|
|
||||||
delete $domain->{$awsType};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( $classDef->{javaType} =~ /^Set/ ) {
|
|
||||||
delete $domain->{$awsType};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
see => [$url],
|
see => [$url],
|
||||||
packages => $packages,
|
categories => $categories,
|
||||||
domain => $domain
|
domain => $domain
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sub build_command {
|
sub build_query {
|
||||||
my $command = $_[0];
|
my $type = shift;
|
||||||
|
my $query = build_bean( $type, "Request" );
|
||||||
|
my $tree = parse(${ $query->{see} }[0]);
|
||||||
|
|
||||||
#print "parsing $$command{see}[0]...\n";
|
my @{seeAlsoA} =
|
||||||
my $tree = parse( $$command{see}[0] );
|
$tree->look_down( '_tag', 'div', 'class', 'itemizedlist' )
|
||||||
|
->look_down( '_tag', 'a' );
|
||||||
|
|
||||||
#$tree->dump;
|
foreach ( @{seeAlsoA} ) {
|
||||||
my ${requestExampleDiv} =
|
push @{ $query->{see} }, $_->as_text();
|
||||||
$tree->look_down( '_tag', 'h3', 'id',
|
|
||||||
"ApiReference-query-$$command{awsType}-Example-Request-1" )
|
|
||||||
->look_up( '_tag', 'div', 'class', 'section' );
|
|
||||||
$$command{options}->{example} = ${requestExampleDiv}->as_HTML();
|
|
||||||
|
|
||||||
my ${reqParamTBody} =
|
|
||||||
$tree->look_down( '_tag', 'h2', 'id',
|
|
||||||
"ApiReference-query-$$command{awsType}-Request" )
|
|
||||||
->look_up( '_tag', 'div', 'class', 'section' )
|
|
||||||
->look_down( '_tag', 'tbody' );
|
|
||||||
my @{parameterRows};
|
|
||||||
if ( defined($reqParamTBody) ) {
|
|
||||||
@{parameterRows} = ${reqParamTBody}->look_down( '_tag', 'tr' );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
my @optionParameters;
|
$tree->eof;
|
||||||
my @requiredParameters;
|
$tree->delete;
|
||||||
|
|
||||||
foreach my $parameterRow ( @{parameterRows} ) {
|
return $query;
|
||||||
my @{row} = $parameterRow->look_down( '_tag', 'td' );
|
}
|
||||||
|
|
||||||
|
sub build_fields {
|
||||||
|
my @{fieldRows} = @_;
|
||||||
|
my @params;
|
||||||
|
foreach my $fieldRow ( @{fieldRows} ) {
|
||||||
|
my @{row} = $fieldRow->look_down( '_tag', 'td' );
|
||||||
my %param;
|
my %param;
|
||||||
$param{name} = ${row}[0]->as_text();
|
$param{name} = ${row}[0]->as_text();
|
||||||
|
my $enumDiv =
|
||||||
|
${row}[1]->look_down( '_tag', 'div', "class", "itemizedlist" );
|
||||||
|
if ( defined $enumDiv ) {
|
||||||
|
my $enum;
|
||||||
|
my @enumEntries = $enumDiv->look_down( '_tag', 'p' );
|
||||||
|
foreach my $enumEntry (@enumEntries) {
|
||||||
|
$enumEntry = $enumEntry->as_text();
|
||||||
|
my ( $code, $state ) = split( /: /, $enumEntry );
|
||||||
|
chomp($code);
|
||||||
|
chomp($state);
|
||||||
|
$enum->{$code} = $state;
|
||||||
|
}
|
||||||
|
$param{enum} = $enum;
|
||||||
|
$param{desc} = ${row}[1]->look_down( '_tag', 'p' )->as_text();
|
||||||
|
}
|
||||||
|
else {
|
||||||
my @{data} = ${row}[1]->look_down( '_tag', 'p' );
|
my @{data} = ${row}[1]->look_down( '_tag', 'p' );
|
||||||
foreach ( @{data} ) {
|
foreach ( @{data} ) {
|
||||||
$_ = $_->as_text();
|
$_ = $_->as_text();
|
||||||
if (s/Default: //) {
|
if (s/Default: //) {
|
||||||
$param{param} = $_;
|
$param{default} = $_;
|
||||||
}
|
}
|
||||||
elsif (s/Type: //) {
|
elsif (s/Type: //) {
|
||||||
$param{type} = $_;
|
$param{type} = $_;
|
||||||
$param{javaType} = parse_java_type($_);
|
get_subtypes($_);
|
||||||
|
}
|
||||||
|
elsif (s/Ancestor: //) {
|
||||||
|
$param{ancestor} = $_;
|
||||||
|
}
|
||||||
|
elsif (s/Children: //) {
|
||||||
|
$param{children} = $_;
|
||||||
|
}
|
||||||
|
elsif (s/Constraints: //) {
|
||||||
|
$param{constraints} = $_;
|
||||||
|
if (m/.*default: ([0-9]+)/) {
|
||||||
|
$param{default} = $1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif (s/Valid Values: //) {
|
||||||
|
if (/\|/) {
|
||||||
|
my @valid_values = split(' \| ');
|
||||||
|
$param{valid_values} = \@valid_values;
|
||||||
|
}
|
||||||
|
elsif (/([0-9]+) ?\-([0-9]+)/) {
|
||||||
|
$param{valid_values} = "$1-$2";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$param{desc} = $_;
|
$param{desc} = $_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( ${row}[2]->as_text() =~ /No/ ) {
|
}
|
||||||
push @optionParameters, \%param;
|
|
||||||
|
if ( defined ${row}[2] && ${row}[2]->as_text() =~ /No/ ) {
|
||||||
|
$param{optional} = 'true';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
push @optionParameters, \%param;
|
$param{optional} = 'false';
|
||||||
push @requiredParameters, \%param;
|
|
||||||
}
|
}
|
||||||
|
push @params, \%param;
|
||||||
}
|
}
|
||||||
$$command{options}->{parameters} = \@optionParameters;
|
return \@params;
|
||||||
$$command{parameters} = \@requiredParameters;
|
}
|
||||||
|
|
||||||
my ${responseExampleDiv} =
|
sub build_bean {
|
||||||
$tree->look_down( '_tag', 'h3', 'id',
|
my $type = shift;
|
||||||
"ApiReference-query-$$command{awsType}-Example-Response-1" )
|
my $class = shift;
|
||||||
|
my $bean = { type => $type, };
|
||||||
|
|
||||||
|
my $see = "${refUrl}/ApiReference-ItemType-${type}.html";
|
||||||
|
if ( defined $class ) {
|
||||||
|
$_ = $type;
|
||||||
|
if ( $class =~ /Response/ ) {
|
||||||
|
|
||||||
|
# responses are related to the query. In this case, we must take
|
||||||
|
# off the suffix Response to get the correct metadata url.
|
||||||
|
s/$class//;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# if we are the query object, then there is a different master url.
|
||||||
|
$see = "${refUrl}/ApiReference-query-${type}.html";
|
||||||
|
}
|
||||||
|
my $query = "${refUrl}/ApiReference-query-${_}.html";
|
||||||
|
push @{ $bean->{see} }, $query;
|
||||||
|
my $tree = parse($query);
|
||||||
|
|
||||||
|
if ( !defined $tree ) {
|
||||||
|
print "could not parse tree $_[0]\n";
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
my $id = "ApiReference-query-${_}-Example-${class}-1";
|
||||||
|
my ${requestExampleDiv} =
|
||||||
|
$tree->look_down( '_tag', 'h3', 'id', "$id" )
|
||||||
->look_up( '_tag', 'div', 'class', 'section' );
|
->look_up( '_tag', 'div', 'class', 'section' );
|
||||||
$$command{handler}->{example} = ${responseExampleDiv}->as_HTML();
|
$bean->{example_html} = ${requestExampleDiv}->as_HTML();
|
||||||
|
$bean->{example_code} =
|
||||||
$command = build_response($command);
|
${requestExampleDiv}
|
||||||
|
->look_down( '_tag', 'pre', 'class', 'programlisting' )->as_text();
|
||||||
my @{seeAlsoA} =
|
|
||||||
$tree->look_down( '_tag', 'div', 'class', 'itemizedlist' )
|
|
||||||
->look_down( '_tag', 'a' );
|
|
||||||
foreach ( @{seeAlsoA} ) {
|
|
||||||
push @{ $command->{see} }, $_->as_text();
|
|
||||||
}
|
|
||||||
$tree->eof;
|
$tree->eof;
|
||||||
$tree->delete;
|
$tree->delete;
|
||||||
|
|
||||||
# print_command($command);
|
|
||||||
return $command;
|
|
||||||
}
|
|
||||||
|
|
||||||
sub build_response {
|
|
||||||
my $command = $_[0];
|
|
||||||
$$command{response}->{fields} =
|
|
||||||
build_fields( $$command{response}->{see}[0] );
|
|
||||||
remove_request_ids( $$command{response} );
|
|
||||||
return $command;
|
|
||||||
}
|
|
||||||
|
|
||||||
# request id is not a domain concern
|
|
||||||
sub remove_request_ids {
|
|
||||||
my $response = shift;
|
|
||||||
my @fields = @{ ${response}->{fields} };
|
|
||||||
for ( 0 .. $#fields ) {
|
|
||||||
if ( $fields[$_]->{name} eq "requestId" ) {
|
|
||||||
splice( @{ ${response}->{fields} }, $_, 1 );
|
|
||||||
}
|
}
|
||||||
|
push @{ $bean->{see} }, $see unless defined $bean->{see};
|
||||||
|
|
||||||
|
my $tree = parse($see);
|
||||||
|
|
||||||
|
if ( !defined $tree ) {
|
||||||
|
print "could not parse tree $_[0]\n";
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sub build_fields {
|
|
||||||
|
|
||||||
#print "parsing $_[0]\n";
|
|
||||||
my $tree = parse( $_[0] );
|
|
||||||
|
|
||||||
|
# $tree->dump();
|
||||||
$tree->eof;
|
$tree->eof;
|
||||||
my @{fields};
|
my $id = "ApiReference-ItemType-${type}-Ancestors";
|
||||||
|
my ${ancestorH2} = $tree->look_down( '_tag', 'h2', 'id', "$id" );
|
||||||
|
my ${ancestorDiv} =
|
||||||
|
${ancestorH2}->look_up( '_tag', 'div', 'class', 'section' )
|
||||||
|
if defined ${ancestorH2};
|
||||||
|
my ${ancestorLink} =
|
||||||
|
${ancestorDiv}->look_down( '_tag', 'a', 'class', 'xref' )
|
||||||
|
if defined ${ancestorDiv};
|
||||||
|
if ( defined ${ancestorLink} ) {
|
||||||
|
$bean->{ancestor} = ${ancestorLink}->as_text();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$bean->{ancestor} = "None";
|
||||||
|
}
|
||||||
|
|
||||||
my @{fieldRows} = my $body = ${tree}->look_down( '_tag', 'tbody' );
|
my @{fieldRows} = my $body = ${tree}->look_down( '_tag', 'tbody' );
|
||||||
return [] unless defined $body; #TODO
|
|
||||||
|
if ( !defined $body ) {
|
||||||
|
print "could not parse body $_[0]\n";
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
@{fieldRows} = $body->look_down( '_tag', 'tr' );
|
@{fieldRows} = $body->look_down( '_tag', 'tr' );
|
||||||
|
|
||||||
foreach ( @{fieldRows} ) {
|
my $fields = build_fields( @{fieldRows} );
|
||||||
my @row = $_->look_down( '_tag', 'td' );
|
|
||||||
my %field;
|
|
||||||
$field{name} = ${row}[0]->as_text();
|
|
||||||
my @{data} = ${row}[1]->look_down( '_tag', 'p' );
|
|
||||||
foreach ( @{data} ) {
|
|
||||||
$_ = $_->as_text();
|
|
||||||
if (s/Type: //) {
|
|
||||||
$field{type} = $_;
|
|
||||||
$field{javaType} = parse_java_type($_);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$field{desc} = $_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
push @fields, \%field;
|
|
||||||
}
|
|
||||||
|
|
||||||
$tree->delete;
|
$tree->delete;
|
||||||
return \@fields;
|
$bean->{fields} = $fields;
|
||||||
|
return $bean;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# start app!
|
# start app!
|
||||||
my $app = build_app($appUrl);
|
my $app = build_app($appUrl);
|
||||||
|
|
||||||
my $app_json = to_json( $app, { utf8 => 1, pretty => 1 } );
|
my $app_json = to_json( $app, { utf8 => 1, pretty => 1 } );
|
||||||
print $app_json
|
print $app_json
|
||||||
|
|
Loading…
Reference in New Issue