File Coverage

blib/lib/Alvis/NLPPlatform.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3              
4              
5             package Alvis::NLPPlatform;
6              
7              
8             our $VERSION='0.6';
9              
10              
11 3     3   66564 use strict;
  3         7  
  3         102  
12 3     3   16 use warnings;
  3         4  
  3         84  
13              
14 3     3   1412 use Alvis::NLPPlatform::XMLEntities;
  3         6  
  3         96  
15 3     3   1615 use Alvis::NLPPlatform::Canonical;
  3         5  
  3         109  
16 3     3   2033 use Alvis::NLPPlatform::Annotation;
  0            
  0            
17             use Alvis::NLPPlatform::UserNLPWrappers;
18             use Time::HiRes qw(gettimeofday tv_interval);
19             use IO::Socket;
20             use Sys::Hostname;
21             use XML::LibXML;
22             use IO::Socket;
23             use IO::Socket::INET;
24             use Fcntl qw(:DEFAULT :flock :seek);
25             use Alvis::Pipeline;
26             use File::Path qw(mkpath);
27             use File::Touch;
28              
29             #use Data::Dumper;
30              
31             my $cur_doc_nb;
32             my $done_parsing;
33              
34             our $last_doc;
35              
36             our @tab_end_sections_byaddr;
37             our @tab_end_sections_bytoken;
38             our %hash_tokens;
39             our %hash_words;
40             our %hash_words_punct;
41             #our %hash_words_punct2words;
42             our %hash_sentences;
43             our %hash_postags;
44             our %hash_named_entities;
45             our %hash_lemmas;
46              
47             our $number_of_words;
48             our $number_of_sentences;
49             our $nb_relations;
50             our $dont_annotate;
51              
52             our @word_start;
53             our @word_end;
54              
55             our @en_start;
56             our @en_end;
57             our @en_type;
58              
59             our @en_tokens_start;
60             our @en_tokens_end;
61             our %en_tokens_hash;
62              
63             our $last_semantic_unit;
64             our $last_semantic_feature;
65              
66             our %last_words;
67             our @found_terms;
68             our @found_terms_tidx;
69             our @found_terms_smidx;
70             our @found_terms_phr;
71             our @found_terms_words;
72              
73             my $phrase_idx;
74              
75             my $id;
76              
77             # Timer
78              
79             my $timer_mem;
80              
81             # because those variables have to be viewed in the sigint handler !!!
82             my $nlp_host;
83             my $nlp_port;
84             my $connection_retry;
85              
86             # ENVIRONMENT VARIABLES
87             my $NLPTOOLS;
88             my $ALVISTMP;
89             our $ALVISLOGFILE;
90             my $HOSTNAME;
91             my $TMPFILE;
92             my $ALVISRSC;
93              
94             our $ALVISDEBUG = 0;
95              
96             my $ENABLE_TOKEN;
97             my $ENABLE_NER;
98             my $ENABLE_WORD;
99             my $ENABLE_SENTENCE;
100             my $ENABLE_POS;
101             my $ENABLE_LEMMA;
102             my $ENABLE_TERM_TAG;
103             my $ENABLE_SYNTAX;
104             my $ENABLE_SEMANTIC_TAG;
105              
106             # Dependencies mask
107             my $MASK_TOKEN=1;
108             my $MASK_NER=2;
109             my $MASK_WORD=4;
110             my $MASK_SENTENCE=8;
111             my $MASK_POS=16;
112             my $MASK_LEMMA=32;
113             my $MASK_TERM_TAG=64;
114             my $MASK_SYNTAX=128;
115             my $MASK_SEMANTIC_TAG=256;
116              
117             # LOG MANAGEMENT
118             our @tab_errors;
119             my $log_entry;
120              
121             # BENCHMARKING
122             my $time_load = 0;
123             my $time_tok = 0;
124             my $time_ne = 0;
125             my $time_word = 0;
126             my $time_sent = 0;
127             my $time_pos = 0;
128             my $time_lemm = 0;
129             my $time_term = 0;
130             my $time_synt = 0;
131             my $time_semtag = 0;
132             my $time_render = 0;
133             my $time_total = 0;
134              
135              
136              
137              
138             sub compute_dependencies{
139             my $h_config = $_[0];
140             my $val=0;
141             if($h_config->{'linguistic_annotation'}->{'ENABLE_TOKEN'}){
142             $val|=1;
143             }
144             if($h_config->{'linguistic_annotation'}->{'ENABLE_NER'}){
145             $val|=3;
146             }
147             if($h_config->{'linguistic_annotation'}->{'ENABLE_WORD'}){
148             $val|=5;
149             }
150             if($h_config->{'linguistic_annotation'}->{'ENABLE_SENTENCE'}){
151             $val|=13;
152             }
153             if($h_config->{'linguistic_annotation'}->{'ENABLE_POS'}){
154             $val|=29;
155             }
156             if($h_config->{'linguistic_annotation'}->{'ENABLE_LEMMA'}){
157             $val|=61;
158             }
159             if($h_config->{'linguistic_annotation'}->{'ENABLE_TERM_TAG'}){
160             $val|=77;
161             }
162             if($h_config->{'linguistic_annotation'}->{'ENABLE_SYNTAX'}){
163             $val|=157;
164             }
165              
166             if($h_config->{'linguistic_annotation'}->{'ENABLE_SEMANTIC_TAG'}){
167             $val|=511;
168             }
169              
170             print STDERR "Dependency mask: $val\n";
171              
172             if($val&$MASK_TOKEN){$ENABLE_TOKEN=1;}else{$ENABLE_TOKEN=0;}
173             if($val&$MASK_NER){$ENABLE_NER=1;}else{$ENABLE_NER=0;}
174             if($val&$MASK_WORD){$ENABLE_WORD=1;}else{$ENABLE_WORD=0;}
175             if($val&$MASK_SENTENCE){$ENABLE_SENTENCE=1;}else{$ENABLE_SENTENCE=0;}
176             if($val&$MASK_POS){$ENABLE_POS=1;}else{$ENABLE_POS=0;}
177             if($val&$MASK_LEMMA){$ENABLE_LEMMA=1;}else{$ENABLE_LEMMA=0;}
178             if($val&$MASK_TERM_TAG){$ENABLE_TERM_TAG=1;}else{$ENABLE_TERM_TAG=0;}
179             if($val&$MASK_SYNTAX){$ENABLE_SYNTAX=1;}else{$ENABLE_SYNTAX=0;}
180             if($val&$MASK_SEMANTIC_TAG){$ENABLE_SEMANTIC_TAG=1;}else{$ENABLE_SEMANTIC_TAG=0;}
181              
182             print STDERR "TOKENS: "; if($ENABLE_TOKEN){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
183             print STDERR "NER: "; if($ENABLE_NER){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
184             print STDERR "WORDS: "; if($ENABLE_WORD){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
185             print STDERR "SENTENCES: "; if($ENABLE_SENTENCE){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
186             print STDERR "POS: "; if($ENABLE_POS){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
187             print STDERR "LEMMA: "; if($ENABLE_LEMMA){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
188             print STDERR "TERM_TAGGING: "; if($ENABLE_TERM_TAG){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
189             print STDERR "SYNTAX: "; if($ENABLE_SYNTAX){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
190             print STDERR "SEMANTIC TAGGING: "; if($ENABLE_SEMANTIC_TAG){print STDERR "Enabled\n";}else{print STDERR "Disabled\n";}
191             return;
192             }
193              
194              
195             ###########################################################################
196              
197             sub starttimer(){
198             my $sec;
199             my $usec;
200             ($sec,$usec)=gettimeofday();
201             $usec/=1000000;
202             $timer_mem=($sec+$usec);
203             }
204              
205              
206              
207             sub endtimer(){
208             my $sec;
209             my $usec;
210             ($sec,$usec)=gettimeofday();
211             $usec/=1000000;
212             return (($sec+$usec)-$timer_mem);
213             }
214              
215              
216              
217             sub linguistic_annotation {
218             my $h_config = $_[0];
219             my $doc_hash = $_[1];
220              
221             my $nb_max_tokens = 0;
222              
223             $Alvis::NLPPlatform::Annotation::phrase_idx = 1;
224             $Alvis::NLPPlatform::Annotation::syntactic_relation_idx = 1;
225              
226             print STDERR "Working Language: " . $Alvis::NLPPlatform::Annotation::ALVISLANGUAGE . "\n";
227              
228             starttimer();
229             if ($ENABLE_TOKEN) {
230            
231             # Tokenize
232             Alvis::NLPPlatform::UserNLPWrappers->tokenize($h_config,$doc_hash);
233             # print STDERR $Alvis::NLPPlatform::Annotation::nb_max_tokens. "\n";
234             $time_tok+=endtimer();
235             print STDERR "\tTokenization Time : $time_tok\n";
236             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Tokenization Time : $time_tok";
237            
238             if ($Alvis::NLPPlatform::Annotation::nb_max_tokens >0) {
239             # Scan for NE
240             if($ENABLE_NER==1){
241             starttimer();
242             Alvis::NLPPlatform::UserNLPWrappers->scan_ne($h_config, $doc_hash);
243             $time_ne+=endtimer();
244             print STDERR "\tNamed Entity Recognition Time : $time_ne\n";
245             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Named Entity Recognition Time : $time_ne";
246             }
247              
248             # Word segmentation
249             if($ENABLE_WORD==1){
250             starttimer();
251             Alvis::NLPPlatform::UserNLPWrappers->word_segmentation($h_config, $doc_hash);
252             $time_word+=endtimer();
253             print STDERR "\tWord Segmentation Time : $time_word\n";
254             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Word Segmentation Time : $time_word";
255             }
256              
257             if($dont_annotate==1){
258             print STDERR "Skipped document\n";
259             undef %$doc_hash;
260             %$doc_hash=();
261             $doc_hash=0;
262             push @tab_errors,"SKIPPED DOCUMENT\n";
263             push @tab_errors,"URL: ".$Alvis::NLPPlatform::Annotation::documenturl."\n";
264             push @tab_errors,"Language tag: ".$Alvis::NLPPlatform::Annotation::ALVISLANGUAGE."\n";
265             push @tab_errors,"Temporary files can be found with the following prefix: $TMPFILE\n";
266             }
267              
268             # Sentence segmentation
269             if($ENABLE_SENTENCE==1){
270             starttimer();
271             if(!$dont_annotate){Alvis::NLPPlatform::UserNLPWrappers->sentence_segmentation($h_config, $doc_hash)};
272             $time_sent+=endtimer();
273             print STDERR "\tSentence Segmentation Time : $time_sent\n";
274             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Sentence Segmentation Time : $time_sent";
275             }
276              
277             # PoS tagging / Lemmatization
278             if($ENABLE_POS==1){
279             starttimer();
280             if(!$dont_annotate){Alvis::NLPPlatform::UserNLPWrappers->pos_tag($h_config, $doc_hash)};
281             $time_pos+=endtimer();
282             print STDERR "\tPart of Speech Tagging Time : $time_pos\n";
283             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Part of Speech Tagging Time : $time_pos";
284             }
285              
286             # Term tagging
287             if($ENABLE_TERM_TAG==1){
288             starttimer();
289             if(!$dont_annotate){Alvis::NLPPlatform::UserNLPWrappers->term_tag($h_config, $doc_hash)};
290             $time_term+=endtimer();
291             print STDERR "\tTerm Tagging Time : $time_term\n";
292             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Term Tagging Time : $time_term";
293             }
294              
295             # Syntactic parsing
296             if($ENABLE_SYNTAX==1){
297             starttimer();
298             if(!$dont_annotate){Alvis::NLPPlatform::UserNLPWrappers->syntactic_parsing($h_config, $doc_hash)};
299             $time_synt+=endtimer();
300             print STDERR "\tSyntactic Parsing Time : $time_synt\n";
301             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Syntactic Parsing Time : $time_synt";
302             }
303              
304             # Semantic tagging
305             if($ENABLE_SEMANTIC_TAG==1){
306             starttimer();
307             if(!$dont_annotate){Alvis::NLPPlatform::UserNLPWrappers->semantic_feature_tagging($h_config, $doc_hash)};
308             $time_semtag+=endtimer();
309             print STDERR "\tSemantic Feature Tagging Time : $time_semtag\n";
310             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "Semantic Feature Tagging Time : $time_semtag";
311             }
312              
313             }
314             }
315             }
316              
317              
318             ###########################################################################
319             ###########################################################################
320              
321             sub platform_reset {
322             # %$doc_hash = ();
323             @Alvis::NLPPlatform::tab_end_sections_byaddr = ();
324             @Alvis::NLPPlatform::tab_end_sections_bytoken = ();
325             %Alvis::NLPPlatform::hash_tokens = ();
326             %Alvis::NLPPlatform::hash_words = ();
327             %Alvis::NLPPlatform::hash_words_punct = ();
328             %Alvis::NLPPlatform::hash_sentences = ();
329             %Alvis::NLPPlatform::hash_postags = ();
330             %Alvis::NLPPlatform::hash_named_entities = ();
331             %Alvis::NLPPlatform::hash_lemmas = ();
332            
333             $Alvis::NLPPlatform::number_of_words = 0;
334             $Alvis::NLPPlatform::number_of_sentences = 0;
335             $Alvis::NLPPlatform::nb_relations = 0;
336             $Alvis::NLPPlatform::dont_annotate = 0;
337            
338             @Alvis::NLPPlatform::word_start = ();
339             @Alvis::NLPPlatform::word_end = ();
340            
341             @Alvis::NLPPlatform::en_start = ();
342             @Alvis::NLPPlatform::en_end = ();
343             @Alvis::NLPPlatform::en_type = ();
344            
345             @Alvis::NLPPlatform::en_tokens_start = ();
346             @Alvis::NLPPlatform::en_tokens_end = ();
347             %Alvis::NLPPlatform::en_tokens_hash = ();
348              
349             $Alvis::NLPPlatform::last_semantic_unit = 0;
350             $Alvis::NLPPlatform::last_semantic_feature = 0;
351              
352             %Alvis::NLPPlatform::last_words = ();
353             @Alvis::NLPPlatform::found_terms = ();
354             @Alvis::NLPPlatform::found_terms_tidx = ();
355             @Alvis::NLPPlatform::found_terms_smidx = ();
356             @Alvis::NLPPlatform::found_terms_phr = ();
357             @Alvis::NLPPlatform::found_terms_words = ();
358              
359             $Alvis::NLPPlatform::phrase_idx = 1;
360              
361             return(0);
362             }
363              
364              
365             ###########################################################################
366             ###########################################################################
367             ###########################################################################
368              
369             sub standalone {
370             my $config = shift;
371             my $HOSTNAME = shift;
372             my $doc = shift;
373              
374             # print STDERR "$ref_doc\n";
375             # my $tab_docs_xml = shift;
376             # my $doc_num = shift;
377              
378             my $i;
379             my @cur_doc;
380             my $j;
381             my $tmpfile;
382             my $render_time;
383              
384             my @records;
385             my $rec;
386             my $docR;
387             my $id;
388              
389             my @doc_collection_out;
390              
391              
392             $tmpfile = $config->{'ALVISTMP'} . "/$HOSTNAME.$$.outfile";
393              
394             # print STDERR $doc;
395              
396             @records=&split_to_docRecs($doc);
397              
398             $Alvis::NLPPlatform::last_doc = 0;
399              
400             unlink $config->{'ALVISTMP'} . "/$HOSTNAME.$$.corpus.yatea.tmp";
401              
402             for($i=0;$i
403             if ($i == $#records) {
404             $Alvis::NLPPlatform::last_doc = 1;
405             }
406             $rec = $records[$i];
407             ($id,$docR)=@$rec;
408             warn "Process document $id\n";
409              
410             open FILETMP_OUT, ">$tmpfile";
411             binmode(FILETMP_OUT, ":utf8");
412             # binmode(FILETMP_OUT);
413             # print FILETMP_OUT Encode::decode_utf8($doc);
414             Alvis::NLPPlatform::platform_reset();
415             $render_time = Alvis::NLPPlatform::standalone_main($config, $docR, \*FILETMP_OUT, 1); #${$tab_docs_xml->[$doc_num]}[1] ; ${$ref_doc}[1]
416             close(FILETMP_OUT);
417              
418             open FILETMP_OUT, "$tmpfile" or die "No such file or directory\n";
419             @cur_doc = ;
420             $j = 0;
421             while(($j< scalar @cur_doc) && ($cur_doc[$j] !~ s/\@RENDER_TIME_NOT_SET\@/$render_time/)) {
422             $j++;
423             }
424             close(FILETMP_OUT);
425              
426             if (!((exists $config->{"XML_OUTPUT"}->{"NO_STD_XML_OUTPUT"}) && ($config->{"XML_OUTPUT"}->{"NO_STD_XML_OUTPUT"} == 1))) {
427             if (scalar(@records) > 1) {
428             if ($i == 0){
429             pop @cur_doc;
430             } else {
431             shift @cur_doc;
432             shift @cur_doc;
433             }
434             }
435             # push @doc_collection_out, @cur_doc;
436             print @cur_doc;
437             }
438             $time_total=$time_load+$time_tok+$time_ne+$time_word+$time_sent+$time_pos+$time_lemm+$time_term+$time_synt + $time_semtag + $time_render;
439             warn "Total processing time: $time_total\n";
440             }
441              
442             # print STDERR "$tmpfile\n";
443             unlink $tmpfile;
444             # return @cur_doc;
445             return @doc_collection_out;
446             }
447              
448             sub standalone_main {
449             my $h_config = $_[0];
450             my $doc_xml = $_[1];
451             my $descriptor = $_[2];
452             my $printCollectionHeaderFooter = $_[3];
453              
454             my $xmlhead="";#"\n\n";
455             my $xmlfoot="";#\n";
456              
457             my $doc_hash;
458              
459             $last_semantic_unit=0;
460             $last_semantic_feature = 0;
461              
462             $cur_doc_nb=1;
463             compute_dependencies($h_config);
464             $NLPTOOLS=$h_config->{'NLP_tools_root'};
465             $ALVISTMP=$h_config->{'ALVISTMP'};
466             $HOSTNAME=hostname
467             $ALVISRSC=$h_config->{'NLP_misc'}->{'NLP_resources'};
468             if (!exists $h_config->{'TMPFILE'}) {
469             $h_config->{'TMPFILE'}="$ALVISTMP/$HOSTNAME.$$";
470             }
471             $ALVISLOGFILE= "$ALVISTMP/alvis.$HOSTNAME.$$.log";
472              
473             if (exists $h_config->{'DEBUG'}) {
474             $ALVISDEBUG = $h_config->{'DEBUG'};
475             }
476            
477              
478             print STDERR "\n";
479              
480              
481             $time_load=0;
482             $time_tok=0;
483             $time_ne=0;
484             $time_word=0;
485             $time_sent=0;
486             $time_pos=0;
487             $time_lemm=0;
488             $time_term=0;
489             $time_render=0;
490              
491             # Load document record
492             print STDERR "Loading DR... ";
493             undef %$doc_hash;
494             %$doc_hash=();
495             $doc_hash=0;
496              
497             %hash_tokens=();
498              
499             $dont_annotate=0;
500             %hash_words=();
501             %hash_words_punct=();
502             %hash_sentences=();
503             %hash_postags=();
504             @word_start=();
505             @word_end=();
506              
507             %last_words=();
508             @found_terms=();
509             @found_terms_tidx=();
510             @found_terms_smidx=();
511             @found_terms_phr=();
512             @found_terms_words=();
513              
514             $phrase_idx=1;
515              
516             @tab_errors=();
517              
518             starttimer();
519              
520              
521             # $doc_xml =~ s/("<\?xml version=\"1.0\" encoding=\"$charset\"?>\n
522             $doc_hash=Alvis::NLPPlatform::Annotation::load_xml($doc_xml, $h_config);
523             $time_load+=endtimer();
524              
525             # Recording computing data (time and entity size)
526             # init
527             $doc_hash->{"log_processing0"}->{"datatype"}="log_processing";
528             $doc_hash->{"log_processing0"}->{"log_id"} = "time";
529             $doc_hash->{"log_processing1"}->{"datatype"}="log_processing";
530             $doc_hash->{"log_processing1"}->{"log_id"} = "element_size";
531             $doc_hash->{"log_processing2"}->{"datatype"}="log_processing";
532             $doc_hash->{"log_processing2"}->{"log_id"} = "host";
533             $doc_hash->{"log_processing2"}->{"comments"} = $HOSTNAME;
534              
535             # Recording statistical data (time and entity size)
536             # XML loading time
537             my @tmp_c;
538             $doc_hash->{"log_processing0"}->{"comments"} = \@tmp_c;
539              
540             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "XML loading Time : $time_load";
541             print STDERR "\tXML loading Time : $time_load\n";
542             my @tmp_d;
543             $doc_hash->{"log_processing1"}->{"comments"} = \@tmp_d;
544            
545              
546             if($doc_hash!=0)
547             {
548             print STDERR "done - documentRecord ".$Alvis::NLPPlatform::Annotation::document_record_id;
549             print STDERR " (document $cur_doc_nb)\n";
550              
551              
552             Alvis::NLPPlatform::linguistic_annotation($h_config, $doc_hash);
553              
554             # Save to XML file
555             $cur_doc_nb++;
556             print STDERR "Rendering XML... ";
557              
558             starttimer();
559             $time_render = 0;
560             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "XML rendering Time : \@RENDER_TIME_NOT_SET\@";
561             Alvis::NLPPlatform::Annotation::render_xml($doc_hash, $descriptor, $printCollectionHeaderFooter, $h_config);
562             $time_render+=endtimer();
563              
564             # TODO : recording the xml rendering time
565              
566             # Recording statistical data (time and entity size)
567             # XML rendering (unsuable)
568             print STDERR "done\n";
569             print STDERR "\tXML rendering Time : $time_render\n";
570            
571             }else{
572             print STDERR "done parsing - no more documents.\n";
573             last;
574             }
575             print STDERR "\n";
576              
577             # log errors
578             open LOGERRORS,">>$ALVISLOGFILE";
579             if(scalar @tab_errors>0){
580             print LOGERRORS "Document $Alvis::NLPPlatform::Annotation::document_record_id (number $cur_doc_nb)\n";
581             foreach $log_entry(@tab_errors){
582             print LOGERRORS "$log_entry";
583             }
584             }
585             # }
586              
587             close LOGERRORS;
588              
589             # $time_total=$time_load+$time_tok+$time_ne+$time_word+$time_sent+$time_pos+$time_lemm+$time_term+$time_render;
590              
591             return($time_render);
592             }
593              
594              
595             sub client_main {
596            
597              
598             my $doc_hash = $_[0];
599             my $r_config = $_[1];
600              
601             $last_semantic_unit=0;
602             $last_semantic_feature = 0;
603              
604             $cur_doc_nb=1;
605             compute_dependencies($r_config);
606             $NLPTOOLS=$r_config->{'NLP_tools_root'};
607             $ALVISTMP=$r_config->{'ALVISTMP'};
608             $HOSTNAME=hostname
609             $ALVISRSC=$r_config->{'NLP_misc'}->{'NLP_resources'};
610             if (!exists $r_config->{'TMPFILE'}) {
611             $r_config->{'TMPFILE'}="$ALVISTMP/$HOSTNAME.$$";
612             }
613              
614             print STDERR "\n";
615              
616             $ALVISLOGFILE= "$ALVISTMP/alvis.$HOSTNAME.$$.log";
617             # $ALVISLOGFILE=$r_config->{'TMPFILE'} . ".log";
618              
619             if (exists $r_config->{'DEBUG'}) {
620             $ALVISDEBUG = $r_config->{'DEBUG'};
621             }
622              
623             $time_load=0;
624             $time_tok=0;
625             $time_ne=0;
626             $time_word=0;
627             $time_sent=0;
628             $time_pos=0;
629             $time_lemm=0;
630             $time_term=0;
631             $time_synt=0;
632             $time_render=0;
633              
634             $doc_hash->{"log_processing2"}->{"datatype"}="log_processing";
635             $doc_hash->{"log_processing2"}->{"log_id"} = "host";
636             $doc_hash->{"log_processing2"}->{"comments"} = $HOSTNAME;
637              
638             # Load document record
639             print STDERR "Loading DR... ";
640              
641             %hash_tokens=();
642              
643             $dont_annotate=0;
644             %hash_words=();
645             %hash_words_punct=();
646             %hash_sentences=();
647             %hash_postags=();
648             @word_start=();
649             @word_end=();
650              
651             %last_words=();
652             @found_terms=();
653             @found_terms_smidx=();
654             @found_terms_tidx=();
655             @found_terms_phr=();
656             @found_terms_words=();
657              
658             $phrase_idx=1;
659              
660             @tab_errors=();
661            
662             Alvis::NLPPlatform::platform_reset();
663              
664              
665             if($doc_hash!=0)
666             {
667             print STDERR "done - documentRecord ".$Alvis::NLPPlatform::Annotation::document_record_id;
668             print STDERR " (document $cur_doc_nb)\n";
669              
670             &linguistic_annotation($r_config, $doc_hash);
671              
672             }else{
673             print STDERR "done parsing - no more documents.\n";
674             last;
675             }
676             print STDERR "\n";
677              
678             # log errors
679             open LOGERRORS,">>$ALVISLOGFILE";
680             if(scalar @tab_errors>0){
681             print LOGERRORS "Document $Alvis::NLPPlatform::Annotation::document_record_id (number $cur_doc_nb)\n";
682             foreach $log_entry(@tab_errors){
683             print LOGERRORS "$log_entry";
684             }
685             }
686             # }
687              
688             close LOGERRORS;
689              
690              
691             return($doc_hash);
692            
693             }
694              
695             sub load_config
696             {
697              
698             my ($rcfile) = @_;
699            
700             # Read de configuration file
701              
702             if ((!defined $rcfile) || ($rcfile eq "")) {
703             $rcfile = "/alvis-nlpplatform/nlpplatform.rc";
704             }
705            
706             my $conf = new Config::General('-ConfigFile' => $rcfile,
707             '-InterPolateVars' => 1,
708             '-InterPolateEnv' => 1
709             );
710            
711             my %config = $conf->getall;
712             mkpath($config{'ALVISTMP'});
713             return(%config);
714             }
715              
716              
717             sub print_config
718             {
719             my $config = $_[0];
720             my $var;
721              
722             my %general_vars = ( "ALVISTMP" => "Temporary directory",
723             "PLATFORM_ROOT" => "Platform Root Directory",
724             "NLP_tools_root" => "Root directory of the NLP tools",
725             );
726             print STDERR "General variables\n";
727             foreach $var (keys %general_vars) {
728             if (defined $config->{$var}) {
729             print STDERR "\t". $general_vars{$var} . " : " . $config->{$var} . "\n";
730             }
731             }
732              
733             print STDERR "Printing Section\n";
734             if (defined $config->{"alvis_connection"}) {
735             print STDERR " Section Definition of the Alvis connection\n";
736              
737             my %alvis_connection_vars = ("HARVESTER_PORT" => "Harvester port",
738             "NEXTSTEP" => "Send information to the next step of the pipeline?",
739             "NEXTSTEP_HOST" => "Next step host",
740             "NEXTSTEP_PORT" => "Next step port",
741             "SPOOLDIR" => "Spool directory",
742             "OUTDIR" => "Output directory",
743             );
744             foreach $var (keys %alvis_connection_vars) {
745             if (defined $config->{"alvis_connection"}->{$var}) {
746             print STDERR "\t" . $alvis_connection_vars{$var} . " : " . $config->{"alvis_connection"}->{$var} . "\n";
747             }
748             }
749             }
750              
751             if (defined $config->{"NLP_connection"}) {
752             print STDERR " Section Definition of the NLP connection\n";
753              
754             my %nlp_connection_vars = ("SERVER" => "NLP Server host",
755             "PORT" => "NLP Server port",
756             "RETRY_CONNECTION" => "Number of time for retrying the connection",
757             );
758             foreach $var (keys %nlp_connection_vars) {
759             if (defined $config->{"NLP_connection"}->{$var}) {
760             print STDERR "\t" . $nlp_connection_vars{$var} . " : " . $config->{"NLP_connection"}->{$var} . "\n";
761             }
762             }
763             }
764              
765             if (defined $config->{"XML_INPUT"}) {
766             print STDERR " Section Configuration of the XML INPUT\n";
767              
768             my %xml_input_vars = ("PRESERVEWHITESPACE" => "Preserve XML White space?",
769             "LINGUISTIC_ANNOTATION_LOADING" => "Loading previous linguistic annotation?",
770             );
771             foreach $var (keys %xml_input_vars) {
772             if (defined $config->{"XML_INPUT"}->{$var}) {
773             print STDERR "\t" . $xml_input_vars{$var} . " : " . $config->{"XML_INPUT"}->{$var} . "\n";
774             }
775             }
776             }
777              
778             if (defined $config->{"XML_OUTPUT"}) {
779             print STDERR " Section Configuration of the XML OUTPUT\n";
780              
781             my %xml_output_vars = ("NO_STD_XML_OUTPUT" => "No printing standard XML output?",
782             );
783             foreach $var (keys %xml_output_vars) {
784             if (defined $config->{"XML_OUTPUT"}->{$var}) {
785             print STDERR "\t" . $xml_output_vars{$var} . " : " . $config->{"XML_OUTPUT"}->{$var} . "\n";
786             }
787             }
788             }
789              
790             &compute_dependencies($config);
791              
792             if (defined $config->{"NLP_misc"}) {
793             print STDERR " Section Miscellaneous NLP configuration features\n";
794              
795             my %NLP_misc_vars = ("NLP_resources" => "NLP resource directory",
796             "SAVE_IN_OUTDIR" => "Saving Annotated documents in the output directory?",
797             "TERM_LIST_EN" => "File containing the terms for English",
798             "TERM_LIST_FR" => "File containing the terms for French",
799             );
800             foreach $var (keys %NLP_misc_vars) {
801             if (defined $config->{"NLP_misc"}->{$var}) {
802             print STDERR "\t" . $NLP_misc_vars{$var} . " : " . $config->{"NLP_misc"}->{$var} . "\n";
803             }
804             }
805             }
806              
807             if (defined $config->{"NLP_tools"}) {
808             print STDERR " Section NLP tool path and command line\n";
809              
810             my %NLP_tools_vars = ("NETAG_EN" => "English Named Entity Recognizer command line",
811             "NETAG_FR" => "French Named Entity Recognizer command line",
812             "WORDSEG_EN" => "English Word Segmentizer command line",
813             "WORDSEG_FR" => "French Word Segmentizer command line",
814             "POSTAG_EN" => "English POS Tagger command line",
815             "POSTAG_FR" => "French POS Tagger command line",
816             "SYNTACTIC_PATH_EN" => "English Parser command line",
817             "SYNTACTIC_PATH_FR" => "French Parser command line",
818             );
819             foreach $var (keys %NLP_tools_vars) {
820             if (defined $config->{"NLP_tools"}->{$var}) {
821             print STDERR "\t" . $NLP_tools_vars{$var} . " : " . $config->{"NLP_tools"}->{$var} . "\n";
822             }
823             }
824             }
825              
826              
827             if (defined $config->{"CONVERTERS"}) {
828             print STDERR " Section INPUT CONVERTERS\n";
829              
830             my %Converter_vars = ("SupplMagicFile" => "File for Additional Definition of Magic Number",
831             );
832             foreach $var (keys %Converter_vars) {
833             if (defined $config->{"CONVERTERS"}->{$var}) {
834             print STDERR "\t" . $Converter_vars{$var} . " : " . $config->{"CONVERTERS"}->{$var} . "\n";
835             }
836             }
837             print STDERR "\tRecognized formats:\n";
838             $Converter_vars{"STYLESHEET"} = 1;
839             my $format;
840             foreach $format (keys %{$config->{"CONVERTERS"}}) {
841             if (!exists($Converter_vars{$format})) {
842             print STDERR "\t\t$format\n";
843             }
844             }
845              
846             }
847            
848             }
849              
850             sub client
851             {
852              
853             my ($rcfile) = @_;
854              
855             my %config = Alvis::NLPPlatform::load_config($rcfile);
856              
857             $nlp_host = $config{"NLP_connection"}->{"SERVER"};
858             $nlp_port = $config{"NLP_connection"}->{"PORT"};
859             $connection_retry=$config{"alvis_connection"}->{"RETRY_CONNECTION"};
860              
861             my $line;
862             my $doc_xml_size;
863             my $doc_xml;
864             # my $connection_retry;
865             my $sock=0;
866             my $time_render;
867             my $sig_handler = "";
868              
869             while(1) {
870            
871             # to not stop the connection (should crash the server)
872             $sig_handler = $SIG{'INT'};
873             $SIG{'INT'}='IGNORE'; # to prevent zombification
874            
875             $connection_retry=$config{"alvis_connection"}->{"RETRY_CONNECTION"};
876             do {
877             $sock=new IO::Socket::INET( PeerAddr => $nlp_host,
878             PeerPort => $nlp_port,
879             Proto => 'tcp');
880            
881             warn "Could not create socket: $! \n" unless $sock;
882             $connection_retry--;
883             sleep(1);
884             } while(!defined($sock) && ($connection_retry >0));
885            
886             if ($connection_retry ==0) {
887             die "Timeout. Could not create socket: $! \n";
888             }
889             # $sock=new IO::Socket::INET( PeerAddr => $nlp_host,
890             # PeerPort => $nlp_port,
891             # Proto => 'tcp');
892              
893             # die "Could not create socket: $!\n" unless $sock;
894             $sock -> autoflush(1); ###############
895             binmode($sock, ":utf8");
896             print STDERR `date`;
897             print STDERR "Established connection to server.\n";
898            
899             print STDERR "Requesting document...";
900             print $sock "REQUEST\n";
901             print STDERR "done.\n";
902              
903             print STDERR "Receiving document...\n";
904              
905             # SENDING $id
906            
907             while($line = <$sock>) {
908             print STDERR "$line";
909             $line=uc $line;
910             if ($line =~ /SENDING ([^\n]+)\n/) {
911             $id = $1;
912             last;
913             } else {
914             warn "Out of protocol message\n";
915             close $sock;
916             next;
917             }
918             }
919              
920             print STDERR "GETTING $id\n";
921              
922             # SIZE of $doc_xml
923              
924             while ($line = <$sock>) {
925             print STDERR "$line";
926             $line=uc $line;
927             if ($line =~ /SIZE ([^\n]+)\n/) {
928             $doc_xml_size = $1;
929             last;
930             } else {
931             warn "Out of protocol message\n";
932             close $sock;
933             next;
934             }
935             }
936            
937             print STDERR "READING $doc_xml_size bytes\n";
938             $doc_xml = "";
939             print STDERR length($doc_xml) . "\r";
940             while ((defined $sock) && ($line = <$sock>) && ($line ne "\n")) { # (length($doc_xml) < $doc_xml_size) &&
941             print STDERR length($doc_xml) . "\r";
942             $doc_xml .= $line;
943             }
944             if (length($doc_xml) > $doc_xml_size) {
945             warn "Received more bytes than expected\n";
946             }
947             print STDERR length($doc_xml) . "\n";
948             print STDERR "\n";
949             print STDERR "READING $id done.\n";
950             print STDERR "Sending ACK...";
951             print $sock "ACK\n";
952             print STDERR "done.\n";
953            
954             close $sock;
955              
956             # restore the normal behaviour
957             $SIG{'INT'} = \&sigint_handler;
958              
959             print STDERR "Processing $id";
960            
961             my $doc_hash;
962            
963             Alvis::NLPPlatform::starttimer();
964             $doc_hash=Alvis::NLPPlatform::Annotation::load_xml($doc_xml, \%config);
965             my $time_load+=Alvis::NLPPlatform::endtimer();
966              
967             # Recording computing data (time and entity size)
968             # init
969             # $doc_hash->{"log_processing"} = {};
970             $doc_hash->{"log_processing0"}->{"datatype"}="log_processing";
971             $doc_hash->{"log_processing0"}->{"log_id"} = "time";
972             $doc_hash->{"log_processing1"}->{"datatype"}="log_processing";
973             $doc_hash->{"log_processing1"}->{"log_id"} = "element_size";
974            
975             # Recording statistical data (time and entity size)
976             # XML loading time
977             my @tmp_c;;
978             $doc_hash->{"log_processing0"}->{"comments"} = \@tmp_c;
979            
980             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "XML loading Time : $time_load";
981            
982             my @tmp_d;;
983             $doc_hash->{"log_processing1"}->{"comments"} = \@tmp_d;
984            
985            
986             $doc_hash = Alvis::NLPPlatform::client_main($doc_hash, \%config);
987            
988             # to not stop the connection (should crash the server)
989             $sig_handler = $SIG{'INT'};
990             $SIG{'INT'}='IGNORE'; # to prevent zombification
991              
992             $connection_retry=$config{"alvis_connection"}->{"RETRY_CONNECTION"};
993             do {
994             $sock=new IO::Socket::INET( PeerAddr => $nlp_host,
995             PeerPort => $nlp_port,
996             Proto => 'tcp');
997            
998             warn "Could not create socket: $! \n" unless $sock;
999             $connection_retry--;
1000             sleep(1);
1001             } while(!defined($sock) && ($connection_retry >0));
1002            
1003             if ($connection_retry ==0) {
1004             die "Timeout. Could not create socket: $! \n";
1005             }
1006             binmode $sock, ":utf8";
1007            
1008             print STDERR "Established connection to server.\n";
1009            
1010             print STDERR "Giving back annotated document...\n";
1011             # Communitation with the server
1012             print $sock "GIVEBACK\n$id\n";
1013            
1014             # Save to XML file
1015              
1016             print STDERR "\tRendering XML... ";
1017              
1018             starttimer();
1019             $time_render = 0;
1020             push @{$doc_hash->{"log_processing0"}->{"comments"}}, "XML rendering Time : \@RENDER_TIME_NOT_SET\@";
1021             Alvis::NLPPlatform::Annotation::render_xml($doc_hash, $sock, 1,\%config);
1022             $time_render+=endtimer();
1023              
1024             # TODO : recording the xml rendering time
1025             print STDERR "done\n";
1026            
1027             print $sock "\n";
1028            
1029             print STDERR "done.\n";
1030            
1031             # the render time is sent
1032              
1033             print $sock "RENDER TIME\n$time_render\n";
1034              
1035             print STDERR "Awaiting acknowledgement...";
1036             my $line;
1037             while($line=<$sock>){
1038             chomp $line;
1039             $line=uc $line;
1040             if($line=~/ACK/gi){
1041             close($sock);
1042             last;
1043             } }
1044             print STDERR "OK.\n";
1045              
1046             close($sock);
1047              
1048             # restore the normal behaviour
1049             $SIG{'INT'} = $sig_handler;
1050             print STDERR "Closed connection to server.\n";
1051             }
1052             return($time_render);
1053             }
1054              
1055              
1056             sub sigint_handler {
1057              
1058             my ($signal) = @_;
1059             my $sock;
1060              
1061             # $nlp_host = $r_config->{"NLP_connection"}->{"SERVER"};
1062             # $nlp_port = $r_config->{"NLP_connection"}->{"PORT"};
1063              
1064              
1065             warn "Receiving SIGINT -- Aborting NL processing\n";
1066              
1067            
1068              
1069             do {
1070             $sock=new IO::Socket::INET( PeerAddr => $nlp_host,
1071             PeerPort => $nlp_port,
1072             Proto => 'tcp');
1073              
1074             warn "Could not create socket: $! \n" unless $sock;
1075             $connection_retry--;
1076             sleep(1);
1077             } while(!defined($sock) && ($connection_retry >0));
1078              
1079             if ($connection_retry ==0) {
1080             die "Timeout. Could not create socket: $! \n";
1081             }
1082             $sock -> autoflush(1); ###############
1083             binmode $sock, ":utf8";
1084              
1085              
1086             print STDERR "Established connection to server.\n";
1087              
1088             print STDERR "Sending aborting message\n";
1089              
1090             print $sock "ABORTING\n$id\n";
1091              
1092             print STDERR "Aborting message sent\n";
1093              
1094             print STDERR "Awaiting acknowledgement...";
1095             my $line;
1096             while($line=<$sock>){
1097             chomp $line;
1098             $line=uc $line;
1099             if($line=~/ACK/gi){
1100             close($sock);
1101             last;
1102             }
1103             }
1104             print STDERR "OK.\n";
1105              
1106             close($sock);
1107             exit;
1108             }
1109              
1110              
1111             sub server
1112             {
1113             my ($rcfile) = @_;
1114              
1115             print STDERR "config File : $rcfile \n";
1116              
1117             my %config = Alvis::NLPPlatform::load_config($rcfile);
1118              
1119             $nlp_host = $config{"NLP_connection"}->{"SERVER"};
1120             $nlp_port = $config{"NLP_connection"}->{"PORT"};
1121             $connection_retry = $config{"alvis_connection"}->{"RETRY_CONNECTION"};
1122             # print STDERR Dumper(\%config);
1123              
1124             my $charset = 'UTF-8';
1125              
1126             # header and footer
1127              
1128             my $xmlhead="\n\n";
1129             my $xmlfoot="\n";
1130              
1131             # connection to the crawler
1132              
1133             my $pipe = new Alvis::Pipeline::Read(port => $config{"alvis_connection"}->{"HARVESTER_PORT"}, spooldir => $config{"alvis_connection"}->{"SPOOLDIR"},
1134             loglevel=>10)
1135             or die "can't create read-pipe on port " . $config{"alvis_connection"}->{"HARVESTER_PORT"} . ": $!";
1136              
1137             $|=1;
1138              
1139             touch($config{"ALVISTMP"} . "/.proc_id");
1140              
1141             &init_server(\%config);
1142              
1143             unlink($config{"ALVISTMP"} . "/.proc_id");
1144             touch($config{"ALVISTMP"} . "/.proc_id");
1145             mkpath($config{"alvis_connection"}->{"OUTDIR"});
1146             my $n=1;
1147              
1148             my $annotated_xml;
1149              
1150             $SIG{'CHLD'}='IGNORE'; # to prevent zombification
1151              
1152             my $sock=new IO::Socket::INET(LocalPort => $config{"NLP_connection"}->{"PORT"},
1153             Proto => 'tcp',
1154             Listen => 10,
1155             Reuse => 1);
1156              
1157             die "Could not create socket: $!\n" unless $sock;
1158              
1159             $sock -> autoflush(1); ###############
1160              
1161             my $client_sock=0;
1162             my $name;
1163             my @records;
1164             my $id;
1165             my $sub_dir;
1166             my %processing_id;
1167              
1168             while(1){
1169             warn "beginning of the loop\n";
1170             # await client connection
1171             if ($client_sock=$sock->accept()) {
1172             warn "Accepting a connection\n";
1173             if (fork() == 0) {
1174             close($sock);
1175             binmode($client_sock, ":utf8");
1176             my ($client_port,$client_iaddr) = sockaddr_in(getpeername($client_sock));
1177             warn "Getting information about remote host\n";
1178             $name=gethostbyaddr($client_iaddr,AF_INET);
1179             &disp_log($name,"Client (".inet_ntoa($client_iaddr).":".$client_port.") has connected.");
1180             $client_sock -> autoflush(1); ###############
1181            
1182             ##############################
1183             # CLIENT HANDLING CODE
1184             my $line;
1185             $line=<$client_sock>;
1186             chomp $line;
1187             $line=uc $line;
1188             $line=~m/^\s*([A-Z]+)$/g;
1189            
1190             ## CLIENT IS REQUESTING A DOCUMENT
1191             if($1 eq "REQUEST"){
1192             &disp_log($name,"Client is requesting a document.");
1193             # send document
1194            
1195             &disp_log($name,"Sending document to client.");
1196              
1197             my $xml = "";
1198             warn "Reading the pipe\n";
1199             if ($xml = $pipe->read(1)) {
1200             $xml .= "\n" if $xml !~ /\n$/;
1201            
1202             @records=&split_to_docRecs($xml);
1203             if (scalar(@records))
1204             {
1205             my $rec = shift (@records);
1206             ($id,$xml)=@$rec;
1207             if (scalar (@records)) {
1208             # if there is more than one records other are store again in the pipeline
1209             # use of combineExport code
1210             my $pipe_out = new Alvis::Pipeline::Write(host => "localhost",
1211             port => $config{"alvis_connection"}->{"HARVESTER_PORT"},
1212             loglevel => 10)
1213             or die "can't create ALVIS write-pipe for port '" . $config{"alvis_connection"}->{"HARVESTER_PORT"} . "': $!";
1214             foreach my $rec_out (@records) {
1215             $pipe_out->write($xmlhead . $rec_out . $xmlfoot);
1216             }
1217             }
1218              
1219             if (defined($id))
1220             {
1221             warn "Received\t$n\t$id\n";
1222            
1223             `date`;
1224             if (defined(open(I,">:utf8",$config{"ALVISTMP"} . "/${id}.xml")))
1225             {
1226             print I $xml;
1227             close(I);
1228             }
1229             else
1230             {
1231             die("Unable to open " . $config{"ALVISTMP"} . "/${id}.xml for writing.");
1232             }
1233            
1234             my $xml2 = $xml;
1235             &disp_log($name,"Sending Document to client (" . (length($xml2) + 1 ) . " bytes).");
1236             &disp_log($name, "SENDING $id");
1237             &record_id($id,\%config);
1238             print $client_sock "SENDING $id\n";
1239             print $client_sock "SIZE " . (length($xml2) + 1 ) . "\n";
1240             $xml2 = "";
1241             print $client_sock "$xml\n";
1242             print $client_sock "\n";
1243             # await acknowledgement
1244             &disp_log($name,"Document sent to client.");
1245             &disp_log($name,"Awaiting ACK from client...");
1246             while($line=<$client_sock>){
1247             chomp $line;
1248             $line=uc $line;
1249             if($line=~/ACK/gi){
1250             close($client_sock);
1251             last;
1252             }
1253             }
1254             &disp_log($name,"Received ACK from client - Request fulfilled.");
1255             close($client_sock);
1256             }
1257             else
1258             {
1259             warn "No id for record #$id of record \"$rec\"\n";
1260             }
1261             }
1262             else
1263             {
1264             my $doc_text;
1265             if (ref($xml))
1266             {
1267             $doc_text=$xml->toString();
1268             }
1269             else
1270             {
1271             $doc_text=$xml;
1272             }
1273             warn "Could not split into documentRecords document $doc_text";
1274             }
1275             } else {
1276             $pipe->close();
1277             warn "No documents in pipeline\n"
1278             if $n == 0;
1279             }
1280            
1281             $n++;
1282             close($client_sock);
1283             }
1284            
1285            
1286             ## CLIENT IS ABOUT TO GIVE BACK AN ANNOTATED DOCUMENT
1287             if($1 eq "GIVEBACK"){
1288             &disp_log($name,"Client is giving back a document.");
1289             # receive document
1290             &disp_log($name,"Receiving annotated document from client...");
1291            
1292             $id = <$client_sock>;
1293             chomp $id;
1294              
1295             &disp_log($name,"Annotated document ID: $id");
1296            
1297             # Recording the annotation document (local)
1298             $sub_dir=&sub_dir_from_id($id);
1299             if ($config{"NLP_misc"}->{"SAVE_IN_OUTDIR"}) {
1300             mkpath( $config{"alvis_connection"}->{"OUTDIR"} . "/$sub_dir");
1301             }
1302             my $xml = "";
1303             if (($config{"NLP_misc"}->{"SAVE_IN_OUTDIR"} == 0) || (defined(open(O,">:utf8", $config{"alvis_connection"}->{"OUTDIR"} . "/$sub_dir/${id}.xml"))))
1304             {
1305             while((defined $sock) && ($line=<$client_sock>) && ($line ne "\n")) {
1306             # recording the annotation document (local)
1307             # building xml string for sending to the next step
1308             $xml .= $line;
1309             # print STDERR $line;
1310             }
1311             # print STDERR $line;
1312             # get the RENDER TIME
1313             if ((defined $sock) && ($line = <$client_sock>) && ($line eq "RENDER TIME\n")) {
1314             if ((defined $sock) && ($line = <$client_sock>)) {
1315             chomp $line;
1316             $xml =~ s/\@RENDER_TIME_NOT_SET\@/$line/;
1317             # print STDERR $line;
1318             } else {
1319             warn "\n***\nValue of render time is not sent\n***\n\n";
1320             }
1321             } else {
1322             warn "\n***\nRender time is not sent\n***\n\n";
1323             }
1324             if ($config{"NLP_misc"}->{"SAVE_IN_OUTDIR"}) {
1325             print O $xml;
1326             close(O);
1327             }
1328             # sending the annotated document to the newt step
1329             if ($config{"alvis_connection"}->{"NEXTSTEP"}) {
1330             warn "Sending the annotated document to the next step... \n";
1331             my $pipe_out_nextstep = new Alvis::Pipeline::Write(host => $config{"alvis_connection"}->{"NEXTSTEP_HOST"},
1332             port => $config{"alvis_connection"}->{"NEXTSTEP_PORT"},
1333             loglevel => 10)
1334             or die "can't create ALVIS write-pipe for '" . $config{"alvis_connection"}->{"NEXTSTEP_HOST"} . "' port '" . $config{"alvis_connection"}->{"nextstep_port"} . "': $!";
1335             $pipe_out_nextstep->write($xml);
1336             warn "done\n";
1337             } else {
1338             warn "Not sending to a nextstep\n";
1339             }
1340             } else {
1341             if ($config{"NLP_misc"}->{"SAVE_IN_OUTDIR"}) {
1342             $sub_dir=&sub_dir_from_id($id);
1343             die("Unable to open " . $config{"alvis_connection"}->{"OUTDIR"}. " //$sub_dir/${id}.xml for writing.");
1344             }
1345             }
1346            
1347             &disp_log($name,"Received annotated document from client.");
1348            
1349             warn "deleting $config{ALVISTMP}/${id}.xml\n";
1350             unlink "$config{ALVISTMP}/${id}.xml";
1351             &delete_id($id, \%config);
1352             # send acknowledgement
1353             &disp_log($name,"Sending ACK to client...");
1354             print $client_sock "ACK\n";
1355             &disp_log($name,"Sent ACK to client - Finished giving back.");
1356             close($client_sock);
1357             }
1358             # CLIENT INFORMS SERVER FOR ABORTING NL PROCESSING
1359             if ($1 eq "ABORTING") {
1360             &disp_log($name,"Client is aborting NL processing of a document.");
1361             $line = <$client_sock>;
1362             chomp $line;
1363             # use of combineExport code
1364             my $pipe_out = new Alvis::Pipeline::Write(host => "localhost",
1365             port => $config{"alvis_connection"}->{"HARVESTER_PORT"},
1366             loglevel => 10)
1367             or die "can't create ALVIS write-pipe for port '" . $config{"alvis_connection"}->{"HARVESTER_PORT"} . "': $!";
1368             $id = $line;
1369             open ABORTING_FILE, "$config{ALVISTMP}/${id}.xml" or die "Cannot open file $config{ALVISTMP}/${id}.xml \n";
1370             my $rec_out = "";
1371             while($line = ) {
1372             $rec_out .= $line;
1373             }
1374             $pipe_out->write($xmlhead . $rec_out . $xmlfoot);
1375             close ABORTING_FILE;
1376             &delete_id($id,\%config);
1377             &disp_log($name,"Sending ACK to client...");
1378             print $client_sock "ACK\n";
1379             &disp_log($name,"Sent ACK to client - Finished aborting.");
1380             }
1381             ## CLIENT REQUESTS TO BE DISCONNECTED BY THE SERVER
1382             if(
1383             ($1 eq "QUIT") ||
1384             ($1 eq "LOGOUT") ||
1385             ($1 eq "EXIT")){
1386             &disp_log($name,"Disconnecting client.");
1387             }
1388             &disp_log($name,"Disconnecting client.");
1389             close($client_sock);
1390             exit;
1391             } else {
1392             close($client_sock);
1393             }
1394             }
1395             warn "End of loop\n";
1396             }
1397             # END OF CLIENT HANDLING CODE
1398             ##############################
1399              
1400             }
1401              
1402              
1403              
1404             sub disp_log{
1405             my $date=`date`;
1406             chomp $date;
1407             print STDERR "$date: ";
1408             print STDERR "(client=".$_[0].") ";
1409             print STDERR $_[1]."\n";
1410             }
1411              
1412              
1413             sub split_to_docRecs
1414             {
1415             my $xml=shift;
1416              
1417             my @recs=();
1418            
1419             my $doc;
1420             my $Parser=XML::LibXML->new();
1421              
1422              
1423             # print STDERR $xml;
1424              
1425             eval
1426             {
1427             $doc=$Parser->parse_string($xml);
1428             };
1429             if ($@)
1430             {
1431             warn "Parsing the doc failed: $@. Trying to get the IDs..\n";
1432             eval
1433             {
1434             $xml=~s//&unparseable_id($2)/esgo;
1435             };
1436             }
1437             else
1438             {
1439             if ($doc)
1440             {
1441              
1442             my $root=$doc->documentElement();
1443              
1444             # print STDERR "\n\n==> ";
1445              
1446             # # $doc->setEncoding("UTF-8");
1447              
1448             # print STDERR $doc->encoding();
1449              
1450             # print STDERR "\n";
1451              
1452             # print STDERR $doc->version();
1453              
1454             # print STDERR "\n";
1455              
1456             # print STDERR $root->nodeName();
1457              
1458            
1459              
1460             # print STDERR "\n\n";
1461              
1462             for my $rec_node ($root->getChildrenByTagName('documentRecord'))
1463             {
1464             my $id=$rec_node->getAttribute("id");
1465             if (defined($id))
1466             {
1467             $xml=$rec_node->toString();
1468             push(@recs,[$id,$xml]);
1469             }
1470             else
1471             {
1472             my $rec_str=$rec_node->toString();
1473             $rec_str=~s/\n/ /sgo;
1474             warn "No id for record $rec_str\n";
1475             }
1476             }
1477             }
1478             else
1479             {
1480             my $doc_str=$xml;
1481             $doc_str=~s/\n/ /sgo;
1482             warn "Parsing the doc failed. Doc: $doc_str\n";
1483             }
1484             }
1485              
1486             return @recs;
1487             }
1488              
1489              
1490             sub unparseable_id
1491             {
1492             my $id=shift;
1493            
1494             warn "$id is in an unparseable chunk\n";
1495             }
1496              
1497              
1498             sub sub_dir_from_id
1499             {
1500             my $id=shift;
1501              
1502             return substr($id,0,2);
1503             }
1504              
1505              
1506              
1507             sub record_id {
1508             my ($doc_id, $r_config) = @_;
1509              
1510             my $file_id = $r_config->{"ALVISTMP"} . "/.proc_id";
1511             my $fh = new IO::File("+<$file_id")
1512             or die "can't read '$file_id': $!";
1513             flock($fh, LOCK_EX) or die "can't lock '$file_id': $!";
1514             seek($fh, 0, SEEK_END) or die "can't seek to start of '$file_id': $!";
1515              
1516             # my @tab_proc_id;
1517              
1518             # while($line = $fh->getline()) {
1519             # if ($line ne "$doc_id\n") {
1520             # push @tab_proc_id, $line;
1521             # }
1522             # }
1523            
1524             $fh->print("$doc_id\n") or die "can't write in '$file_id': $!";
1525              
1526            
1527             flock($fh, LOCK_UN) or die "can't unlock '$file_id': $!";
1528             $fh->close() or die "Truly unbelievable";
1529            
1530             }
1531              
1532              
1533             sub delete_id {
1534             my ($doc_id, $r_config) = @_;
1535             my $line;
1536             my @tab_proc_id;
1537              
1538             my $file_id = $r_config->{"ALVISTMP"} . "/.proc_id";
1539             my $fh = new IO::File("<$file_id")
1540             or die "can't read '$file_id': $!";
1541             flock($fh, LOCK_EX) or die "can't lock '$file_id': $!";
1542             while($line = $fh->getline()) {
1543             if ($line ne "$doc_id\n") {
1544             push @tab_proc_id, $line;
1545             }
1546             }
1547             $fh->close() or die "Truly unbelievable";
1548             $fh = new IO::File(">$file_id")
1549             or die "can't write '$file_id': $!";
1550             # seek($fh, 0, SEEK_SET) or die "can't seek to start of '$file_id': $!";
1551             foreach $line (@tab_proc_id) {
1552             $fh->print("$line") or die "can't write in '$file_id': $!";
1553             }
1554            
1555             flock($fh, LOCK_UN) or die "can't unlock '$file_id': $!";
1556             $fh->close() or die "Truly unbelievable";
1557            
1558             }
1559              
1560             sub init_server {
1561             my $r_config = $_[0];
1562             my $doc_id;
1563             my $line;
1564             my $rec_out = "";
1565             my @tab_proc_id;
1566              
1567             my $xmlhead=""; #\n\n";
1568             my $xmlfoot=""; #\n";
1569              
1570             print STDERR "Starting Server Initialisation ...\n";
1571              
1572             # warn "Receiving SIGINT -- Aborting any NL processing\n";
1573              
1574             my $pipe_out = new Alvis::Pipeline::Write(host => "localhost",
1575             port => $r_config->{"alvis_connection"}->{"HARVESTER_PORT"},
1576             loglevel => 10)
1577             or die "can't create ALVIS write-pipe for port '" . $r_config->{"alvis_connection"}->{"HARVESTER_PORT"} . "': $!";
1578             my $file_id = $r_config->{ALVISTMP} . "/.proc_id";
1579             my $fh = new IO::File("+<$file_id")
1580             or die "can't read '$file_id': $!";
1581             flock($fh, LOCK_EX) or die "can't lock '$file_id': $!";
1582             while($line = $fh->getline()) {
1583             chomp $line;
1584             push @tab_proc_id, $line;
1585             }
1586              
1587             warn "Recording " . scalar(@tab_proc_id) ." documents in the pipe...";
1588              
1589             foreach $doc_id (@tab_proc_id) {
1590             warn "Recording $doc_id in the pipe...";
1591             # use of combineExport code
1592             open ABORTING_FILE, $r_config->{ALVISTMP} . "/$doc_id.xml" ;
1593             $rec_out = "";
1594             while($line = ) {
1595             $rec_out .= $line;
1596             }
1597             $pipe_out->write($xmlhead . $rec_out . $xmlfoot);
1598             close ABORTING_FILE;
1599             unlink $r_config->{ALVISTMP} . "/$doc_id.xml" ;
1600            
1601             warn "$doc_id recorded in the pipe";
1602            
1603             }
1604             flock($fh, LOCK_UN) or die "can't unlock '$file_id': $!";
1605             $fh->close() or die "Truly unbelievable";
1606             print STDERR "Server Initialisation Done\n";
1607             }
1608              
1609              
1610             sub token_id_is_in_list_refid_token
1611             {
1612             my $list_refid_token = $_[0];
1613             my $token_to_search = $_[1];
1614            
1615             # warn "searching $token_to_search\n";
1616              
1617             my $tok_id;
1618              
1619             foreach $tok_id (@$list_refid_token) {
1620             if ($tok_id eq $token_to_search) {
1621             return 1;
1622             }
1623             }
1624             return 0;
1625             }
1626              
1627             sub token_id_follows_list_refid_token
1628             {
1629             my $list_refid_token = $_[0];
1630             my $token_to_search = $_[1];
1631            
1632             # warn "searching $token_to_search\n";
1633              
1634             # print STDERR "$list_refid_token\n";
1635             # print STDERR scalar(@$list_refid_token) . "\n";
1636              
1637             if ($list_refid_token->[scalar(@$list_refid_token) - 1] =~ /token([0-9]+)/) {
1638             my $last_token_id = $1;
1639             if ($token_to_search =~ /token([0-9]+)/) {
1640             my $token_to_search_id = $1;
1641             if ($token_to_search_id == $last_token_id + 1) {
1642             return 1;
1643             }
1644             }
1645             }
1646             return 0;
1647             }
1648              
1649             sub token_id_just_before_last_of_list_refid_token
1650             {
1651             my $list_refid_token = $_[0];
1652             my $token_to_search = $_[1];
1653            
1654             # warn "searching $token_to_search\n";
1655              
1656             # print STDERR "$list_refid_token\n";
1657             # print STDERR "$token_to_search\n";
1658             # print STDERR scalar(@$list_refid_token) . "\n";
1659              
1660             if ($list_refid_token->[0] =~ /token([0-9]+)/) {
1661             my $last_token_id = $1;
1662             if ($token_to_search =~ /token([0-9]+)/) {
1663             my $token_to_search_id = $1;
1664             if ($token_to_search_id < $last_token_id) {
1665             return 1;
1666             }
1667             }
1668             }
1669             return 0;
1670             }
1671              
1672              
1673             1;
1674              
1675             __END__