File Coverage

blib/lib/Visio.pm
Criterion Covered Total %
statement 16 18 88.8
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 22 24 91.6


line stmt bran cond sub pod time code
1             package Visio;
2              
3              
4             #PLEASE SEE MSPATENTLICENSE
5             # "This product may incorporate intellectual property owned by
6             # Microsoft Corporation. The terms and conditions upon which Microsoft
7             # is licensing such intellectual property may be found at
8             # http://msdn.microsoft.com/library/en-us/odcXMLRef/html/odcXMLRefLegalNotice.asp"
9              
10             # Copyright 2005 Aamer Akhter. All rights reserved.
11              
12             # Redistribution and use in source and binary forms, with or without
13             # modification, are permitted provided that the following conditions are
14             # met:
15              
16             # 1. Redistributions of source code must retain the above copyright
17             # notice, this list of conditions and the following disclaimer.
18              
19             # 2. Redistributions in binary form must reproduce the above copyright
20             # notice, this list of conditions and the following disclaimer in the
21             # documentation and/or other materials provided with the distribution.
22              
23             # THIS SOFTWARE IS PROVIDED BY THE LICENSOR(S) ``AS IS'' AND ANY EXPRESS
24             # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25             # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26             # DISCLAIMED. IN NO EVENT SHALL THE LICENSOR(S) OR OTHER CONTRIBUTORS BE
27             # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28             # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29             # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
30             # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31             # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
32             # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
33             # IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34              
35             # The views and conclusions contained in the software and documentation
36             # are those of the authors and should not be interpreted as representing
37             # official policies, either expressed or implied, of the Licensor(s).
38              
39             # The software may be subject to additional license restrictions
40             # provided by the Licensor(s).
41              
42              
43              
44              
45 1     1   537762 use 5.008;
  1         5  
  1         46  
46 1     1   5 use strict;
  1         2  
  1         32  
47 1     1   4 use strict;
  1         6  
  1         20  
48 1     1   17 use warnings;
  1         1  
  1         40  
49 1     1   211280 use Log::Log4perl qw(get_logger);
  1         861838  
  1         8  
50 1     1   772 use XML::LibXML;
  0            
  0            
