xref: /onnv-gate/usr/src/lib/libbsm/xmlHandlers.pm (revision 4176:9c92120b1c02)
1*4176Stz204579#
2*4176Stz204579# CDDL HEADER START
3*4176Stz204579#
4*4176Stz204579# The contents of this file are subject to the terms of the
5*4176Stz204579# Common Development and Distribution License (the "License").
6*4176Stz204579# You may not use this file except in compliance with the License.
7*4176Stz204579#
8*4176Stz204579# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4176Stz204579# or http://www.opensolaris.org/os/licensing.
10*4176Stz204579# See the License for the specific language governing permissions
11*4176Stz204579# and limitations under the License.
12*4176Stz204579#
13*4176Stz204579# When distributing Covered Code, include this CDDL HEADER in each
14*4176Stz204579# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4176Stz204579# If applicable, add the following below this CDDL HEADER, with the
16*4176Stz204579# fields enclosed by brackets "[]" replaced with your own identifying
17*4176Stz204579# information: Portions Copyright [yyyy] [name of copyright owner]
18*4176Stz204579#
19*4176Stz204579# CDDL HEADER END
20*4176Stz204579#
21*4176Stz204579#
22*4176Stz204579# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*4176Stz204579# Use is subject to license terms.
24*4176Stz204579#
25*4176Stz204579# ident	"%Z%%M%	%I%	%E% SMI"
26*4176Stz204579#
27*4176Stz204579
28*4176Stz204579# <t> xmlHandlers -- package for generating a tree from an XML doc
29*4176Stz204579
30*4176Stz204579use XML::Parser;
31*4176Stz204579
32*4176Stz204579package xmlHandlers;
33*4176Stz204579
34*4176Stz204579$level = -1;
35*4176Stz204579
36*4176Stz204579%endCallback = ();
37*4176Stz204579%startCallback = ();
38*4176Stz204579
39*4176Stz204579$currentObj = 0;
40*4176Stz204579@objStack = ();
41*4176Stz204579
42*4176Stz2045791;
43*4176Stz204579
44*4176Stz204579# <s> methods
45*4176Stz204579
46*4176Stz204579# pkg reference, object name (tag), optional fileName.
47*4176Stz204579
48*4176Stz204579
49*4176Stz204579sub new {
50*4176Stz204579    my $pkg = shift;
51*4176Stz204579    my $parent = shift;   # ref to parent object
52*4176Stz204579    my $class = shift;     # for debug use
53*4176Stz204579
54*4176Stz204579    my @kids = ();        # list of child objects
55*4176Stz204579
56*4176Stz204579    push (@objStack, $parent);
57*4176Stz204579    $currentObj = bless {'class'       => $class,
58*4176Stz204579	                 'kids'       => \@kids,
59*4176Stz204579#			 'parent'     => $parent,
60*4176Stz204579		         'attributes' => 0,
61*4176Stz204579		         'content'    => ''}, $pkg;
62*4176Stz204579
63*4176Stz204579    if (@_) {               # if fileName passed, go!
64*4176Stz204579	die "parent for document creation must be null"
65*4176Stz204579	    if ($parent);
66*4176Stz204579	executeXML (shift);
67*4176Stz204579    }
68*4176Stz204579    return $currentObj;
69*4176Stz204579}
70*4176Stz204579
71*4176Stz204579# we'll call you when your object is started
72*4176Stz204579# class method
73*4176Stz204579
74*4176Stz204579sub registerStartCallback {
75*4176Stz204579    my $objName = shift;  #  call me when you get <objName>
76*4176Stz204579    my $callback = shift; #  \&foo($objRef, $source);
77*4176Stz204579
78*4176Stz204579    if ($startCallback{$objName}) {
79*4176Stz204579	print STDERR "duplicate callback for $objName\n";
80*4176Stz204579	return;
81*4176Stz204579    }
82*4176Stz204579    $startCallback{$objName} =  $callback;
83*4176Stz204579}
84*4176Stz204579
85*4176Stz204579
86*4176Stz204579# we'll call you when your object is completed
87*4176Stz204579# class method
88*4176Stz204579
89*4176Stz204579sub registerEndCallback {
90*4176Stz204579    my $objName = shift;  #  call me when you get </objName>
91*4176Stz204579    my $callback = shift; #  \&foo($objRef);
92*4176Stz204579
93*4176Stz204579    if ($endCallback{$objName}) {
94*4176Stz204579	print STDERR "duplicate callback for $objName\n";
95*4176Stz204579	return;
96*4176Stz204579    }
97*4176Stz204579    $endCallback{$objName} =  $callback;
98*4176Stz204579}
99*4176Stz204579
100*4176Stz204579sub start {
101*4176Stz204579}
102*4176Stz204579sub end {
103*4176Stz204579}
104*4176Stz204579
105*4176Stz204579sub char {
106*4176Stz204579    my ($obj, $class, $string) = @_;
107*4176Stz204579
108*4176Stz204579
109*4176Stz204579}
110*4176Stz204579
111*4176Stz204579sub add {
112*4176Stz204579    my $parent = shift;
113*4176Stz204579    my $kid = shift;
114*4176Stz204579
115*4176Stz204579    push (@{$parent->{'kids'}}, $kid);
116*4176Stz204579#    $kid->{'parent'} = $parent;
117*4176Stz204579}
118*4176Stz204579
119*4176Stz204579# <s> internal functions
120*4176Stz204579sub executeXML {
121*4176Stz204579    my $file = shift;
122*4176Stz204579
123*4176Stz204579    # ErrorContext  - 0 don't report errors
124*4176Stz204579    #               - other = number of lines to display
125*4176Stz204579    # ParseparamEnt - 1 allow parsing of dtd
126*4176Stz204579    my $parser = XML::Parser->new(ErrorContext => 1,
127*4176Stz204579				  ParseParamEnt => 1);
128*4176Stz204579
129*4176Stz204579    $parser->setHandlers (Char       => \&charHandler,
130*4176Stz204579			  Start      => \&startHandler,
131*4176Stz204579			  Default    => \&defaultHandler,
132*4176Stz204579			  End        => \&endHandler,
133*4176Stz204579			  Proc       => \&procHandler,
134*4176Stz204579			  Comment    => \&commentHandler,
135*4176Stz204579			  ExternEnt  => \&externalHandler);
136*4176Stz204579
137*4176Stz204579    $parser->parsefile ($file);
138*4176Stz204579}
139*4176Stz204579
140*4176Stz204579sub charHandler {
141*4176Stz204579    my ($xmlObj, $string) = @_;
142*4176Stz204579
143*4176Stz204579    chomp $string;
144*4176Stz204579    $string =~ s/^\s+//;
145*4176Stz204579    $string =~ s/\s+$//;
146*4176Stz204579    unless ($string =~ /^\s*$/) {
147*4176Stz204579#	print "charHandler: $currentObj->{'class'} $string\n" if $main::debug;
148*4176Stz204579	$currentObj->{'content'} .= ' ' if ($currentObj->{'content'});
149*4176Stz204579	$currentObj->{'content'} .= $string;
150*4176Stz204579    }
151*4176Stz204579}
152*4176Stz204579
153*4176Stz204579# create new object and attach to tree
154*4176Stz204579
155*4176Stz204579sub startHandler {
156*4176Stz204579    my $xmlObj = shift;
157*4176Stz204579    my $tag = shift;
158*4176Stz204579
159*4176Stz204579    my $obj;
160*4176Stz204579    my $parent = $currentObj;
161*4176Stz204579
162*4176Stz204579    $obj = new xmlHandlers($currentObj, $tag);
163*4176Stz204579
164*4176Stz204579    $parent->add ($obj);
165*4176Stz204579
166*4176Stz204579    $obj->processAttributes ($tag, @_);
167*4176Stz204579
168*4176Stz204579    my $functionRef;
169*4176Stz204579    if ($functionRef = $startCallback{$tag}) {
170*4176Stz204579	&$functionRef($obj, 'start');
171*4176Stz204579    }
172*4176Stz204579    elsif ($main::debug) {
173*4176Stz204579#	print "no start callback for $tag\n";
174*4176Stz204579    }
175*4176Stz204579}
176*4176Stz204579
177*4176Stz204579sub endHandler {
178*4176Stz204579    my $xmlObj = shift;
179*4176Stz204579    my $element = shift;
180*4176Stz204579
181*4176Stz204579#    print "end tag $element\n" if $main::debug;
182*4176Stz204579
183*4176Stz204579    my $functionRef;
184*4176Stz204579    if ($functionRef = $endCallback{$element}) {
185*4176Stz204579	&$functionRef($currentObj, 'end');
186*4176Stz204579    }
187*4176Stz204579    elsif ($main::debug) {
188*4176Stz204579#	print "no end callback for $element\n";
189*4176Stz204579    }
190*4176Stz204579#    $currentObj = $currentObj->{'parent'};
191*4176Stz204579    $currentObj = pop (@objStack);
192*4176Stz204579}
193*4176Stz204579
194*4176Stz204579sub defaultHandler {
195*4176Stz204579    my ($obj, $string) = @_;
196*4176Stz204579
197*4176Stz204579    unless (!$main::debug || ($string =~ /^\s*$/)) {
198*4176Stz204579	if ($string =~ /<\?xml/) {
199*4176Stz204579	    $string =~ s/<\?\S+\s+(.*)/$1/;
200*4176Stz204579	    my (%parameters) =
201*4176Stz204579		parseProcInstruction ($string);
202*4176Stz204579	    print STDERR "Got call to default, guessed what to do: $string\n";
203*4176Stz204579	}
204*4176Stz204579	else {
205*4176Stz204579	    print STDERR "Got call to default, didn't know what to do: $string\n";
206*4176Stz204579	}
207*4176Stz204579    }
208*4176Stz204579}
209*4176Stz204579
210*4176Stz204579sub externalHandler {
211*4176Stz204579    my ($obj, $base, $sysid, $pubid) = @_;
212*4176Stz204579
213*4176Stz204579    $base = '' if !$base;
214*4176Stz204579    $pubid = '' if !$pubid;
215*4176Stz204579    print "external:  base $base\nexternal:  sysid $sysid\nexternal:  pubid $pubid\n";
216*4176Stz204579}
217*4176Stz204579
218*4176Stz204579sub commentHandler {
219*4176Stz204579    my ($obj, $element) = @_;
220*4176Stz204579
221*4176Stz204579    return unless $main::debug;
222*4176Stz204579
223*4176Stz204579    unless ($element =~ /^\s*$/) {
224*4176Stz204579	print "comment:  $element\n";
225*4176Stz204579    }
226*4176Stz204579}
227*4176Stz204579
228*4176Stz204579sub procHandler {
229*4176Stz204579    my $xmlObj = shift;
230*4176Stz204579    my $target = shift;
231*4176Stz204579    my $data   = shift;
232*4176Stz204579
233*4176Stz204579    my (%parameters) =
234*4176Stz204579      parseProcInstruction ($data);
235*4176Stz204579
236*4176Stz204579    $currentObj->processAttributes ($target, $data, @_);
237*4176Stz204579}
238*4176Stz204579#<s> misc subs
239*4176Stz204579
240*4176Stz204579sub parseProcInstruction {
241*4176Stz204579    my ($args) = @_;
242*4176Stz204579
243*4176Stz204579    my (@outputArray) = ();
244*4176Stz204579
245*4176Stz204579    while ($args =~ s/([^ =]+)=\"([^"]+)\"(.*)/$3/) { # "
246*4176Stz204579	push (@outputArray, $1);
247*4176Stz204579	push (@outputArray, $2);
248*4176Stz204579    }
249*4176Stz204579    return (@outputArray);
250*4176Stz204579}
251*4176Stz204579
252*4176Stz204579sub processAttributes {
253*4176Stz204579    my $pkg = shift;
254*4176Stz204579    my ($element, %content) = @_;
255*4176Stz204579
256*4176Stz204579#    print "processAttributes:  element = $element\n" if $main::debug;
257*4176Stz204579
258*4176Stz204579    my $hashCount = 0;
259*4176Stz204579    foreach $attributeName (keys %content) {
260*4176Stz204579	if ($attributeName =~ /^\s*$/) {
261*4176Stz204579	    delete $content{$attributeName};  # remove null entries
262*4176Stz204579	    next;
263*4176Stz204579	}
264*4176Stz204579	$hashCount++;
265*4176Stz204579#	print "attribute: $attributeName = $content{$attributeName}\n"
266*4176Stz204579#	    if $main::debug;
267*4176Stz204579    }
268*4176Stz204579    if ($hashCount && $pkg->{'attributes'}) {
269*4176Stz204579	print STDERR "need to write attribute merge logic\n";
270*4176Stz204579    }
271*4176Stz204579    else {
272*4176Stz204579	$pkg->{'attributes'} = \%content;
273*4176Stz204579    }
274*4176Stz204579}
275*4176Stz204579
276*4176Stz204579sub getKid {
277*4176Stz204579    my $pkg = shift;
278*4176Stz204579    my $whichKid = shift;
279*4176Stz204579
280*4176Stz204579    my @kids = $pkg->getKids();
281*4176Stz204579    my $kid;
282*4176Stz204579    foreach $kid (@kids) {
283*4176Stz204579	my $class = $kid->getClass();
284*4176Stz204579	return $kid if $class eq $whichKid;
285*4176Stz204579    }
286*4176Stz204579    return undef;
287*4176Stz204579}
288*4176Stz204579
289*4176Stz204579sub getKids {
290*4176Stz204579    my $pkg = shift;
291*4176Stz204579
292*4176Stz204579    return @{$pkg->{'kids'}};
293*4176Stz204579}
294*4176Stz204579
295*4176Stz204579sub getAttributes {
296*4176Stz204579    my $pkg = shift;
297*4176Stz204579
298*4176Stz204579    my $ref = $pkg->{'attributes'};
299*4176Stz204579
300*4176Stz204579    return %$ref;
301*4176Stz204579}
302*4176Stz204579
303*4176Stz204579sub getAttr {
304*4176Stz204579    my $pkg = shift;
305*4176Stz204579    my $attr = shift;
306*4176Stz204579
307*4176Stz204579    my $ref = $pkg->{'attributes'};
308*4176Stz204579
309*4176Stz204579    return $$ref{$attr};
310*4176Stz204579}
311*4176Stz204579
312*4176Stz204579sub getClass {
313*4176Stz204579    my $pkg = shift;
314*4176Stz204579
315*4176Stz204579    return $pkg->{'class'};
316*4176Stz204579}
317*4176Stz204579
318*4176Stz204579sub getContent {
319*4176Stz204579    my $pkg = shift;
320*4176Stz204579
321*4176Stz204579    my $content = $pkg->{'content'};
322*4176Stz204579    return $content ? $content : undef;
323*4176Stz204579}
324