ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/ActiveDoc/ActiveDoc.pm
Revision: 1.23
Committed: Wed Feb 23 14:53:28 2000 UTC (25 years, 2 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.22: +27 -0 lines
Log Message:
Added currentparser interface

File Contents

# User Rev Content
1 williamc 1.1 #
2 williamc 1.6 # ActiveDoc.pm
3     #
4     # Originally Written by Christopher Williams
5     #
6     # Description
7 williamc 1.1 #
8     # Interface
9     # ---------
10 williamc 1.15 # new(ActiveConfig[,options]) : A new ActiveDoc object
11 williamc 1.6 # url() : Return/set the docs url - essential
12     # file() : Return the local filename of document
13 williamc 1.21 # ProcessFile() : Return the filename of PreProcessed document
14 williamc 1.6 #
15     # parse(parselabel): Parse the document file for the given parse level
16 williamc 1.21 # parent() : return the object ref of the calling parent
17 williamc 1.6 # newparse(parselabel) : Create a new parse type
18     # addtag(parselabel,tagname,start,obj,text,obj,end,obj)
19     # : Add tags to the parse given by label
20 williamc 1.9 # checktag(tagname, hashref, param) : check for existence of param in
21     # hashref from a tag call
22 williamc 1.12 # includeparse(local_parsename, objparsename, activedoc) : copy the parse from
23     # one object to another
24 williamc 1.23 # currentparser() : return the current parser object
25 williamc 1.12 # currentparsename([name]) : get/set current parse name
26 williamc 1.6 # getfile(url) : get a processedfile object given a url
27 williamc 1.9 # activatedoc(url) : Return the object ref for a doc described by the given url
28 williamc 1.14 # -- any parse called "init" will also be run
29 williamc 1.6 # config([ActiveConfig]) : Set up/return Configuration for the document
30     # basequery([ActiveConfig]) : Set up/return UserQuery for the doc
31     # copydocconfig(ActiveDoc) : Copy the basic configuration from the ActiveDoc
32     # copydocquery(ActiveDoc) : Copy the basicquery from the ActiveDoc
33 williamc 1.10 # userinterface() : Return the defaullt userinterface
34 williamc 1.20 # option(var) : return the value of the option var ( or undef )
35 williamc 1.14 # requestoption("message") : Ask the user to supply a value for an option
36     # if it dosnt already exist
37 williamc 1.20 # askuser(Query) : send a query object to the userinterface
38     # verbose(string) : Print string in verbosity mode
39 williamc 1.6 #
40     # -- error methods --
41     # error(string) : Report an general error to the user
42     # parseerror(string) : Report an error during parsing a file
43     # line() : Return the current line number of the document
44     # and the ProcessedFileObj it is in
45 williamc 1.23 #
46     # -- support for inheriting classes
47     # _saveactivedoc(filehandle)
48     # _restoreactivedoc(filehandle)
49 williamc 1.2
50     package ActiveDoc::ActiveDoc;
51 williamc 1.6 require 5.004;
52     use ActiveDoc::Parse;
53     use ActiveDoc::ActiveConfig;
54     use ActiveDoc::PreProcessedFile;
55 williamc 1.10 use ObjectUtilities::StorableObject;
56 williamc 1.6 use URL::URLhandler;
57    
58 williamc 1.10 @ISA = qw(ObjectUtilities::StorableObject);
59 williamc 1.6
60     sub new {
61     my $class=shift;
62     $self={};
63     bless $self, $class;
64     $self->config(shift);
65 williamc 1.14
66 williamc 1.15 # have some override options been passed
67     if ( @_ ) {
68     $self->basequery(shift);
69 williamc 1.14 }
70     else {
71 williamc 1.15 # --- is there a starter document?
72     my $basedoc=$self->config()->basedoc();
73     if ( defined $basedoc ) {
74 williamc 1.21 $self->copydocquery($basedoc);
75 williamc 1.20 $self->verbose("Initialising from $basedoc");
76 williamc 1.15 }
77     else {
78 williamc 1.19 $self->error("ActiveDoc Error : No base doc found");
79 williamc 1.15 }
80 williamc 1.14 }
81 williamc 1.21 $self->verbose("New ActiveDoc (".ref($self).") Created");
82 williamc 1.14 $self->_init2();
83     }
84    
85     sub _init2 {
86    
87     my $self=shift;
88 williamc 1.6 # A URL handler per document
89     $self->{urlhandler}=URL::URLhandler->new($self->config()->cache());
90    
91 williamc 1.10 # A default UserInterface
92 williamc 1.11 $self->{userinterface}=ActiveDoc::SimpleUserInterface->new();
93 williamc 1.6 $self->init(@_);
94     return $self;
95 williamc 1.14
96 williamc 1.6 }
97    
98 williamc 1.20 sub verbose {
99     my $self=shift;
100     my $string=shift;
101    
102     if ( $self->option('verbose_all') ||
103     $self->option('verbose_'.ref($self)) ) {
104 williamc 1.21 print ">".ref($self)."($self) : \n->".$string."\n";
105 williamc 1.20 }
106     }
107    
108 williamc 1.6 # ----- parse related routines --------------
109     sub parse {
110     my $self=shift;
111     $parselabel=shift;
112    
113 williamc 1.21 my $file=$self->ProcessFile();
114 williamc 1.6 if ( $file ) {
115 williamc 1.14 if ( exists $self->{parsers}{$parselabel} ) {
116 williamc 1.21 $self->verbose("Parsing $parselabel in file $file");
117 williamc 1.14 $self->{currentparsename}=$parselabel;
118     $self->{currentparser}=$self->{parsers}{$parselabel};
119     $self->{parsers}{$parselabel}->parse($file,@_);
120     delete $self->{currentparser};
121     $self->{currentparsename}="";
122 williamc 1.21 $self->verbose("Parse $parselabel Complete");
123 williamc 1.14 }
124 williamc 1.6 }
125     else {
126     print "Cannot parse - file not known\n";
127     }
128 williamc 1.1 }
129    
130 williamc 1.12 sub currentparsename {
131     my $self=shift;
132     @_?$self->{currentparsename}=shift
133     :$self->{currentparsename};
134     }
135    
136 williamc 1.23 sub currentparser {
137     my $self=shift;
138     return $self->{currentparser};
139     }
140    
141    
142 williamc 1.6 sub newparse {
143     my $self=shift;
144     my $parselabel=shift;
145    
146     $self->{parsers}{$parselabel}=ActiveDoc::Parse->new();
147     $self->{parsers}{$parselabel}->addignoretags();
148     $self->{parsers}{$parselabel}->addgrouptags();
149 williamc 1.12 }
150    
151 williamc 1.13 sub cleartags {
152     my $self=shift;
153     my $parselabel=shift;
154    
155     $self->{parsers}{$parselabel}->cleartags();
156     }
157    
158    
159 williamc 1.12 sub includeparse {
160     my $self=shift;
161     my $parselabel=shift;
162     my $remoteparselabel=shift;
163     my $activedoc=shift;
164    
165     # Some error trapping
166     if ( ! exists $self->{parsers}{$parselabel} ) {
167     $self->error("Unknown local parse name specified");
168     }
169     if ( ! exists $activedoc->{parsers}{$remoteparselabel} ) {
170     $self->error("Unknown parse name specified in remote obj $activedoc");
171     }
172    
173     #
174     my $rp=$activedoc->{parsers}{$remoteparselabel};
175     $self->{parsers}{$parselabel}->includeparse($rp);
176 williamc 1.2 }
177 williamc 1.6
178     sub addtag {
179     my $self=shift;
180     my $parselabel=shift;
181     if ( $#_ != 6 ) {
182     $self->error("Incorrect addtags specification\n".
183     "called with :\n@_ \n");
184 williamc 1.4 }
185 williamc 1.6 $self->{parsers}{$parselabel}->addtag(@_);
186     }
187 williamc 1.2
188 williamc 1.6 sub addurltags {
189     my $self=shift;
190     my $parselabel=shift;
191    
192     $self->{parsers}{$parselabel}->
193     addtag("Base", \&Base_start, $self, "", $self,
194     \&Base_end, $self);
195 williamc 1.1 }
196    
197 williamc 1.6 sub url {
198 williamc 1.2 my $self=shift;
199 williamc 1.8 # get file & preprocess
200 williamc 1.21 if ( @_ ) {
201     $self->{File}=$self->getfile(shift);
202     $self->verbose("url downloaded to $self->{File}");
203     }
204 williamc 1.8 $self->{File}->url();
205 williamc 1.2 }
206    
207 williamc 1.6 sub copydocconfig {
208 williamc 1.1 my $self=shift;
209 williamc 1.6 my $ActiveDoc=shift;
210    
211     $self->config($ActiveDoc->config());
212    
213 williamc 1.1 }
214    
215 williamc 1.6 sub copydocquery {
216     my $self=shift;
217     my $ActiveDoc=shift;
218    
219 williamc 1.19 if ( defined $ActiveDoc->basequery() ) {
220     $self->basequery($ActiveDoc->basequery());
221     }
222     else {
223     $self->error("Cannot copy basequery - undefined");
224     }
225 williamc 1.1 }
226    
227 williamc 1.6 sub config {
228 williamc 1.1 my $self=shift;
229 williamc 1.6 @_?$self->{ActiveConfig}=shift
230     : $self->{ActiveConfig};
231     }
232 williamc 1.1
233 williamc 1.6 sub basequery {
234     my $self=shift;
235 williamc 1.21 @_?$self->{Query}=shift
236     :$self->{Query};
237 williamc 1.10 }
238    
239 williamc 1.14 sub option {
240 williamc 1.10 my $self=shift;
241     my $param=shift;
242 williamc 1.15 if ( defined $self->basequery()) {
243     return $self->basequery()->getparam($param);
244     }
245     else {
246     return $undef;
247     }
248 williamc 1.14 }
249    
250     sub requestoption {
251     my $self=shift;
252     my $param=shift;
253     my $string=shift;
254    
255 williamc 1.15 my $par=undef;
256     if ( defined $self->basequery()) {
257     $par=$self->basequery()->getparam($param);
258 williamc 1.14 while ( ! defined $par ) {
259     $self->basequery()->querytype( $param, "basic");
260     $self->basequery()->querymessage( $param, $string);
261     $self->userinterface()->askuser($self->basequery());
262 williamc 1.15 $par=$self->basequery()->getparam($param);
263 williamc 1.14 }
264 williamc 1.15 }
265 williamc 1.14 return $par;
266 williamc 1.2 }
267    
268 williamc 1.20 sub askuser {
269     my $self=shift;
270     return $self->userinterface()->askuser(@_);
271     }
272    
273 williamc 1.22 sub getfile {
274 williamc 1.3 my $self=shift;
275 williamc 1.6 my $origurl=shift;
276    
277     my $fileref;
278 williamc 1.20 my ($url, $file);
279 williamc 1.21 if ( (defined ($it=$self->option('url_update'))) &&
280     ( $it eq "1" || $origurl=~/^$it/ )) {
281     $self->verbose("Forced download of $origurl");
282     ($url, $file)=$self->{urlhandler}->download($origurl);
283 williamc 1.20 }
284     else {
285 williamc 1.21 $self->verbose("Attempting to get $origurl");
286 williamc 1.20 ($url, $file)=$self->{urlhandler}->get($origurl);
287     }
288 williamc 1.6 # do we already have an appropriate object?
289 williamc 1.7 ($fileref)=$self->config()->find($url);
290     #undef $fileref;
291 williamc 1.6 if ( defined $fileref ) {
292 williamc 1.20 $self->verbose("Found $url in database");
293 williamc 1.6 $fileref->update();
294     }
295     else {
296     if ( $file eq "" ) {
297     $self->parseerror("Unable to get $origurl");
298     }
299     #-- set up a new preprocess file
300 williamc 1.21 $self->verbose("Making a new preprocessed file $url");
301 williamc 1.6 $fileref=ActiveDoc::PreProcessedFile->new($self->config());
302     $fileref->url($url);
303     $fileref->update();
304     }
305     return $fileref;
306 williamc 1.3 }
307    
308 williamc 1.9 sub activatedoc {
309     my $self=shift;
310     my $url=shift;
311    
312     # first get a preprocessed copy of the file
313 williamc 1.14 # my $fileob=$self->getfile($url);
314 williamc 1.9
315     # now parse it for the <DocType> tag
316 williamc 1.14 my $tempdoc=ActiveDoc::ActiveDoc->new($self->config());
317 williamc 1.16 $tempdoc->{urlhandler}=$self->{urlhandler};
318 williamc 1.17 my $fullurl=$tempdoc->url($url);
319     $url=$fullurl;
320 williamc 1.14 $tempdoc->{doctypefound}=0;
321     $tempdoc->newparse("doctype");
322     $tempdoc->addtag("doctype","Doc", \&Doc_Start, $tempdoc,
323     "", $tempdoc, "", $tempdoc);
324     $tempdoc->parse("doctype");
325 williamc 1.9
326 williamc 1.14 if ( ! defined $tempdoc->{docobject} ) {
327     print "No <Doc type=> Specified in ".$url."\n";
328 williamc 1.9 exit 1;
329     }
330     # Set up a new object of the specified type
331 williamc 1.14 eval "require $tempdoc->{docobject}";
332     die $@ if $@;
333     my $newobj=$tempdoc->{docobject}->new($self->config());
334     undef $tempdoc;
335 williamc 1.10 $newobj->url($url);
336 williamc 1.21 $newobj->parent($self);
337 williamc 1.14 $newobj->_initparse();
338 williamc 1.9 return $newobj;
339     }
340    
341 williamc 1.21 sub parent {
342     my $self=shift;
343    
344     @_?$self->{parent}=shift
345     :$self->{parent};
346     }
347    
348 williamc 1.14 sub _initparse {
349     my $self=shift;
350    
351     $self->parse("init");
352     }
353 williamc 1.6 # -------- Error Handling and Error services --------------
354    
355 williamc 1.3 sub error {
356 williamc 1.6 my $self=shift;
357     my $string=shift;
358    
359     die $string."\n";
360     }
361    
362     sub parseerror {
363     my $self=shift;
364     my $string=shift;
365    
366 williamc 1.20 if ( $self->currentparsename() eq "" ) {
367 williamc 1.18 $self->error($string);
368     }
369     else {
370     ($line, $file)=$self->line();
371     print "Parse Error in ".$file->url().", line ".
372 williamc 1.6 $line."\n";
373 williamc 1.18 print $string."\n";
374 williamc 1.20 exit;
375 williamc 1.18 }
376 williamc 1.6 }
377    
378     sub checktag {
379     my $self=shift;
380     my $tagname=shift;
381     my $hashref=shift;
382     my $param=shift;
383 williamc 1.3
384 williamc 1.6 if ( ! exists $$hashref{$param} ) {
385     $self->parseerror("Incomplete Tag <$tagname> : $param required");
386     }
387     }
388 williamc 1.3
389 williamc 1.6 sub line {
390 williamc 1.7 my $self=shift;
391 williamc 1.9
392 williamc 1.6 my ($line, $fileobj)=
393 williamc 1.9 $self->{File}->realline($self->{currentparser}->line());
394 williamc 1.6 return ($line, $fileobj);
395 williamc 1.7 }
396    
397     sub tagstartline {
398     my $self=shift;
399 williamc 1.8 my ($line, $fileobj)=$self->{File}->line(
400 williamc 1.7 $self->{currentparser}->tagstartline());
401     return ($line, $fileobj);
402 williamc 1.3 }
403 williamc 1.6
404     sub file {
405 williamc 1.2 my $self=shift;
406    
407 williamc 1.8 $self->{File}->file();
408 williamc 1.21 }
409    
410     sub ProcessFile {
411     my $self=shift;
412    
413     return $self->{File}->ProcessedFile();
414 williamc 1.2 }
415    
416 williamc 1.6 # --------------- Initialisation Methods ---------------------------
417 williamc 1.2
418 williamc 1.6 sub init {
419     # Dummy Routine - override for derived classes
420 williamc 1.1 }
421    
422 williamc 1.6 # ------------------- Tag Routines -----------------------------------
423 williamc 1.1 #
424 williamc 1.6 # Base - for setting url bases
425 williamc 1.1 #
426 williamc 1.6 sub Base_start {
427     my $self=shift;
428     my $name=shift;
429     my $hashref=shift;
430 williamc 1.2
431 williamc 1.6 $self->checktag($name, $hashref, 'type' );
432     $self->checktag($name, $hashref, 'base' );
433    
434     # Keep track of base tags
435     push @{$self->{basestack}}, $$hashref{"type"};
436     # Set the base
437     $self->{urlhandler}->setbase($$hashref{"type"},$hashref);
438 williamc 1.1 }
439    
440 williamc 1.6 sub Base_end {
441     my $self=shift;
442 williamc 1.1 my $name=shift;
443 williamc 1.6 my $type;
444 williamc 1.1
445 williamc 1.6 if ( $#{$self->{basestack}} == -1 ) {
446 williamc 1.19 $self->parseerror("Parse Error : unmatched </$name>");
447 williamc 1.6 }
448     else {
449     $type = pop @{$self->{basestack}};
450     $self->{urlhandler}->unsetbase($type);
451     }
452 williamc 1.9 }
453    
454     sub Doc_Start {
455     my $self=shift;
456     my $name=shift;
457     my $hashref=shift;
458    
459     $self->checktag($name, $hashref, "type");
460 williamc 1.10 $self->{doctypefound}++;
461     if ( $self->{doctypefound} == 1 ) { # only take first doctype
462     $self->{docobject}=$$hashref{'type'};
463     }
464     }
465    
466     sub userinterface {
467     my $self=shift;
468     @_?$self->{userinterface}=shift
469     :$self->{userinterface}
470 williamc 1.23 }
471    
472     sub _saveactivedoc {
473     my $self=shift;
474     my $fh=shift;
475     print "Storing $self\n";
476     print $fh $self->url()."\n";
477     }
478    
479     sub _restoreactivedoc {
480     my $self=shift;
481     my $fh=shift;
482    
483     my $url=<$fh>;
484     chomp $url;
485     $self->url($url);
486 williamc 1.1 }