/[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.29 - (hide annotations) (download)
Wed Oct 12 14:46:06 2005 UTC (19 years, 9 months ago) by wakaba
Branch: MAIN
Changes since 1.28: +101 -424 lines
++ manakai/lib/Message/Util/ChangeLog	12 Oct 2005 14:38:20 -0000
2005-10-12  Wakaba  <wakaba@suika.fam.cx>

	* PerlCode.dis (ForClassCompat): Removed.

	* ManakaiNode.dis (ManakaiDOMNodeObject, ManakaiDOMNodeReference):
	Removed.
	(newNode): New method.
	(generateUniqueID): Algorithm has changed to save random
	string generation time.

	* DIS.dis (AUTOLOAD): "$Error::Level" fixed to "$Error::Depth".

++ manakai/lib/Message/DOM/ChangeLog	12 Oct 2005 14:30:20 -0000
2005-10-12  Wakaba  <wakaba@suika.fam.cx>

	* DOMCore.dis: Don't set "infoset:prefix" internal
	property unless it has non-null value.
	(newObject): "refNode" parameter introduced.
	(ManakaiDOMNode.newObject): Calls "NodeStem.newNode"
	method if "refNode" parameter is specified.
	(cloneNode): Don't set "read-only" flag.
	(getNodeReference): Caches the result.
	(selectAttributeNodeForRemove): Don't removes any other
	non-namespace-aware attribute nodes.

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.29 $Date: 2005/10/12 00:31:05 $
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.27 my $tid = $self->{<H::mn:treeID>};
405     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     for my $p (@{$nt->{<H::mn:xrefnode0>}||[]}) {
435     if (defined $node->{$p} and
436     ${$node->{$p}->{<H::mn:treeID>}||$tid} ne $$tid) {
437     $node->{$p}->{<H::mn:rc>}--;
438     ${$node->{$p}->{<H::mn:groveReferenceCounter>}}--;
439     $xrnode{${$node->{$p}->{<H::mn:treeID>}}} = $node->{$p};
440     }
441     }
442    
443 wakaba 1.10 %$node = ();
444 wakaba 1.27 } # @node
445    
446     CORE::delete $xrnode{$$tid};
447     for my $node (values %xrnode) {
448     unless (<Code::isGroveReferenced:: $node = $node>) {
449     $node-><M::NodeStem.destroy>;
450     }
451 wakaba 1.10 }
452 wakaba 1.1 @@ImplNote:
453     @@@lang:en
454     @@@@:
455     This method is different from Perl <Perl::DESTROY> special
456     purpose method.
457     \
458     An <QUOTE::uninitialized> warning in this method might mean
459     some method puts an <Perl::undef> into a list of nodes.
460    
461     @IntMethod:
462     @@Name: importTree
463     @@Description:
464     @@@lang:en
465     @@@@:
466     Changes the tree identifier of the nodes belong to another tree
467     to be same as this node's tree identifier.
468     @@Param:
469     @@@Name: node
470 wakaba 1.29 @@@Type: NodeStem
471 wakaba 1.1 @@@Description:
472     @@@@lang:en
473     @@@@@:
474     Any node from the tree to change its identifier.
475     @@Return:
476     @@@PerlDef:
477 wakaba 1.10 my @node = ($node);
478 wakaba 1.25 my $newgrc = $self->{<H::mn:groveReferenceCounter>};
479     my $newtid = $self->{<H::mn:treeID>};
480 wakaba 1.27 my $oldtid = $node->{<H::mn:treeID>};
481     my @xrnode;
482 wakaba 1.25 NODES: while (@node) {
483     my $node = shift @node;
484     next NODES unless ref $node;
485     next NODES if ${$node->{<H::mn:treeID>}} eq $$newtid;
486 wakaba 1.10 my @n;
487 wakaba 1.23 my $nt = $Message::Util::ManakaiNode::ManakaiNodeRef::Prop{
488     $node->{<H::mn:type>}
489     };
490 wakaba 1.25 for my $p (@{$nt->{<H::mn:subnode2>}||[]}) {
491 wakaba 1.29 my $ref = ref $node->{$p};
492     if ($ref eq 'HASH') {
493     push @n, values %{$node->{$p}};
494     } elsif ($ref eq 'ARRAY') {
495 wakaba 1.10 push @n, @{$node->{$p}};
496     }
497     }
498 wakaba 1.29 for my $p (@n, map {$node->{$_}} @{$nt->{<H::mn:subnode1>}||[]}) {
499     my $ref = ref $p;
500     if ($ref eq 'ARRAY') {
501 wakaba 1.10 push @node, @$p;
502 wakaba 1.29 } elsif ($ref eq 'HASH') {
503 wakaba 1.10 push @node, values %$p;
504     }
505     }
506 wakaba 1.25 for my $p (@{$nt->{<H::mn:origin0>}||[]},
507     \ @{$nt->{<H::mn:subnode0>}||[]}) {
508 wakaba 1.29 push @node, $node->{$p} if defined $node->{$p};
509 wakaba 1.10 }
510 wakaba 1.25
511 wakaba 1.27 for (@{$nt->{<H::mn:xrefnode0>}||[]}) {
512     push @xrnode, $node->{$_} if defined $node->{$_};
513     }
514    
515 wakaba 1.25 ${$node->{<H::mn:groveReferenceCounter>}} -= $node->{<H::mn:rc>};
516     $node->{<H::mn:treeID>} = $newtid;
517     $node->{<H::mn:groveReferenceCounter>} = $newgrc;
518 wakaba 1.29 $$newgrc += $node->{<H::mn:rc>};
519 wakaba 1.10 }
520 wakaba 1.1
521 wakaba 1.27 for my $n (@xrnode) {
522     if (${$n->{<H::mn:treeID>}} eq $$oldtid) {
523     $n->{<H::mn:rc>}++;
524     ${$n->{<H::mn:groveReferenceCounter>}}++;
525     } elsif (${$n->{<H::mn:treeID>}} eq $$newtid) {
526     $n->{<H::mn:rc>}--;
527     ${$n->{<H::mn:groveReferenceCounter>}}--;
528     ## Is it necessary to test whether rc is 0 or not
529     ## and if so call "destroy" method? Maybe it need not
530     ## (or should not, rather).
531     }
532     }
533    
534 wakaba 1.1 @IntMethod:
535     @@Name: changeTreeID
536     @@Description:
537     @@@lang:en
538     @@@@:
539     Changes tree identifier of all nodes traversable from this node.
540 wakaba 1.29
541 wakaba 1.27 If a node has <Q::mn:xrefnode0> property value and it
542     is a node in the tree to which the node formally belongs,
543     then reference counters are updated to new status.
544 wakaba 1.1 @@Param:
545     @@@Name: treeID
546     @@@Type:
547 wakaba 1.7 DISPerl:String::ManakaiDOM:all
548 wakaba 1.1 @@@Description:
549     @@@@lang:en
550     @@@@@:
551     The new tree identifier.
552 wakaba 1.20 @@@InCase:
553 wakaba 1.21 @@@@Type: DISPerl|SCALAR||ManakaiDOM|all
554 wakaba 1.20 @@@@enDesc:
555     A reference to the new tree identifier.
556     The tree will reference the identifier as it.
557 wakaba 1.25 @@Param:
558     @@@Name: groveRC
559     @@@Type: DISPerl|SCALAR||ManakaiDOM|all
560     @@@enDesc:
561     The new reference counter.
562 wakaba 1.1 @@Return:
563     @@@PerlDef:
564 wakaba 1.20 my $tid = ref $treeID ? $treeID : \$treeID;
565 wakaba 1.27 my $oldtid = $self->{<H::mn:treeID>};
566     my @xrnode;
567 wakaba 1.10 my @node = ($self);
568 wakaba 1.25 NODES: while (@node) {
569     my $node = shift @node;
570     next NODES unless ref $node;
571     next NODES if ${$node->{<H::mn:treeID>}} eq $$tid;
572 wakaba 1.10 my @n;
573 wakaba 1.23 my $nt = $Message::Util::ManakaiNode::ManakaiNodeRef::Prop{
574     $node->{<H::mn:type>}
575     };
576 wakaba 1.25 for my $p (@{$nt->{<H::mn:subnode2>}||[]}) {
577 wakaba 1.10 if (ref $node->{$p} eq 'ARRAY') {
578     push @n, @{$node->{$p}};
579     } elsif (ref $node->{$p} eq 'HASH') {
580     push @n, values %{$node->{$p}};
581     }
582     }
583     for my $p (@n,
584 wakaba 1.25 map {$node->{$_}} @{$nt->{<H::mn:subnode1>}||[]}) {
585 wakaba 1.10 if (ref $p eq 'ARRAY') {
586     push @node, @$p;
587     } elsif (ref $p eq 'HASH') {
588     push @node, values %$p;
589     }
590     }
591 wakaba 1.25 for my $p (@{$nt->{<H::mn:origin0>}||[]},
592     \ @{$nt->{<H::mn:subnode0>}||[]}) {
593 wakaba 1.10 push @node, $node->{$p};
594     }
595 wakaba 1.25
596 wakaba 1.27 for (@{$nt->{<H::mn:xrefnode0>}||[]}) {
597     push @xrnode, $node->{$_} if defined $node->{$_};
598     }
599    
600 wakaba 1.25 ${$node->{<H::mn:groveReferenceCounter>}} -= $node->{<H::mn:rc>};
601 wakaba 1.20 $node->{<H::mn:treeID>} = $tid;
602 wakaba 1.25 $node->{<H::mn:groveReferenceCounter>} = $groveRC;
603     ${$node->{<H::mn:groveReferenceCounter>}} += $node->{<H::mn:rc>};
604 wakaba 1.1 }
605    
606 wakaba 1.27 for my $n (@xrnode) {
607     if (${$n->{<H::mn:treeID>}} eq $$oldtid) {
608     $n->{<H::mn:rc>}++;
609     ${$n->{<H::mn:groveReferenceCounter>}}++;
610     } elsif (${$n->{<H::mn:treeID>}} eq $$tid) {
611     $n->{<H::mn:rc>}--;
612     ${$n->{<H::mn:groveReferenceCounter>}}--;
613     ## Is it necessary to test whether rc is 0 or not
614     ## and if so call "destroy" method? Maybe it need not
615     ## (or should not, rather).
616     }
617     }
618    
619 wakaba 1.1 @IntMethod:
620     @@Name: isSameNode
621     @@Description:
622     @@@lang:en
623     @@@@:
624     Returns whether a node is the same as this node or not.
625     \
626     {NOTE:: The sameness is different from the equality;
627     two nodes are same iff they are same hash reference.
628     \
629     }
630     @@Operator:
631     @@@ContentType:
632     lang:Perl
633     @@@@: eq
634     @@Param:
635     @@@Name: node
636 wakaba 1.10 @@@Type: NodeStem
637 wakaba 1.1 @@@Description:
638     @@@@lang:en
639     @@@@@:
640     A node to compare with.
641     @@Return:
642     @@@Type:
643 wakaba 1.7 DISPerl:Boolean::ManakaiDOM:all
644 wakaba 1.1 @@@Description:
645     @@@@lang:en
646     @@@@@: Whether the two nodes are same or not.
647     @@@PerlDef:
648 wakaba 1.10 if (ref $node and
649 wakaba 1.23 UNIVERSAL::isa ($node, <ClassName::ManakaiNodeStem>) and
650 wakaba 1.19 $node->{<H::mn:nodeID>} eq $self->{<H::mn:nodeID>}) {
651 wakaba 1.10 $r = true;
652     }
653 wakaba 1.1 @IntMethod:
654     @@Name: orphanate
655     @@Description:
656     @@@lang:en
657     @@@@:
658     Notifies that this node (and its neibors if any) is no longer
659     part of the main tree. If the new tree containing this node
660     has been referred yet, then the tree is preserved except its
661     tree identifier has changed. Otherwise, i.e. the tree is
662     useless any more, then it is destructed.
663     \
664     {NOTE:: Interaction on deleting a relationship from multiply
665     organized <QUOTE::trees> (such as DOM tree and
666     styled displaying tree) is less studied. This
667     method might be modified or addition of another method(s)
668     might be required when style sheet, XBL, or other
669     technologies has been implemented.
670     \
671     }
672     @@Return:
673     @@@PerlDef:
674 wakaba 1.20 if ($self-><M::NodeStem.isExternallyReferred>) {
675 wakaba 1.25 my $grc = 0;
676 wakaba 1.20 $self-><M::NodeStem.changeTreeID>
677 wakaba 1.25 (\(<Code::ManakaiDOM:generateUniqueID>), \$grc);
678 wakaba 1.20 } else {
679     $self-><M::NodeStem.destroy>;
680     }
681 wakaba 1.27
682     @ResourceDef:
683 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
684 wakaba 1.27 @@QName: mn|setXRefNode
685     @@enDesc:
686     Sets a <Q::mn:xrefnode0> property.
687     @@rdf:type: DISPerl|BlockCode
688     @@PerlDef:
689     $referrer->{$propName} = $referent;
690     if (${$referrer->{<H::mn:treeID>}} ne ${$referent->{<H::mn:treeID>}}) {
691     $referent->{<H::mn:rc>}++;
692     ${$referent->{<H::mn:groveReferenceCounter>}}++;
693     }
694    
695     @ResourceDef:
696 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
697 wakaba 1.27 @@QName: mn|unsetXRefNode
698     @@enDesc:
699     Unsets a <Q::mn:xrefnode0> property.
700     @@rdf:type: DISPerl|BlockCode
701     @@PerlDef:
702     if (defined $referrer->{$propName}) {
703 wakaba 1.28 my $__referent = $referrer->{$propName};
704     if (${$referrer->{<H::mn:treeID>}} ne ${$__referent->{<H::mn:treeID>}}) {
705     $__referent->{<H::mn:rc>}--;
706     ${$__referent->{<H::mn:groveReferenceCounter>}}--;
707     unless (<Code::isGroveReferenced:: $node = $__referent>) {
708     $__referent-><M::NodeStem.destroy>;
709 wakaba 1.27 }
710     }
711     CORE::delete $referrer->{$propName};
712     }
713 wakaba 1.10 ##NodeStem
714 wakaba 1.1
715     ## -- Public node object
716    
717     ClassDef:
718 wakaba 1.29 @resourceFor: ManakaiDOM|ForClass
719     @resourceFor: ManakaiDOM|ForIF
720 wakaba 1.10
721     @QName:
722     @@@: NodeRef
723 wakaba 1.29 @@ForCheck: ManakaiDOM|ForIF
724 wakaba 1.10
725     @QName:
726     @@@: ManakaiNodeRef
727 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
728 wakaba 1.10
729     @Implement:
730     @@@: NodeRef
731 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
732 wakaba 1.10
733 wakaba 1.22 @DISLang:role:
734     @@@: mn|NodeRefRole
735 wakaba 1.29 @@ForCheck: ManakaiDOM|ForClass
736 wakaba 1.22
737 wakaba 1.1 @Description:
738     @@lang:en
739     @@@:
740     References to the node object corresponding to it. From
741     applications' view, any node object is hidden and
742     <Class::ManakaiDOM:ManakaiDOMNodeReference> seems as if
743     the node itself.
744     @ImplNote:
745     @@lang:en
746     @@@:
747 wakaba 1.13 {P:: A <Class::ManakaiDOM:ManakaiDOMNodeReference> is a blessed hash
748 wakaba 1.1 reference; currently there is a hash key defined:
749     \
750 wakaba 1.29 - <Q::mn:node>::: A node object
751 wakaba 1.1 (<Class::ManakaiDOM:ManakaiDOMNodeObject>) to which
752     this is referring.
753 wakaba 1.13
754 wakaba 1.29 - <Q::mn:isWeak>::: Whether the reference is <QUOTE::weak>
755 wakaba 1.13 or not.
756     }
757    
758     @ResourceDef:
759     @@Name: free
760     @@rdf:type: DISLang|Method
761     @@enDesc:
762     Frees the grove referenced by this object. Once
763     this operation is done, results of operations to objects belonging
764     to the grove are unknown.
765     @@Return:
766     @@@PerlDef:
767 wakaba 1.19 $self->{<H::mn:node>}-><M::NodeStem.destroy>;
768 wakaba 1.1
769     @IntMethod:
770     @@Name: destroy
771     @@Description:
772     @@@lang:en
773     @@@@: Destroy this reference object.
774     @@Operator:
775     @@@ContentType:
776     lang:Perl
777     @@@@: DESTROY
778     @@Return:
779     @@@PerlDef:
780 wakaba 1.25 @@@@@:
781 wakaba 1.29 if (my $node = $self->{<H::mn:node>}) {
782 wakaba 1.25 CORE::delete $self->{<H::mn:node>};
783     unless ($self->{<H::mn:isWeak>}) {
784     $node->{<H::mn:rc>}--;
785     ${$node->{<H::mn:groveReferenceCounter>}}--;
786     unless (<Code::isGroveReferenced:: $node = $node>) {
787     $node-><M::NodeStem.destroy>;
788     }
789     }
790     } else {
791     warn ref ($self) . q{->DESTROY: there is no associated }.
792     q{node object - you have a global variable or }.
793     qq{potential memory-leak detected\n};
794     }
795 wakaba 1.1 @@@@ImplNote:
796     @@@@@lang:en
797     @@@@@@:
798     {P::Warning during the global destruction might mean:
799     \
800     - there be a loop in the manakai internal implementation -
801     it should be a bug.
802     \
803     - there be a loop created by application, e.g.
804     event handler containing a reference to any node
805     belonging to the same tree.
806     \
807     - there be a global variable that contains a node reference
808     and it is not altered or <Perl::undef>ed until the global
809     destruction.
810     \
811     - or other unknown bad situation.
812     \
813     }
814     @@ImplNote:
815     @@@lang:en
816     @@@@:
817     Don't override this method unintentionally - for example,
818     inheritting <PerlModule::Tie::Array> would hide this method
819     from that class, since that module defines its own
820     destructor.
821 wakaba 1.10 ##NodeRef
822 wakaba 1.22
823     ResourceDef:
824     @QName: mn|NodeRefRole
825     @rdf:type: DISLang|Role
826     @For: =ManakaiDOM|all
827     @enDesc:
828     The <QUOTE::dis> definition for a class which plays the role
829     of <Q::mn|NodeRefRole> provides a set of <QUOTE::dis> properties such
830     as <Q::mn|subnode0> which identify the set of object internal
831     property names (or hash key names) used to construct groves.
832    
833     PropDef:
834     @QName: mn|type
835     @mn:stemName: t
836    
837     PropDef:
838     @QName: mn|noderef
839     @dataType: DISCore|QName
840     @multipleProperties: DISCore|UnorderedList
841    
842     PropDef:
843     @QName: mn|subnode0
844     @enDesc:
845     A property of type <Q::mn|subnode0> takes a value of
846     reference to another node (<Q::mn|NodeStem||ManakaiDOM|Perl>)
847     in the same grove. The referenced node is considered
848     to make a part of the node and just one <Q::mn|origin0>
849     property of the referenced node <kwd:MUST> have a reference
850     to the node. That is, these properties shows
851     a origin-subnode-relationship.
852     @dataType: DISCore|QName
853     @multipleProperties: DISCore|UnorderedList
854 wakaba 1.23 @mn:stemName: s0
855 wakaba 1.22
856     PropDef:
857     @QName: mn|subnode1
858     @enDesc:
859     A property of type <Q::mn|subnode1> is similar to <Q::mn|subnode0>
860     properties, but its value is an array or hash reference whose
861     values are references to subnodes.
862     @rdfs:subPropertyOf: mn|noderef
863     @dataType: DISCore|QName
864     @multipleProperties: DISCore|UnorderedList
865 wakaba 1.23 @mn:stemName: s
866 wakaba 1.22
867     PropDef:
868     @QName: mn|subnode2
869     @enDesc:
870     A property of type <Q::mn|subnode2> is similar to <Q::mn|subnode1>
871     properties, but its value is an array or hash reference whose
872     values are array or hash references whose values are
873     references to subnodes.
874     @rdfs:subPropertyOf: mn|noderef
875     @dataType: DISCore|QName
876     @multipleProperties: DISCore|UnorderedList
877 wakaba 1.23 @mn:stemName: s2
878 wakaba 1.22
879     PropDef:
880     @QName: mn|origin0
881     @rdfs:subPropertyOf: mn|noderef
882     @dataType: DISCore|QName
883     @multipleProperties: DISCore|UnorderedList
884 wakaba 1.23 @mn:stemName: o
885 wakaba 1.27
886     PropDef:
887     @QName: mn|xrefnode0
888     @rdfs:subPropertyOf: mn|noderef
889     @dataType: DISCore|QName
890     @multipleProperties: DISCore|UnorderedList
891     @mn:stemName: x
892     @rdf:type: DISSource|ResourceProperty
893     @enDesc:
894     An <Q::mn:xrefnode0> property references a node <html5:var::m> in the tree
895     <html5:var::s> that might be different from the tree <html5:var::t> to which
896     the subject node <html5::var::n> of the property belongs.
897    
898     When the property value is set and <html5:var::s> is
899     different from <html5:var::t>, then reference counters for
900     <html5:var::m> and <html5:var::s> are increased, so that
901     the tree <html5:var::s> would not be deleted while this
902     link has been maintained. When the property value is unset
903     or an <M::NodeStem||ManakaiDOM|Perl.importTree> operation
904     makes two trees to one, then two reference counters
905     are decreased.
906 wakaba 1.22
907     PropDef:
908     @QName: mn|irefnode0
909     @rdfs:subPropertyOf: mn|noderef
910     @dataType: DISCore|QName
911     @multipleProperties: DISCore|UnorderedList
912 wakaba 1.23 @mn:stemName: i
913 wakaba 1.22
914     PropDef:
915     @QName: mn|anydata1
916     @rdfs:subPropertyOf: mn|noderef
917     @dataType: DISCore|QName
918     @multipleProperties: DISCore|UnorderedList
919 wakaba 1.23 @mn:stemName: a1
920 wakaba 1.22
921     PropDef:
922     @QName: mn|anydata2
923     @rdfs:subPropertyOf: mn|noderef
924     @dataType: DISCore|QName
925     @multipleProperties: DISCore|UnorderedList
926 wakaba 1.23 @mn:stemName: a2
927 wakaba 1.6
928     PropDef:
929 wakaba 1.19 @QName: mn|nodeID
930     @enDesc:
931     The globally unique identifier of the node.
932     @mn:stemName: nid
933    
934     PropDef:
935     @QName: mn|treeID
936     @enDesc:
937     The globally unique identifier of the grove to which the
938     node belongs.
939     @mn:stemName: tid
940    
941     PropDef:
942     @QName: mn|rc
943     @enDesc:
944     The number of the reference that points the node.
945     @mn:stemName: rc
946    
947     PropDef:
948 wakaba 1.25 @QName: mn|groveReferenceCounter
949     @enDesc:
950     A reference to the number of references that reference
951     a node in the grove.
952     @mn:stemName: grc
953    
954     PropDef:
955 wakaba 1.19 @QName: mn|node
956     @mn:refName: node
957     @rdfs:domain: mn|NodeRef||ManakaiDOM|Perl
958     @rdfs:range: mn|NodeStem||ManakaiDOM|Perl
959    
960     PropDef:
961     @QName: mn|isWeak
962 wakaba 1.6 @enDesc:
963     Whether a reference is weak or not.
964 wakaba 1.19 @rdfs:domain: mn|NodeRef||ManakaiDOM|Perl
965 wakaba 1.16 @Type: DISPerl|Boolean
966 wakaba 1.19 @mn:refName: w
967    
968     PropDef:
969     @QName: mn|stemName
970     @enDesc:
971     The key name of the property when it is used in <Class::ManakaiNodeStem
972     ::ManakaiDOM:Perl>.
973     @dataType: DISCore|String
974     @multipleProperties: DISCore|Single
975     @rdfs:domain: rdfs|Property
976     @rdfs:subPropertyOf: DISPerl|propHashKey
977    
978     PropDef:
979     @QName: mn|refName
980     @enDesc:
981     The key name of the property when it is used in <Class::ManakaiNodeRef
982     ::ManakaiDOM:Perl>.
983     @dataType: DISCore|String
984     @multipleProperties: DISCore|Single
985     @rdfs:domain: rdfs|Property
986     @rdfs:subPropertyOf: DISPerl|propHashKey
987 wakaba 1.6
988     ElementTypeBinding:
989     @Name:PropDef
990     @ElementType:
991     dis:ResourceDef
992     @ShadowContent:
993     @@rdf:type:
994     rdf:Property
995 wakaba 1.16 @@For: =ManakaiDOM|all
996 wakaba 1.6
997     ElementTypeBinding:
998     @Name:enDesc
999     @ElementType:
1000     dis:Description
1001     @ShadowContent:
1002     @@lang:en
1003 wakaba 1.1
1004     ## -- Frequently used code fragments
1005    
1006     ResourceDef:
1007     @QName:
1008     ManakaiDOM:generateUniqueID
1009 wakaba 1.29 @rdf:type: DISPerl|InlineCode
1010 wakaba 1.1 @Description:
1011     @@lang:en
1012     @@@:
1013     Generates a global-unique opaque string.
1014     \
1015     {NOTE:: A URI reference is generated by this code.
1016     \
1017     }
1018 wakaba 1.16
1019     @For: =ManakaiDOM|Perl
1020    
1021 wakaba 1.1 @PerlDef:
1022     (
1023 wakaba 1.29 'tag:suika.fam.cx,2005-09:' . time . ':' . $$ . ':' .
1024     ($Message::Util::ManakaiNode::UniqueIDR ||=
1025     [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
1026     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
1027     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1028     [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
1029     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
1030     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1031     [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
1032     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
1033     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1034     [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
1035     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
1036     0 1 2 3 4 5 6 7 8 9/]->[rand 62] .
1037     [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
1038     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
1039     0 1 2 3 4 5 6 7 8 9/]->[rand 62]) .
1040     (++$Message::Util::ManakaiNode::UniqueIDN)
1041 wakaba 1.1 )
1042     ##ManakaiDOM:generateUniqueID
1043    
1044     ## -- lang:dis vocabulary
1045    
1046     TreeElementType:
1047     @QName:
1048     dis:GetProp
1049     @dataType:
1050     dis:TypeQName
1051     @rdfs:range:
1052     rdf:Property
1053     @Description:
1054     @@lang:en
1055     @@@:
1056     Gets the non-nodal value of a <Class::ManakaiDOM:ManakaiDOMNodeReference>
1057     property (actualy <Class::ManakaiDOM:ManakaiDOMNodeObject> property).
1058    
1059     TreeElementType:
1060     @QName:
1061     dis:SetProp
1062 wakaba 1.29 @dataType: DISCore|QName
1063 wakaba 1.1 @rdfs:range:
1064     rdf:Property
1065     @Description:
1066     @@lang:en
1067     @@@:
1068     Sets the non-nodal value of a <Class::ManakaiDOM:ManakaiDOMNodeReference>
1069     property (actualy <Class::ManakaiDOM:ManakaiDOMNodeObject> property).
1070    
1071     ## -- Syntax sugar
1072    
1073     ElementTypeBinding:
1074     @Name: TreeElementType
1075     @ElementType:
1076     dis:ResourceDef
1077     @ShadowContent:
1078     @@rdf:type:
1079     DISLang:TreeElementType
1080 wakaba 1.16 @@For: =ManakaiDOM|all
1081 wakaba 1.1
1082     ElementTypeBinding:
1083     @Name: ClassDef
1084     @ElementType:
1085     dis:ResourceDef
1086     @ShadowContent:
1087     @@rdf:type:
1088     @@@@:
1089 wakaba 1.10 dis:MultipleResource
1090 wakaba 1.29 @@@ForCheck: !ManakaiDOM|ForClass !ManakaiDOM|ForIF
1091 wakaba 1.10 @@rdf:type:
1092 wakaba 1.25 @@@@: DISLang|Interface
1093     @@@ForCheck: ManakaiDOM|ForIF
1094 wakaba 1.10 @@rdf:type:
1095 wakaba 1.25 @@@@: DISLang|Class
1096 wakaba 1.29 @@@ForCheck: ManakaiDOM|ForClass
1097 wakaba 1.25 @@ForCheck: ManakaiDOM|Perl
1098 wakaba 1.1
1099     ElementTypeBinding:
1100     @Name: IntMethod
1101     @ElementType:
1102     dis:ResourceDef
1103     @ShadowContent:
1104     @@rdf:type:
1105     DISLang:Method
1106     @@ManakaiDOM:isForInternal:1
1107    
1108     ElementTypeBinding:
1109     @Name: Return
1110     @ElementType:
1111     dis:ResourceDef
1112     @ShadowContent:
1113     @@rdf:type:
1114     DISLang:MethodReturn
1115    
1116     ElementTypeBinding:
1117     @Name: Param
1118     @ElementType:
1119     dis:ResourceDef
1120     @ShadowContent:
1121     @@rdf:type:
1122     DISLang:MethodParameter
1123    
1124     ElementTypeBinding:
1125     @Name: PerlDef
1126     @ElementType:
1127     dis:Def
1128     @ShadowContent:
1129     @@ContentType:
1130     lang:Perl
1131    
1132     ElementTypeBinding:
1133     @Name: InCase
1134     @ElementType:
1135     dis:ResourceDef
1136     @ShadowContent:
1137     @@rdf:type:
1138     ManakaiDOM:InCase

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24