# # Copyright (c) 2002 Dr. Klemens Waldhör. All rights reserved. This program is free # software; you can redistribute it and/or modify it under the same terms # as Perl itself. package wktm::xindice; use Time::Local; use XML::DOM; use Frontier::Client; use strict; use vars qw(@EXPORT @ISA $VERSION); require Exporter; $VERSION = "1.1"; @ISA = qw(Exporter); @EXPORT = qw(); sub errorhandler { print "error !"; return; } my $DEBUGOUTPUT = *STDOUT; my $DEBUG = 0; # Function new # Description create an xindice XML RPC object # Parameter Type Comment # url string url to connect too # Returns object reference # Annotation: sub new { my $classname = shift; my $self = {}; bless($self, $classname); $self->{URL} = shift; # url $self->{DEBUG} = shift; $self->{XINDICEVERSION} = shift; # if 1 we use the old calls otherwise the new calls $self->{ENCODING} = shift; # "UTF-8"; if ($self->{ENCODING} eq "") { $self->{ENCODING} = "UTF-8"; } $self->{COLLECTION} = "/db"; my $server = Frontier::Client->new( 'url' => $self->{URL} , 'encoding' => $self->{ENCODING}, 'debug' => $self->{DEBUG}); $self->{SERVER} = $server; $self->{ERROR} = 0; $self->{ERRORMSG} = ""; $self->{RECURSIVE} = 0; $self->{LASTCOMMAND} = 0; $self->{DBNAME} = '/db'; return $self; } sub returnServer { my $self = shift; return $self->{SERVER}; } # Function setRecursive # Description sets the that collections should be handled recursively # Parameter Type Comment # Returns list with collections # Annotation: sub setRecursive { my $self = shift; $self->{RECURSIVE} = 1; return $self->{RECURSIVE}; } # Function setNotRecursive # Description sets the that collections should not be handled recursively # Parameter Type Comment # Returns list with collections # Annotation: sub setNotRecursive { my $self = shift; $self->{RECURSIVE} = 0; return $self->{RECURSIVE}; } # Function setCollection # Description sets the default collection to be used # Parameter Type Comment # Returns list with collections # Annotation: sub setCollection { my $self = shift; return eval { $self->{COLLECTION} = shift; return $self->{COLLECTION}; }; } # Function runCommand # Description runs a specific XML RPC command # Parameter Type Comment # Returns result of command # Annotation: sub runCommand { my $self = shift; my $method= shift; my @args = @_; my $result; return eval { $result = $self->{SERVER}->call($method, @args); }; } # New methods for XINDICE running under TOMCAT # calling the rpc stuff # my $args = {}; # $args->{'message'} = 'ListCollections'; # $args->{'name'} = 'dv-test'; # $args->{'collection'} = '/db'; # $result = $server->call('run',$args); # Function listCollections # Description list xindice collections # Parameter Type Comment # Returns list with collections # Annotation: sub listCollections { my $self = shift; my $collection = shift; my $result; if ($collection eq "") { $collection = $self->{COLLECTION}; } if ($self->{XINDICEVERSION} == 1) { my $method = "db.listCollections"; $self->{LASTCOMMAND} = $method; my @args = ($collection); $result = eval { $result = $self->{SERVER}->call($method, @args); }; $self->{'result'} = $result; } else { # h.put("message", "ListCollections"); # h.put("collection", "/db"); my $args = {}; $args->{'message'} = 'ListCollections'; $args->{'name'} = $collection; $args->{'collection'} = $collection; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } } return $result; } # Function listAllCollections # Description list xindice collections including the sub collections # Parameter Type Comment # Returns list with all sub-collections # Annotation: my @allcollections = (); my $recounter = 0; sub listAllCollectionsRec { my $self = shift; my $collection = shift; $recounter++; my $result = $self->listCollections($collection); if (defined $result) { my @result = @$result; if (scalar @result == 0) { return; } foreach my $elem (@result) { my @resultnew = $self->listAllCollectionsRec("$collection/$elem"); push @allcollections, "$collection/$elem"; } } return; } sub listAllCollections { my $self = shift; my $collection = $self->{COLLECTION}; $recounter = 0; @allcollections = (); my @result = $self->listAllCollectionsRec($collection); $self->{LASTCOMMAND} = "listAllCollections"; return \@allcollections; } # Function listIndexers # Description list xindice indexers # Parameter Type Comment # Returns list with indexers # Annotation: sub listIndexers { my $self = shift; my $collection = shift; if ($collection eq "") { $collection = $self->{COLLECTION}; } my $result; if ($collection eq "") { $collection = $self->{COLLECTION}; } if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.listIndexers'; my @args = ($collection); $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; } } else { # h.put("message", "ListIndexers"); # h.put("collection", "/db"); my $args = {}; $args->{'message'} = 'ListIndexers'; $args->{'name'} = $collection; $args->{'collection'} = $collection; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } } return $result; } # Function listAllIndexers # Description list all xindice indexers # Parameter Type Comment # Returns list with indexers # Annotation: sub listAllIndexers { my $self = shift; my $collection = $self->{COLLECTION}; my @allindexers = (); $recounter = 0; my $result = $self->listAllCollections; if (scalar @$result > 0) { foreach my $elem (@$result) { my $indresult = $self->listIndexers($elem); if (defined $indresult && ref $indresult) { push @allindexers, @$indresult; } } } $self->{LASTCOMMAND} = "listAllIndexers"; return \@allindexers; } # Function listDocuments # Description list xindice documents # Parameter Type Comment # Returns list with documents # Annotation: sub listDocuments { my $self = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.listDocuments'; my @args = ($self->{COLLECTION}); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # h.put("message", "ListDocuments"); # h.put("collection", "/db"); my $args = {}; my $result; $args->{'message'} = 'ListDocuments'; $args->{'name'} = $self->{COLLECTION}; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function getDocumentCount # Description get document count for collection # Parameter Type Comment # Returns list with documents # Annotation: sub getDocumentCount { my $self = shift; my $id = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.getDocumentCount'; my @args = ($self->{COLLECTION}); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # h.put("message", "GetDocumentCount"); # h.put("collection", "/db"); my $args = {}; my $result; $args->{'message'} = 'GetDocumentCount'; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function getDocument # Description gets a specific document # Parameter Type Comment # Returns document as string # Annotation: sub getDocument { my $self = shift; my $id = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.getDocument'; my @args = ($self->{COLLECTION}, $id); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # h.put("message", "GetDocument"); # h.put("name", "testdoc"); # h.put("collection", "/db"); my $args = {}; my $result; $args->{'message'} = 'GetDocument'; $args->{'name'} = $id; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function getDocuments # Description gets all documents of a collection # Parameter Type Comment # Returns document list # Annotation: sub getDocuments { my $self = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $id = shift; my $method= 'db.getDocuments'; my @args = ($self->{COLLECTION}); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { return 0; # now support for this ??? } } # Function insertDocument # Description inserts a document into XINDICE collection # Parameter Type Comment # Returns document as string # Annotation: sub insertDocument { my $self = shift; my $id = shift; my $content = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.insertDocument'; my @args = ($self->{COLLECTION}, $id, $content); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # h.put("message", "InsertDocument"); # h.put("name", "testdoc"); # h.put("collection", "/db"); # h.put("document", " PUT FULL DOCUMENT AS A STRING HERE"); my $args = {}; my $result; $args->{'message'} = 'InsertDocument'; $args->{'name'} = $id; $args->{'collection'} = $self->{COLLECTION}; $args->{'document'} = $content; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function insertFile # Description inserts a file into XINDICE collection # Parameter Type Comment # Returns document as string # Annotation: sub insertFile { my $self = shift; my $id = shift; my $filename = shift; my $content = ""; open INP, $filename or return ""; my @content = ; close INP; for my $elem (@content) { $content = $content . $elem; } $content =~ s///; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.insertDocument'; my @args = ($self->{COLLECTION}, $id, $content); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { return $self->insertDocument($id, $content); } } # Function setDocument # Description sets a document into XINDICE collection # Parameter Type Comment # Returns document as string # Annotation: sub setDocument { my $self = shift; my $id = shift; my $content = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.setDocument'; my @args = ($self->{COLLECTION}, $id, $content); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # h.put("message", "SetDocument"); # h.put("name", "testdoc"); # h.put("collection", "/db"); # h.put("document", " PUT FULL DOCUMENT AS A STRING HERE"); my $args = {}; my $result; $args->{'message'} = 'InsertDocument'; $args->{'name'} = $id; $args->{'collection'} = $self->{COLLECTION}; $args->{'document'} = $content; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function removeDocument # Description removes a document into XINDICE collection # Parameter Type Comment # Returns document as string # Annotation: sub removeDocument { my $self = shift; my $id = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.removeDocument'; my @args = ($self->{COLLECTION}, $id); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # h.put("message", "RemoveDocument"); # h.put("name", "test"); # h.put("collection", "/db"); my $args = {}; my $result; $args->{'message'} = 'RemoveDocument'; $args->{'name'} = $id; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function createCollection # Description creates a new collection # Parameter Type Comment # Returns int # Annotation: sub createCollection { my $self = shift; my $collectionname = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.createCollection'; my @args = ($self->{COLLECTION}, $collectionname); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # h.put("message", "CreateCollection"); # h.put("name", "test"); # h.put("collection", "/db"); my $args = {}; my $result; $args->{'message'} = 'CreateCollection'; $args->{'name'} = $collectionname; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function dropCollection # Description drop a collection # Parameter Type Comment # Returns int # Annotation: sub dropCollection { my $self = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.dropCollection'; my @args = ($self->{COLLECTION}); # print "Run $method\n"; my $result = $self->{SERVER}->call($method, @args); # print "After Run $method - $result\n"; $self->{COLLECTION} = ""; $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # RemoveCollection( collection, name ) # now we must determine the name of the last collection ... my $collection = $self->{COLLECTION}; if ($collection =~ /(.*)\/(.*$)/) # use greedy matching here !!! { my $args = {}; my $result; my $collectiontodelete = $2; $self->{COLLECTION} = $1; $args->{'message'} = 'RemoveCollection'; $args->{'name'} = $collectiontodelete; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } else { return 0; } } } # Function createIndexer # Description creates a new indexer # Parameter Type Comment # Returns int # Annotation: sub createIndexer { my $self = shift; my $indexname = shift; my $pattern = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.createIndexer'; my @args = ($self->{COLLECTION}, $indexname, $pattern); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # CreateIndexer( collection, configuration|name) my $args = {}; my $result; $args->{'message'} = 'CreateIndexer'; $args->{'name'} = $indexname; $args->{'collection'} = $self->{COLLECTION}; $args->{'pattern'} = $pattern; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function dropIndexer # Description creates a new OID # Parameter Type Comment # Returns int # Annotation: sub dropIndexer { my $self = shift; my $indexname = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.dropIndexer'; my @args = ($self->{COLLECTION}, $indexname); my $result = $self->{SERVER}->call($method, @args); $self->{LASTCOMMAND} = $method; $self->{'result'} = $result; return $result; }; } else { # RemoveIndexer( collection, name ) my $args = {}; my $result; $args->{'message'} = 'RemoveIndexer'; $args->{'name'} = $indexname; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } return $result; } } # Function createNewOID # Description creates a new OID # Parameter Type Comment # Returns string with OID # Annotation: sub createNewOID { my $self = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.createNewOID'; my @args = ($self->{COLLECTION}); my $result = $self->{SERVER}->call($method, @args); $self->{'result'} = $result; $self->{LASTCOMMAND} = $method; return $result; }; } else { # CreateNewOID( collection ) my $args = {}; my $result; $args->{'message'} = 'CreateNewOID'; $args->{'collection'} = $self->{COLLECTION}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } } } # Function queryCollection # Description queries a collection # Parameter Type Comment # Returns string # Annotation: sub queryCollection { my $self = shift; my $query = shift; my $type = "XPath"; if ($self->{XINDICEVERSION} == 1) { return eval { my $method= 'db.queryCollection'; my %hash = (); my @args = ($self->{COLLECTION}, $type, $query, {X => "http://www.xmldb.org/xpath"}); my $result = $self->{SERVER}->call($method, @args); $self->{'result'} = $result; $self->{LASTCOMMAND} = $method; return $result; }; } else { # Query( collection, type, query, [name] ) my $args = {}; my $result; $args->{'message'} = 'Query'; $args->{'collection'} = $self->{COLLECTION}; $args->{'type'} = $type; $args->{'query'} = $query; $args->{'namespaces'} = {}; $result = eval { $self->{SERVER}->call('run',$args); }; $self->{'result'} = $result; if (ref $result) { $result = ${$result}{'result'}; } } } # Function queryAllCollections # Description queries all collection including sub-collections # Parameter Type Comment # Returns list of matches # Annotation: sub queryAllCollections { my $self = shift; my $query = shift; my $currentcollection = $self->{COLLECTION}; my @result = (); my $list = $self->listAllCollections; if (scalar @$list != 0) { foreach my $elem (@$list) { $self->{COLLECTION} = $elem; push @result, $self->queryCollection($query); } } $self->{LASTCOMMAND} = "queryAllCollections"; $self->{COLLECTION} = $currentcollection; return \@result; } # Function queryDocument # Description queries a collection # Parameter Type Comment # Returns string # Annotation: sub queryDocument { my $self = shift; if ($self->{XINDICEVERSION} == 1) { return eval { my $query = shift; my $id = shift; my $method= 'db.queryDocument'; my $type = "XPath"; my %hash = (); my @args = ($self->{COLLECTION}, $type, $query, %hash, $id); my $result = $self->{SERVER}->call($method, @args); $self->{'result'} = $result; $self->{LASTCOMMAND} = $method; return $result; }; } else { my $args = {}; $args->{collection} = $self->{COLLECTION}; $args->{name} = shift; $args->{type} = shift; $args->{query} = shift; $args->{namespaces} = {}; $args->{message} = "Query"; return $self->run($args)->{result}; } } # Function storeNonXMLDocuments # Description stores non xml documents using CDATA # Parameter Type Comment # Returns string # Annotation: my $exchange = "%%%%%%%%&&&&&"; sub storeNonXMLDocuments { my $self = shift; return eval { my $uniqueid = shift; my $content = shift; my $method= 'storeNonXMLDocuments'; $content =~ s/]]>/$exchange/gm; $content = ""; my $result = $self->insertDocument($uniqueid, $content); $self->{'result'} = $result; $self->{LASTCOMMAND} = $method; return $result; }; } # Function storeNonXMLDocuments # Description stores non xml documents using CDATA # Parameter Type Comment # Returns string # Annotation: sub storeNonXMLFile { my $self = shift; return eval { my $uniqueid = shift; my $filename = shift; my $content = ""; open INP, $filename or return "File does not exist"; my @content = ; close INP; for my $elem (@content) { $elem =~ s/]]>/$exchange/gm; $content = $content . $elem; } $content = "\n\n"; my $method= 'storeNonXMLDocuments'; my $result = $self->insertDocument($uniqueid, $content); $self->{LASTCOMMAND} = $method; return $result; }; } # Function getNonXMLDocuments # Description gets non xml documents using CDATA # Parameter Type Comment # Returns string # Annotation: sub getNonXMLDocuments { my $self = shift; return eval { my $uniqueid = shift; my $method= 'getNonXMLDocuments'; my $content = $self->getDocument($uniqueid); $content =~ s/$exchange/]]>/gm; $content =~ s///; $content =~ s/<\/nonxml>//; $content =~ s/<\?xml version=\"1.0\"\?>//; $self->{LASTCOMMAND} = $method; return $content; }; } # Function updateIndexer # Description updates an Indexer (only for 1.1) # Parameter Type Comment # Returns string # Annotation: sub updateIndexer { my $args = {}; my $self = shift; $args->{collection} = $self->{COLLECTION}; $args->{message} = "UpdateIndexer"; return eval { $self->run($args)->{result}; }; } # Function shutdown # Description shutsdown the xindice server # Parameter Type Comment # Returns string # Annotation: sub shutdown { my $args = {}; my $self = shift; $args->{message} = "Shutdown"; return eval { $self->run($args)->{result}; }; } # Function getApiVersion # Description gets the api version # Parameter Type Comment # Returns string # Annotation: sub getApiVersion { my $args = {}; my $self = shift; $args->{message} = "GetApiVersion"; return eval { $self->run($args)->{result}; }; } # Function getIndexerConfiguration # Description gets the Indexer Configuration # Parameter Type Comment # Returns string # Annotation: sub getIndexerConfiguration { my $args = {}; my $self = shift; $args->{collection} = shift; $args->{message} = "GetIndexerConfiguration"; return eval { $self->run($args)->{result}; }; } # Function getServerVersion # Description gets the server version # Parameter Type Comment # Returns string # Annotation: sub getServerVersion { my $args = {}; my $self = shift; $args->{message} = "GetServerVersion"; return eval { $self->run($args)->{result}; } } # Function run # Description run a message # Parameter Type Comment # Returns string # Annotation: sub run { my $self = shift; my $args = shift; return $self->call('run', $args); } 1;