51             use Carp;
52             use Data::Dumper;
53             use vars qw($VERSION);
54              
55             use Visio::Page;
56             use Visio::Master;
57              
58             $VERSION = sprintf "%d.%03d", q$Revision: 1.10 $ =~ /: (\d+)\.(\d+)/;
59              
60             Log::Log4perl->init_once(\ qq{
61             log4perl.logger = DEBUG, Screen
62             log4perl.appender.Screen = Log::Log4perl::Appender::ScreenColoredLevels
63             log4perl.appender.Screen.layout = PatternLayout
64             log4perl.appender.Screen.layout.ConversionPattern=[%d] [%c] [%F{1}:%L] [%p] %m%n
65             });
66             my $log = get_logger('visio');
67             my $vNS = 'visio';
68             my $vNSURI = 'http://schemas.microsoft.com/visio/2003/core';
69              
70             our $xmlParser = XML::LibXML->new();
71              
72             # Preloaded methods go here.
73              
74             sub new {
75             my $class = shift;
76             my $opts = shift;
77             my $fileName = $$opts{fromFile};
78             my $self = {};
79             $self->{xmlparser} = $Visio::xmlParser;
80              
81             if (defined $fileName) {
82             $self->{xmldoc} = $self->{xmlparser}->parse_file($fileName);
83             $log->debug("visio object created from $fileName");
84             $self->{xmlroot} = $self->{xmldoc}->documentElement();
85             bless($self,$class);
86             } else {
87             $self->{xmldoc} = $self->{xmlparser}->parse_string(<<'EOT');
88            
89            
90             EOT
91             $self->{xmlroot} = $self->{xmldoc}->documentElement();
92             bless($self,$class);
93             $log->debug("visio xml object created");
94             }
95             $self->{vNSURI} = $self->{xmlroot}->namespaceURI;
96             #add the visio ns as a prefix
97             $self->{xmlroot}->setNamespace
98             (
99             ($self->{vNSURI}),
100             $vNS,
101             0
102             );
103             return $self;
104             }
105              
106             sub addpage {
107             my $self = shift;
108             my $pagesN;
109              
110             #if pages nodes does not exist, create it;
111             $pagesN = generic_create_node($self->{xmlroot},
112             'Pages'
113             );
114              
115             if (defined $self->{maxpageid}) {
116             $self->{maxpageid} = $self->{maxpageid} + 1;
117             } else {
118             $self->{maxpageid} = 0;
119             }
120             my $page = new Visio::Page($pagesN,$self->{maxpageid});
121             return $page;
122             }
123              
124             sub toFile {
125             my $self = shift;
126             my $filename = shift;
127             $self->{xmldoc}->toFile($filename,1);
128             }
129              
130             sub toString {
131             my $self = shift;
132             $self->{xmldoc}->toString(2);
133             }
134              
135             sub toXmlDoc {
136             my $self = shift;
137             return $self->{xmldoc};
138             }
139              
140             sub set_docprop_node {
141             my $self = shift;
142             my $nodeType = shift;
143             my $text = shift;
144             my $dpt = $self->create_docprop_node($nodeType);
145             my $textNode = $self->{xmldoc}->createTextNode($text);
146             $dpt->removeChildNodes();
147             $log->debug("doc $nodeType set");
148             $dpt->appendChild($textNode);
149             }
150              
151             sub set_docprop_timenode {
152             my $self = shift;
153             my $nodeType = shift;
154             my $text = shift;
155             $text = visio_timeformat() if (!defined $text);
156             $self->set_docprop_node($nodeType,$text);
157             }
158              
159             sub visio_timeformat {
160             my $time = shift;
161             if (!defined $time) {$time = time()};
162             my @gmTime = gmtime($time);
163             $gmTime[4]++; # perl months are from 0..11
164             $gmTime[5] += 1900; # perl years
165             return sprintf("%4d-%02d-%02dT%02d:%02d:%02d",
166             $gmTime[5],
167             $gmTime[3],
168             $gmTime[4],
169             $gmTime[2],
170             $gmTime[1],
171             $gmTime[0]
172             );
173             }
174              
175             sub set_timeSaved {
176             my $self = shift;
177             my $text = shift;
178             $self->set_docprop_timenode('TimeSaved',$text);
179             }
180              
181             sub set_timeCreated {
182             my $self = shift;
183             my $text = shift;
184             $self->set_docprop_timenode('TimeCreated',$text);
185             }
186              
187              
188             sub set_title {
189             my $self = shift;
190             my $text = shift;
191             $self->set_docprop_node('Title',$text);
192             }
193              
194             sub set_subject {
195             my $self = shift;
196             my $text = shift;
197             $self->set_docprop_node('Subject',$text);
198             }
199              
200             sub set_manager {
201             my $self = shift;
202             my $text = shift;
203             $self->set_docprop_node('Manager',$text);
204             }
205              
206             sub set_company {
207             my $self = shift;
208             my $text = shift;
209             $self->set_docprop_node('Company',$text);
210             }
211              
212             sub set_desc {
213             my $self = shift;
214             my $text = shift;
215             $self->set_docprop_node('Desc',$text);
216             }
217              
218             sub set_creator {
219             my $self = shift;
220             my $text = shift;
221             $self->set_docprop_node('Creator',$text);
222             }
223              
224             sub find_master_dom {
225             my $self = shift;
226             my $opts = shift;
227             my $nname = $opts->{'name'};
228             my $xp = "/$vNS:VisioDocument/$vNS:Masters/$vNS:Master";
229             my $xpSel = "";
230             if (defined $nname) {
231             $xpSel .= "\@Name = '$nname'";
232             }
233             $xp .= "[$xpSel]";
234             $log->debug("searching with $xp");
235             return $self->{xmlroot}->findnodes($xp);
236             }
237              
238              
239             sub create_master {
240             my $self = shift;
241             my $opts = shift;
242             my $fromDom = $$opts{'fromDom'};
243             my $master;
244             my $mastersNode = generic_create_node($self->{xmlroot},
245             'Masters'
246             );
247             if (defined $self->{maxMasterid}) {
248             $self->{maxMasterid} = $self->{maxMasterid} + 1;
249             } else {
250             $self->{maxMasterid} = 0;
251             }
252             if (defined $fromDom) {
253             $master = new Visio::Master($mastersNode,
254             $self->{maxMasterid},
255             {fromDom=>$fromDom}
256             );
257             }
258             return $master;
259             }
260              
261              
262              
263              
264             #================ PRIIVATE FUNCTIONS
265              
266              
267             sub create_docprop_node {
268             my $self = shift;
269             my $node = shift;
270             my $dp = $self->create_docprop();
271             return generic_create_node($dp, $node);
272             }
273              
274             sub create_docprop {
275             my $self = shift;
276             #see of DocumentProperties already exists, if not crate it
277             my $docpropNL = $self->{xmlroot}->findnodes("DocumentProperties");
278             return $docpropNL->pop if ($docpropNL->size() > 0);
279             $log->debug('creating DocumentProperties node');
280             my $docpropN = $self->{xmldoc}->createElement("DocumentProperties");
281             $self->{xmlroot}->insertBefore(
282             $docpropN,
283             $self->{xmlroot}->firstChild
284             );
285             }
286              
287             sub generic_create_node {
288             my $parent = shift;
289             my $node = shift;
290             my $nodeNL = $parent->findnodes("$node");
291             return $nodeNL->pop if ($nodeNL->size() > 0);
292             $log->debug("creating $parent/$node node");
293             my $uri = $parent->namespaceURI;
294             if (!defined $uri) {
295             $uri = $vNSURI;
296             }
297             my $nodeN = $parent->ownerDocument->createElement("$node");
298             $parent->appendChild($nodeN);
299             return $nodeN;
300             }
301              
302             sub generic_settext {
303             my $node = shift;
304             my $text = shift;
305             my $textNode = $node->ownerDocument->createTextNode($text);
306             $node->removeChildNodes();
307             $log->debug("doc $node text set");
308             $node->appendChild($textNode);
309             }
310              
311              
312             1;
313             __END__