#!/usr/bin/perl
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL NETMESH INC. BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
# OF THE POSSIBILITY OF SUCH DAMAGE.
#
# The use of this software is governed by a license agreement that
# is contained in the package that you downloaded.

package MyErrorHandler;

use strict;
use vars qw(@ISA);
@ISA = qw(XML::Xerces::PerlErrorHandler);

my $errorBuffer = undef;

sub warning {
    my $line = $_[1]->getLineNumber;
    my $column = $_[1]->getColumnNumber;
    my $message = $_[1]->getMessage;

    $errorBuffer .= "WARNING: Line $line, Column $column: $message\n";
}

sub error {
    my $line = $_[1]->getLineNumber;
    my $column = $_[1]->getColumnNumber;
    my $message = $_[1]->getMessage;

    $errorBuffer .= "ERROR: Line $line, Column $column: $message\n";
}

sub fatal_error {
    my $line = $_[1]->getLineNumber;
    my $column = $_[1]->getColumnNumber;
    my $message = $_[1]->getMessage;

    $errorBuffer .= "FATAL: Line $line, Column $column: $message\n";
}

sub getErrors {
   return $errorBuffer;
}

1;

#####

package main;

use strict;
use CGI;
use XML::Xerces;
use LWP::Simple;
use File::Temp;

my $q = new CGI();
my $url = $q->param( 'url' );

my $content = <<HTML;
<html>
 <head>
  <title>NetMesh script: Test validity of an XRDS document</title>
  <link rel="stylesheet" href="http://lid.netmesh.org/css/lid.css" type="text/css">
  <link rel="stylesheet" href="/css/netmesh.css" type="text/css">
 </head>
 <body>
  <h1>NetMesh script: Test validity of an XRDS document</h1>
HTML
if( $url ) {
$content .= <<HTML;
  <h2>Test result:</h2>
  <p>Document: <a href="$url">$url</a></p>
  <div style="border-width: 1px; border-style: solid; border-color: #808080; background: #e8e8e8; padding: 10px;">
HTML
my $error = performCheck( $url );
if( $error ) {
    $content .= "<pre class=\"error\">\n" . $error . "</pre>\n";
} else {
    $content .= "<p>No errors found.</p>\n";
}
$content .= <<HTML;
  </div>
HTML
}

$content .= <<HTML;
  <h2>New test:</h1>
  <form method="GET" action="">
   <p>Enter the URL to an XRDS document that you would like to check:</p>
   <input type="text" size="64" maxLength="256" name="url" value="$url">
   <input type="submit" value="Check!" name="submit">
  </form>
  <p>Go <a href="../">back</a></p>
 </body>
</html>
HTML
return( $content, 'text/html');

#####

sub performCheck {
    my $url = shift;

    my $errorHandler = MyErrorHandler->new;

    my $parser = XML::Xerces::XMLReaderFactory::createXMLReader();
    $parser->setErrorHandler( $errorHandler );

    my $contentHandler = new XML::Xerces::PerlContentHandler() ;
    $parser->setContentHandler($contentHandler) ;

    eval {
        $parser->setFeature("$XML::Xerces::XMLUni::fgSAX2CoreNameSpaces", 1 );
        $parser->setFeature("$XML::Xerces::XMLUni::fgSAX2CoreNameSpacePrefixes", 1 );
        $parser->setFeature("$XML::Xerces::XMLUni::fgSAX2CoreValidation", 1);
        $parser->setFeature("$XML::Xerces::XMLUni::fgXercesDynamic", 1);
        $parser->setFeature("$XML::Xerces::XMLUni::fgXercesSchema", 1 );
        $parser->setFeature("$XML::Xerces::XMLUni::fgXercesSchemaFullChecking", 1 );
        $parser->setFeature("$XML::Xerces::XMLUni::fgXercesValidationErrorAsFatal", 0 );
    };
    return $@ if $@;

    my $input = LWP::Simple::get( $url );
    return "Could not open URL $url." unless( $input );

    my( $inputFh, $inputFile ) = File::Temp::tempfile( UNLINK => 0 );
    print $inputFh $input;
    close( $inputFh );

    eval {
        my $is = XML::Xerces::LocalFileInputSource->new( $inputFile );
        $parser->parse($is) ;
    } ;
    unlink $inputFile;

    return $@ if $@;

    my $error = $errorHandler->getErrors();
    return $error if( $error );

    return undef;
}

####

