jpx2eclipse.pl
#!/usr/bin/perl
#
# Convert a JBuilder JPX file to an Eclipse .project
use warnings;
use strict;
use XML::Simple;
use Getopt::Long;
use Data::Dumper;
use File::Basename;
use File::Spec;
use Cwd 'abs_path';
our %OPTIONS = ();
GetOptions(\%OPTIONS, "help|?",
"dryrun|n");
die <<EOM if $OPTIONS{"help"} or not @ARGV;
jpx2eclipse [OPTIONS] <jpx>
~~~~~~~~~~~
Options:
--help, -h This message
--dryrun, -n Don\'t write modifications to disk
Please report bugs to <andrew\@bleb.org>. Thanks.
EOM
our $JPX = $ARGV[0] or die "no JPX specified.\n";
my $xml = XMLin($JPX) or die "unable to parse XML.\n";
chdir(dirname($JPX));
our $DEST = $xml->{property}->{WorkingDirectory}->{value} or die "unable to find destination dir.\n";
our $NAME = (fileparse($JPX,qr{\.jpx}))[0];
our $TOMCAT = ($xml->{property}->{'server.name'}->{value} || '') =~ /Tomcat/i;
#print Dumper($xml);
&writeProject($NAME, $TOMCAT);
&writeClasspath($xml);
&writeTomcat($xml) if $TOMCAT;
&writeAnt($xml);
exit;
# -----------------------------------------------------------------------
# Write the .project file
# -----------------------------------------------------------------------
sub writeProject {
my ($name, $tomcat) = @_;
if ($OPTIONS{dryrun}) {
*OUT = \*STDOUT;
warn "not writing $DEST/.project\n";
} else {
open(OUT, ">$DEST/.project") or die "Unable to open .project: $!\n";
}
print OUT <<EOM;
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>$NAME</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
EOM
print OUT " <nature>com.sysdeo.eclipse.tomcat.tomcatnature</nature>\n" if $tomcat;
print OUT " </natures>\n</projectDescription>\n";
if (!$OPTIONS{dryrun}) {
close(OUT) or die "Unable to close .project: $!\n";
}
}
# -----------------------------------------------------------------------
# Write the .tomcatPlugin file, if this is a J2EE app
# -----------------------------------------------------------------------
sub writeTomcat {
my ($data) = @_;
if ($OPTIONS{dryrun}) {
*OUT = \*STDOUT;
warn "not writing $DEST/.tomcatplugin\n";
} else {
open(OUT, ">$DEST/.tomcatplugin") or die "Unable to open .tomcatplugin: $!\n";
}
my $context;
foreach my $n (keys(%{ $xml->{node} })) {
if ($xml->{node}->{$n}->{type} eq 'WebModuleNode') {
$context = $n;
last;
}
}
$context ||= $NAME;
my $warloc = abs_path(dirname(File::Spec->canonpath( $JPX )));
$warloc =~ s!/cygdrive/(\w)/!$1:/!;
print OUT <<EOM;
<?xml version="1.0" encoding="UTF-8"?>
<tomcatProjectProperties>
<rootDir>/</rootDir>
<exportSource>false</exportSource>
<reloadable>true</reloadable>
<redirectLogger>false</redirectLogger>
<updateXml>true</updateXml>
<warLocation>$warloc/${context}.war</warLocation>
<extraInfo></extraInfo>
<webPath>/$context</webPath>
EOM
if (defined(@{ $data->{_libs} })) {
print OUT " <webClassPathEntries>\n";
foreach my $path (@{ $data->{_libs} }) {
print OUT " <webClassPathEntry>$path</webClassPathEntry>\n";
}
print OUT " </webClassPathEntries>\n";
}
print "</tomcatProjectProperties>\n";
$data->{_warloc} = "$warloc/${context}.war";
if (!$OPTIONS{dryrun}) {
close(OUT) or die "Unable to close .tomcatplugin: $!\n";
}
}
# -----------------------------------------------------------------------
# Write the .classpath file
# -----------------------------------------------------------------------
sub writeClasspath {
my ($data) = @_;
my $srcdir = $data->{property}->{SourcePath}->{value};
my $outdir = $data->{property}->{OutPath}->{value};
$srcdir =~ s/^$DEST//;
$outdir = "$srcdir/../$outdir" unless $outdir =~ s/^$DEST//;
$srcdir =~ s!^/!!;
$outdir =~ s!^/!!;
if ($OPTIONS{dryrun}) {
*OUT = \*STDOUT;
warn "not writing $DEST/.classpath\n";
} else {
open(OUT, ">$DEST/.classpath") or die "Unable to open .classpath: $!\n";
}
print OUT <<EOM;
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="$srcdir"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="$outdir"/>
EOM
print OUT <<EOT if $TOMCAT;
<classpathentry kind="var" path="TOMCAT_HOME/common/lib/servlet-api.jar"/>
<classpathentry kind="var" path="TOMCAT_HOME/common/lib/jasper-runtime.jar"/>
<classpathentry kind="var" path="TOMCAT_HOME/common/lib/jsp-api.jar"/>
EOT
my @libs = split(/;/, $data->{property}->{Libraries}->{value});
my %available = ( JUnit => ["var#JUNIT_HOME/junit.jar"] );
while (<*.library>) {
my $xml = XMLin($_, ForceArray => [ 'path' ]);
my $name = $xml->{fullname} || $_;
$name =~ s/[^\w\. ]+//;
next if $name =~ /Servlet/i or !defined($xml->{class}->{path});
my $required = $xml->{required} || '';
$required =~ s/[^\w ]+//;
push @libs, $required if $required;
my @e = ();
foreach my $p (@{ $xml->{class}->{path} }) {
push @e, "lib#$1" if $p =~ /^\[(.*)\]$/;
}
$available{$name} = \@e;
}
foreach my $l (@libs) {
next if $l =~ /Servlet/i;
unless ($available{$l}) {
warn "Unable to find library $l...\n";
next;
}
foreach my $e (@{ $available{$l} }) {
eval {
$e =~ s/^(.*?)#//;
my ($type, $path) = ($1, $e);
$path = abs_path($e) if $type eq 'lib';
$path =~ s!/cygdrive/(\w)/!$1:/!;
print OUT ' <classpathentry kind="'.$type.'" path="'.$path."\"/>\n";
push @{ $data->{_libs} }, $path if $type eq 'lib';
}; if ($@) {
warn $@;
}
}
}
print OUT "</classpath>\n";
if (!$OPTIONS{dryrun}) {
close(OUT) or die "Unable to close .classpath: $!\n";
}
}
# -----------------------------------------------------------------------
# Write the build.xml file if required
# -----------------------------------------------------------------------
sub writeAnt {
my ($data) = @_;
return unless $TOMCAT and $data->{_libs};
# -- Don't clobber the file if modified...
#
if (open(IN, "<$DEST/build.xml")) {
my $read = '';
while(<IN>) { $read .= $_; }
close(IN);
return unless $read =~ /<!-- Remove this line to prevent auto-clobbering -->/i;
}
# -- Create the output stream...
#
if ($OPTIONS{dryrun}) {
*OUT = \*STDOUT;
warn "not writing $DEST/build.xml\n";
} else {
open(OUT, ">$DEST/build.xml") or die "Unable to open build.xml: $!\n";
}
# -- Write the file...
#
my $date = localtime();
my $warloc = $data->{_warloc};
print OUT <<EOM;
<project name="$NAME">
<description>Ant build file for $NAME WAR file.
Auto-generated by jpx2eclipse on $date</description>
<!-- REMOVE THIS LINE TO PREVENT AUTO-CLOBBERING -->
<property name="pkg" location="WEB-INF"/>
<property name="dist" location="$warloc"/>
<defaultexcludes add="**/*.bak" echo="true"/>
<defaultexcludes add="**/*~"/>
<defaultexcludes add="**/.*"/>
<defaultexcludes add="**/.svn"/>
<defaultexcludes add="**/src/**"/>
<defaultexcludes add="**/work/**"/>
<!-- Build WAR file -->
<target name="package" description="Produce a WAR file suitable for deployment">
<war destfile="\${dist}" webxml="\${pkg}/web.xml">
<webinf dir="\${pkg}" excludes="**/web.xml"/>
<fileset dir="\${basedir}" excludes="**/WEB-INF/**"/>
EOM
foreach my $e (@{ $data->{_libs} }) {
my ($name, $dir, undef) = fileparse($e);
print OUT " <lib file=\"$e\"/>\n";#dir=\"$dir\" files=\"$name\"/>\n";
}
print OUT <<EOM;
</war>
</target>
</project>
EOM
if (!$OPTIONS{dryrun}) {
close(OUT) or die "Unable to close build.xml: $!\n";
}
}
Generated by GNU Enscript 1.6.5.90.