File Coverage

blib/lib/E2/Node.pm
Criterion Covered Total %
statement 46 132 34.8
branch 11 84 13.1
condition 1 16 6.2
subroutine 8 27 29.6
pod 12 15 80.0
total 78 274 28.4


line stmt bran cond sub pod time code
1             # E2::Node
2             # Jose M. Weeks
3             # 11 July 2003
4             #
5             # See bottom for pod documentation.
6              
7             package E2::Node;
8              
9 6     6   735 use 5.006;
  6         23  
  6         244  
10 6     6   32 use strict;
  6         13  
  6         165  
11 6     6   28 use warnings;
  6         10  
  6         181  
12 6     6   108 use Carp;
  6         11  
  6         366  
13              
14 6     6   4153 use E2::Interface;
  6         20  
  6         11712  
15              
16             our @ISA = "E2::Interface";
17             our $VERSION = "0.33";
18             our $DEBUG; *DEBUG = *E2::Interface::DEBUG;
19              
20             # Prototypes
21              
22             sub new;
23              
24             sub clear;
25              
26             sub title;
27             sub node_id;
28             sub author;
29             sub author_id;
30             sub createtime;
31             sub type;
32              
33             sub bookmark;
34              
35             sub load;
36             sub load_by_id;
37             sub load_from_xml;
38              
39             # Object Methods
40              
41             sub new {
42 5     5 1 12 my $arg = shift;
43 5   33     36 my $class = ref( $arg ) || $arg;
44 5         55 my $self = $class->SUPER::new();
45              
46 5         30 $self->clear;
47              
48 5         16 return $self;
49             }
50              
51             sub clear {
52 15 50   15 0 52 my $self = shift or croak "Usage: clear E2NODE";
53              
54 15 50       37 warn "E2::Node::clear\n" if $DEBUG > 1;
55              
56 15         25 $self->{title} = undef; # Title of the node
57 15         39 $self->{node_id} = undef; # node_id
58 15         24 $self->{author} = undef; # Author (node creator)
59 15         68 $self->{author_id} = undef; # user_id of author
60 15         24 $self->{time} = undef; # Creation time
61 15         23 $self->{type} = undef; # Writeup type
62              
63 15         30 return 1;
64             }
65              
66             sub type_as_string {
67 0     0 0 0 return undef;
68             }
69              
70             sub autodetect {
71 0 0   0 1 0 my $self = shift or croak "Usage: autodetect E2NODE";
72            
73 0 0       0 warn "E2::Node::autodetect\n" if $DEBUG > 1;
74            
75 0         0 bless $self;
76 0         0 return 1;
77             }
78              
79             sub load {
80 0 0   0 1 0 my $self = shift or croak "Usage: load E2NODE, TITLE [, TYPE] [, SOFTLINK ]";
81 0 0       0 my $title = shift or croak "Usage: load E2NODE, TITLE [, TYPE] [, SOFTLINK ]";
82 0   0     0 my $type = shift || $self->type_as_string;
83 0   0     0 my $softlink = shift||0;
84              
85 0 0       0 warn "E2::Node::load\n" if $DEBUG > 1;
86              
87 0 0       0 warn "Loading node $title" if $DEBUG > 2;
88            
89 0 0       0 $softlink = $self->node_id if $softlink == -1;
90              
91 0 0 0     0 warn "[softlinking $softlink]" if $DEBUG > 2 && $softlink;
92            
93 0         0 my %opt;
94              
95 0         0 $opt{node} = $title;
96 0         0 $opt{displaytype} = 'xmltrue';
97 0 0       0 $opt{type} = $type if $type;
98 0 0       0 $opt{lastnode_id} = $softlink if $softlink;
99              
100             return $self->thread_then(
101             [ \&E2::Interface::process_request, $self, %opt ],
102             sub {
103 0     0   0 my $r = shift;
104 0         0 return $self->load_from_xml( $r );
105 0         0 });
106             }
107              
108             sub load_by_id {
109 0 0   0 1 0 my $self = shift or croak "Usage: load_by_id E2NODE, NODE_ID [, SOFTLINK ]";
110 0 0       0 my $id = shift or croak "Usage: load_by_id E2NODE, NODE_ID [, SOFTLINK ]";
111 0   0     0 my $softlink = shift||0;
112            
113 0 0       0 warn "E2::Node::load_by_id\n" if $DEBUG > 1;
114              
115 0 0       0 warn "Loading node_id $id" if $DEBUG > 2;
116              
117 0 0       0 $softlink = $self->node_id if $softlink == -1;
118              
119 0         0 my %opt;
120              
121 0         0 $opt{node_id} = $id;
122 0         0 $opt{displaytype} = 'xmltrue';
123 0 0       0 $opt{lastnode_id} = $softlink if $softlink;
124            
125             return $self->thread_then( [ \&E2::Interface::process_request, $self, %opt ],
126             sub {
127 0     0   0 my $r = shift;
128 0         0 return $self->load_from_xml( $r );
129 0         0 });
130             }
131              
132              
133             sub load_from_xml {
134 5 50   5 1 80 my $self = shift or croak "Usage: load_from_xml E2NODE, XML_STRING";
135 5 50       23 my $xml = shift or croak "Usage: load_from_xml E2NODE, XML_STRING";
136              
137 5 50       17 warn "E2::Node::load_from_xml\n" if $DEBUG > 1;
138              
139 5         58 my %type_to_class = (
140             e2node => 'E2::E2Node',
141             writeup => 'E2::E2Node',
142             user => 'E2::User',
143             usergroup => 'E2::Usergroup',
144             room => 'E2::Room',
145             superdoc => 'E2::Superdoc',
146             superdocnolinks => 'E2::Superdoc'
147             );
148              
149             # Determine what type the XML says it is.
150              
151 5         47 $xml =~ /(.*?)<\/type>/s;
152 5         20 my $verified_type = $1;
153            
154 5 50       34 if( !$verified_type ) {
155 0         0 croak "Invalid document";
156             }
157              
158             # If we hit a search page then the node doesn't exist
159             # FIXME: search page
160              
161 5 50       52 if( ! ($xml =~ /]*node_id="(.*?)"/s) ) {
162 0         0 croak "Invalid document";
163             }
164              
165 5 50       28 if( $1 == 1140332 ) {
166             #&& # Search node_id
167             # (!$type || lc($type) ne 'superdoc') ) {
168 0 0       0 warn "Hit search superdoc" if $DEBUG;
169 0         0 $self->clear;
170 0         0 return undef;
171             }
172              
173             #if( $type && lc($type) ne lc($verified_type) ) {
174             # return undef;
175             #}
176              
177             # Now, if we are an E2::Node, figure out what type of node
178             # the XML is describing and bless $self into that class.
179              
180 5 50       23 if( ref($self) eq "E2::Node" ) {
181              
182 0         0 $self->clear;
183              
184 0         0 my $class = $type_to_class{$verified_type};
185 0 0       0 if( !$class ) {
186 0         0 croak "Invalid document";
187             }
188              
189             # Convert class name to module name and
190             # re-bless $self to that class.
191              
192 0         0 my $c = $class;
193 0         0 $c =~ s/::/\//g;
194 0         0 $c .= ".pm";
195              
196 0         0 require $c;
197 0         0 bless $self, $class;
198              
199 0 0       0 warn "Autodetected type $class" if $DEBUG > 2;
200              
201             # Otherwise, make sure the node is of the type
202             # we expect.
203              
204             } else {
205 5 50       39 if( lc($self->type_as_string) ne lc($verified_type) ) {
206 0         0 croak "Wrong node type";
207             }
208             }
209              
210             # These are the default handlers. Descendants can add handlers by
211             # returning a hash (of 'tag' => sub { ... } pairs) in the method
212             # twig_handlers
213            
214             my %handlers = (
215             'node' => sub {
216 0     0   0 (my $a, my $b) = @_;
217 0         0 $self->{node_id} = $b->{att}->{node_id};
218 0         0 $self->{createtime} = $b->{att}->{createtime};
219             },
220             'node/type' => sub {
221 0     0   0 (my $a, my $b) = @_;
222 0         0 $self->{type} = $b->text;
223             },
224             'node/title' => sub {
225 0     0   0 (my $a, my $b) = @_;
226 0         0 $self->{title} = $b->text;
227             },
228             'node/author' => sub {
229 0     0   0 (my $a, my $b) = @_;
230 0         0 $self->{author} = $b->text;
231 0         0 $self->{author_id} = $b->{att}->{user_id};
232             }
233 5         105 );
234            
235 5         51 my %h2 = $self->twig_handlers;
236              
237 5 50       181 if( %h2 ) {
238 5         67 %handlers = ( %handlers, %h2 ); # Append twig_handlers
239             }
240              
241 5         91 $self->clear;
242              
243 5         62 $self->parse_twig( $xml, \%handlers );
244              
245 0           return 1;
246             }
247              
248             sub bookmark {
249 0 0   0 0   my $self = shift or croak "Usage: bookmark E2NODE [, NODE_ID ]";
250 0   0       my $node_id = shift || $self->node_id;
251              
252 0 0         warn "E2::Node::bookmark\n" if $DEBUG > 1;
253              
254 0 0         if( !$self->logged_in ) {
255 0           croak "Not logged in";
256             }
257              
258 0 0         if( !$node_id ) {
259 0           croak "No node specified";
260             }
261              
262             return $self->thread_then( [ \&E2::Interface::process_request,
263             $self,
264             node_id => $node_id,
265             op => "bookmark",
266             displaytype => "xmltrue"
267             ],
268             sub {
269 0     0     return 1;
270 0           });
271             }
272              
273             #---------------
274             # Access methods
275             #---------------
276              
277             sub exists {
278 0 0   0 1   my $self = shift or croak "Usage: exists E2NODE";
279              
280 0 0         if( !$self->node_id ) { return 0; }
  0            
281 0           else { return 1; }
282             }
283              
284             sub author {
285 0 0   0 1   my $self = shift or croak "Usage: author E2NODE";
286              
287 0           return $self->{author};
288             }
289              
290             sub author_id {
291 0 0   0 1   my $self = shift or croak "Usage: author_id E2NODE";
292              
293 0           return $self->{author_id};
294             }
295              
296             sub node_id {
297 0 0   0 1   my $self = shift or croak "Usage: node_id E2NODE";
298              
299 0           return $self->{node_id};
300             }
301              
302             sub title {
303 0 0   0 1   my $self = shift or croak "Usage: title E2NODE";
304              
305 0           return $self->{title}
306             }
307              
308             sub createtime {
309 0 0   0 1   my $self = shift or croak "Usage: createtime E2NODE";
310              
311 0           return $self->{createtime};
312             }
313              
314             sub type {
315 0 0   0 1   my $self = shift or croak "Usage: type E2NODE";
316              
317 0           return $self->{type};
318             }
319              
320             1;
321             __END__