Filename | /var/www/foswiki11/lib/Foswiki/Plugins/PlantUMLPlugin.pm |
Statements | Executed 182 statements in 2.54ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
13 | 1 | 1 | 322µs | 368µs | commonTagsHandler | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 143µs | 312µs | initPlugin | Foswiki::Plugins::PlantUMLPlugin::
29 | 11 | 1 | 59µs | 59µs | _writeDebug | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 14µs | 27µs | BEGIN@4 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 10µs | 15µs | BEGIN@5 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 10µs | 34µs | BEGIN@11 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 9µs | 30µs | BEGIN@10 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 4µs | 4µs | BEGIN@13 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 4µs | 4µs | BEGIN@7 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@14 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@16 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@8 | Foswiki::Plugins::PlantUMLPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@15 | Foswiki::Plugins::PlantUMLPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:168] | Foswiki::Plugins::PlantUMLPlugin::
0 | 0 | 0 | 0s | 0s | __ANON__[:171] | Foswiki::Plugins::PlantUMLPlugin::
0 | 0 | 0 | 0s | 0s | _handleUML | Foswiki::Plugins::PlantUMLPlugin::
0 | 0 | 0 | 0s | 0s | _showError | Foswiki::Plugins::PlantUMLPlugin::
0 | 0 | 0 | 0s | 0s | cleanAttachments | Foswiki::Plugins::PlantUMLPlugin::
0 | 0 | 0 | 0s | 0s | deleteAttach | Foswiki::Plugins::PlantUMLPlugin::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Foswiki::Plugins::PlantUMLPlugin; | ||||
2 | |||||
3 | # Always use strict to enforce variable scoping | ||||
4 | 2 | 28µs | 2 | 41µs | # spent 27µs (14+13) within Foswiki::Plugins::PlantUMLPlugin::BEGIN@4 which was called:
# once (14µs+13µs) by Foswiki::Plugin::BEGIN@2.24 at line 4 # spent 27µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@4
# spent 13µs making 1 call to strict::import |
5 | 2 | 25µs | 2 | 21µs | # spent 15µs (10+6) within Foswiki::Plugins::PlantUMLPlugin::BEGIN@5 which was called:
# once (10µs+6µs) by Foswiki::Plugin::BEGIN@2.24 at line 5 # spent 15µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@5
# spent 6µs making 1 call to warnings::import |
6 | |||||
7 | 2 | 19µs | 1 | 4µs | # spent 4µs within Foswiki::Plugins::PlantUMLPlugin::BEGIN@7 which was called:
# once (4µs+0s) by Foswiki::Plugin::BEGIN@2.24 at line 7 # spent 4µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@7 |
8 | 2 | 23µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::PlantUMLPlugin::BEGIN@8 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.24 at line 8 # spent 3µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@8 |
9 | |||||
10 | 2 | 29µs | 2 | 51µs | # spent 30µs (9+21) within Foswiki::Plugins::PlantUMLPlugin::BEGIN@10 which was called:
# once (9µs+21µs) by Foswiki::Plugin::BEGIN@2.24 at line 10 # spent 30µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@10
# spent 21µs making 1 call to Exporter::import |
11 | 2 | 31µs | 2 | 59µs | # spent 34µs (10+25) within Foswiki::Plugins::PlantUMLPlugin::BEGIN@11 which was called:
# once (10µs+25µs) by Foswiki::Plugin::BEGIN@2.24 at line 11 # spent 34µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@11
# spent 25µs making 1 call to Exporter::import |
12 | |||||
13 | 2 | 24µs | 1 | 4µs | # spent 4µs within Foswiki::Plugins::PlantUMLPlugin::BEGIN@13 which was called:
# once (4µs+0s) by Foswiki::Plugin::BEGIN@2.24 at line 13 # spent 4µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@13 |
14 | 2 | 18µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::PlantUMLPlugin::BEGIN@14 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.24 at line 14 # spent 3µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@14 |
15 | 2 | 18µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::PlantUMLPlugin::BEGIN@15 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.24 at line 15 # spent 3µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@15 |
16 | 2 | 1.82ms | 1 | 3µs | # spent 3µs within Foswiki::Plugins::PlantUMLPlugin::BEGIN@16 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.24 at line 16 # spent 3µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::BEGIN@16 |
17 | |||||
18 | # $VERSION is referred to by Foswiki, and is the only global variable that | ||||
19 | # *must* exist in this package. This should always be in the format | ||||
20 | # $Rev: 14572 (2012-04-06) $ so that Foswiki can determine the checked-in status of the | ||||
21 | # extension. | ||||
22 | 1 | 500ns | our $VERSION = '$Rev: 14572 (2012-04-06) $'; | ||
23 | |||||
24 | # $RELEASE is used in the "Find More Extensions" automation in configure. | ||||
25 | # It is a manually maintained string used to identify functionality steps. | ||||
26 | # You can use any of the following formats: | ||||
27 | # tuple - a sequence of integers separated by . e.g. 1.2.3. The numbers | ||||
28 | # usually refer to major.minor.patch release or similar. You can | ||||
29 | # use as many numbers as you like e.g. '1' or '1.2.3.4.5'. | ||||
30 | # isodate - a date in ISO8601 format e.g. 2009-08-07 | ||||
31 | # date - a date in 1 Jun 2009 format. Three letter English month names only. | ||||
32 | # Note: it's important that this string is exactly the same in the extension | ||||
33 | # topic - if you use %$RELEASE% with BuildContrib this is done automatically. | ||||
34 | 1 | 400ns | our $RELEASE = '1.1.2'; | ||
35 | |||||
36 | # Short description of this plugin | ||||
37 | # One line description, is shown in the %SYSTEMWEB%.TextFormattingRules topic: | ||||
38 | 1 | 200ns | our $SHORTDESCRIPTION = 'Draw UML using PlantUML'; | ||
39 | |||||
40 | # You must set $NO_PREFS_IN_TOPIC to 0 if you want your plugin to use | ||||
41 | # preferences set in the plugin topic. This is required for compatibility | ||||
42 | # with older plugins, but imposes a significant performance penalty, and | ||||
43 | # is not recommended. Instead, leave $NO_PREFS_IN_TOPIC at 1 and use | ||||
44 | # =$Foswiki::cfg= entries, or if you want the users | ||||
45 | # to be able to change settings, then use standard Foswiki preferences that | ||||
46 | # can be defined in your %USERSWEB%.SitePreferences and overridden at the web | ||||
47 | # and topic level. | ||||
48 | # | ||||
49 | # %SYSTEMWEB%.DevelopingPlugins has details of how to define =$Foswiki::cfg= | ||||
50 | # entries so they can be used with =configure=. | ||||
51 | 1 | 200ns | our $NO_PREFS_IN_TOPIC = 1; | ||
52 | |||||
53 | # | ||||
54 | # General plugin information | ||||
55 | # | ||||
56 | 1 | 100ns | my $web; # Current web being processed | ||
57 | 1 | 100ns | my $usWeb; # Web name with subwebs delimiter changed to underscore | ||
58 | 1 | 100ns | my $topic; # Current topic | ||
59 | 1 | 100ns | my $user; # Current user | ||
60 | 1 | 100ns | my $installWeb; # Web where plugin topic is installed | ||
61 | |||||
62 | 1 | 100ns | my $HASH_CODE_LENGTH = 32; | ||
63 | |||||
64 | 1 | 300ns | my $plantUMLPath = ''; | ||
65 | 1 | 200ns | my $attachPath = ''; | ||
66 | 1 | 100ns | my $attachUrlPath = ''; | ||
67 | 1 | 100ns | my $javaPath = ''; | ||
68 | 1 | 200ns | my $debugDefault = ''; | ||
69 | 1 | 200ns | my $libraryDefault = ''; | ||
70 | 1 | 300ns | my $hideAttachDefault = ''; | ||
71 | 1 | 200ns | my $engineCmd = "%JAVA|F% -jar %PLANTUML|F% -o %tempDir|F% %INFILE|F%"; | ||
72 | 1 | 6µs | my $plantUMLCommentprefix = 'PlantUML_autogenerated_hash:'; | ||
73 | |||||
74 | |||||
75 | # spent 312µs (143+169) within Foswiki::Plugins::PlantUMLPlugin::initPlugin which was called:
# once (143µs+169µs) by Foswiki::Plugin::__ANON__[/var/www/foswiki11/lib/Foswiki/Plugin.pm:241] at line 234 of /var/www/foswiki11/lib/Foswiki/Plugin.pm | ||||
76 | |||||
77 | 1 | 4µs | ( $topic, $web, $user, $installWeb ) = @_; | ||
78 | |||||
79 | # Get plugin debug flag | ||||
80 | 1 | 3µs | 1 | 41µs | $debugDefault = # spent 41µs making 1 call to Foswiki::Func::getPreferencesFlag |
81 | Foswiki::Func::getPreferencesFlag('PLANTUMLPLUGIN_DEBUG') || 0; | ||||
82 | |||||
83 | # Disable the plugin if a topic revision is requested in the query. | ||||
84 | 1 | 400ns | my $query; | ||
85 | 1 | 16µs | 1 | 9µs | if ( $Foswiki::Plugins::VERSION >= 2.1 ) { # spent 9µs making 1 call to version::vxs::VCMP |
86 | 1 | 3µs | 1 | 6µs | $query = Foswiki::Func::getRequestObject(); # spent 6µs making 1 call to Foswiki::Func::getRequestObject |
87 | 1 | 6µs | 1 | 6µs | _writeDebug('$Foswiki::Plugins::VERSION >= 2.1 == TRUE'); # spent 6µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
88 | } | ||||
89 | else { | ||||
90 | $query = Foswiki::Func::getCgiQuery(); | ||||
91 | _writeDebug('$Foswiki::Plugins::VERSION >= 2.1 == FALSE'); | ||||
92 | } | ||||
93 | 1 | 13µs | 2 | 4µs | _writeDebug("Foswiki plugin version is $Foswiki::Plugins::VERSION"); # spent 3µs making 1 call to version::vxs::stringify
# spent 1µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
94 | |||||
95 | # Disable the plugin if comparing two revisions (context = diff | ||||
96 | 1 | 3µs | 1 | 5µs | if ( Foswiki::Func::getContext()->{'diff'} ) { # spent 5µs making 1 call to Foswiki::Func::getContext |
97 | _writeDebug('Foswiki::Func::getContext()->{diff} == TRUE'); | ||||
98 | |||||
99 | if ( !$Foswiki::cfg{Plugins}{PlantUMLPlugin} | ||||
100 | {generateDiffAttachments} ) | ||||
101 | { | ||||
102 | _writeDebug('PlantUMLPlugin - Disabled - diff context'); | ||||
103 | return 0; | ||||
104 | } | ||||
105 | } | ||||
106 | |||||
107 | 1 | 800ns | $usWeb = $web; | ||
108 | 1 | 7µs | $usWeb =~ s/\//_/g; #Convert any subweb separators to underscore | ||
109 | |||||
110 | # check for Plugins.pm versions | ||||
111 | 1 | 10µs | 1 | 5µs | if ( $Foswiki::Plugins::VERSION < 1 ) { # spent 5µs making 1 call to version::vxs::VCMP |
112 | _writeDebug('$Foswiki::Plugins::VERSION < 1 == TRUE'); | ||||
113 | Foswiki::Func::writeWarning( | ||||
114 | 'Version mismatch between PlantUMLPlugin and Plugins.pm'); | ||||
115 | return 0; | ||||
116 | } | ||||
117 | |||||
118 | # path to plantUML) | ||||
119 | $plantUMLPath = | ||||
120 | 1 | 4µs | $Foswiki::cfg{PlantUMLPlugin}{plantUMLPath} | ||
121 | || $Foswiki::cfg{Plugins}{PlantUMLPlugin}{plantUMLPath} | ||||
122 | || ''; | ||||
123 | |||||
124 | # path to java) | ||||
125 | 1 | 3µs | $javaPath = | ||
126 | $Foswiki::cfg{PlantUMLPlugin}{javaPath} | ||||
127 | || $Foswiki::cfg{Plugins}{PlantUMLPlugin}{javaPath} | ||||
128 | || ''; | ||||
129 | |||||
130 | # Fix the various paths - trim whitespace and add a trailing slash if none is provided. | ||||
131 | |||||
132 | 1 | 1µs | if ($plantUMLPath) { | ||
133 | 1 | 2µs | $plantUMLPath =~ s/\s+$//; | ||
134 | } | ||||
135 | |||||
136 | 1 | 500ns | if ($javaPath) { | ||
137 | 1 | 600ns | $javaPath =~ s/\s+$//; | ||
138 | } | ||||
139 | |||||
140 | # path to store attachments - optional. If not provided, Foswiki attachment API is used | ||||
141 | $attachPath = | ||||
142 | 1 | 3µs | $Foswiki::cfg{plantUMLPlugin}{attachPath} | ||
143 | || $Foswiki::cfg{Plugins}{plantUMLPlugin}{attachPath} | ||||
144 | || ''; | ||||
145 | |||||
146 | # URL to retrieve attachments - optional. If not provided, Foswiki pub path is used. | ||||
147 | 1 | 1µs | $attachUrlPath = | ||
148 | $Foswiki::cfg{plantUMLPlugin}{attachUrlPath} | ||||
149 | || $Foswiki::cfg{Plugins}{plantUMLPlugin}{attachUrlPath} | ||||
150 | || ''; | ||||
151 | |||||
152 | 1 | 3µs | 1 | 32µs | $hideAttachDefault = # spent 32µs making 1 call to Foswiki::Func::getPreferencesValue |
153 | Foswiki::Func::getPreferencesValue('PLANTUMLPLUGIN_HIDEATTACHMENTS') | ||||
154 | || 'on'; | ||||
155 | |||||
156 | # Get plugin library default | ||||
157 | 1 | 3µs | 1 | 28µs | $libraryDefault = # spent 28µs making 1 call to Foswiki::Func::getPreferencesValue |
158 | Foswiki::Func::getPreferencesValue('PLANTUMLPLUGIN_LIBRARY') | ||||
159 | || 'System.PlantUMLPlugin'; | ||||
160 | |||||
161 | |||||
162 | # Tell WyswiygPlugin to protect <dot>...</dot> markup | ||||
163 | 1 | 900ns | if ( defined &Foswiki::Plugins::WysiwygPlugin::addXMLTag ) { | ||
164 | 1 | 1µs | 1 | 1µs | _writeDebug("defined &Foswiki::Plugins::WysiwygPlugin::addXMLTag == TRUE"); # spent 1µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
165 | |||||
166 | # Check if addXMLTag is defined, so that PlantUMLPluginPlugin | ||||
167 | # continues to work with older versions of WysiwygPlugin | ||||
168 | 1 | 6µs | 1 | 16µs | Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'uml', sub { 1 } ); # spent 16µs making 1 call to Foswiki::Plugins::WysiwygPlugin::addXMLTag |
169 | |||||
170 | # Some older versions of the plugin used upper-case DOT tags - protect these as well. | ||||
171 | 1 | 7µs | 1 | 12µs | Foswiki::Plugins::WysiwygPlugin::addXMLTag( 'UML', sub { 1 } ); # spent 12µs making 1 call to Foswiki::Plugins::WysiwygPlugin::addXMLTag |
172 | } | ||||
173 | |||||
174 | # Plugin correctly initialized | ||||
175 | _writeDebug( | ||||
176 | 1 | 3µs | 1 | 1µs | "- Foswiki::Plugins::PlantUMLPluginPlugin::initPlugin( $web.$topic ) initialized OK" # spent 1µs making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
177 | ); | ||||
178 | |||||
179 | 1 | 2µs | 1 | 800ns | _writeDebug("Init: plantUMLPath = $plantUMLPath"); # spent 800ns making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
180 | 1 | 2µs | 1 | 700ns | _writeDebug("Init: javaPath = $javaPath"); # spent 700ns making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
181 | 1 | 2µs | 1 | 700ns | _writeDebug("Init: attachPath = $attachPath"); # spent 700ns making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
182 | 1 | 2µs | 1 | 800ns | _writeDebug("Init: attachUrlPath = $attachUrlPath"); # spent 800ns making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
183 | 1 | 2µs | 1 | 700ns | _writeDebug("Init: libraryDefault = $libraryDefault"); # spent 700ns making 1 call to Foswiki::Plugins::PlantUMLPlugin::_writeDebug |
184 | |||||
185 | 1 | 6µs | return 1; | ||
186 | } ### sub initPlugin | ||||
187 | |||||
188 | # spent 368µs (322+46) within Foswiki::Plugins::PlantUMLPlugin::commonTagsHandler which was called 13 times, avg 28µs/call:
# 13 times (322µs+46µs) by Foswiki::Plugin::invoke at line 294 of /var/www/foswiki11/lib/Foswiki/Plugin.pm, avg 28µs/call | ||||
189 | ### my ( $text, $topic, $web ) = @_; # do not uncomment, use $_[0], $_[1]... instead | ||||
190 | 13 | 38µs | 13 | 40µs | _writeDebug("commonTagsHandler"); # spent 40µs making 13 calls to Foswiki::Plugins::PlantUMLPlugin::_writeDebug, avg 3µs/call |
191 | |||||
192 | 13 | 22µs | return if $_[3]; # Called in an include; do not process DOT macros | ||
193 | |||||
194 | 7 | 8µs | 7 | 6µs | _writeDebug("commonTagsHandler - continue"); # spent 6µs making 7 calls to Foswiki::Plugins::PlantUMLPlugin::_writeDebug, avg 786ns/call |
195 | |||||
196 | 7 | 7µs | $topic = $_[1]; # Can't trust globals | ||
197 | 7 | 3µs | $web = $_[2]; | ||
198 | 7 | 2µs | $usWeb = $web; | ||
199 | 7 | 21µs | $usWeb =~ s/\//_/g; #Convert any subweb separators to underscore | ||
200 | 7 | 10µs | my @hashes = ""; | ||
201 | |||||
202 | #pass everything within <uml> tags to _handleUML function | ||||
203 | 7 | 134µs | ( $_[0] =~ s/<UML(.*?)>(.*?)<\/(UML)>/&_handleUML($2,$1,\@hashes)/gise ); | ||
204 | |||||
205 | # $3 will be left set if any matches were found in the topic. If found, do cleanup processing | ||||
206 | 7 | 31µs | if ( $3 && ( $3 eq 'uml' ) ) { | ||
207 | _writeDebug("PlantUMLPluginPlugin - FOUND MATCH - $3, hashes: @hashes"); | ||||
208 | cleanAttachments($web, $topic, \@hashes); | ||||
209 | } | ||||
210 | } ### sub commonTagsHandler | ||||
211 | |||||
212 | sub _handleUML { | ||||
213 | _writeDebug("_handleUML"); | ||||
214 | |||||
215 | my $tempDir = File::Spec->tmpdir(); | ||||
216 | |||||
217 | my $attr = $_[1] || ''; # Attributes from the <uml ...> tag | ||||
218 | my $desc = $_[0] || ''; # PlantUML input between the <uml> ... </uml> tags | ||||
219 | my $hashes = $_[2]; | ||||
220 | |||||
221 | my %params = Foswiki::Func::extractParameters($attr); #extract all parms into a hash array | ||||
222 | |||||
223 | my $attachName = $params{file} || ''; | ||||
224 | my $attachExt = ".png"; | ||||
225 | |||||
226 | my $fname = ''; | ||||
227 | |||||
228 | _writeDebug("_handleUML tempDir is: $tempDir"); | ||||
229 | _writeDebug("_handleUML attr is: $attr"); | ||||
230 | _writeDebug("_handleUML desc is: $desc"); | ||||
231 | _writeDebug("_handleUML hashes are: $hashes"); | ||||
232 | _writeDebug("_handleUML attachName [1] is: $attachName"); | ||||
233 | |||||
234 | # Name of attachment given as tag attribute is not implemented | ||||
235 | |||||
236 | # Make sure attachName is clean | ||||
237 | # if ( $attachName ne '' ) { | ||||
238 | # $attachName = Foswiki::Sandbox::sanitizeAttachmentName($attachName); | ||||
239 | |||||
240 | # # Validate the filename if the Sandbox *can* validate filenames | ||||
241 | # # (older Foswikis cannot) otherwise just untaint | ||||
242 | # my $validator = | ||||
243 | # defined(&Foswiki::Sandbox::validateAttachmentName) | ||||
244 | # ? \&Foswiki::Sandbox::validateAttachmentName | ||||
245 | # : sub { return shift @_; }; | ||||
246 | # $attachName = Foswiki::Sandbox::untaint( $attachName, $validator ); | ||||
247 | # } | ||||
248 | |||||
249 | # compute the MD5 hash of this string. This used to detect | ||||
250 | # if any parameters or input change from run to run | ||||
251 | # Attachments recreated if the hash changes | ||||
252 | |||||
253 | # Hash is calculated against the <uml> command parameters and input, | ||||
254 | # along with any parameters that are set in the Default topic which would modify the results. | ||||
255 | # Parameters that are only set as part of the <dot> command do not need to be explicitly coded, | ||||
256 | # as they are include in $attr. | ||||
257 | |||||
258 | my $hashCode = | ||||
259 | md5_hex( 'UML' | ||||
260 | . $desc | ||||
261 | . $attr); | ||||
262 | $hashCode =~ s/\s//g; | ||||
263 | push(@{$hashes}, $hashCode); | ||||
264 | |||||
265 | _writeDebug("Computed hash is $hashCode"); | ||||
266 | |||||
267 | # If a filename is not provided, set it to a name, with incrementing number. | ||||
268 | if ( $attachName eq '' ) { | ||||
269 | _writeDebug('$attachName eq \'\''); | ||||
270 | |||||
271 | $attachName = 'PlantUMLPlugin_' . "$hashCode"."$attachExt"; | ||||
272 | $attachName = Foswiki::Sandbox::untaintUnchecked($attachName); | ||||
273 | } | ||||
274 | # else | ||||
275 | # { | ||||
276 | # _writeDebug('$attachName ne == FALSE2'); | ||||
277 | # $attachName = "$attachName"."$attachExt"; | ||||
278 | # } | ||||
279 | |||||
280 | _writeDebug("_handleUML attachName [2] is: $attachName"); | ||||
281 | |||||
282 | if ( not Foswiki::Func::attachmentExists( $web, $topic, "$attachName" ) ) | ||||
283 | { | ||||
284 | _writeDebug('not Foswiki::Func::attachmentExists( $web, $topic, "$attachName" )'); | ||||
285 | |||||
286 | $desc =~ s/.*(\@startuml).*/$1/gi; | ||||
287 | |||||
288 | unless (-e $javaPath) { | ||||
289 | _writeDebug('Java path invalid.'); | ||||
290 | return _showError(1, "", "Path to java is invalid: $javaPath"); | ||||
291 | } | ||||
292 | unless (-e $plantUMLPath) { | ||||
293 | _writeDebug('PlantUML path invalid.'); | ||||
294 | return _showError(1, "", "Path to plantUML is invalid: $plantUMLPath"); | ||||
295 | } | ||||
296 | _writeDebug( | ||||
297 | " >>> Processing changed uml tag or missing file $attachName <<< " | ||||
298 | ); | ||||
299 | # Create a new temporary file to pass to GraphViz | ||||
300 | my $umlFile = new File::Temp( | ||||
301 | TEMPLATE => 'PlantUMLPluginXXXXXXXXXX', | ||||
302 | DIR => $tempDir, | ||||
303 | SUFFIX => '.uml' | ||||
304 | ); | ||||
305 | Foswiki::Func::saveFile( "$umlFile", $desc ); | ||||
306 | my $pngFile = $tempDir.'/'.File::Basename::basename("$umlFile", ".uml").$attachExt; | ||||
307 | |||||
308 | # Execute uml - generating all output into the Foswiki temp directory | ||||
309 | _writeDebug("sysCommand: javaPath is $javaPath"); | ||||
310 | _writeDebug("sysCommand: plantUMLPath is $plantUMLPath"); | ||||
311 | _writeDebug("sysCommand: pngFile is $pngFile"); | ||||
312 | _writeDebug("sysCommand: umlFile is $umlFile"); | ||||
313 | |||||
314 | my ( $output, $status ) = Foswiki::Sandbox->sysCommand( | ||||
315 | "$javaPath -jar $plantUMLPath -o $tempDir $umlFile" | ||||
316 | ); | ||||
317 | |||||
318 | if ($status) { | ||||
319 | _writeDebug('$status'); | ||||
320 | _writeDebug("output is: $output"); | ||||
321 | |||||
322 | $umlFile =~ tr!\\!/!; | ||||
323 | return _showError( | ||||
324 | $status, | ||||
325 | $output, | ||||
326 | "Processing $umlFile failed. Command: $javaPath -jar $plantUMLPath -o $tempDir $umlFile" | ||||
327 | ); | ||||
328 | } ### if ($status) | ||||
329 | $umlFile =~ tr!\\!/!; | ||||
330 | |||||
331 | $fname = $attachName; | ||||
332 | my @stats = stat $pngFile; | ||||
333 | my $fileSize = $stats[7]; | ||||
334 | my $fileDate = $stats[9]; | ||||
335 | _writeDebug( | ||||
336 | "attaching $fname using Foswiki API - Web = $web, Topic = $topic, File=$pngFile date $fileDate" | ||||
337 | ); | ||||
338 | $fname = Foswiki::Sandbox::untaintUnchecked($fname); #untaint - fails on trunk | ||||
339 | |||||
340 | _writeDebug("SaveAttachement: fname is $fname"); | ||||
341 | _writeDebug("SaveAttachement: stats is @stats"); | ||||
342 | _writeDebug("SaveAttachement: fileDate is $fileDate"); | ||||
343 | _writeDebug("SaveAttachement: fileSize is $fileSize"); | ||||
344 | _writeDebug("SaveAttachement: plantUMLCommentprefixhashcode is $plantUMLCommentprefix$hashCode"); | ||||
345 | |||||
346 | Foswiki::Func::saveAttachment( | ||||
347 | $web, $topic, "$fname", | ||||
348 | { | ||||
349 | file => "$pngFile", | ||||
350 | filedate => $fileDate, | ||||
351 | filesize => $fileSize, | ||||
352 | comment => "$plantUMLCommentprefix$hashCode", | ||||
353 | hide => 1 | ||||
354 | } | ||||
355 | ); | ||||
356 | $pngFile =~ tr!\\!/!; | ||||
357 | unlink $pngFile, $umlFile; | ||||
358 | } | ||||
359 | else | ||||
360 | { | ||||
361 | _writeDebug("Attachment Exists: $attachName"); | ||||
362 | } | ||||
363 | |||||
364 | # ############################## | ||||
365 | # End Generation of attachments | ||||
366 | # ############################### | ||||
367 | # Build the path to use for attachment URL's | ||||
368 | # $attachUrlPath is used only if attachments are stored in an explicit path | ||||
369 | # and $attachUrlPath is provided, and use of the API is not forced. | ||||
370 | |||||
371 | my $urlPath = Foswiki::Func::getPubUrlPath(); | ||||
372 | |||||
373 | # Build a manual link for each specified file type except for | ||||
374 | # The "inline" file format, and any image map file | ||||
375 | |||||
376 | # my $fileLink = '<br />'; | ||||
377 | # $fileLink .= | ||||
378 | # '<a href=' | ||||
379 | # . $urlPath | ||||
380 | # . Foswiki::urlEncode("/$web/$topic/$fname") | ||||
381 | # . ">[$attachName]</a> "; | ||||
382 | |||||
383 | my $loc = $urlPath . "/$web/$topic"; | ||||
384 | my $src = Foswiki::urlEncode("$loc/$attachName"); | ||||
385 | |||||
386 | my $returnData = "<noautolink>\n"; | ||||
387 | |||||
388 | $returnData .= | ||||
389 | "<img src=\"$src\" type=\"image/PNG"; | ||||
390 | $returnData .= " alt=\"$attachName diagram\""; | ||||
391 | $returnData .= "> \n"; | ||||
392 | |||||
393 | $returnData .= "</noautolink>"; | ||||
394 | |||||
395 | _writeDebug("returnData is $returnData"); | ||||
396 | |||||
397 | return $returnData; | ||||
398 | } | ||||
399 | |||||
400 | # spent 59µs within Foswiki::Plugins::PlantUMLPlugin::_writeDebug which was called 29 times, avg 2µs/call:
# 13 times (40µs+0s) by Foswiki::Plugins::PlantUMLPlugin::commonTagsHandler at line 190, avg 3µs/call
# 7 times (6µs+0s) by Foswiki::Plugins::PlantUMLPlugin::commonTagsHandler at line 194, avg 786ns/call
# once (6µs+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 87
# once (1µs+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 164
# once (1µs+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 176
# once (1µs+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 93
# once (800ns+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 182
# once (800ns+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 179
# once (700ns+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 181
# once (700ns+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 183
# once (700ns+0s) by Foswiki::Plugins::PlantUMLPlugin::initPlugin at line 180 | ||||
401 | |||||
402 | 29 | 99µs | if ($debugDefault eq '1') { | ||
403 | |||||
404 | &Foswiki::Func::writeDebug( 'PlantUMLPlugin - ' . $_[0] ); | ||||
405 | } | ||||
406 | } | ||||
407 | |||||
408 | sub cleanAttachments { | ||||
409 | my $web = $_[0]; | ||||
410 | my $topic = $_[1]; | ||||
411 | my @hashes = @{$_[2]}; | ||||
412 | my ($meta, $text) = Foswiki::Func::readTopic( $web, $topic ); | ||||
413 | my @attachments = $meta->find('FILEATTACHMENT'); | ||||
414 | foreach my $att (@attachments) { | ||||
415 | my $comment = $att->{comment}; | ||||
416 | if ($comment =~ m/$plantUMLCommentprefix[\w]{$HASH_CODE_LENGTH}/) { | ||||
417 | $comment =~ s/$plantUMLCommentprefix//g; | ||||
418 | my $count = grep /$comment/, @hashes; | ||||
419 | if ( $count == 0) | ||||
420 | { | ||||
421 | _writeDebug("Deleting attachment: $att->{name}"); | ||||
422 | deleteAttach($web, $topic, $att->{name}); | ||||
423 | } | ||||
424 | else | ||||
425 | { | ||||
426 | _writeDebug("Attachment required: $att->{name}"); | ||||
427 | } | ||||
428 | } | ||||
429 | } | ||||
430 | } | ||||
431 | |||||
432 | sub deleteAttach { | ||||
433 | my $fn = Foswiki::Sandbox::normalizeFileName( $_[2] ); | ||||
434 | my $web = $_[0]; | ||||
435 | my $topic = $_[1]; | ||||
436 | |||||
437 | _writeDebug(" Deleting Attachment $web/$topic/$fn"); | ||||
438 | |||||
439 | if ( Foswiki::Func::attachmentExists( $web, $topic, $fn ) ) { | ||||
440 | if ( | ||||
441 | !Foswiki::Func::topicExists( | ||||
442 | $Foswiki::cfg{TrashWebName}, | ||||
443 | 'TrashAttachment' | ||||
444 | ) | ||||
445 | ) | ||||
446 | { | ||||
447 | _writeDebug(' ### Creating missing TrashAttachment topic '); | ||||
448 | my $text = | ||||
449 | "---+ %MAKETEXT{\"Placeholder for trashed attachments\"}%\n"; | ||||
450 | Foswiki::Func::saveTopic( "$Foswiki::cfg{TrashWebName}", | ||||
451 | "TrashAttachment", undef, $text, undef ); | ||||
452 | } # if (! Foswiki::Func::topicExists | ||||
453 | |||||
454 | _writeDebug(" >>> Trashing $web . $topic . $fn"); | ||||
455 | |||||
456 | my $i = 0; | ||||
457 | my $of = $fn; | ||||
458 | while ( | ||||
459 | Foswiki::Func::attachmentExists( | ||||
460 | $Foswiki::cfg{TrashWebName}, 'TrashAttachment', | ||||
461 | "$web.$topic.$of" | ||||
462 | ) | ||||
463 | ) | ||||
464 | { | ||||
465 | _writeDebug(" ------ duplicate in trash $of"); | ||||
466 | $i++; | ||||
467 | $of .= "$i"; | ||||
468 | } # while (Foswiki::Func | ||||
469 | |||||
470 | Foswiki::Func::moveAttachment( $web, $topic, $fn, | ||||
471 | $Foswiki::cfg{TrashWebName}, | ||||
472 | 'TrashAttachment', "$web.$topic.$of" ); | ||||
473 | } | ||||
474 | } | ||||
475 | |||||
476 | sub _showError { | ||||
477 | my ( $status, $output, $text) = @_; | ||||
478 | |||||
479 | my $line = 1; | ||||
480 | $output .= "<pre>$text\n</pre>"; | ||||
481 | return | ||||
482 | "<font color=\"red\"><nop>PlantUML Error ($status): $output</font>"; | ||||
483 | } | ||||
484 |