/[suikacvs]/messaging/manakai/lib/Message/Util/ManakaiNode.dis
Suika

Contents of /messaging/manakai/lib/Message/Util/ManakaiNode.dis

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.33 - (hide annotations) (download)
Wed Mar 8 11:43:07 2006 UTC (19 years, 4 months ago) by wakaba
Branch: MAIN
Changes since 1.32: +2 -2 lines
++ manakai/lib/Message/Util/ChangeLog	8 Mar 2006 11:43:02 -0000
2006-03-08  Wakaba  <wakaba@suika.fam.cx>

	* ManakaiNode.dis (destroy): Don't cause |uninitialized value
	as SCALAR reference| error even if the node is disposed
	and it no longer has tree id.

++ manakai/lib/Message/DOM/ChangeLog	8 Mar 2006 11:41:45 -0000
2006-03-08  Wakaba  <wakaba@suika.fam.cx>

	* XDoctype.dis (replaceChild): Method implementations are added.

	* Tree.dis (replaceChild): Method implementations are added.

	* DOMXML.dis (replaceChild): Method implementations are added.

1 wakaba 1.1 Module:
2     @QName:
3     Util:ManakaiNode
4     @FullName:
5     @@lang: en
6     @@@:
7     Manakai Generic Node Implementation
8     @Namespace:
9     http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/ManakaiNode#
10    
11     @Description:
12     @@lang:en
13     @@@:
14     The <Module::Util:ManakaiNode> module provides a basic
15     implementation for glaph (perhaps tree) structures.
16    
17 wakaba 1.18 @DISCore:author: DISCore|Wakaba
18 wakaba 1.1 @License:
19     license:Perl+MPL
20     @Date:
21 wakaba 1.33 $Date: 2005/11/23 07:58:40 $
22 wakaba 1.1
23     @Require:
24     @@Module:
25 wakaba 1.29 @@@QName: DISlib|DISPerl
26     @@@WithFor: ManakaiDOM|all
27 wakaba 1.2
28     @DefaultFor:
29     ManakaiDOM:Perl
30 wakaba 1.1
31     Namespace:
32     @dis:
33     http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#dis--
34 wakaba 1.4 @DISlib:
35     http://suika.fam.cx/~wakaba/archive/2004/dis/
36 wakaba 1.26 @kwd:
37     http://suika.fam.cx/~wakaba/archive/2005/rfc2119/
38 wakaba 1.1 @lang:
39     http://suika.fam.cx/~wakaba/archive/2004/8/18/lang#
40     @license:
41     http://suika.fam.cx/~wakaba/archive/2004/8/18/license#
42     @ManakaiDOM:
43     http://suika.fam.cx/~wakaba/archive/2004/8/18/manakai-dom#
44 wakaba 1.10 @mn:
45     http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/ManakaiNode#
46 wakaba 1.1 @rdf:
47     http://www.w3.org/1999/02/22-rdf-syntax-ns#
48     @rdfs:
49     http://www.w3.org/2000/01/rdf-schema#
50     @Util:
51     http://suika.fam.cx/~wakaba/archive/2005/manakai/Util/
52    
53     ResourceDef:
54     @QName:
55     Util:
56     @rdf:type:
57     dis:ModuleGroup
58     @FullName:
59     @@lang:en
60     @@@:
61     The manakai support modules
62 wakaba 1.17 @DISPerl:packageName:
63 wakaba 1.14 Message::Util::
64 wakaba 1.17 @DISPerl:interfacePackageName:
65     Message::Util::IF::
66 wakaba 1.28 @ImplNote:
67     @@lang:en
68     @@@:
69     This resource is also defined in <Module::Util:DIS> and
70     <Module::Util:PerlCode> modules.
71 wakaba 1.13
72 wakaba 1.1 ## -- Internal node object
73    
74     ClassDef:
75 wakaba 1.29 @resourceFor: ManakaiDOM|ForIF
76     @resourceFor: ManakaiDOM|ForClass
77 wakaba 1.10
78     @QName:
79     @@@: NodeStem
80 wakaba 1.29 @@ForCheck: ManakaiDOM|ForIF
81 wakaba 1.10
82     @QName:
83     @@@: ManakaiNodeStem
84 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
85 wakaba 1.10
86     @Implement:
87     @@@: NodeStem
88 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
89 wakaba 1.10
90     @Implement:
91     @@@: NodeStem
92 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
93 wakaba 1.10
94 wakaba 1.1 @Description:
95     @@lang:en
96     @@@:
97     Internal (actual) node objects that is accessed via
98     <Class::ManakaiDOM:ManakaiDOMNodeReference> objects referring it.
99     @ImplNote:
100     @@lang:en
101     @@@:
102     No public interface should be defined for any class inheriting
103     this class - applications should access to nodes only via
104     <Class::ManakaiDOM:ManakaiDOMNodeReference> objects.
105     @ImplNote:
106 wakaba 1.13 @@ForCheck: ManakaiDOM|ForClass
107 wakaba 1.1 @@lang:en
108     @@@:
109 wakaba 1.13 A <Class::> object is a blessed hash
110 wakaba 1.1 reference. Each hash key and value pair is called as a
111     <DFN::property>. Currently, several core properties
112 wakaba 1.29 are defined. Applications of this class
113     define additional properties for their own purpose and scope.
114 wakaba 1.1
115     @IntMethod:
116     @@Name: new
117     @@Description:
118     @@@lang:en
119     @@@@:
120     Constructs a new instance of
121     <Class::ManakaiDOM:ManakaiDOMNodeObject> and returns it.
122 wakaba 1.22 @@Param:
123     @@@Name: className
124     @@@Type: DISLang|String||ManakaiDOM|all
125     @@@enDesc:
126     The name of a class which is typically used as reference
127     to the node. The class <kwd:SHOULD> implement the
128     <IF::NodeRef> interface. The <QUOTE::dis> definition
129     for the class <kwd:SHOULD> play the role of <Q::mn|NodeRefRole
130     ||ManakaiDOM|all>.
131 wakaba 1.1 @@Return:
132 wakaba 1.10 @@@Type: NodeStem
133 wakaba 1.1 @@@Description:
134     @@@@lang:en
135     @@@@@:
136     The newly created <Class::ManakaiDOM:ManakaiDOMNodeObject> instance.
137 wakaba 1.7 @@@PerlDef:
138 wakaba 1.25 my $grc = 0;
139 wakaba 1.20 $r = bless {
140 wakaba 1.25 <H::mn:type> => $className,
141     <H::mn:groveReferenceCounter> => \$grc,
142     <H::mn:rc> => 0,
143 wakaba 1.20 <H::mn:treeID> => \ (<Code::ManakaiDOM:generateUniqueID>),
144     <H::mn:nodeID> => <Code::ManakaiDOM:generateUniqueID>,
145     }, ref $self || $self;
146 wakaba 1.10
147 wakaba 1.1 @IntMethod:
148 wakaba 1.29 @@Name: newNode
149     @@enDesc:
150     Returns a new node that belongs to the same grove with
151     the node.
152 wakaba 1.1 @@Param:
153 wakaba 1.29 @@@Name: className
154     @@@Type: DISLang|String||ManakaiDOM|all
155     @@@enDesc:
156     The name of a class which is typically used as reference
157     to the node. The class <kwd:SHOULD> implement the
158     <IF::NodeRef> interface. The <QUOTE::dis> definition
159     for the class <kwd:SHOULD> play the role of <Q::mn|NodeRefRole
160     ||ManakaiDOM|all>.
161 wakaba 1.1 @@Return:
162 wakaba 1.29 @@@Type: NodeStem
163     @@@enDesc: The newly created node.
164 wakaba 1.1 @@@PerlDef:
165 wakaba 1.29 $r = bless {
166     <H::mn:type> => $className,
167     <H::mn:groveReferenceCounter>
168     => $self->{<H::mn:groveReferenceCounter>},
169     <H::mn:rc> => 0,
170     <H::mn:treeID> => $self->{<H::mn:treeID>},
171     <H::mn:nodeID> => <Code::ManakaiDOM:generateUniqueID>,
172     }, ref $self;
173 wakaba 1.6
174     @ResourceDef:
175     @@QName: getNewReference
176 wakaba 1.29 @@rdf:type: DISPerl|BlockCode
177     @@ForCheck: ManakaiDOM|ForClass
178 wakaba 1.6 @@Description:
179     @@@lang:en
180     @@@@:
181     Creates a new node reference object.
182     @@ResourceDef:
183     @@@rdf:type:
184     DISPerl:CodeParameter
185     @@@Name: $object
186 wakaba 1.10 @@@Type: NodeStem
187 wakaba 1.6 @@@In:1
188     @@@enDesc:
189     A node object for which a reference is created.
190     @@@DISPerl:paramStyle: var
191     @@ResourceDef:
192     @@@rdf:type:
193     DISPerl:CodeParameter
194     @@@Name: $ref
195 wakaba 1.10 @@@Type: NodeRef
196 wakaba 1.6 @@@Out:1
197     @@@enDesc:
198     A node reference for <P::$object>. It may or may not
199     be same as <P::$object>.
200     @@@DISPerl:paramStyle: var
201     @@ResourceDef:
202     @@@rdf:type:
203     DISPerl:CodeParameter
204     @@@Name: $class
205 wakaba 1.29 @@@Type: DISLang|String||ManakaiDOM|all
206 wakaba 1.6 @@@enDesc:
207     A package name with which <P::$ref> is blessed.
208     @@@In:1
209     @@@DISPerl:paramStyle: any
210     @@PerlDef:
211 wakaba 1.19 $object->{<H::mn:rc>}++;
212 wakaba 1.25 ${$object->{<H::mn:groveReferenceCounter>}}++;
213 wakaba 1.6 $ref = bless {
214 wakaba 1.19 <H::mn:node> => $object,
215 wakaba 1.6 }, $class;
216    
217     @ResourceDef:
218     @@QName: getWeakReference
219 wakaba 1.29 @@rdf:type: DISPerl|BlockCode
220     @@ForCheck: ManakaiDOM|ForClass
221 wakaba 1.6 @@Description:
222     @@@lang:en
223     @@@@:
224     Creates a new weak node reference object.
225     \
226     The weak node reference is actually a node reference
227     except that this code fragment does not increment
228     the reference count of the object. When all non-weak
229     references to the object are destructed, then
230     the object is destructed and any operation via
231     weak references will lead unexpected result.
232     \
233     {NOTE:: It is intended that internal code creates a weak reference
234     so that it gets access to public interface.
235     \
236     }
237     @@ResourceDef:
238     @@@rdf:type:
239     DISPerl:CodeParameter
240     @@@Name: $object
241 wakaba 1.10 @@@Type: NodeStem
242 wakaba 1.6 @@@In:1
243     @@@enDesc:
244     A node object for which a reference is created.
245     @@@DISPerl:paramStyle: var
246     @@ResourceDef:
247     @@@rdf:type:
248     DISPerl:CodeParameter
249     @@@Name: $ref
250 wakaba 1.10 @@@Type: NodeRef
251 wakaba 1.6 @@@Out:1
252     @@@enDesc:
253     A node reference for <P::$object>. It may or may not
254     be same as <P::$object>.
255     @@@DISPerl:paramStyle: var
256     @@ResourceDef:
257     @@@rdf:type:
258     DISPerl:CodeParameter
259     @@@Name: $class
260 wakaba 1.29 @@@Type: DISLang|String||ManakaiDOM|all
261 wakaba 1.6 @@@enDesc:
262     A package name with which <P::$ref> is blessed.
263     @@@In:1
264     @@@DISPerl:paramStyle: any
265     @@PerlDef:
266     $ref = bless {
267 wakaba 1.19 <H::mn:node> => $object,
268     <H::mn:isWeak> => true,
269 wakaba 1.8 }, $class;
270    
271     @ResourceDef:
272     @@QName: getWeakRef
273 wakaba 1.29 @@rdf:type: DISPerl|InlineCode
274     @@ForCheck: ManakaiDOM|ForClass
275 wakaba 1.8 @@Description:
276     @@@lang:en
277     @@@@:
278 wakaba 1.29 Creates a new weak node reference object.
279 wakaba 1.8 \
280     The weak node reference is actually a node reference
281     except that this code fragment does not increment
282 wakaba 1.29 the reference count of the object. When all non-weak
283 wakaba 1.8 references to the object are destructed, then
284 wakaba 1.29 the object is destructed and any operation via
285 wakaba 1.8 weak references will lead unexpected result.
286     \
287     {NOTE:: It is intended that internal code creates a weak reference
288 wakaba 1.29 so that it gets access to public interface.
289 wakaba 1.8 \
290     }
291     @@ResourceDef:
292     @@@rdf:type:
293     DISPerl:CodeParameter
294     @@@Name: $object
295 wakaba 1.10 @@@Type: NodeStem
296 wakaba 1.8 @@@In:1
297     @@@enDesc:
298     A node object for which a reference is created.
299     @@@DISPerl:paramStyle: var
300     @@ResourceDef:
301     @@@rdf:type:
302     DISPerl:CodeParameter
303     @@@Name: $class
304 wakaba 1.29 @@@Type: DISLang|String||ManakaiDOM|all
305 wakaba 1.8 @@@enDesc:
306 wakaba 1.29 A package name with which <P::$ref> is blessed.
307 wakaba 1.8 @@@In:1
308     @@@DISPerl:paramStyle: any
309     @@PerlDef:
310 wakaba 1.9 (bless {
311 wakaba 1.19 <H::mn:node> => $object,
312     <H::mn:isWeak> => true,
313 wakaba 1.9 }, $class)
314 wakaba 1.6
315 wakaba 1.1 @IntMethod:
316     @@Name: isExternallyReferred
317     @@Description:
318     @@@lang:en
319     @@@@:
320     Checks whether the tree containing this node has been referred
321     from the outside of the tree or not.
322     @@Return:
323     @@@Type:
324 wakaba 1.7 DISPerl:Boolean::ManakaiDOM:all
325 wakaba 1.1 @@@InCase:
326 wakaba 1.15 @@@@Value:
327     @@@@@@:1
328     @@@@@ContentType: DISCore|Boolean
329 wakaba 1.1 @@@@Description:
330     @@@@@lang:en
331     @@@@@@:
332     There is one or more nodes in the tree that has been
333     referred via <Class::ManakaiDOM:ManakaiDOMNodeReference> objects.
334     @@@InCase:
335 wakaba 1.15 @@@@Value:
336     @@@@@@:0
337     @@@@@ContentType: DISCore|Boolean
338 wakaba 1.1 @@@@Description:
339     @@@@@lang:en
340     @@@@@@: No external reference found.
341     @@@PerlDef:
342 wakaba 1.19 if ($self->{<H::mn:rc>}) {
343 wakaba 1.10 $r = true;
344     } else {
345     my @node = ($self);
346     my %checked;
347 wakaba 1.25 NODES: while (@node) {
348     my $node = shift @node;
349     next NODES unless ref $node;
350 wakaba 1.19 if ($node->{<H::mn:rc>}) {
351 wakaba 1.10 $r = true;
352     last NODES;
353 wakaba 1.19 } elsif ($checked{$node->{<H::mn:nodeID>}}) {
354 wakaba 1.10 next NODES;
355     }
356     my @n;
357 wakaba 1.23 my $nt = $Message::Util::ManakaiNode::ManakaiNodeRef::Prop{
358     $node->{<H::mn:type>}
359     };
360 wakaba 1.25 for my $p (@{$nt->{<H::mn:subnode2>}}) {
361 wakaba 1.10 if (ref $node->{$p} eq 'ARRAY') {
362     push @n, @{$node->{$p}};
363     } elsif (ref $node->{$p} eq 'HASH') {
364     push @n, values %{$node->{$p}};
365     }
366     }
367     for my $p (@n,
368 wakaba 1.25 map {$node->{$_}} @{$nt->{<H::mn:subnode1>}}) {
369 wakaba 1.10 if (ref $p eq 'ARRAY') {
370     push @node, @$p;
371     } elsif (ref $p eq 'HASH') {
372     push @node, values %$p;
373     }
374     }
375 wakaba 1.25 for my $p (@{$nt->{<H::mn:origin0>}}) {
376 wakaba 1.10 unshift @node, $node->{$p} if $node->{$p};
377     ## NOTE: Puts the top of the list,
378     ## since upper-level nodes are expected to be referred
379     ## more than lower-levels.
380     }
381 wakaba 1.23 for my $p (@{$nt->{<H::mn:subnode0>}}) {
382 wakaba 1.10 push @node, $node->{$p} if $node->{$p};
383     }
384 wakaba 1.25 $checked{$node->{<H::mn:nodeID>}} = true;
385 wakaba 1.10 }
386     }
387 wakaba 1.1
388 wakaba 1.25 @ResourceDef:
389     @@QName: mn|isGroveReferenced
390     @@rdf:type: DISPerl|InlineCode
391 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
392 wakaba 1.25 @@PerlDef:
393     (${$node->{<H::mn:groveReferenceCounter>}} > 0)
394    
395 wakaba 1.1 @IntMethod:
396     @@Name: destroy
397     @@Description:
398     @@@lang:en
399     @@@@:
400     Destructs the tree containing this node.
401     @@Return:
402     @@@PerlDef:
403 wakaba 1.10 my @node = ($self);
404 wakaba 1.33 my $tid = $self->{<H::mn:treeID>} || \'';
405 wakaba 1.27 my %xrnode;
406 wakaba 1.25 NODES: while (@node) {
407     my $node = shift @node;
408     next NODES unless ref $node and defined $node->{<H::mn:nodeID>};
409 wakaba 1.10 my @n;
410 wakaba 1.23 my $nt = $Message::Util::ManakaiNode::ManakaiNodeRef::Prop{
411     $node->{<H::mn:type>}
412     };
413 wakaba 1.25 for my $p (@{$nt->{<H::mn:subnode2>}||[]}) {
414 wakaba 1.29 my $ref = ref $node->{$p};
415     if ($ref eq 'HASH') {
416     push @n, values %{$node->{$p}};
417     } elsif ($ref eq 'ARRAY') {
418 wakaba 1.10 push @n, @{$node->{$p}};
419     }
420     }
421 wakaba 1.29 for my $p (@n, map {$node->{$_}} @{$nt->{<H::mn:subnode1>}||[]}) {
422     my $ref = ref $p;
423     if ($ref eq 'ARRAY') {
424 wakaba 1.10 push @node, @$p;
425 wakaba 1.29 } elsif ($ref eq 'HASH') {
426 wakaba 1.10 push @node, values %$p;
427     }
428     }
429 wakaba 1.25 for my $p (@{$nt->{<H::mn:origin0>}||[]},
430     \ @{$nt->{<H::mn:subnode0>}||[]}) {
431 wakaba 1.10 push @node, $node->{$p};
432     }
433 wakaba 1.27
434 wakaba 1.32 $node-><M::NodeStem.destroyNodeStem>;
435    
436 wakaba 1.27 for my $p (@{$nt->{<H::mn:xrefnode0>}||[]}) {
437     if (defined $node->{$p} and
438     ${$node->{$p}->{<H::mn:treeID>}||$tid} ne $$tid) {
439     $node->{$p}->{<H::mn:rc>}--;
440     ${$node->{$p}->{<H::mn:groveReferenceCounter>}}--;
441     $xrnode{${$node->{$p}->{<H::mn:treeID>}}} = $node->{$p};
442     }
443     }
444    
445 wakaba 1.10 %$node = ();
446 wakaba 1.27 } # @node
447    
448     CORE::delete $xrnode{$$tid};
449     for my $node (values %xrnode) {
450     unless (<Code::isGroveReferenced:: $node = $node>) {
451     $node-><M::NodeStem.destroy>;
452     }
453 wakaba 1.10 }
454 wakaba 1.1 @@ImplNote:
455     @@@lang:en
456     @@@@:
457     This method is different from Perl <Perl::DESTROY> special
458     purpose method.
459     \
460     An <QUOTE::uninitialized> warning in this method might mean
461     some method puts an <Perl::undef> into a list of nodes.
462 wakaba 1.32
463     @IntMethod:
464     @@Name: destroyNodeStem
465     @@enDesc:
466     The <M::NodeStem.destryoNodeStem> method is called just before
467     the <IF::NodeStem> is being destructed.
468    
469     {NOTE:: This method plays the role of <Perl::DESTROY>
470     special-purpose method in Perl. Note that
471     when the <Perl::DESTROY> method is invoked,
472     all data contained in the <IF::NodeStem> has
473     already been removed while when this method
474     is invoked they are there yet.
475     }
476     @@Return:
477     @@@PerlDef:
478     ## No action by default
479 wakaba 1.1
480     @IntMethod:
481     @@Name: importTree
482     @@Description:
483     @@@lang:en
484     @@@@:
485     Changes the tree identifier of the nodes belong to another tree
486     to be same as this node's tree identifier.
487     @@Param:
488     @@@Name: node
489 wakaba 1.29 @@@Type: NodeStem
490 wakaba 1.1 @@@Description:
491     @@@@lang:en
492     @@@@@:
493     Any node from the tree to change its identifier.
494     @@Return:
495     @@@PerlDef:
496 wakaba 1.10 my @node = ($node);
497 wakaba 1.25 my $newgrc = $self->{<H::mn:groveReferenceCounter>};
498     my $newtid = $self->{<H::mn:treeID>};
499 wakaba 1.27 my $oldtid = $node->{<H::mn:treeID>};
500     my @xrnode;
501 wakaba 1.25 NODES: while (@node) {
502     my $node = shift @node;
503     next NODES unless ref $node;
504     next NODES if ${$node->{<H::mn:treeID>}} eq $$newtid;
505 wakaba 1.10 my @n;
506 wakaba 1.23 my $nt = $Message::Util::ManakaiNode::ManakaiNodeRef::Prop{
507     $node->{<H::mn:type>}
508     };
509 wakaba 1.25 for my $p (@{$nt->{<H::mn:subnode2>}||[]}) {
510 wakaba 1.29 my $ref = ref $node->{$p};
511     if ($ref eq 'HASH') {
512     push @n, values %{$node->{$p}};
513     } elsif ($ref eq 'ARRAY') {
514 wakaba 1.10 push @n, @{$node->{$p}};
515     }
516     }
517 wakaba 1.29 for my $p (@n, map {$node->{$_}} @{$nt->{<H::mn:subnode1>}||[]}) {
518     my $ref = ref $p;
519     if ($ref eq 'ARRAY') {
520 wakaba 1.10 push @node, @$p;
521 wakaba 1.29 } elsif ($ref eq 'HASH') {
522 wakaba 1.10 push @node, values %$p;
523     }
524     }
525 wakaba 1.25 for my $p (@{$nt->{<H::mn:origin0>}||[]},
526     \ @{$nt->{<H::mn:subnode0>}||[]}) {
527 wakaba 1.29 push @node, $node->{$p} if defined $node->{$p};
528 wakaba 1.10 }
529 wakaba 1.25
530 wakaba 1.27 for (@{$nt->{<H::mn:xrefnode0>}||[]}) {
531     push @xrnode, $node->{$_} if defined $node->{$_};
532     }
533    
534 wakaba 1.25 ${$node->{<H::mn:groveReferenceCounter>}} -= $node->{<H::mn:rc>};
535     $node->{<H::mn:treeID>} = $newtid;
536     $node->{<H::mn:groveReferenceCounter>} = $newgrc;
537 wakaba 1.29 $$newgrc += $node->{<H::mn:rc>};
538 wakaba 1.10 }
539 wakaba 1.1
540 wakaba 1.27 for my $n (@xrnode) {
541     if (${$n->{<H::mn:treeID>}} eq $$oldtid) {
542     $n->{<H::mn:rc>}++;
543     ${$n->{<H::mn:groveReferenceCounter>}}++;
544     } elsif (${$n->{<H::mn:treeID>}} eq $$newtid) {
545     $n->{<H::mn:rc>}--;
546     ${$n->{<H::mn:groveReferenceCounter>}}--;
547     ## Is it necessary to test whether rc is 0 or not
548     ## and if so call "destroy" method? Maybe it need not
549     ## (or should not, rather).
550     }
551     }
552    
553 wakaba 1.1 @IntMethod:
554     @@Name: changeTreeID
555     @@Description:
556     @@@lang:en
557     @@@@:
558     Changes tree identifier of all nodes traversable from this node.
559 wakaba 1.29
560 wakaba 1.27 If a node has <Q::mn:xrefnode0> property value and it
561     is a node in the tree to which the node formally belongs,
562     then reference counters are updated to new status.
563 wakaba 1.1 @@Param:
564     @@@Name: treeID
565     @@@Type:
566 wakaba 1.7 DISPerl:String::ManakaiDOM:all
567 wakaba 1.1 @@@Description:
568     @@@@lang:en
569     @@@@@:
570     The new tree identifier.
571 wakaba 1.20 @@@InCase:
572 wakaba 1.21 @@@@Type: DISPerl|SCALAR||ManakaiDOM|all
573 wakaba 1.20 @@@@enDesc:
574     A reference to the new tree identifier.
575     The tree will reference the identifier as it.
576 wakaba 1.25 @@Param:
577     @@@Name: groveRC
578     @@@Type: DISPerl|SCALAR||ManakaiDOM|all
579     @@@enDesc:
580     The new reference counter.
581 wakaba 1.1 @@Return:
582     @@@PerlDef:
583 wakaba 1.20 my $tid = ref $treeID ? $treeID : \$treeID;
584 wakaba 1.27 my $oldtid = $self->{<H::mn:treeID>};
585     my @xrnode;
586 wakaba 1.10 my @node = ($self);
587 wakaba 1.25 NODES: while (@node) {
588     my $node = shift @node;
589     next NODES unless ref $node;
590     next NODES if ${$node->{<H::mn:treeID>}} eq $$tid;
591 wakaba 1.10 my @n;
592 wakaba 1.23 my $nt = $Message::Util::ManakaiNode::ManakaiNodeRef::Prop{
593     $node->{<H::mn:type>}
594     };
595 wakaba 1.25 for my $p (@{$nt->{<H::mn:subnode2>}||[]}) {
596 wakaba 1.10 if (ref $node->{$p} eq 'ARRAY') {
597     push @n, @{$node->{$p}};
598     } elsif (ref $node->{$p} eq 'HASH') {
599     push @n, values %{$node->{$p}};
600     }
601     }
602     for my $p (@n,
603 wakaba 1.25 map {$node->{$_}} @{$nt->{<H::mn:subnode1>}||[]}) {
604 wakaba 1.10 if (ref $p eq 'ARRAY') {
605     push @node, @$p;
606     } elsif (ref $p eq 'HASH') {
607     push @node, values %$p;
608     }
609     }
610 wakaba 1.25 for my $p (@{$nt->{<H::mn:origin0>}||[]},
611     \ @{$nt->{<H::mn:subnode0>}||[]}) {
612 wakaba 1.10 push @node, $node->{$p};
613     }
614 wakaba 1.25
615 wakaba 1.27 for (@{$nt->{<H::mn:xrefnode0>}||[]}) {
616     push @xrnode, $node->{$_} if defined $node->{$_};
617     }
618    
619 wakaba 1.25 ${$node->{<H::mn:groveReferenceCounter>}} -= $node->{<H::mn:rc>};
620 wakaba 1.20 $node->{<H::mn:treeID>} = $tid;
621 wakaba 1.25 $node->{<H::mn:groveReferenceCounter>} = $groveRC;
622     ${$node->{<H::mn:groveReferenceCounter>}} += $node->{<H::mn:rc>};
623 wakaba 1.1 }
624    
625 wakaba 1.27 for my $n (@xrnode) {
626     if (${$n->{<H::mn:treeID>}} eq $$oldtid) {
627     $n->{<H::mn:rc>}++;
628     ${$n->{<H::mn:groveReferenceCounter>}}++;
629     } elsif (${$n->{<H::mn:treeID>}} eq $$tid) {
630     $n->{<H::mn:rc>}--;
631     ${$n->{<H::mn:groveReferenceCounter>}}--;
632     ## Is it necessary to test whether rc is 0 or not
633     ## and if so call "destroy" method? Maybe it need not
634     ## (or should not, rather).
635     }
636     }
637    
638 wakaba 1.1 @IntMethod:
639     @@Name: isSameNode
640     @@Description:
641     @@@lang:en
642     @@@@:
643     Returns whether a node is the same as this node or not.
644     \
645     {NOTE:: The sameness is different from the equality;
646     two nodes are same iff they are same hash reference.
647     \
648     }
649     @@Operator:
650     @@@ContentType:
651     lang:Perl
652     @@@@: eq
653     @@Param:
654     @@@Name: node
655 wakaba 1.10 @@@Type: NodeStem
656 wakaba 1.1 @@@Description:
657     @@@@lang:en
658     @@@@@:
659     A node to compare with.
660     @@Return:
661     @@@Type:
662 wakaba 1.7 DISPerl:Boolean::ManakaiDOM:all
663 wakaba 1.1 @@@Description:
664     @@@@lang:en
665     @@@@@: Whether the two nodes are same or not.
666     @@@PerlDef:
667 wakaba 1.10 if (ref $node and
668 wakaba 1.23 UNIVERSAL::isa ($node, <ClassName::ManakaiNodeStem>) and
669 wakaba 1.19 $node->{<H::mn:nodeID>} eq $self->{<H::mn:nodeID>}) {
670 wakaba 1.10 $r = true;
671     }
672 wakaba 1.1 @IntMethod:
673     @@Name: orphanate
674     @@Description:
675     @@@lang:en
676     @@@@:
677     Notifies that this node (and its neibors if any) is no longer
678     part of the main tree. If the new tree containing this node
679     has been referred yet, then the tree is preserved except its
680     tree identifier has changed. Otherwise, i.e. the tree is
681     useless any more, then it is destructed.
682     \
683     {NOTE:: Interaction on deleting a relationship from multiply
684     organized <QUOTE::trees> (such as DOM tree and
685     styled displaying tree) is less studied. This
686     method might be modified or addition of another method(s)
687     might be required when style sheet, XBL, or other
688     technologies has been implemented.
689     \
690     }
691     @@Return:
692     @@@PerlDef:
693 wakaba 1.20 if ($self-><M::NodeStem.isExternallyReferred>) {
694 wakaba 1.25 my $grc = 0;
695 wakaba 1.20 $self-><M::NodeStem.changeTreeID>
696 wakaba 1.25 (\(<Code::ManakaiDOM:generateUniqueID>), \$grc);
697 wakaba 1.20 } else {
698     $self-><M::NodeStem.destroy>;
699     }
700 wakaba 1.27
701     @ResourceDef:
702 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
703 wakaba 1.27 @@QName: mn|setXRefNode
704     @@enDesc:
705     Sets a <Q::mn:xrefnode0> property.
706     @@rdf:type: DISPerl|BlockCode
707     @@PerlDef:
708     $referrer->{$propName} = $referent;
709     if (${$referrer->{<H::mn:treeID>}} ne ${$referent->{<H::mn:treeID>}}) {
710     $referent->{<H::mn:rc>}++;
711     ${$referent->{<H::mn:groveReferenceCounter>}}++;
712     }
713    
714     @ResourceDef:
715 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
716 wakaba 1.27 @@QName: mn|unsetXRefNode
717     @@enDesc:
718     Unsets a <Q::mn:xrefnode0> property.
719     @@rdf:type: DISPerl|BlockCode
720     @@PerlDef:
721     if (defined $referrer->{$propName}) {
722 wakaba 1.28 my $__referent = $referrer->{$propName};
723     if (${$referrer->{<H::mn:treeID>}} ne ${$__referent->{<H::mn:treeID>}}) {
724     $__referent->{<H::mn:rc>}--;
725     ${$__referent->{<H::mn:groveReferenceCounter>}}--;
726     unless (<Code::isGroveReferenced:: $node = $__referent>) {
727     $__referent-><M::NodeStem.destroy>;
728 wakaba 1.27 }
729     }
730     CORE::delete $referrer->{$propName};
731     }
732 wakaba 1.10 ##NodeStem
733 wakaba 1.1
734     ## -- Public node object
735    
736     ClassDef:
737 wakaba 1.29 @resourceFor: ManakaiDOM|ForClass
738     @resourceFor: ManakaiDOM|ForIF
739 wakaba 1.10
740     @QName:
741     @@@: NodeRef
742 wakaba 1.29 @@ForCheck: ManakaiDOM|ForIF
743 wakaba 1.10
744     @QName:
745     @@@: ManakaiNodeRef
746 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
747 wakaba 1.10
748     @Implement:
749     @@@: NodeRef
750 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
751 wakaba 1.10
752 wakaba 1.22 @DISLang:role:
753     @@@: mn|NodeRefRole
754 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
755 wakaba 1.22
756 wakaba 1.1 @Description:
757     @@lang:en
758     @@@:
759     References to the node object corresponding to it. From
760     applications' view, any node object is hidden and
761     <Class::ManakaiDOM:ManakaiDOMNodeReference> seems as if
762     the node itself.
763     @ImplNote:
764     @@lang:en
765     @@@:
766 wakaba 1.13 {P:: A <Class::ManakaiDOM:ManakaiDOMNodeReference> is a blessed hash
767 wakaba 1.1 reference; currently there is a hash key defined:
768     \
769 wakaba 1.29 - <Q::mn:node>::: A node object
770 wakaba 1.1 (<Class::ManakaiDOM:ManakaiDOMNodeObject>) to which
771     this is referring.
772 wakaba 1.13
773 wakaba 1.29 - <Q::mn:isWeak>::: Whether the reference is <QUOTE::weak>
774 wakaba 1.13 or not.
775     }
776    
777     @ResourceDef:
778     @@Name: free
779     @@rdf:type: DISLang|Method
780     @@enDesc:
781     Frees the grove referenced by this object. Once
782     this operation is done, results of operations to objects belonging
783     to the grove are unknown.
784     @@Return:
785     @@@PerlDef:
786 wakaba 1.19 $self->{<H::mn:node>}-><M::NodeStem.destroy>;
787 wakaba 1.1
788     @IntMethod:
789     @@Name: destroy
790     @@Description:
791     @@@lang:en
792     @@@@: Destroy this reference object.
793     @@Operator:
794     @@@ContentType:
795     lang:Perl
796     @@@@: DESTROY
797     @@Return:
798     @@@PerlDef:
799 wakaba 1.25 @@@@@:
800 wakaba 1.29 if (my $node = $self->{<H::mn:node>}) {
801 wakaba 1.25 CORE::delete $self->{<H::mn:node>};
802     unless ($self->{<H::mn:isWeak>}) {
803     $node->{<H::mn:rc>}--;
804     ${$node->{<H::mn:groveReferenceCounter>}}--;
805     unless (<Code::isGroveReferenced:: $node = $node>) {
806     $node-><M::NodeStem.destroy>;
807     }
808     }
809     } else {
810     warn ref ($self) . q{->DESTROY: there is no associated }.
811     q{node object - you have a global variable or }.
812     qq{potential memory-leak detected\n};
813     }
814 wakaba 1.1 @@@@ImplNote:
815     @@@@@lang:en
816     @@@@@@:
817     {P::Warning during the global destruction might mean:
818     \
819     - there be a loop in the manakai internal implementation -
820     it should be a bug.
821     \
822     - there be a loop created by application, e.g.
823     event handler containing a reference to any node
824     belonging to the same tree.
825     \
826     - there be a global variable that contains a node reference
827     and it is not altered or <Perl::undef>ed until the global
828     destruction.
829     \
830     - or other unknown bad situation.
831     \
832     }
833     @@ImplNote:
834     @@@lang:en
835     @@@@:
836     Don't override this method unintentionally - for example,
837     inheritting <PerlModule::Tie::Array> would hide this method
838     from that class, since that module defines its own
839     destructor.
840 wakaba 1.10 ##NodeRef
841 wakaba 1.22
842     ResourceDef:
843     @QName: mn|NodeRefRole
844     @rdf:type: DISLang|Role
845     @For: =ManakaiDOM|all
846     @enDesc:
847     The <QUOTE::dis> definition for a class which plays the role
848     of <Q::mn|NodeRefRole> provides a set of <QUOTE::dis> properties such
849     as <Q::mn|subnode0> which identify the set of object internal
850     property names (or hash key names) used to construct groves.
851    
852     PropDef:
853     @QName: mn|type
854     @mn:stemName: t
855    
856     PropDef:
857     @QName: mn|noderef
858     @dataType: DISCore|QName
859     @multipleProperties: DISCore|UnorderedList
860    
861     PropDef:
862     @QName: mn|subnode0
863     @enDesc:
864     A property of type <Q::mn|subnode0> takes a value of
865     reference to another node (<Q::mn|NodeStem||ManakaiDOM|Perl>)
866     in the same grove. The referenced node is considered
867     to make a part of the node and just one <Q::mn|origin0>
868     property of the referenced node <kwd:MUST> have a reference
869     to the node. That is, these properties shows
870     a origin-subnode-relationship.
871     @dataType: DISCore|QName
872     @multipleProperties: DISCore|UnorderedList
873 wakaba 1.23 @mn:stemName: s0
874 wakaba 1.22
875     PropDef:
876     @QName: mn|subnode1
877     @enDesc:
878     A property of type <Q::mn|subnode1> is similar to <Q::mn|subnode0>
879     properties, but its value is an array or hash reference whose
880     values are references to subnodes.
881     @rdfs:subPropertyOf: mn|noderef
882     @dataType: DISCore|QName
883     @multipleProperties: DISCore|UnorderedList
884 wakaba 1.23 @mn:stemName: s
885 wakaba 1.22
886     PropDef:
887     @QName: mn|subnode2
888     @enDesc:
889     A property of type <Q::mn|subnode2> is similar to <Q::mn|subnode1>
890     properties, but its value is an array or hash reference whose
891     values are array or hash references whose values are
892     references to subnodes.
893     @rdfs:subPropertyOf: mn|noderef
894     @dataType: DISCore|QName
895     @multipleProperties: DISCore|UnorderedList
896 wakaba 1.23 @mn:stemName: s2
897 wakaba 1.22
898     PropDef:
899     @QName: mn|origin0
900     @rdfs:subPropertyOf: mn|noderef
901     @dataType: DISCore|QName
902     @multipleProperties: DISCore|UnorderedList
903 wakaba 1.23 @mn:stemName: o
904 wakaba 1.27
905     PropDef:
906     @QName: mn|xrefnode0
907     @rdfs:subPropertyOf: mn|noderef
908     @dataType: DISCore|QName
909     @multipleProperties: DISCore|UnorderedList
910     @mn:stemName: x
911     @rdf:type: DISSource|ResourceProperty
912     @enDesc:
913     An <Q::mn:xrefnode0> property references a node <html5:var::m> in the tree
914     <html5:var::s> that might be different from the tree <html5:var::t> to which
915     the subject node <html5::var::n> of the property belongs.
916    
917     When the property value is set and <html5:var::s> is
918     different from <html5:var::t>, then reference counters for
919     <html5:var::m> and <html5:var::s> are increased, so that
920     the tree <html5:var::s> would not be deleted while this
921     link has been maintained. When the property value is unset
922     or an <M::NodeStem||ManakaiDOM|Perl.importTree> operation
923     makes two trees to one, then two reference counters
924     are decreased.
925 wakaba 1.22
926     PropDef:
927     @QName: mn|irefnode0
928     @rdfs:subPropertyOf: mn|noderef
929     @dataType: DISCore|QName
930     @multipleProperties: DISCore|UnorderedList
931 wakaba 1.23 @mn:stemName: i
932 wakaba 1.30
933     PropDef:
934     @QName: mn|anydata0
935     @rdfs:subPropertyOf: mn|noderef
936     @dataType: DISCore|QName
937     @multipleProperties: DISCore|UnorderedList
938     @mn:stemName: a0
939 wakaba 1.22
940     PropDef:
941     @QName: mn|anydata1
942     @rdfs:subPropertyOf: mn|noderef
943     @dataType: DISCore|QName
944     @multipleProperties: DISCore|UnorderedList
945 wakaba 1.23 @mn:stemName: a1
946 wakaba 1.22
947     PropDef:
948     @QName: mn|anydata2
949     @rdfs:subPropertyOf: mn|noderef
950     @dataType: DISCore|QName
951     @multipleProperties: DISCore|UnorderedList
952 wakaba 1.23 @mn:stemName: a2
953 wakaba 1.6
954     PropDef:
955 wakaba 1.19 @QName: mn|nodeID
956     @enDesc:
957     The globally unique identifier of the node.
958     @mn:stemName: nid
959    
960     PropDef:
961     @QName: mn|treeID
962     @enDesc:
963     The globally unique identifier of the grove to which the
964     node belongs.
965     @mn:stemName: tid
966    
967     PropDef:
968     @QName: mn|rc
969     @enDesc:
970     The number of the reference that points the node.
971     @mn:stemName: rc
972    
973     PropDef:
974 wakaba 1.25 @QName: mn|groveReferenceCounter
975     @enDesc:
976     A reference to the number of references that reference
977     a node in the grove.
978     @mn:stemName: grc
979    
980     PropDef:
981 wakaba 1.19 @QName: mn|node
982     @mn:refName: node
983     @rdfs:domain: mn|NodeRef||ManakaiDOM|Perl
984     @rdfs:range: mn|NodeStem||ManakaiDOM|Perl
985    
986     PropDef:
987     @QName: mn|isWeak
988 wakaba 1.6 @enDesc:
989     Whether a reference is weak or not.
990 wakaba 1.19 @rdfs:domain: mn|NodeRef||ManakaiDOM|Perl
991 wakaba 1.16 @Type: DISPerl|Boolean
992 wakaba 1.19 @mn:refName: w
993    
994     PropDef:
995     @QName: mn|stemName
996     @enDesc:
997     The key name of the property when it is used in <Class::ManakaiNodeStem
998     ::ManakaiDOM:Perl>.
999     @dataType: DISCore|String
1000     @multipleProperties: DISCore|Single
1001     @rdfs:domain: rdfs|Property
1002     @rdfs:subPropertyOf: DISPerl|propHashKey
1003    
1004     PropDef:
1005     @QName: mn|refName
1006     @enDesc:
1007     The key name of the property when it is used in <Class::ManakaiNodeRef
1008     ::ManakaiDOM:Perl>.
1009     @dataType: DISCore|String
1010     @multipleProperties: DISCore|Single
1011     @rdfs:domain: rdfs|Property
1012     @rdfs:subPropertyOf: DISPerl|propHashKey
1013 wakaba 1.6
1014     ElementTypeBinding:
1015     @Name:PropDef
1016     @ElementType:
1017     dis:ResourceDef
1018     @ShadowContent:
1019     @@rdf:type:
1020     rdf:Property
1021 wakaba 1.16 @@For: =ManakaiDOM|all
1022 wakaba 1.6
1023     ElementTypeBinding:
1024     @Name:enDesc
1025     @ElementType:
1026     dis:Description
1027     @ShadowContent:
1028     @@lang:en
1029 wakaba 1.1
1030     ## -- Frequently used code fragments
1031    
1032     ResourceDef:
1033     @QName:
1034     ManakaiDOM:generateUniqueID
1035 wakaba 1.29 @rdf:type: DISPerl|InlineCode
1036 wakaba 1.1 @Description:
1037     @@lang:en
1038     @@@:
1039     Generates a global-unique opaque string.
1040     \
1041     {NOTE:: A URI reference is generated by this code.
1042     \
1043     }
1044 wakaba 1.16
1045     @For: =ManakaiDOM|Perl
1046    
1047 wakaba 1.1 @PerlDef:
1048     (
1049 wakaba 1.29 'tag:suika.fam.cx,2005-09:' . time . ':' . $$ . ':' .
1050     ($Message::Util::ManakaiNode::UniqueIDR ||=
1051     [qw/A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1052     a b c d e f g h i j k l m n o p q r s t u v w x y z
1053     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1054     [qw/A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1055     a b c d e f g h i j k l m n o p q r s t u v w x y z
1056     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1057     [qw/A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1058     a b c d e f g h i j k l m n o p q r s t u v w x y z
1059     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1060     [qw/A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1061     a b c d e f g h i j k l m n o p q r s t u v w x y z
1062     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1063     [qw/A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
1064     a b c d e f g h i j k l m n o p q r s t u v w x y z
1065     0 1 2 3 4 5 6 7 8 9/]->[rand 62]) .
1066     (++$Message::Util::ManakaiNode::UniqueIDN)
1067 wakaba 1.1 )
1068     ##ManakaiDOM:generateUniqueID
1069    
1070     ## -- lang:dis vocabulary
1071    
1072     TreeElementType:
1073     @QName:
1074     dis:GetProp
1075 wakaba 1.31 @dataType: DISCore|QName
1076 wakaba 1.1 @rdfs:range:
1077     rdf:Property
1078     @Description:
1079     @@lang:en
1080     @@@:
1081     Gets the non-nodal value of a <Class::ManakaiDOM:ManakaiDOMNodeReference>
1082     property (actualy <Class::ManakaiDOM:ManakaiDOMNodeObject> property).
1083    
1084     TreeElementType:
1085     @QName:
1086     dis:SetProp
1087 wakaba 1.29 @dataType: DISCore|QName
1088 wakaba 1.1 @rdfs:range:
1089     rdf:Property
1090     @Description:
1091     @@lang:en
1092     @@@:
1093     Sets the non-nodal value of a <Class::ManakaiDOM:ManakaiDOMNodeReference>
1094     property (actualy <Class::ManakaiDOM:ManakaiDOMNodeObject> property).
1095    
1096     ## -- Syntax sugar
1097    
1098     ElementTypeBinding:
1099     @Name: TreeElementType
1100     @ElementType:
1101     dis:ResourceDef
1102     @ShadowContent:
1103     @@rdf:type:
1104     DISLang:TreeElementType
1105 wakaba 1.16 @@For: =ManakaiDOM|all
1106 wakaba 1.1
1107     ElementTypeBinding:
1108     @Name: ClassDef
1109     @ElementType:
1110     dis:ResourceDef
1111     @ShadowContent:
1112     @@rdf:type:
1113     @@@@:
1114 wakaba 1.10 dis:MultipleResource
1115 wakaba 1.29 @@@ForCheck: !ManakaiDOM|ForClass !ManakaiDOM|ForIF
1116 wakaba 1.10 @@rdf:type:
1117 wakaba 1.25 @@@@: DISLang|Interface
1118     @@@ForCheck: ManakaiDOM|ForIF
1119 wakaba 1.10 @@rdf:type:
1120 wakaba 1.25 @@@@: DISLang|Class
1121 wakaba 1.29 @@@ForCheck: ManakaiDOM|ForClass
1122 wakaba 1.25 @@ForCheck: ManakaiDOM|Perl
1123 wakaba 1.1
1124     ElementTypeBinding:
1125     @Name: IntMethod
1126     @ElementType:
1127     dis:ResourceDef
1128     @ShadowContent:
1129     @@rdf:type:
1130     DISLang:Method
1131     @@ManakaiDOM:isForInternal:1
1132    
1133     ElementTypeBinding:
1134     @Name: Return
1135     @ElementType:
1136     dis:ResourceDef
1137     @ShadowContent:
1138     @@rdf:type:
1139     DISLang:MethodReturn
1140    
1141     ElementTypeBinding:
1142     @Name: Param
1143     @ElementType:
1144     dis:ResourceDef
1145     @ShadowContent:
1146     @@rdf:type:
1147     DISLang:MethodParameter
1148    
1149     ElementTypeBinding:
1150     @Name: PerlDef
1151     @ElementType:
1152     dis:Def
1153     @ShadowContent:
1154     @@ContentType:
1155     lang:Perl
1156    
1157     ElementTypeBinding:
1158     @Name: InCase
1159     @ElementType:
1160     dis:ResourceDef
1161     @ShadowContent:
1162     @@rdf:type:
1163     ManakaiDOM:InCase

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24