ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/ActiveDoc/ActiveDoc.pm
Revision: 1.18
Committed: Wed Jan 26 12:28:06 2000 UTC (25 years, 3 months ago) by williamc
Content type: text/plain
Branch: MAIN
Changes since 1.17: +9 -4 lines
Log Message:
parseerror defaults to regular error if called outside of a current parse

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