#Copyright Massachusetts Institute of technology, I.N.R.I.A., 2000-2001, 
#Written by Eric Prud'hommeaux  and Dominique Hazael-Massieux for the World Wide Web Consortium

# Overload of W3C::Rnodes::UnixPermAgent to handle ,v files.

use strict;
require Exporter;
#require AutoLoader;

package W3C::Rnodes::CvsLogAgent;
use W3C::Util::Exception;
use W3C::Rnodes::UnixPermAgent;
use W3C::Rnodes::ACL qw(&buildDBRuleId
			$ACCESS_CHACL
                        $ACCESS_RACL);

use vars qw($REVISION $VERSION $DSLI @ISA @EXPORT @EXPORT_OK);
$REVISION = '$Id: CvsLogAgent.pm,v 1.9 2005/03/17 05:56:53 eric Exp $ ';
@ISA = qw(W3C::Rnodes::UnixPermAgent Exporter); # AutoLoader);
@EXPORT = qw();
@EXPORT_OK = qw();
$VERSION = 0.10;
$DSLI = 'adpO';

#####
# getAclsFor - creates new entry for resource, acls set according to file permissions
#
# return (new id, redirection location)

sub _mapToLocalFile {
    my ($self, $singleResource, $isDir) = @_;
    if (!$isDir) {
	if (!($singleResource =~ s/\Z/\,v/)) {
	    &throw(new W3C::Util::Exception(-message => "Could not execute CVS ,v file to uri map \"s/\\Z/\\,v/\""));
	}
    }
    return CGI::unescape($singleResource);
}

sub _mapFromLocalFile {
    my ($self, $singleResource, $isDir) = @_;
    if (!$isDir) {
	if (!($singleResource =~ s/\%2Cv\Z//)) {
	    &throw(new W3C::Util::Exception(-message => "Could not execute CVS ,v file to uri map \"s/\\%2Cv\\Z//\" on \"$singleResource\""));
	}
    }
    return $singleResource;
}

sub _getFileSystemRulesFor {
    my ($self, $aclDB, $mapped, $resource, $isDir) = @_;
    my $count = 0;
    if ($isDir) { # 'cause the afs probing may go away.
	$count = $self->SUPER::_getFileSystemRulesFor($aclDB, $mapped, $resource, $isDir);
    } else {
        my $webId = $self->_getAuthorsNameFromLog($mapped,$resource) ;
        if ($webId) {
            my $access = $ACCESS_CHACL | $ACCESS_RACL ;
            $aclDB->addDBRule($resource, &buildDBRuleId('U', $webId), $access, {'source'=> $self->{-sourceID}});
            $count++ ;
        }
    }
    return $count;
}

sub _getAuthorsNameFromLog {
    my ($self,$mapped,$resource) = @_ ;
    if (!open(CVSLOG,$mapped)) {
	&throw(new W3C::Util::NoSuchFileException(-file => $mapped, -resource => $resource));
    }
    my $line;
    while ($line=<CVSLOG>) {
        if ($line eq "1.1\n") {
            my $line = <CVSLOG>;
	    if (!$line) {
		&throw(new W3C::Rnodes::Util::Exception(-message => "CVS log file trunkated or in a bad format"));
	    }

	    # line looks like this:
	    # date	2002.01.17.12.47.18;	author sfarrell;	state Exp;
	    if ($line =~ m/author ([^\;]+)\;/) {
		my $author = $1;
                close CVSLOG;
                return $author;
            }
        }
    }
    close CVSLOG;
}

1;

__END__

=head1 NAME

W3C::Rnodes::CvsLogAgent - ACLImporter for W3C::Rnodes

=head1 SYNOPSIS

    use W3C::Rnodes::CvsLogAgent;
    my $cvsAgent = new W3C::Rnodes::CvsLogAgent(-properties => $self->{PROPERTIES}, 
						 -sourceID => $SOURCE_CVS, 
						 -getFilepathMaps => sub {
						     $self->_getCVSFilepathMaps(@_)}, 
						 -getFilesystemIdsAndTypes => sub {
						     $self->_getFilesystemIdsAndTypes(@_)});
    $self->{ACL_IMPORTERS} = [$cvsAgent];

=head1 DESCRIPTION

W3C::Rnodex::CvsLogAgent is an ACLImporter for reading ACLs from the identity of the first editor of a resource in a CVS repository through the CVS log.

This module is part of the W3C::Rnodes CPAN module.

=head1 FUTURE PLANS

Maybe some day, if i've got nothing else to do, work on a pserver version.

=head1 AUTHOR

Dominique Hazael-Massieux <dom@w3.org>

=head1 SEE ALSO

W3C::Rnodes::ACL(3) perl(1).

=cut
