Article 1CP6A CodeSOD: An Ant Pushes a Perl

CodeSOD: An Ant Pushes a Perl

by
Remy Porter
from The Daily WTF on (#1CP6A)

It's an old joke that Perl is a "write only language". Despite some of its issues, back in the early 2000s, Perl was one of the best options out there for scripting languages and rapid-development automation.

Speaking of automation, build automation is really important. Back in the early 2000s, before Maven really caught on, your build automation tool for Java was Ant. Ant, like everything invented in the early 2000s, was driven by an XML scripting tool. Since it was tuned specifically for Java, it had some high-level operations to streamline tasks like generating proxy classes for calling web services based on a supplied WSDL file.

Actually, speaking of code generation, Carrie sends us this code block. It's a Perl script that's called from an Ant build. It runs after generating a class based off a WSDL. It parses Java code using Regular Expressions and injects a ListWrapper class which doesn't adhere to the List contract. But hey, it does have a use strict declaration, guaranteeing you'll get errors if you access uninitialized variables.

use strict;use warnings;my $dir = $ARGV[0];readDir($dir);sub readDir { my ($dir) = @_; opendir my $dirHandle, $dir or die "Cannot open $dir.\n$!\n"; foreach my $file(readdir($dirHandle)) { next if $file =~ m/^\./; if(-d "$dir/$file") { readDir("$dir/$file"); next; } my %seenFields; my %multiples; my $fileName = "$dir/$file"; open IN, "<$fileName" or die "Cannot open $fileName.\n$!\n"; my @methods; my $file = ""; my $currentLine; my $containsContent = 0; while(<IN>) { if($_ =~ m/\@XmlElementRef\(name\s*=\s*"(.*?)".+namespace\s*=\s*"(.*?)".+type\s*=\s*(.*?.class)/) { my $field = ucfirst($1); my $namespace = $2; my $class = $3; $multiples{$1}++; if($multiples{$field} > 1) { $_ =~ s/name\s*=\s*"$1"/name = "$1$multiples{$1}"/gis; $field = $1 . $multiples{$1}; } my $fieldlc = lc($field); my $retObject = substr($class, 0, length($class) - 6); die if not defined $retObject; my $methodName = $field; unless(defined $seenFields{$methodName}) { $seenFields{$methodName} = 1; my $method = <<EOF; public List get$field() { List all = getContent(); ListWrapper retVal = new ListWrapper(all); for(java.lang.Object current : all) { java.lang.String className = null; if(current instanceof javax.xml.bind.JAXBElement) { className = ((javax.xml.bind.JAXBElement)current).getName().getLocalPart().toLowerCase(); } else { className = current.getClass().getSimpleName().toLowerCase(); } boolean good = false; if(className.equalsIgnoreCase("$fieldlc")) { good = true; } else { if(className.length() > 4) { className = className.substring(0, className.length() - 4); if(className.equalsIgnoreCase("$fieldlc")) { good = true; } } } if(good) { retVal.addWrapped(current); } } return retVal; }EOF push(@methods, $method); } } elsif ($_ =~ m/getContent\(\)/) { $containsContent = 1; } $currentLine = $_; $file .= $currentLine if defined $currentLine; } close IN; if($containsContent) { print "$fileName\n"; for my $method(@methods) { $file .= $method; } $file .= <<EOF; private class ListWrapper<T> extends ArrayList<T> { private List contentsList; public ListWrapper(List contents) { super(); contentsList = contents; } public boolean addWrapped(T toAdd) { return super.add(toAdd); } \@Override public boolean add(T toAdd) { return contentsList.add(toAdd); } \@Override public boolean addAll(java.util.Collection<? extends T> toAdd) { return contentsList.addAll(toAdd); } \@Override public T set(int index, T element) { int realIndex = contentsList.indexOf(this.get(index)); return (T)contentsList.set(realIndex, element); } }}EOF open OUT, ">$fileName" or die "Cannot open $fileName.\n$!\n"; print OUT $file; close OUT; } } closedir $dirHandle;}
puppetlabs50.png[Advertisement] Manage IT infrastructure as code across all environments with Puppet. Puppet Enterprise now offers more control and insight, with role-based access control, activity logging and all-new Puppet Apps. Start your free trial today! TheDailyWtf?d=yIl2AUoC8zAsd2dV4AiO2U
External Content
Source RSS or Atom Feed
Feed Location http://syndication.thedailywtf.com/TheDailyWtf
Feed Title The Daily WTF
Feed Link http://thedailywtf.com/
Reply 0 comments