/[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.35 - (hide annotations) (download)
Sat Dec 30 12:00:43 2006 UTC (18 years, 6 months ago) by wakaba
Branch: MAIN
Changes since 1.34: +23 -54 lines
++ manakai/lib/Message/Markup/ChangeLog	30 Dec 2006 11:55:48 -0000
	* Atom.dis, SuikaWiki.dis, H2H.dis, SuikaWikiConfig21.dis: |For|
	specifications are removed.

	* SuikaWikiConfig21.dis: |WithFor| and |DefaultFor|
	specifications are removed.
	(ForEmpty, ForLatest): Removed.

2006-12-30  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/Util/ChangeLog	30 Dec 2006 11:57:42 -0000
	* PerlCode.dis, DIS.dis, ManakaiNode.dis,
	ManakaiNodeTest.dis: |For| specifications are removed.

	* common.dis: New module.

	* DIS.dis, PerlCode.dis, ManakaiNode.dis: |Util:| resource
	definitions are removed (and moved to |common.dis|).

	* DIS.dis (ForEmpty, ForLatest): Removed.

	* DIS.dis: |WithFor| and |DefaultFor| are removed.

2006-12-30  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/Util/Error/ChangeLog	30 Dec 2006 11:59:28 -0000
2006-12-30  Wakaba  <wakaba@suika.fam.cx>

	* Core.dis, DOMException.dis: |WithFor|, |DefaultFor|,
	and |For| specificaitons are removed.

++ manakai/lib/Message/Util/Formatter/ChangeLog	30 Dec 2006 11:59:59 -0000
2006-12-30  Wakaba  <wakaba@suika.fam.cx>

	* Muf2003.dis: |WithFor|, |DefaultFor|, and |For|
	specifications are removed.

++ manakai/lib/Message/Util/DIS/ChangeLog	30 Dec 2006 11:58:54 -0000
	* Perl.dis, Value.dis, DNLite.dis,
	DPG.dis, Test.dis: |WithFor|, |For|, and |DefaultFor|
	specifications are removed.

2006-12-30  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/DOM/ChangeLog	30 Dec 2006 11:53:43 -0000
        SimpleLS.dis, DOMMain.dis, XDP.dis: |For| specifications
	are removed.

2006-12-30  Wakaba  <wakaba@suika.fam.cx>

	* CharacterData.dis, DOMCore.dis, DOMFeature.dis,
        GenericLS.dis, TreeCore.dis, DOMString.dis,
        XML.dis, Element.dis, Document.dis, TreeStore,dis,
        Traversal.dis, XDoctype.dis, XMLParser.dis, DOMLS.dis,
++ manakai/lib/Message/URI/ChangeLog	30 Dec 2006 11:54:30 -0000
	* Generic.dis: |For| specifications are removed.

2006-12-30  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/Charset/ChangeLog	30 Dec 2006 11:54:10 -0000
	* Encode.dis: |For| specifications are removed.

2006-12-30  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/manakai/ChangeLog	30 Dec 2006 12:00:29 -0000
	* XML.dis: |DefaultFor| specification is removed.

2006-12-30  Wakaba  <wakaba@suika.fam.cx>

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24