ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/ActiveDoc/ActiveDoc.pm
Revision: 1.25
Committed: Wed Mar 29 09:45:47 2000 UTC (25 years, 1 month ago) by williamc
Content type: text/plain
Branch: MAIN
CVS Tags: ProtoEnd
Branch point for: V0_9branch
Changes since 1.24: +4 -1 lines
Log Message:
tweaking

File Contents

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