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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14 - (hide annotations) (download)
Sun Oct 2 23:35:32 2005 UTC (19 years, 1 month ago) by wakaba
Branch: MAIN
Changes since 1.13: +64 -86 lines
File MIME type: text/plain
++ manakai/bin/ChangeLog	2 Oct 2005 23:24:29 -0000
2005-10-02  Wakaba  <wakaba@suika.fam.cx>

	* mkdisdump.pl (append_document_documentation): Outputs "doc:as"
	properties if available.
	(append_module_documentation): Outputs "dis:AppName"
	and "idl:prefix" attribute if available.
	(append_idl_interface_documentation): Removed (Merged
	to "append_interface_documentation").
	(ReferredResource): Don't set "is_partial" flag
	if ReferredResource value is greater than "1".

++ manakai/lib/Message/Util/ChangeLog	2 Oct 2005 23:27:03 -0000
2005-10-02  Wakaba  <wakaba@suika.fam.cx>

	* DIS.dis (getAnyResource): New method.
	(isTypeURI): Now it is a method of "DIS:DISAnyResource" interface.
	(getPropertyResource, getPropertyResourceList): Now
	they uses "getAnyResource" method.
	(getPropertyModuleList): Removed.

++ manakai/lib/Message/Util/DIS/ChangeLog	2 Oct 2005 23:27:51 -0000
2005-10-02  Wakaba  <wakaba@suika.fam.cx>

	* DISDoc.dis (dd:id): Now it is an alias for "dis:ddid" property.

++ manakai/lib/Message/DOM/ChangeLog	2 Oct 2005 23:25:32 -0000
2005-10-02  Wakaba  <wakaba@suika.fam.cx>

	* DOMFeature.dis (Module): "idl:prefix" and "idl:moduleName"
	properties added.

++ manakai/lib/manakai/ChangeLog	2 Oct 2005 23:34:39 -0000
2005-10-02  Wakaba  <wakaba@suika.fam.cx>

	* DISSource.dis: New module split from "DISCore.dis".

	* DISCore.dis: "dis" resource concept such as "DISCore:Module"
	and "DISCore:Resource" added.
	(DISCore:File): New class.

	* DISLang.dis (DISLang:Array, DISLang:Exception,
	DISLang:Constructor): New classes.
	(DISLang:File): New class.
	(ManakaiDOM:Java, lang:Java): Moved to new "Java.dis" module.

	* Java.dis: New module.

	* DISPerl.dis (DISPerl:File): New class.
	(Package, Module, Class, Interface, Sub, Const, AnyExported): New
	classes.

	* Document.dis (dis:ddid): New property.
	(doc:subsection): New rel.
	(doc:as): New attribute.
	(ManakaiDOM:InCase): Moved from "DISCore.dis".

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24