/[suikacvs]/messaging/manakai/bin/mkdisdump.pl
Suika

Contents of /messaging/manakai/bin/mkdisdump.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.17 - (show annotations) (download)
Fri Sep 21 08:09:16 2007 UTC (17 years, 2 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.16: +1 -1 lines
File MIME type: text/plain
Error occurred while calculating annotation data.
FILE REMOVED
++ manakai/bin/ChangeLog	21 Sep 2007 07:55:21 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* daf.pl, mkdisdump.pl, grep-dis.pl, mkdommemlist.pl: Removed.

++ manakai/lib/Message/IMT/ChangeLog	21 Sep 2007 08:02:20 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* InternetMediaType.pm: Don't raise CoreException even if
	a read-only attribute is attempted to be modified.

++ manakai/lib/Message/Markup/ChangeLog	21 Sep 2007 07:46:59 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* SuikaWikiConfig21.dis, SuikaWikiConfig21.pm, common.dis,
	H2H.dis: Removed.

++ manakai/lib/Message/Util/ChangeLog	21 Sep 2007 07:44:10 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* Makefile (clean): Don't remove generated files.

	* ManakaiNode.dis, ManakaiNodeTest.dis, PerlCode.dis,
	PerlCode.pm, ManakaiNode.pm, common.dis, DIS.dis, DIS.pm: Removed.

	* DIS/, AutoLoad/: Removed.

++ manakai/lib/Message/Util/Error/ChangeLog	21 Sep 2007 07:44:55 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* Core.dis, DOMException.pm, DOMException.dis: Removed.

++ manakai/lib/Message/Util/Formatter/ChangeLog	21 Sep 2007 08:09:07 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* Base.pm (___error_def): Error description key names
	are updated.

	* Muf2003.dis: Removed.

++ manakai/lib/manakai/ChangeLog	21 Sep 2007 07:52:20 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* DISLang.dis, Document.dis, NaturalLanguage.dis, DISMarkup.dis,
	ECMAScript.dis, Test.dis, Charset.dis, DISPerl.dis, Java.dis,
	XML.dis, DISCore.dis, DISRDF.dis, DISIDL.dis, DISSource.dis,
	Message.dis, daf-perl-t.pl, daf-dtd-modules.pl, daf-perl-pm.pl,
	dis-catalog, mndebug.pl: Removed.

++ manakai/t/ChangeLog	21 Sep 2007 08:00:31 -0000
2007-09-21  Wakaba  <wakaba@suika.fam.cx>

	* util-mnode.t: Removed.

1 #!/usr/bin/perl -w
2 use strict;
3
4 =head1 NAME
5
6 mkdisdump.pl - Generating Perl Module Documentation Source
7
8 =head1 SYNOPSIS
9
10 perl path/to/mkdisdump.pl input.cdis \
11 {--module-name=ModuleName | --module-uri=module-uri} \
12 [--for=for-uri] [options] > ModuleName.pm
13 perl path/to/cdis2pm.pl --help
14
15 =head1 DESCRIPTION
16
17 The C<cdis2pm> script generates a Perl module from a compiled "dis"
18 ("cdis") file. It is intended to be used to generate a manakai
19 DOM Perl module files, although it might be useful for other purpose.
20
21 This script is part of manakai.
22
23 =cut
24
25 use Message::Util::QName::Filter {
26 ddel => q<http://suika.fam.cx/~wakaba/archive/2005/disdoc#>,
27 ddoct => q<http://suika.fam.cx/~wakaba/archive/2005/8/disdump-xslt#>,
28 DIS => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#>,
29 dis => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis-->,
30 dis2pm => q<http://suika.fam.cx/~wakaba/archive/2004/11/8/dis2pm#>,
31 DISCore => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Core#>,
32 DISLang => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Lang#>,
33 DISPerl => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Perl#>,
34 doc => q<http://suika.fam.cx/~wakaba/archive/2004/dis/Document#>,
35 DOMLS => q<http://suika.fam.cx/~wakaba/archive/2004/dom/ls#>,
36 dump => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/DIS#DISDump/>,
37 dx => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/DOMException#>,
38 ecore => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/Error/Core/>,
39 idl => q<http://suika.fam.cx/~wakaba/archive/2004/dis/IDL#>,
40 infoset => q<http://www.w3.org/2001/04/infoset#>,
41 lang => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#>,
42 ManakaiDOM => q<http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#>,
43 Markup => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Markup#>,
44 Util => q<http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/>,
45 xml => q<http://www.w3.org/XML/1998/namespace>,
46 xmlns => q<http://www.w3.org/2000/xmlns/>,
47 };
48
49 =head1 OPTIONS
50
51 =over 4
52
53 =item --for=I<for-uri> (Optional)
54
55 Specifies the "For" URI reference for which the outputed module is.
56 If this parameter is ommitted, the default "For" URI reference
57 for the module, if any, or the C<ManakaiDOM:all> is assumed.
58
59 =item --help
60
61 Shows the help message.
62
63 =item --module-uri=I<module-uri>
64
65 A URI reference that identifies a module to output. Either
66 C<--module-name> or C<--module-uri> is required.
67
68 =item --verbose / --noverbose (default)
69
70 Whether a verbose message mode should be selected or not.
71
72 =item --with-implementators-note / --nowith-implementators-note (default)
73
74 Whether the implemetator's notes should also be included
75 in the result or not.
76
77 =back
78
79 =cut
80
81 use Getopt::Long;
82 use Pod::Usage;
83 use Storable;
84 use Message::Util::Error;
85 my %Opt = (
86 module_uri => {},
87 resource_uri => {},
88 );
89 GetOptions (
90 'debug' => \$Opt{debug},
91 'dis-file-suffix=s' => \$Opt{dis_suffix},
92 'daem-file-suffix=s' => \$Opt{daem_suffix},
93 'for=s' => \$Opt{For},
94 'help' => \$Opt{help},
95 'module-uri=s' => sub {
96 shift;
97 my ($nuri, $furi) = split /\s+/, shift, 2;
98 $furi ||= '';
99 $Opt{module_uri}->{$nuri}->{$furi} = 1;
100 },
101 'resource-uri=s' => sub {
102 shift;
103 my ($nuri, $furi) = split /\s+/, shift, 2;
104 $furi ||= '';
105 $Opt{resource_uri}->{$nuri}->{$furi} = 1;
106 },
107 'search-path|I=s' => sub {
108 shift;
109 my @value = split /\s+/, shift;
110 while (my ($ns, $path) = splice @value, 0, 2, ()) {
111 unless (defined $path) {
112 die qq[$0: Search-path parameter without path: "$ns"];
113 }
114 push @{$Opt{input_search_path}->{$ns} ||= []}, $path;
115 }
116 },
117 'search-path-catalog-file-name=s' => sub {
118 shift;
119 require File::Spec;
120 my $path = my $path_base = shift;
121 $path_base =~ s#[^/]+$##;
122 $Opt{search_path_base} = $path_base;
123 open my $file, '<', $path or die "$0: $path: $!";
124 while (<$file>) {
125 if (s/^\s*\@//) { ## Processing instruction
126 my ($target, $data) = split /\s+/;
127 if ($target eq 'base') {
128 $Opt{search_path_base} = File::Spec->rel2abs ($data, $path_base);
129 } else {
130 die "$0: $target: Unknown target";
131 }
132 } elsif (/^\s*\#/) { ## Comment
133 #
134 } elsif (/\S/) { ## Catalog entry
135 s/^\s+//;
136 my ($ns, $path) = split /\s+/;
137 push @{$Opt{input_search_path}->{$ns} ||= []},
138 File::Spec->rel2abs ($path, $Opt{search_path_base});
139 }
140 }
141 ## NOTE: File paths with SPACEs are not supported
142 ## NOTE: Future version might use file: URI instead of file path.
143 },
144 'with-implementators-note' => \$Opt{with_impl_note},
145 'verbose!' => \$Opt{verbose},
146 ) or pod2usage (2);
147 pod2usage ({-exitval => 0, -verbose => 1}) if $Opt{help};
148 $Opt{file_name} = shift;
149 pod2usage ({-exitval => 2, -verbose => 0}) unless $Opt{file_name};
150 pod2usage (2) unless (keys %{$Opt{module_uri}}) + (keys %{$Opt{resource_uri}});
151 $Message::DOM::DOMFeature::DEBUG = 1 if $Opt{debug};
152 $Opt{dis_suffix} = '.dis' unless defined $Opt{dis_suffix};
153 $Opt{daem_suffix} = '.daem' unless defined $Opt{daem_suffix};
154
155 sub status_msg ($) {
156 my $s = shift;
157 $s .= "\n" unless $s =~ /\n$/;
158 print STDERR $s;
159 }
160
161 sub status_msg_ ($) {
162 my $s = shift;
163 print STDERR $s;
164 }
165
166 sub verbose_msg ($) {
167 my $s = shift;
168 $s .= "\n" unless $s =~ /\n$/;
169 print STDERR $s if $Opt{verbose};
170 }
171
172 sub verbose_msg_ ($) {
173 my $s = shift;
174 print STDERR $s if $Opt{verbose};
175 }
176
177 {
178 my $ResourceCount = 0;
179 sub progress_inc (;$) {
180 $ResourceCount += (shift || 1);
181 if (($ResourceCount % 10) == 0) {
182 print STDERR "*";
183 print STDERR " " if ($ResourceCount % (10 * 10)) == 0;
184 print STDERR "\n" if ($ResourceCount % (10 * 50)) == 0;
185 }
186 }
187
188 sub progress_reset () {
189 $ResourceCount = 0;
190 }
191 }
192
193 my $start_time;
194 BEGIN { $start_time = time }
195
196 use Message::DOM::GenericLS;
197 use Message::DOM::SimpleLS;
198 use Message::Util::DIS::DISDump;
199 use Message::Util::DIS::DISDoc;
200 use Message::Util::DIS::DNLite;
201
202 my $impl = $Message::DOM::ImplementationRegistry->get_implementation
203 ({
204 ExpandedURI q<ManakaiDOM:Minimum> => '3.0',
205 '+' . ExpandedURI q<DOMLS:Generic> => '3.0',
206 '+' . ExpandedURI q<DIS:Doc> => '2.0',
207 '+' . ExpandedURI q<DIS:DNLite> => '1.0',
208 ExpandedURI q<DIS:Dump> => '1.0',
209 });
210
211 ## -- Load input dac database file
212 status_msg_ qq<Opening dac file "$Opt{file_name}"...>;
213 our $db = $impl->get_feature (ExpandedURI q<DIS:DNLite> => '1.0')
214 ->pl_load_dis_database ($Opt{file_name}, sub ($$) {
215 my ($db, $mod) = @_;
216 my $ns = $mod->namespace_uri;
217 my $ln = $mod->local_name;
218 verbose_msg qq<Database module <$ns$ln> is requested>;
219 my $name = dac_search_file_path_stem ($ns, $ln, $Opt{daem_suffix});
220 if (defined $name) {
221 return $name.$Opt{daem_suffix};
222 } else {
223 return $ln.$Opt{daem_suffix};
224 }
225 });
226 status_msg qq<done\n>;
227
228 our %ReferredResource;
229 our %ClassMembers;
230 our %ClassInheritance;
231 our @ClassInheritance;
232 our %ClassImplements;
233
234 sub append_module_group_documentation (%) {
235 my %opt = @_;
236 my $section = $opt{result_parent}
237 ->append_child ($opt{result_parent}->owner_document
238 ->create_element_ns (ExpandedURI q<dump:>, 'moduleGroup'));
239
240 add_uri ($opt{source_resource} => $section);
241
242 my $path = $opt{source_resource}->get_property_text
243 (ExpandedURI q<dis:FileName>,
244 $opt{source_resource}->local_name);
245 $section->resource_file_path_stem ($path);
246
247 $section->set_attribute_ns
248 (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
249
250 append_description (source_resource => $opt{source_resource},
251 result_parent => $section,
252 has_label => 1);
253
254 ## -- Member modules
255
256 for my $rres (@{$opt{source_resource}->get_property_module_list
257 (ExpandedURI q<DISCore:module>)}) {
258 $Opt{module_uri}->{$rres->name_uri}->{$rres->for_uri} = 1;
259 my $mod_el = $section->append_child
260 ($section->owner_document
261 ->create_element_ns (ExpandedURI q<dump:>, 'module'));
262 $mod_el->ref ($rres->uri);
263 }
264
265 ## -- Member resources
266
267 for my $rres (@{$opt{source_resource}->get_property_resource_list
268 (ExpandedURI q<DISCore:resource>)}) {
269 progress_inc;
270 if ($rres->is_type_uri (ExpandedURI q<doc:Document>)) {
271 append_document_documentation (source_resource => $rres,
272 result_parent => $section);
273 } else {
274 #
275 }
276 }
277 status_msg "";
278 } # append_module_group_documentation
279
280 sub append_document_documentation (%) {
281 my %opt = @_;
282 my $section = $opt{result_parent}
283 ->append_child ($opt{result_parent}->owner_document
284 ->create_element_ns (ExpandedURI q<dump:>, 'document'));
285 my $od = $section->owner_document;
286
287 add_uri ($opt{source_resource} => $section);
288
289 my $path = $opt{source_resource}->get_property_text
290 (ExpandedURI q<dis:FileName>,
291 lcfirst $opt{source_resource}->local_name);
292 $section->resource_file_path_stem ($path);
293
294 $section->set_attribute_ns
295 (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
296
297 if ($opt{source_resource}->is_type_uri (ExpandedURI q<doc:Document>)) {
298 $section->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'rel'))
299 ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri',
300 ExpandedURI q<doc:Document>);
301 }
302
303 ## TODO: Conneg
304 for my $con (@{$opt{source_resource}->get_property_value_list
305 (ExpandedURI q<doc:content>)}) {
306 my $cond = $con->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
307 my $tree = $cond->get_disdoc_tree
308 ($od, ExpandedURI q<lang:disdoc>,
309 $opt{source_resource}->database,
310 default_name_uri => $opt{source_resource}->source_node_id,
311 default_for_uri => $opt{source_resource}->for_uri);
312 $section
313 ->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'content'))
314 ->append_child (transform_disdoc_tree ($tree));
315 }
316
317 append_document_properties
318 (source_resource => $opt{source_resource},
319 result_parent => $section);
320
321 for my $v (@{$opt{source_resource}->get_property_value_list
322 (ExpandedURI q<doc:part>)}) {
323 my $res = $v->get_resource ($opt{source_resource}->database);
324 $ReferredResource{$res->uri} ||= 2;
325 $ReferredResource{$res->uri} = 2
326 if $ReferredResource{$res->uri} == 1;
327 my $doc = $section->append_child
328 ($od->create_element_ns (ExpandedURI q<dump:>, 'document'));
329 $doc->ref ($res->uri);
330 for my $vv (@{$v->get_property (ExpandedURI q<doc:rel>)||[]}) {
331 $doc->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'rel'))
332 ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $vv->uri);
333 }
334 for my $vv (@{$v->get_property (ExpandedURI q<doc:as>)||[]}) {
335 $doc->append_child ($od->create_element_ns (ExpandedURI q<doc:>, 'as'))
336 ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $vv->uri);
337 }
338 }
339 } # append_document_documentation
340
341 sub append_module_documentation (%) {
342 my %opt = @_;
343 my $section = $opt{result_parent}->create_module ($opt{source_resource}->uri);
344 my $od = $opt{result_parent}->owner_document;
345
346 add_uri ($opt{source_resource} => $section);
347
348 my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
349 if (defined $pl_full_name) {
350 $section->perl_package_name ($pl_full_name);
351
352 my $path = $opt{source_resource}->get_property_text
353 (ExpandedURI q<dis:FileName>, $pl_full_name);
354 $path =~ s#::#/#g;
355 $section->resource_file_path_stem ($path);
356
357 $section->set_attribute_ns
358 (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
359 $pl_full_name =~ s/.*:://g;
360 $section->perl_name ($pl_full_name);
361 }
362
363 for my $con (@{$opt{source_resource}->get_property_value_list
364 (ExpandedURI q<DISCore:AnyAppName>)}) {
365 my $ns = $con->name;
366 my $ln = $1 if ($ns =~ s/(\w+)$//);
367 if ($con->isa ('Message::Util::IF::DVURIValue')) {
368 $section->append_child ($od->create_element_ns ($ns, $ln))
369 ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:ref',
370 $con->string_value);
371 $ReferredResource{$con->uri} ||= 1;
372 } else {
373 $section->append_child ($od->create_element_ns ($ns, $ln))
374 ->text_content ($con->string_value);
375 }
376 if ($con->isa ('Message::Util::IF::DVURIValue')) {
377 $ReferredResource{$con->uri} ||= 1;
378 }
379 }
380
381 append_description (source_resource => $opt{source_resource},
382 result_parent => $section);
383
384 if ($opt{is_partial}) {
385 $section->resource_is_partial (1);
386 return;
387 }
388
389 for my $rres (@{$opt{source_resource}->get_resource_list}) {
390 if ($rres->owner_module eq $opt{source_resource} and## Defined in this module
391 not ($ReferredResource{$rres->uri} < 0)) {
392 ## TODO: Modification required to support modplans
393 progress_inc;
394 if ($rres->is_type_uri (ExpandedURI q<DISLang:Class>)) {
395 append_class_documentation
396 (result_parent => $section,
397 source_resource => $rres);
398 } elsif ($rres->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
399 append_interface_documentation
400 (result_parent => $section,
401 source_resource => $rres);
402 } elsif ($rres->is_type_uri (ExpandedURI q<DISCore:AnyType>)) {
403 append_datatype_documentation
404 (result_parent => $section,
405 source_resource => $rres);
406 }
407 } else { ## Aliases
408 #
409 }
410 }
411 status_msg "";
412 } # append_module_documentation
413
414 sub append_datatype_documentation (%) {
415 my %opt = @_;
416 my $od = $opt{result_parent}->owner_document;
417 my $section = $opt{result_parent}->can ('create_data_type')
418 ? $opt{result_parent}->create_data_type
419 ($opt{source_resource}->uri)
420 : $opt{result_parent}->append_child
421 ($od->create_element_ns
422 (ExpandedURI q<dump:>, 'dataType'));
423
424 add_uri ($opt{source_resource} => $section);
425
426 my $uri = $opt{source_resource}->name_uri;
427 if ($uri) {
428 my $fu = $opt{source_resource}->for_uri;
429 unless ($fu eq ExpandedURI q<ManakaiDOM:all>) {
430 $fu =~ /([\w.-]+)[^\w.-]*$/;
431 $uri .= '-' . $1;
432 }
433 } else {
434 $opt{source_resource}->uri;
435 }
436 $uri =~ s#\b(\d\d\d\d+)/(\d\d?)/(\d\d?)#sprintf '%04d%02d%02d', $1, $2, $3#ge;
437 my @file = map {s/[^\w-]/_/g; $_} split m{[/:#?]+}, $uri;
438
439 $section->resource_file_path_stem (join '/', @file);
440 $section->set_attribute_ns
441 (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x (@file - 1));
442
443 for my $con (@{$opt{source_resource}->get_property_value_list
444 (ExpandedURI q<dis:AppName>)},
445 @{$opt{source_resource}->get_property_value_list
446 (ExpandedURI q<dis:Def>)}) {
447 my $ns = $con->name;
448 my $ln = $1 if ($ns =~ s/(\w+)$//);
449 if ($con->isa ('Message::Util::IF::DVURIValue')) {
450 $section->append_child ($od->create_element_ns ($ns, $ln))
451 ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:ref',
452 $con->string_value);
453 $ReferredResource{$con->uri} ||= 1;
454 } else {
455 $section->append_child ($od->create_element_ns ($ns, $ln))
456 ->text_content ($con->string_value);
457 }
458 }
459
460 append_document_properties
461 (source_resource => $opt{source_resource},
462 result_parent => $section);
463
464 append_description (source_resource => $opt{source_resource},
465 result_parent => $section,
466 has_label => 1);
467
468 if ($opt{is_partial}) {
469 $section->resource_is_partial (1);
470 return;
471 }
472
473 append_subclassof (source_resource => $opt{source_resource},
474 result_parent => $section);
475 } # append_datatype_documentation
476
477 sub append_interface_documentation (%) {
478 my %opt = @_;
479 my $section = $opt{result_parent}->create_interface
480 (my $class_uri = $opt{source_resource}->uri);
481 push @ClassInheritance, $class_uri;
482
483 add_uri ($opt{source_resource} => $section);
484
485 my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
486 my $path;
487 if (defined $pl_full_name) {
488 $section->perl_package_name ($pl_full_name);
489
490 $path = $opt{source_resource}->get_property_text
491 (ExpandedURI q<dis:FileName>, $pl_full_name);
492 $path =~ s#::#/#g;
493 $section->resource_file_path_stem ($path);
494 $section->perl_name ($pl_full_name);
495 } else {
496 $path = $opt{source_resource}->get_property_text
497 (ExpandedURI q<dis:FileName>, $opt{source_resource}->local_name);
498 $section->resource_file_path_stem ($path);
499 }
500 $section->set_attribute_ns
501 (ExpandedURI q<ddoct:>, 'ddoct:basePath',
502 join '', '../' x ($path =~ tr#/#/#));
503 $pl_full_name =~ s/.*:://g;
504
505 $section->is_exception_interface (1)
506 if $opt{source_resource}->is_type_uri (ExpandedURI q<DISLang:Exception>);
507
508 append_description (source_resource => $opt{source_resource},
509 result_parent => $section);
510
511 if ($opt{is_partial}) {
512 $section->resource_is_partial (1);
513 }
514
515 for my $memres (@{$opt{source_resource}->get_child_resource_list}) {
516 if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
517 append_method_documentation (source_resource => $memres,
518 result_parent => $section,
519 class_uri => $class_uri,
520 is_partial => $opt{is_partial});
521 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
522 append_attr_documentation (source_resource => $memres,
523 result_parent => $section,
524 class_uri => $class_uri,
525 is_partial => $opt{is_partial});
526 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
527 append_constgroup_documentation (source_resource => $memres,
528 result_parent => $section,
529 class_uri => $class_uri,
530 is_partial => $opt{is_partial});
531 }
532 }
533
534 return if $opt{is_partial};
535
536 ## Inheritance
537 append_inheritance (source_resource => $opt{source_resource},
538 result_parent => $section,
539 class_uri => $class_uri);
540
541 if ($opt{source_resource}->is_type_uri (ExpandedURI q<idl:AnyInterface>)) {
542 $ReferredResource{ExpandedURI q<idl:void>} ||= 1;
543 }
544 } # append_interface_documentation
545
546 sub append_class_documentation (%) {
547 my %opt = @_;
548 my $section = $opt{result_parent}->create_class
549 (my $class_uri = $opt{source_resource}->uri);
550 push @ClassInheritance, $class_uri;
551
552 add_uri ($opt{source_resource} => $section);
553
554 my $pl_full_name = $opt{source_resource}->pl_fully_qualified_name;
555 if (defined $pl_full_name) {
556 $section->perl_package_name ($pl_full_name);
557
558 my $path = $opt{source_resource}->get_property_text
559 (ExpandedURI q<dis:FileName>, $pl_full_name);
560 $path =~ s#::#/#g;
561
562 $section->resource_file_path_stem ($path);
563 $section->set_attribute_ns
564 (ExpandedURI q<ddoct:>, 'ddoct:basePath', '../' x ($path =~ tr#/#/#));
565 $pl_full_name =~ s/.*:://g;
566 $section->perl_name ($pl_full_name);
567 }
568
569 append_description (source_resource => $opt{source_resource},
570 result_parent => $section);
571
572 if ($opt{is_partial}) {
573 $section->resource_is_partial (1);
574 }
575
576 my $has_const = 0;
577 for my $memres (@{$opt{source_resource}->get_child_resource_list}) {
578 if ($memres->is_type_uri (ExpandedURI q<DISLang:Method>)) {
579 append_method_documentation (source_resource => $memres,
580 result_parent => $section,
581 class_uri => $class_uri,
582 is_partial => $opt{is_partial});
583 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
584 append_attr_documentation (source_resource => $memres,
585 result_parent => $section,
586 class_uri => $class_uri,
587 is_partial => $opt{is_partial});
588 } elsif ($memres->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
589 $has_const = 1;
590 append_constgroup_documentation
591 (source_resource => $memres,
592 result_parent => $section,
593 class_uri => $class_uri,
594 is_partial => $opt{is_partial});
595 }
596 }
597
598 return if $opt{is_partial};
599
600 ## Inheritance
601 append_inheritance (source_resource => $opt{source_resource},
602 result_parent => $section,
603 append_implements => 1,
604 class_uri => $class_uri,
605 has_const => $has_const,
606 is_class => 1);
607
608 } # append_class_documentation
609
610 sub append_method_documentation (%) {
611 my %opt = @_;
612 my $perl_name = $opt{source_resource}->pl_name;
613 my $od = $opt{result_parent}->owner_document;
614 my $m;
615 if (defined $perl_name) {
616 $m = $opt{result_parent}->create_method ($perl_name);
617 $ClassMembers{$opt{class_uri}}->{$perl_name}
618 = {
619 resource => $opt{source_resource},
620 type => 'method',
621 };
622
623 } else { ## Anonymous
624 ## TODO
625 return;
626 }
627
628 add_uri ($opt{source_resource} => $m);
629
630 for my $con (@{$opt{source_resource}->get_property_value_list
631 (ExpandedURI q<DISCore:AnyAppName>)}) {
632 my $ns = $con->name;
633 my $ln = $1 if ($ns =~ s/(\w+)$//);
634 if ($con->isa ('Message::Util::IF::DVURIValue')) {
635 $m->append_child ($od->create_element_ns ($ns, $ln))
636 ->set_attribute_ns (ExpandedURI q<dump:>, 'dump:ref',
637 $con->string_value);
638 $ReferredResource{$con->uri} ||= 1;
639 } else {
640 $m->append_child ($od->create_element_ns ($ns, $ln))
641 ->text_content ($con->string_value);
642 }
643 }
644
645 append_description (source_resource => $opt{source_resource},
646 result_parent => $m,
647 method_resource => $opt{source_resource});
648
649 $m->resource_access ('private')
650 if $opt{source_resource}->get_property_boolean
651 (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
652
653 if ($opt{is_partial}) {
654 $m->resource_is_partial (1);
655 return;
656 }
657
658 my $ret = $opt{source_resource}->get_child_resource_by_type
659 (ExpandedURI q<DISLang:MethodReturn>);
660 if ($ret) {
661 my $r = $m->dis_return;
662
663 try {
664 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
665 $ReferredResource{$u} ||= 1;
666 $r->resource_actual_data_type
667 ($u = $ret->dis_actual_data_type_resource->uri);
668 $ReferredResource{$u} ||= 1;
669
670 ## TODO: Exceptions
671 } catch Message::Util::DIS::ManakaiDISException with {
672
673 };
674
675 append_description (source_resource => $ret,
676 result_parent => $r,
677 has_case => 1,
678 method_resource => $opt{source_resource});
679
680 append_raises (source_resource => $ret,
681 result_parent => $r,
682 method_resource => $opt{source_resource});
683 }
684
685 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
686 if ($cr->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
687 append_param_documentation (source_resource => $cr,
688 result_parent => $m,
689 method_resource => $opt{source_resource});
690 }
691 }
692 } # append_method_documentation
693
694 sub append_attr_documentation (%) {
695 my %opt = @_;
696 my $perl_name = $opt{source_resource}->pl_name;
697 my $m;
698 if (defined $perl_name) {
699 $m = $opt{result_parent}->create_attribute ($perl_name);
700 $ClassMembers{$opt{class_uri}}->{$perl_name}
701 = {
702 resource => $opt{source_resource},
703 type => 'attr',
704 };
705
706 } else { ## Anonymous
707 ## TODO
708 return;
709 }
710
711 add_uri ($opt{source_resource} => $m);
712
713 $m->resource_access ('private')
714 if $opt{source_resource}->get_property_boolean
715 (ExpandedURI q<ManakaiDOM:isForInternal>, 0);
716
717 if ($opt{is_partial}) {
718 $m->resource_is_partial (1);
719 $m->is_read_only_attribute (1)
720 if $opt{source_resource}->get_child_resource_by_type
721 (ExpandedURI q<DISLang:AttributeSet>);
722 return;
723 }
724
725 append_description (source_resource => $opt{source_resource},
726 result_parent => $m,
727 has_case => 1);
728
729 my $ret = $opt{source_resource}->get_child_resource_by_type
730 (ExpandedURI q<DISLang:AttributeGet>);
731 if ($ret) {
732 my $r = $m->dis_get;
733
734 $r->resource_data_type (my $u = $ret->dis_data_type_resource->uri);
735 $ReferredResource{$u} ||= 1;
736 $r->resource_actual_data_type
737 ($u = $ret->dis_actual_data_type_resource->uri);
738 $ReferredResource{$u} ||= 1;
739
740 append_description (source_resource => $ret,
741 result_parent => $r,
742 has_case => 1);
743
744 append_raises (source_resource => $ret,
745 result_parent => $r);
746 }
747
748 my $set = $opt{source_resource}->get_child_resource_by_type
749 (ExpandedURI q<DISLang:AttributeSet>);
750 if ($set) {
751 my $r = $m->dis_set;
752
753 $r->resource_data_type (my $u = $set->dis_data_type_resource->uri);
754 $ReferredResource{$u} ||= 1;
755 $r->resource_actual_data_type ($set->dis_actual_data_type_resource->uri);
756 $ReferredResource{$u} ||= 1;
757
758 append_description (source_resource => $set,
759 result_parent => $r,
760 has_case => 1);
761
762 append_raises (source_resource => $set,
763 result_parent => $r);
764 } else {
765 $m->is_read_only_attribute (1);
766 }
767 } # append_attr_documentation
768
769 sub append_constgroup_documentation (%) {
770 my %opt = @_;
771 my $perl_name = $opt{source_resource}->pl_name;
772 my $m = $opt{result_parent}->create_const_group ($perl_name);
773 $ClassMembers{$opt{class_uri}}->{$perl_name}
774 = {
775 resource => $opt{source_resource},
776 type => 'const-group',
777 };
778
779 add_uri ($opt{source_resource} => $m);
780
781 if ($opt{is_partial}) {
782 $m->resource_is_partial (1);
783 return;
784 }
785
786 append_description (source_resource => $opt{source_resource},
787 result_parent => $m);
788
789 $m->resource_data_type
790 (my $u = $opt{source_resource}->dis_data_type_resource->uri);
791 $ReferredResource{$u} ||= 1;
792 $m->resource_actual_data_type
793 ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
794 $ReferredResource{$u} ||= 1;
795
796 append_subclassof (source_resource => $opt{source_resource},
797 result_parent => $m);
798
799 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
800 if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:Const>)) {
801 append_const_documentation (source_resource => $cr,
802 result_parent => $m);
803 }
804 }
805 } # append_constgroup_documentation
806
807 sub append_const_documentation (%) {
808 my %opt = @_;
809 my $perl_name = $opt{source_resource}->pl_name;
810 my $m = $opt{result_parent}->create_const ($perl_name);
811
812 add_uri ($opt{source_resource} => $m);
813
814 append_description (source_resource => $opt{source_resource},
815 result_parent => $m);
816
817 $m->resource_data_type
818 (my $u = $opt{source_resource}->dis_data_type_resource->uri);
819 $ReferredResource{$u} ||= 1;
820 $m->resource_actual_data_type
821 ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
822 $ReferredResource{$u} ||= 1;
823
824 my $value = $opt{source_resource}->pl_code_fragment;
825 if ($value) {
826 $m->create_value->text_content ($value->stringify);
827 }
828
829 for my $cr (@{$opt{source_resource}->get_child_resource_list}) {
830 if ($cr->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
831 append_xsubtype_documentation (source_resource => $cr,
832 result_parent => $m);
833 }
834 }
835 ## TODO: xparam
836 } # append_const_documentation
837
838 sub append_xsubtype_documentation (%) {
839 my %opt = @_;
840 my $m = $opt{result_parent}->create_exception_sub_code
841 ($opt{source_resource}->uri);
842 add_uri ($opt{source_resource} => $m);
843
844 append_description (source_resource => $opt{source_resource},
845 result_parent => $m);
846
847 ## TODO: xparam
848 } # append_xsubtype_documentation
849
850 sub append_param_documentation (%) {
851 my %opt = @_;
852
853 my $is_named_param = $opt{source_resource}->get_property_boolean
854 (ExpandedURI q<DISPerl:isNamedParameter>, 0);
855
856 my $perl_name = $is_named_param
857 ? $opt{source_resource}->pl_name
858 : $opt{source_resource}->pl_variable_name;
859
860 my $p = $opt{result_parent}->create_parameter ($perl_name, $is_named_param);
861
862 add_uri ($opt{source_resource} => $p);
863
864 $p->is_nullable_parameter ($opt{source_resource}->pl_is_nullable);
865 $p->resource_data_type
866 (my $u = $opt{source_resource}->dis_data_type_resource->uri);
867 $ReferredResource{$u} ||= 1;
868 $p->resource_actual_data_type
869 ($u = $opt{source_resource}->dis_actual_data_type_resource->uri);
870 $ReferredResource{$u} ||= 1;
871
872 append_description (source_resource => $opt{source_resource},
873 result_parent => $p,
874 has_case => 1,
875 method_resource => $opt{method_resource});
876 } # append_param_documentation
877
878 sub append_description (%) {
879 my %opt = @_;
880
881 my $od = $opt{result_parent}->owner_document;
882 my $resd = $opt{source_resource}->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
883 my $doc = transform_disdoc_tree
884 ($resd->get_description
885 ($od, undef,
886 $Opt{with_impl_note},
887 parent_value_arg => $opt{source_value}),
888 method_resource => $opt{method_resource});
889 $opt{result_parent}->create_description->append_child ($doc);
890 ## TODO: Negotiation
891
892 my $fn = $resd->get_full_name ($od);
893 if ($fn) {
894 $opt{result_parent}->create_full_name
895 ->append_child (transform_disdoc_tree
896 ($fn,
897 method_resource => $opt{method_resource}));
898 }
899
900 if ($opt{has_label}) {
901 my $label = $resd->get_label ($od);
902 if ($label) {
903 if ($opt{result_parent}->can ('create_label')) {
904 $opt{result_parent}->create_label
905 ->append_child (transform_disdoc_tree ($label));
906 } else {
907 $opt{result_parent}->append_child
908 ($od->create_element_ns (ExpandedURI q<dump:>, 'label'))
909 ->append_child (transform_disdoc_tree ($label));;
910 }
911 }
912 }
913
914 if ($opt{has_case}) {
915 for my $caser (@{$opt{source_resource}->get_child_resource_list}) {
916 if ($caser->is_type_uri (ExpandedURI q<ManakaiDOM:InCase>)) {
917 my $case = $opt{result_parent}->append_case;
918 my $cased = $caser->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
919 my $label = $cased->get_label ($od);
920 if ($label) {
921 $case->create_label->append_child
922 (transform_disdoc_tree ($label,
923 method_resource => $opt{method_resource}));
924 }
925 my $value = $caser->pl_code_fragment;
926 if ($value) {
927 $case->create_value->text_content ($value->stringify);
928 }
929 $case->resource_data_type
930 (my $u = $caser->dis_data_type_resource->uri);
931 $ReferredResource{$u} ||= 1;
932 $case->resource_actual_data_type
933 ($u = $caser->dis_actual_data_type_resource->uri);
934 $ReferredResource{$u} ||= 1;
935
936 append_description (source_resource => $caser,
937 result_parent => $case,
938 method_resource => $opt{method_resource});
939 }
940 }
941 }
942 } # append_description
943
944 sub append_document_properties (%) {
945 my %opt = @_;
946 my $od = $opt{result_parent}->owner_document;
947
948 for my $con (@{$opt{source_resource}->get_property_value_list
949 (ExpandedURI q<dis:Label>)}) {
950 my $cond = $con->get_feature (ExpandedURI q<DIS:Doc>, '2.0');
951 my $tree = $cond->get_disdoc_tree
952 ($od, ExpandedURI q<lang:disdocInline>,
953 $opt{source_resource}->database,
954 default_name_uri => $opt{source_resource}->source_node_id,
955 default_for_uri => $opt{source_resource}->for_uri);
956 my $ns = $con->name;
957 my $ln = $1 if ($ns =~ s/(\w+)$//);
958 $opt{result_parent}->append_child ($od->create_element_ns ($ns, $ln))
959 ->append_child (transform_disdoc_tree ($tree));
960 }
961 } # append_document_properties
962
963 sub transform_disdoc_tree ($;%) {
964 my ($el, %opt) = @_;
965 my @el = ($el);
966 EL: while (defined (my $el = shift @el)) {
967 if ($el->node_type == $el->ELEMENT_NODE and
968 defined $el->namespace_uri) {
969 my $mmParsed = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'mmParsed');
970 if ($mmParsed) {
971 my $lextype = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'lexType');
972 if ($lextype eq ExpandedURI q<DISCore:TFQNames>) {
973 my $uri = dd_get_tfqnames_uri ($el);
974 if (defined $uri) {
975 $ReferredResource{$uri} ||= 1;
976 next EL;
977 }
978 } elsif ($lextype eq ExpandedURI q<DISCore:QName> or
979 $lextype eq ExpandedURI q<DISCore:NCNameOrQName>) {
980 my $uri = dd_get_qname_uri ($el);
981 if (defined $uri) {
982 $ReferredResource{$uri} ||= 1;
983 next EL;
984 }
985 } elsif ($lextype eq ExpandedURI q<DISLang:MemberRef> or
986 $lextype eq ExpandedURI q<dx:XCRef>) {
987 my @nm = @{$el->get_elements_by_tag_name_ns
988 (ExpandedURI q<ddel:>, 'name')};
989 if (@nm == 1) {
990 my $uri = dd_get_tfqnames_uri ($nm[0]);
991 if (defined $uri) {
992 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
993 $ReferredResource{$uri} ||= 1;
994 next EL;
995 }
996 } elsif (@nm == 3) {
997 my $uri = dd_get_tfqnames_uri ($nm[2]);
998 if (defined $uri) {
999 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
1000 $ReferredResource{$uri} ||= 1;
1001 next EL;
1002 }
1003 } elsif (@nm == 2) {
1004 my $uri = dd_get_tfqnames_uri ($nm[0]);
1005 if (not defined $uri) {
1006 #
1007 } elsif ($nm[1]->get_elements_by_tag_name_ns
1008 (ExpandedURI q<ddel:>, 'prefix')->[0]) {
1009 #my $luri = dd_get_qname_uri ($nm[1]);
1010 ## QName: Currently not used
1011 } else {
1012 my $lnel = $nm[1]->get_elements_by_tag_name_ns
1013 (ExpandedURI q<ddel:>, 'localName')->[0];
1014 my $lname = $lnel ? $lnel->text_content : '';
1015 my $res;
1016 if ($lextype eq ExpandedURI q<dx:XCRef> or
1017 {
1018 ExpandedURI q<ddel:C> => 1,
1019 ExpandedURI q<ddel:X> => 1,
1020 }->{$el->namespace_uri . $el->local_name}) {
1021 ## NOTE: $db
1022 $res = $db->get_resource ($uri)
1023 ->get_const_resource_by_name ($lname);
1024 } else {
1025 ## NOTE: $db
1026 $res = $db->get_resource ($uri)
1027 ->get_child_resource_by_name_and_type
1028 ($lname, ExpandedURI q<DISLang:AnyMethod>);
1029 }
1030 if ($res) {
1031 $el->set_attribute_ns
1032 (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
1033 $ReferredResource{$res->uri} ||= 1;
1034 }
1035 next EL;
1036 }
1037 }
1038 } # lextype
1039 } # mmParsed
1040 elsif ($opt{method_resource} and
1041 $el->namespace_uri eq ExpandedURI q<ddel:> and
1042 $el->local_name eq 'P') {
1043 my $res = $opt{method_resource}
1044 ->get_child_resource_by_name_and_type
1045 ($el->text_content, ExpandedURI q<DISLang:MethodParameter>);
1046 if ($res) {
1047 $el->set_attribute_ns
1048 (ExpandedURI q<dump:>, 'dump:uri', $res->uri);
1049 $ReferredResource{$res->uri} ||= 1;
1050 }
1051 next EL;
1052 }
1053 push @el, @{$el->child_nodes};
1054 } elsif ($el->node_type == $el->DOCUMENT_FRAGMENT_NODE or
1055 $el->node_type == $el->DOCUMENT_NODE) {
1056 push @el, @{$el->child_nodes};
1057 }
1058 } # EL
1059 $el;
1060 } # transform_disdoc_tree
1061
1062 sub dd_get_tfqnames_uri ($;%) {
1063 my ($el, %opt) = @_;
1064 return '' unless $el;
1065 my $turi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
1066 (ExpandedURI q<ddel:>, 'nameQName')->[0]);
1067 my $furi = dd_get_qname_uri ($el->get_elements_by_tag_name_ns
1068 (ExpandedURI q<ddel:>, 'forQName')->[0]);
1069 return undef if not defined $turi or not defined $furi;
1070 my $uri = tfuris2uri ($turi, $furi);
1071 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $uri);
1072 $uri;
1073 } # dd_get_tfqnames_uri
1074
1075 sub dd_get_qname_uri ($;%) {
1076 my ($el, %opt) = @_;
1077 return undef unless $el;
1078 my $plel = $el->get_elements_by_tag_name_ns
1079 (ExpandedURI q<ddel:>, 'prefix')->[0];
1080 my $lnel = $el->get_elements_by_tag_name_ns
1081 (ExpandedURI q<ddel:>, 'localName')->[0];
1082 my $nsuri = ($plel ? $plel : $el)->lookup_namespace_uri
1083 ($plel ? $plel->text_content : undef);
1084 $nsuri = '' unless defined $nsuri;
1085 if ($plel and $nsuri eq '') {
1086 $plel->remove_attribute_ns
1087 (ExpandedURI q<xmlns:>, $plel->text_content);
1088 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
1089 return undef;
1090 } else {
1091 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:namespaceURI', $nsuri);
1092 }
1093 my $r;
1094 if ($lnel) {
1095 $r = $nsuri . $lnel->text_content;
1096 } else {
1097 $r = $el->get_attribute_ns (ExpandedURI q<ddel:>, 'defaultURI');
1098 }
1099 $el->set_attribute_ns (ExpandedURI q<dump:>, 'dump:uri', $r);
1100 $r;
1101 } # dd_get_qname_uri
1102
1103 sub tfuris2uri ($$) {
1104 my ($turi, $furi) = @_;
1105 my $uri;
1106 if ($furi eq ExpandedURI q<ManakaiDOM:all>) {
1107 $uri = $turi;
1108 } else {
1109 my $__turi = $turi;
1110 my $__furi = $furi;
1111 for my $__uri ($__turi, $__furi) {
1112 $__uri =~ s{([^0-9A-Za-z!\$'()*,:;=?\@_./~-])}{sprintf '%%%02X', ord $1}ge;
1113 }
1114 $uri = qq<tag:suika.fam.cx,2005-09:$__turi+$__furi>;
1115 }
1116 $uri;
1117 } # tfuris2uri
1118
1119 sub append_inheritance (%) {
1120 my %opt = @_;
1121 if (($opt{depth} ||= 0) == 100) {
1122 warn "<".$opt{source_resource}->uri.">: Loop in inheritance";
1123 return;
1124 }
1125
1126 my $has_isa = 0;
1127
1128 for my $isa (@{$opt{source_resource}->get_property_resource_list
1129 (ExpandedURI q<dis:ISA>,
1130 default_media_type => ExpandedURI q<DISCore:TFQNames>)}) {
1131 $has_isa = 1;
1132 append_inheritance
1133 (source_resource => $isa,
1134 result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1135 depth => $opt{depth} + 1,
1136 is_class => $opt{is_class});
1137 $ReferredResource{$isa->uri} ||= 1;
1138 if ($opt{class_uri}) {
1139 unshift @ClassInheritance, $isa->uri;
1140 push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1141 }
1142 }
1143
1144 if ($opt{source_resource}->is_defined) {
1145 for my $isa_pack (@{$opt{source_resource}->pl_additional_isa_packages}) {
1146 my $isa;
1147 if ($isa_pack eq 'Message::Util::Error') {
1148 ## NOTE: $db
1149 $isa = $db->get_resource (ExpandedURI q<ecore:MUError>,
1150 for_arg => ExpandedURI q<ManakaiDOM:Perl>);
1151 } elsif ($isa_pack eq 'Tie::Array') {
1152 ## NOTE: $db
1153 $isa = $db->get_resource (ExpandedURI q<DISPerl:TieArray>);
1154 } elsif ($isa_pack eq 'Error') {
1155 ## NOTE: $db
1156 $isa = $db->get_resource (ExpandedURI q<ecore:Error>,
1157 for_arg => ExpandedURI q<ManakaiDOM:Perl>);
1158 } else {
1159 ## TODO: What to do?
1160 }
1161 if ($isa) {
1162 $has_isa = 1;
1163 append_inheritance
1164 (source_resource => $isa,
1165 result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1166 depth => $opt{depth} + 1,
1167 is_class => $opt{is_class});
1168 $ReferredResource{$isa->uri} ||= 1;
1169 if ($opt{class_uri}) {
1170 unshift @ClassInheritance, $isa->uri;
1171 push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1172 }
1173 }
1174 }} # AppISA
1175
1176 if ($opt{has_const}) {
1177 ## NOTE: $db
1178 my $isa = $db->get_resource (ExpandedURI q<DISPerl:Exporter>);
1179 append_inheritance
1180 (source_resource => $isa,
1181 result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1182 depth => $opt{depth} + 1,
1183 is_class => $opt{is_class});
1184 $ReferredResource{$isa->uri} ||= 1;
1185 if ($opt{class_uri}) {
1186 unshift @ClassInheritance, $isa->uri;
1187 push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1188 }
1189 }
1190
1191 if (not $has_isa and $opt{is_class} and
1192 $opt{source_resource}->uri ne ExpandedURI q<DISPerl:UNIVERSAL>) {
1193 ## NOTE: $db
1194 my $isa = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSAL>);
1195 append_inheritance
1196 (source_resource => $isa,
1197 result_parent => $opt{result_parent}->append_new_extends ($isa->uri),
1198 depth => $opt{depth} + 1,
1199 is_class => $opt{is_class});
1200 $ReferredResource{$isa->uri} ||= 1;
1201 if ($opt{class_uri}) {
1202 unshift @ClassInheritance, $isa->uri;
1203 push @{$ClassInheritance{$opt{class_uri}} ||= []}, $isa->uri;
1204 }
1205 }
1206
1207 if ($opt{append_implements}) {
1208 ## NOTE: $db
1209 my $u = $db->get_resource (ExpandedURI q<DISPerl:UNIVERSALInterface>);
1210 for my $impl (@{$opt{source_resource}->get_property_resource_list
1211 (ExpandedURI q<dis:Implement>,
1212 default_media_type => ExpandedURI q<DISCore:TFQNames>,
1213 isa_recursive => 1)}, $u) {
1214 append_inheritance
1215 (source_resource => $impl,
1216 result_parent => $opt{result_parent}->append_new_implements
1217 ($impl->uri),
1218 depth => $opt{depth});
1219 $ReferredResource{$impl->uri} ||= 1;
1220 $ClassImplements{$opt{class_uri}}->{$impl->uri} = 1
1221 if $opt{class_uri};
1222 }
1223 }
1224 } # append_inheritance
1225
1226 sub append_subclassof (%) {
1227 my %opt = @_;
1228
1229 ## NOTE: This subroutine directly access to internal structure
1230 ## of ManakaiDISResourceDefinition
1231
1232 my $a;
1233 $a = sub ($$) {
1234 my ($gdb, $s) = @_;
1235 my %s = keys %$s;
1236 while (my $i = [keys %s]->[0]) {
1237 ## Removes itself
1238 delete $s->{$i};
1239 #warn $i;
1240
1241 my $ires = $gdb->get_resource ($i);
1242 for my $j (keys %$s) {
1243 next if $i eq $j;
1244 if ($ires->{subOf}->{$j}) {
1245 $s->{$i}->{$j} = $s->{$j};
1246 delete $s->{$j};
1247 delete $s{$j};
1248 }
1249 }
1250
1251 delete $s{$i};
1252 } # %s
1253
1254 for my $i (keys %$s) {
1255 $a->($s->{$i}) if keys %{$s->{$i}};
1256 }
1257 };
1258
1259 my $b;
1260 $b = sub ($$) {
1261 my ($s, $p) = @_;
1262 for my $i (keys %$s) {
1263 my $el = $p->append_new_sub_class_of ($i);
1264 $b->($s->{$i}, $el) if keys %{$s->{$i}};
1265 }
1266 };
1267
1268
1269 my $sub = {$opt{source_resource}->uri =>
1270 {map {$_ => {}} keys %{$opt{source_resource}->{subOf}}}};
1271 ## NOTE: $db
1272 $a->($db, $sub);
1273 $b->($sub, $opt{result_parent});
1274 } # append_subclassof
1275
1276 sub add_uri ($$;%) {
1277 my ($res, $el, %opt) = @_;
1278 my $canon_uri = $res->uri;
1279 for my $uri (@{$res->uris}) {
1280 $el->add_uri ($uri, $canon_uri eq $uri ? 0 : 1);
1281 $ReferredResource{$uri} = -1;
1282 }
1283
1284 my $nsuri = $res->namespace_uri;
1285 $el->resource_namespace_uri ($nsuri) if defined $nsuri;
1286 my $lname = $res->local_name;
1287 $el->resource_local_name ($lname) if defined $lname;
1288 } # add_uri
1289
1290 sub append_raises (%) {
1291 my %opt = @_;
1292
1293 for my $el (@{$opt{source_resource}->get_property_value_list
1294 (ExpandedURI q<dx:raises>)}) {
1295 next unless $el->isa ('Message::Util::IF::DVURIValue');
1296 my $e = $el->get_resource ($db);
1297 my ($a, $b, $c); ## NOTE: $db
1298 if ($e->is_type_uri (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1299 $c = $e;
1300 $b = $c->parent_resource;
1301 $a = $b->parent_resource->parent_resource;
1302 } elsif ($e->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1303 $b = $e;
1304 $a = $b->parent_resource->parent_resource;
1305 } else {
1306 $a = $e;
1307 }
1308 my $rel = $opt{result_parent}->create_raises
1309 ($a->uri, $b ? $b->uri : undef, $c ? $c->uri : undef);
1310
1311 append_description (source_resource => $opt{source_resource},
1312 source_value => $el,
1313 result_parent => $rel,
1314 method_resource => $opt{method_resource});
1315 }
1316 } # append_raises
1317
1318
1319 my $doc = $impl->create_disdump_document;
1320
1321 my $body = $doc->document_element;
1322
1323 ## -- Outputs requested modules
1324
1325 for my $res_nuri (keys %{$Opt{resource_uri}}) {
1326 for my $res_furi (keys %{$Opt{resource_uri}->{$res_nuri}}) {
1327 $res_furi = ExpandedURI q<ManakaiDOM:all> unless length $res_furi;
1328 my $res = $db->get_resource ($res_nuri, for_arg => $res_furi);
1329 unless ($res->is_defined) {
1330 die qq{$0: Resource <$res_nuri> for <$res_furi> is not defined};
1331 }
1332
1333 if ($res->is_type_uri (ExpandedURI q<doc:Documentation>)) {
1334 status_msg_ qq<Document <$res_nuri> for <$res_furi>...>;
1335
1336 append_document_documentation
1337 (result_parent => $body,
1338 source_resource => $res);
1339
1340 status_msg qq<done>;
1341 } elsif ($res->is_type_uri (ExpandedURI q<dis:ModuleGroup>)) {
1342 status_msg qq<Module group <$res_nuri> for <$res_furi>...>;
1343
1344 append_module_group_documentation
1345 (result_parent => $body,
1346 source_resource => $res);
1347
1348 status_msg qq<done>;
1349 } else {
1350 die qq{$0: --resource-uri: Resource <$res_nuri> for <$res_furi>}.
1351 qq{ is not a resource set};
1352 }
1353 } # res_furi
1354 } # res_nuri
1355
1356 for my $mod_uri (keys %{$Opt{module_uri}}) {
1357 for my $mod_for (keys %{$Opt{module_uri}->{$mod_uri}}) {
1358 $mod_for = $Opt{For} unless length $mod_for;
1359 my $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1360 unless (defined $mod_for) {
1361 $mod_for = $mod->get_property_text (ExpandedURI q<dis:DefaultFor>);
1362 if (defined $mod_for) {
1363 $mod = $db->get_module ($mod_uri, for_arg => $mod_for);
1364 }
1365 }
1366 unless ($mod->is_defined) {
1367 die qq<$0: Module <$mod_uri> for <$mod_for> is not defined>;
1368 }
1369
1370 status_msg qq<Module <$mod_uri> for <$mod_for>...>;
1371 progress_reset;
1372
1373 append_module_documentation
1374 (result_parent => $body,
1375 source_resource => $mod);
1376
1377 status_msg qq<done>;
1378 } # mod_for
1379 } # mod_uri
1380
1381 ## -- Outputs referenced resources in external modules
1382
1383 status_msg q<Other modules...>;
1384 progress_reset;
1385
1386 my %debug_res_list;
1387 while (my @ruri = grep {$ReferredResource{$_} > 0} keys %ReferredResource) {
1388 U: while (defined (my $uri = shift @ruri)) {
1389 next U if $ReferredResource{$uri} < 0; ## Already done
1390 if ($Opt{debug}) {
1391 warn "Resource <$uri>: $debug_res_list{$uri} times\n"
1392 if ++$debug_res_list{$uri} > 10;
1393 }
1394 progress_inc;
1395 my $res = $db->get_resource ($uri);
1396 unless ($res->is_defined) {
1397 $res = $db->get_module ($uri);
1398 unless ($res->is_defined) {
1399 $ReferredResource{$uri} = -1;
1400 next U;
1401 }
1402 progress_reset;
1403 status_msg qq<Module <$uri>...>;
1404 append_module_documentation
1405 (result_parent => $body,
1406 source_resource => $res,
1407 is_partial => ($ReferredResource{$uri} == 1));
1408 status_msg qq<done>;
1409 progress_reset;
1410 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Class>)) {
1411 my $mod = $res->owner_module;
1412 my $mod_uri = $mod->uri;
1413 unless ($ReferredResource{$mod_uri} < 0) {
1414 $ReferredResource{$mod_uri} = $ReferredResource{$uri}
1415 if $ReferredResource{$mod_uri} < $ReferredResource{$uri};
1416 unshift @ruri, $uri;
1417 unshift @ruri, $mod_uri;
1418 next U;
1419 }
1420 append_class_documentation
1421 (result_parent => $body->create_module ($mod_uri),
1422 source_resource => $res,
1423 is_partial => ($ReferredResource{$uri} == 1));
1424 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1425 my $mod = $res->owner_module;
1426 my $mod_uri = $mod->uri;
1427 unless ($ReferredResource{$mod_uri} < 0) {
1428 $ReferredResource{$mod_uri} = $ReferredResource{$uri}
1429 if $ReferredResource{$mod_uri} < $ReferredResource{$uri};
1430 unshift @ruri, $uri;
1431 unshift @ruri, $mod_uri;
1432 next U;
1433 }
1434 append_interface_documentation
1435 (result_parent => $body->create_module ($mod->uri),
1436 source_resource => $res,
1437 is_partial => ($ReferredResource{$uri} == 1));
1438 } elsif ($res->is_type_uri (ExpandedURI q<DISCore:AnyType>)) {
1439 my $mod = $res->owner_module;
1440 unless ($mod->is_defined) {
1441 $ReferredResource{$uri} = -1;
1442 next U;
1443 } elsif (not ($ReferredResource{$mod->uri} < 0)) {
1444 unshift @ruri, $uri;
1445 unshift @ruri, $mod->uri;
1446 next U;
1447 }
1448 append_datatype_documentation
1449 (result_parent => $body->create_module ($mod->uri),
1450 source_resource => $res);
1451 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:AnyMethod>) or
1452 $res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1453 my $cls = $res->parent_resource;
1454 unless ($cls) {
1455 $ReferredResource{$res->uri} = -1;
1456 next U;
1457 }
1458 if (not ($ReferredResource{$cls->uri} < 0) and
1459 ($cls->is_type_uri (ExpandedURI q<DISLang:Class>) or
1460 $cls->is_type_uri (ExpandedURI q<DISLang:Interface>))) {
1461 unshift @ruri, $uri;
1462 unshift @ruri, $cls->uri;
1463 next U;
1464 }
1465 my $model = $body->create_module ($cls->owner_module->uri);
1466 my $clsel = $cls->is_type_uri (ExpandedURI q<DISLang:Class>)
1467 ? $model->create_class ($cls->uri)
1468 : $model->create_interface ($cls->uri);
1469 if ($res->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1470 append_method_documentation
1471 (result_parent => $clsel,
1472 source_resource => $res);
1473 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Attribute>)) {
1474 append_attr_documentation
1475 (result_parent => $clsel,
1476 source_resource => $res);
1477 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1478 append_constgroup_documentation
1479 (result_parent => $clsel,
1480 source_resource => $res);
1481 } else {
1482 $ReferredResource{$res->uri} = -1;
1483 }
1484 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:MethodParameter>)) {
1485 my $m = $res->parent_resource;
1486 if (not ($ReferredResource{$m->uri} < 0) and
1487 $m->is_type_uri (ExpandedURI q<DISLang:Method>)) {
1488 unshift @ruri, $m->uri;
1489 $ReferredResource{$res->uri} = -1;
1490 next U;
1491 } else {
1492 $ReferredResource{$res->uri} = -1;
1493 }
1494 } elsif ($res->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1495 my $m = $res->parent_resource;
1496 if (not ($ReferredResource{$m->uri} < 0) and
1497 $m->is_type_uri (ExpandedURI q<DISLang:ConstGroup>)) {
1498 unshift @ruri, $m->uri;
1499 $ReferredResource{$res->uri} = -1;
1500 next U;
1501 } else {
1502 $ReferredResource{$res->uri} = -1;
1503 next U;
1504 }
1505 } elsif ($res->is_type_uri
1506 (ExpandedURI q<ManakaiDOM:ExceptionOrWarningSubType>)) {
1507 my $m = $res->parent_resource;
1508 if (not ($ReferredResource{$m->uri} < 0) and
1509 $m->is_type_uri (ExpandedURI q<DISLang:Const>)) {
1510 unshift @ruri, $m->uri;
1511 $ReferredResource{$res->uri} = -1;
1512 next U;
1513 } else {
1514 $ReferredResource{$res->uri} = -1;
1515 next U;
1516 }
1517 } elsif ($res->is_type_uri (ExpandedURI q<doc:Documentation>)) {
1518 append_document_documentation (source_resource => $res,
1519 result_parent => $body);
1520 } else { ## Unsupported type
1521 $ReferredResource{$uri} = -1;
1522 }
1523 } # U
1524 }
1525
1526 status_msg '';
1527 status_msg q<done>;
1528
1529 ## -- Inheriting methods information
1530
1531 {
1532 verbose_msg_ q<Adding inheritance information...>;
1533 my %class_done;
1534 for my $class_uri (@ClassInheritance) {
1535 next if $class_done{$class_uri};
1536 $class_done{$class_uri};
1537 for my $sclass_uri (@{$ClassInheritance{$class_uri}}) {
1538 for my $scm_name (keys %{$ClassMembers{$sclass_uri}}) {
1539 if ($ClassMembers{$class_uri}->{$scm_name}) {
1540 $ClassMembers{$class_uri}->{$scm_name}->{overrides}
1541 ->{$ClassMembers{$sclass_uri}->{$scm_name}->{resource}->uri} = 1;
1542 } else {
1543 $ClassMembers{$class_uri}->{$scm_name}
1544 = {
1545 %{$ClassMembers{$sclass_uri}->{$scm_name}},
1546 is_inherited => 1,
1547 };
1548 }
1549 }
1550 } # superclasses
1551 } # classes
1552
1553 verbose_msg_ q<...>;
1554
1555 for my $class_uri (keys %ClassImplements) {
1556 for my $if_uri (keys %{$ClassImplements{$class_uri}||{}}) {
1557 for my $mem_name (keys %{$ClassMembers{$if_uri}}) {
1558 unless ($ClassMembers{$class_uri}->{$mem_name}) {
1559 ## Not defined - error
1560 $ClassMembers{$class_uri}->{$mem_name}
1561 = {
1562 %{$ClassMembers{$if_uri}->{$mem_name}},
1563 is_inherited => 1,
1564 };
1565 }
1566 $ClassMembers{$class_uri}->{$mem_name}->{implements}
1567 ->{$ClassMembers{$if_uri}->{$mem_name}->{resource}->uri} = 1;
1568 }
1569 } # interfaces
1570 } # classes
1571
1572 verbose_msg_ q<...>;
1573
1574 for my $class_uri (keys %ClassMembers) {
1575 my $cls_res = $db->get_resource ($class_uri);
1576 next unless $cls_res->is_defined;
1577 verbose_msg_ q<.>;
1578 my $cls_el = $body->create_module ($cls_res->owner_module->uri);
1579 if ($cls_res->is_type_uri (ExpandedURI q<DISLang:Interface>)) {
1580 $cls_el = $cls_el->create_interface ($class_uri);
1581 } else {
1582 $cls_el = $cls_el->create_class ($class_uri);
1583 }
1584 for my $mem_name (keys %{$ClassMembers{$class_uri}}) {
1585 my $mem_info = $ClassMembers{$class_uri}->{$mem_name};
1586 my $el;
1587 if ($mem_info->{type} eq 'const-group') {
1588 $el = $cls_el->create_const_group ($mem_name);
1589 } elsif ($mem_info->{type} eq 'attr') {
1590 $el = $cls_el->create_attribute ($mem_name);
1591 } else {
1592 $el = $cls_el->create_method ($mem_name);
1593 }
1594 if ($mem_info->{is_inherited}) {
1595 $el->ref ($mem_info->{resource}->uri);
1596 }
1597 for my $or (keys %{$mem_info->{overrides}||{}}) {
1598 $el->append_new_overrides ($or);
1599 }
1600 for my $or (keys %{$mem_info->{implements}||{}}) {
1601 $el->append_new_implements ($or);
1602 }
1603 } # members
1604 } # classes
1605
1606 verbose_msg q<done>;
1607 undef %ClassMembers;
1608 }
1609
1610 {
1611 status_msg_ qq<Writing file ""...>;
1612
1613 require Encode;
1614 my $lsimpl = $impl->get_feature (ExpandedURI q<DOMLS:Generic> => '3.0');
1615 my $serializer = $lsimpl->create_gls_serializer
1616 ({ExpandedURI q<DOMLS:SerializeDocumentInstance> => ''});
1617 print STDOUT Encode::encode ('utf8', $serializer->write_to_string ($doc));
1618 close STDOUT;
1619 status_msg qq<done>;
1620 $doc->free;
1621 }
1622
1623 verbose_msg_ qq<Checking undefined resources...>;
1624 $db->check_undefined_resource;
1625 verbose_msg qq<done>;
1626
1627 verbose_msg_ qq<Closing database...>;
1628 $db->free;
1629 undef $db;
1630 verbose_msg qq<done>;
1631
1632 {
1633 use integer;
1634 my $time = time - $start_time;
1635 status_msg sprintf qq<%d'%02d''>, $time / 60, $time % 60;
1636 }
1637
1638 exit;
1639
1640 END {
1641 $db->free if $db;
1642 }
1643
1644 sub dac_search_file_path_stem ($$$) {
1645 my ($ns, $ln, $suffix) = @_;
1646 require Cwd;
1647 require File::Spec;
1648 for my $dir ('.', @{$Opt{input_search_path}->{$ns}||[]}) {
1649 my $name = Cwd::abs_path
1650 (File::Spec->canonpath
1651 (File::Spec->catfile ($dir, $ln)));
1652 if (-f $name.$suffix) {
1653 return $name;
1654 }
1655 }
1656 return undef;
1657 } # dac_search_file_path_stem;
1658
1659 =head1 SEE ALSO
1660
1661 L<lib/manakai/dis.pl> and L<bin/cdis2pm.pl> - Old version of
1662 this script.
1663
1664 L<lib/Message/Util/DIS.dis> - The I<dis> object implementation.
1665
1666 L<lib/Message/Util/PerlCode.dis> - The Perl code generator.
1667
1668 L<lib/manakai/DISCore.dis> - The definition for the "dis" format.
1669
1670 L<lib/manakai/DISPerl.dis> - The definition for the "dis" Perl-specific
1671 vocabulary.
1672
1673 =head1 LICENSE
1674
1675 Copyright 2004-2005 Wakaba <w@suika.fam.cx>. All rights reserved.
1676
1677 This program is free software; you can redistribute it and/or
1678 modify it under the same terms as Perl itself.
1679
1680 =cut
1681
1682 1; # $Date: 2005/11/15 14:18:23 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24