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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (show annotations) (download)
Fri Sep 30 13:06:13 2005 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.11: +242 -54 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	30 Sep 2005 12:38:36 -0000
2005-09-30  Wakaba  <wakaba@suika.fam.cx>

	* mkdisdump.pl (append_module_group_documentation,
	append_document_documentation): New functions.
	(append_class_documentation, append_interface_documentation):
	Generates method/attribute/constgroup information (in partial mode)
	even if "is_partial" option is true to compute inheriting
	class member information correctly.
	(--resource-uri): New option.

	* Makefile (error.xml, minimpl.xml): New rules.

++ manakai/lib/Message/Util/ChangeLog	30 Sep 2005 12:50:16 -0000
2005-09-30  Wakaba  <wakaba@suika.fam.cx>

	* DIS.dis (readProperties): Saves property name to values.
	(getPropertyModuleList): New method.


	* ManakaiNode.dis: Use "disPerl:H" instead
	of "disPerl:Q" for hash keys.
	(NodeStem): Property value "mn:treeID"
	has changed to scalar reference.
++ manakai/lib/Message/Util/Error/ChangeLog	30 Sep 2005 12:49:59 -0000
2005-09-30  Wakaba  <wakaba@suika.fam.cx>
	* DOMException.dis (dx:ManakaiErrorModules): New documentation.
++ manakai/lib/Message/Util/DIS/ChangeLog	30 Sep 2005 12:48:08 -0000
2005-09-30  Wakaba  <wakaba@suika.fam.cx>

	* Value.dis (name): New attribute.

	* Perl.dis (plFullyQualifiedName): Use module's package
	name properties if available.

++ manakai/lib/Message/DOM/ChangeLog	30 Sep 2005 12:40:49 -0000
2005-09-30  Wakaba  <wakaba@suika.fam.cx>

	* DOMCore.dis, SimpleLS.dis: Shares namespace URIs and local
	names where possible.

	* DOMFeature.dis: Documentation for DOM Minimum Implementation
	added (still work in progress).

	* Makefile (feature.dae, feature-spec.dae): New rules.

++ manakai/lib/manakai/ChangeLog	30 Sep 2005 12:53:24 -0000
2005-09-30  Wakaba  <wakaba@suika.fam.cx>

	* DISCore.dis: Documentation-related and meta-informational
	resoruces are moved to new "Document.dis" module.  The
	module now references "Document.dis".
	(DISCore:module, DISCore:resource): New properties.

	* DISRDF.dis: Some resources added from FOAF vocabulary.

	* Document.dis: New module.

	* DISIDL.dis: Some IDL comcepts added.  New name
	given to IDL datatypes.

	* DISLang.dis (dis:prefix): Removed.  (Moved to "DISIDL.dis"
	and it is now obsolete.)

2005-09-29  Wakaba  <wakaba@suika.fam.cx>

	* DISPerl.dis (DISPerl:HashStringRef, DISPerl:StringRef): New.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24