[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/se3-unattended/var/se3/unattended/install/linuxaux/opt/perl/lib/site_perl/5.10.0/Net/LDAP/ -> DSML.pm (source)

   1  # Copyright (c) 2002-2006 Graham Barr. All rights reserved. This program is
   2  # free software; you can redistribute it and/or modify it under the same
   3  # terms as Perl itself.
   4  
   5  package Net::LDAP::DSML;
   6  
   7  use strict;
   8  use vars qw(@ISA $VERSION);
   9  use Carp;
  10  use XML::SAX::Base;
  11  use Net::LDAP::Entry;
  12  
  13  @ISA = qw(XML::SAX::Base);
  14  $VERSION = "0.13";
  15  
  16  # OO purists will hate this :)
  17  my %schema_typemap = qw(
  18      attribute-type        at
  19      objectclass-type    oc
  20  );
  21  #    syn
  22  #    mr
  23  #    mru
  24  #    dts
  25  #    dtc
  26  #    nfm
  27  
  28  sub new {
  29    my $pkg = shift;
  30    my %opt = @_;
  31  
  32    my $sax;
  33  
  34    if ($sax = $opt{output}) {
  35      unless (ref($sax) and eval { $sax->isa('XML::SAX::Base') }) {
  36        require XML::SAX::Writer;
  37        $sax = XML::SAX::Writer->new( Output => $sax );
  38      }
  39  
  40      $sax = Net::LDAP::DSML::pp->new( handler => $sax )
  41        if $opt{pretty_print};
  42    }
  43    else {
  44      $sax = Net::LDAP::DSML::output->new;
  45    }
  46  
  47    bless { @_, handler => $sax }, $pkg;
  48  }
  49  
  50  sub start_document {
  51    my ($self, $data) = @_;
  52    $self->{reader} = {};
  53  }
  54  
  55  my %start_jumptable = qw(
  56      entry            entry
  57      attr            entry_attr
  58      objectclass        entry_attr
  59      value            entry_value
  60      oc-value        entry_value
  61      directory-schema    schema
  62      attribute-type        schema_element
  63      objectclass-type    schema_element
  64      name            schema_name
  65      object-identifier    schema_value
  66      syntax            schema_syntax
  67      description        schema_value
  68      equality        schema_value
  69      substring        schema_value
  70      ordering        schema_value
  71      attribute        schema_attr
  72  );
  73  
  74  sub start_element {
  75    my ($self, $data) = @_;
  76    
  77    (my $tag = lc $data->{Name}) =~ s/^dsml://;
  78  
  79    my $label = $start_jumptable{$tag} or return;
  80    my $state = $self->{reader};
  81    goto $label;
  82  
  83  entry:
  84    {
  85      $state->{entry} = { objectName => $data->{Attributes}{'{}dn'}{Value} };
  86      return;
  87    }
  88  
  89  entry_attr:
  90    {
  91      my $name = $tag eq 'objectclass' ? $tag : lc $data->{Attributes}{'{}name'}{Value};
  92      $state->{attr} = $state->{attrs}{$name}
  93        ||= do {
  94      my $aref = [];
  95      push @{$state->{entry}{attributes}}, {
  96        type => $data->{Attributes}{'{}name'}{Value},
  97        vals => $aref
  98      };
  99      $aref;
 100        };
 101      return;
 102    }
 103  
 104  entry_value:
 105    {
 106      push @{$state->{attr}}, '';
 107      $state->{value} = \${$state->{attr}}[-1];
 108      $state->{encoding} = $data->{Attributes}{'{}encoding'}{Value} || '';
 109      return;
 110    }
 111  
 112  schema:
 113    {
 114      $state->{schema} = {};
 115      return;
 116    }
 117  
 118  schema_element:
 119    {
 120      my $Attrs = $data->{Attributes};
 121      my $id = $Attrs->{'{}id'}{Value};
 122      my $elem = $state->{elem} = { type => $schema_typemap{$tag} };
 123      $state->{id}{$id} = $elem if $id;
 124  
 125      my $value;
 126  
 127      if (defined($value = $Attrs->{"{}type"}{Value})) {
 128        $elem->{lc $value} = 1;
 129      }
 130  
 131      foreach my $attr (qw(
 132      single-value
 133      obsolete
 134      user-modification
 135      )) {
 136        my $value = $Attrs->{"{}$attr"}{Value};
 137        $elem->{$attr} = 1 if defined $value and $value =~ /^true$/i;
 138      }
 139  
 140      $elem->{superior} = $value
 141        if defined($value = $Attrs->{"{}superior"}{Value});
 142  
 143      return;
 144    }
 145  
 146  schema_name:
 147    {
 148      my $elem = $state->{elem};
 149      push @{$elem->{name}}, '';
 150      $state->{value} = \${$elem->{name}}[-1];
 151      return;
 152    }
 153  
 154  schema_syntax:
 155    {
 156      my $elem = $state->{elem};
 157      my $bound = $data->{Attributes}{'{}bound'}{Value};
 158      $elem->{max_length} = $bound if defined $bound;
 159  
 160      $elem->{$tag} = '' unless exists $elem->{$tag};
 161      $state->{value} = \$elem->{$tag};
 162      return;
 163    }
 164  
 165  schema_value:
 166    {
 167      my $elem = $state->{elem};
 168      $elem->{$tag} = '' unless exists $elem->{$tag};
 169      $state->{value} = \$elem->{$tag};
 170      return;
 171    }
 172  
 173  schema_attr:
 174    {
 175      my $Attrs = $data->{Attributes};
 176      my $required = $data->{Attributes}{'{}required'}{Value} || 'false';
 177      my $ref = $data->{Attributes}{'{}ref'}{Value} or return;
 178      my $type = $required =~ /^false$/i ? 'may' : 'must';
 179      push @{$state->{elem}{$type}}, $ref;
 180      return;
 181    }
 182  }
 183  
 184  my %end_jumptable = qw(
 185      entry            entry
 186      attr            entry_attr
 187      objectclass        entry_attr
 188      value            value
 189      oc-value        value
 190      syntax            value
 191      description        value
 192      equality        value
 193      substring        value
 194      ordering        value
 195      name            value
 196      object-identifier    value
 197      attribute-type        schema_element
 198      objectclass-type    schema_element
 199      directory-schema    schema
 200  );
 201  
 202  sub end_element {
 203    my ($self, $data) = @_;
 204    (my $tag = lc $data->{Name}) =~ s/^dsml://;
 205  
 206    my $label = $end_jumptable{$tag} or return;
 207    my $state = $self->{reader};
 208    goto $label;
 209  
 210  entry:
 211    {
 212      my $entry = Net::LDAP::Entry->new;
 213      $entry->{asn} = delete $state->{entry};
 214      if (my $handler = $self->{entry}) {
 215        $handler->($entry);
 216      }
 217      else {
 218        push @{$state->{entries}}, $entry;
 219      }
 220      return;
 221    }
 222  
 223  entry_attr:
 224    {
 225      delete $state->{attr};
 226      return;
 227    }
 228  
 229  value:
 230    {
 231      delete $state->{value};
 232      delete $state->{encoding};
 233      return;
 234    }
 235  
 236  schema_element:
 237    {
 238      my $elem = delete $state->{elem};
 239      my $oid  = $elem->{oid};
 240      my $name;
 241  
 242      if (my $aliases = $elem->{name}) {
 243        $name = $elem->{name} = shift @$aliases;
 244        $elem->{aliases} = $aliases if @$aliases;
 245      }
 246      elsif ($oid) {
 247        $name = $oid;
 248      }
 249      else {
 250      croak "Schema element without a name or object-identifier";
 251      }
 252  
 253      $elem->{oid} ||= $name;
 254      $state->{schema}{oid}{$oid} = $state->{schema}{$elem->{type}}{lc $name} = $elem;
 255   
 256      return;
 257    }
 258  
 259  schema:
 260    {
 261      my $id = $state->{id};
 262      my $schema = $state->{schema};
 263      foreach my $elem (values %{$schema->{oc}}) {
 264        if (my $sup = $elem->{superior}) {
 265          $sup =~ /#(.*)|(.*)/;
 266      if (my $ref = $id->{$+}) {
 267        $elem->{superior} = $ref->{name};
 268      }
 269      else {
 270        $elem->{superior} = $+;
 271      }
 272        }
 273        foreach my $mm (qw(must may)) {
 274      if (my $mmref = $elem->{$mm}) {
 275        my @mm = map {
 276          /#(.*)|(.*)/;
 277          my $ref = $id->{$+};
 278          $ref ? $ref->{name} : $+;
 279        } @$mmref;
 280        $elem->{$mm} = \@mm;
 281      }
 282        }
 283      }
 284      require Net::LDAP::Schema;
 285      bless $schema, 'Net::LDAP::Schema'; # Naughty :-)
 286      if (my $handler = $self->{schema}) {
 287        $handler->($schema);
 288      }
 289      return;
 290    }
 291  
 292  }
 293  
 294  sub characters {
 295    my ($self, $data) = @_;
 296    my $state = $self->{reader};
 297    if (my $sref = $state->{value}) {
 298      $$sref = ($state->{encoding}||'') eq 'base64'
 299      ? do { require MIME::Base64; MIME::Base64::decode_base64($data->{Data}) }
 300      : $data->{Data};
 301    }
 302  }
 303  
 304  sub _dsml_context {
 305    my ($self, $new) = @_;
 306    my $context = $self->{writer}{context};
 307    my $handler = $self->{handler};
 308  
 309    unless ($context) {
 310      $context = $self->{writer}{context} = [];
 311      $handler->start_document;
 312  
 313      $handler->xml_decl({
 314        Standalone => '',
 315        Version    => '1.0',
 316        Encoding   => 'utf-8'
 317      });
 318    }
 319  
 320    while (@$context and ($context->[-1] ne $new) and ($context->[-1] ne 'dsml' or $new eq '')) {
 321      my $old = pop @$context;
 322      $handler->end_element({
 323        Name         => "dsml:$old",
 324        LocalName    => $old,
 325        NamespaceURI => 'http://www.dsml.org/DSML',
 326        Prefix       => 'dsml'
 327      });
 328  
 329      $handler->end_prefix_mapping({
 330        NamespaceURI => 'http://www.dsml.org/DSML',
 331        Prefix       => 'dsml'
 332      }) if $old eq 'dsml';
 333    }
 334  
 335    if (!$new) {
 336      $handler->end_document;
 337      delete $self->{writer}{context};
 338    }
 339    elsif (!@$context or $context->[-1] ne $new) {
 340      $self->_dsml_context('dsml') unless $new eq 'dsml' or @$context;
 341      push @$context, $new;
 342      my %data = (
 343        Name       => "dsml:$new",
 344        LocalName       => $new,
 345        NamespaceURI => 'http://www.dsml.org/DSML',
 346        Prefix       => 'dsml',
 347      );
 348  
 349      if ($new eq 'dsml') {
 350        $handler->start_prefix_mapping({
 351      NamespaceURI => 'http://www.dsml.org/DSML',
 352      Prefix       => 'dsml'
 353        });
 354        $data{Attributes} = {
 355      '{http://www.w3.org/2000/xmlns/}dsml' => {
 356        Name         => 'xmlns:dsml',
 357        LocalName    => 'dsml',
 358        NamespaceURI => 'http://www.w3.org/2000/xmlns/',
 359        Value        => 'http://www.dsml.org/DSML',
 360        Prefix       => 'xmlns'
 361      }
 362        };
 363      }
 364      $handler->start_element(\%data);
 365    }
 366  }
 367  
 368  sub start_dsml {
 369    my $self = shift;
 370  
 371    $self->_dsml_context('') if $self->{writer}{context};
 372    $self->_dsml_context('dsml');
 373  }
 374  
 375  sub end_dsml {
 376    my $self = shift;
 377    $self->_dsml_context('') if $self->{writer} and $self->{writer}{context};
 378  }
 379  
 380  sub write_entry {
 381    my $self = shift;
 382    my $handler = $self->{handler};
 383  
 384    $self->_dsml_context('directory-entries');
 385  
 386    my %attr;
 387    my %data = (
 388      NamespaceURI => 'http://www.dsml.org/DSML',
 389      Prefix       => 'dsml',
 390      Attributes   => \%attr,
 391    );
 392    foreach my $entry (@_) {
 393      my $asn = $entry->asn;
 394      @data{qw(Name LocalName)} = qw(dsml:entry entry);
 395      %attr = ( '{}dn' => { Value => $asn->{objectName}, Name => "dn"} );
 396      $handler->start_element(\%data);
 397  
 398      foreach my $attr ( @{$asn->{attributes}} ) {
 399        my $name = $attr->{type};
 400        my $is_oc = lc($name) eq "objectclass";
 401  
 402        if ($is_oc) {
 403      @data{qw(Name LocalName)} = qw(dsml:objectclass objectclass);
 404      %attr = ();
 405      $handler->start_element(\%data);
 406      @data{qw(Name LocalName)} = qw(dsml:oc-value oc-value);
 407        }
 408        else {
 409      @data{qw(Name LocalName)} = qw(dsml:attr attr);
 410      %attr = ( "{}name" => { Value => $name, Name => "name" } );
 411      $handler->start_element(\%data);
 412      @data{qw(Name LocalName)} = qw(dsml:value value);
 413        }
 414  
 415        my %chdata;
 416        foreach my $val (@{$attr->{vals}}) {
 417      if ($val =~ /(^[ :]|[\x00-\x1f\x7f-\xff])/) {
 418        require MIME::Base64;
 419        $chdata{Data} = MIME::Base64::encode($val,"");
 420        %attr = ( '{}encoding' => { Value => 'base64', Name => "encoding"} );
 421      }
 422      else {
 423        $chdata{Data} = $val;
 424        %attr = ();
 425      }
 426      $handler->start_element(\%data);
 427      $handler->characters(\%chdata);
 428      %attr = ();
 429      $handler->end_element(\%data);
 430        }
 431  
 432        @data{qw(Name LocalName)} = $is_oc
 433      ? qw(dsml:objectclass objectclass)
 434      : qw(dsml:attr attr);
 435        %attr = ();
 436        $handler->end_element(\%data);
 437      }
 438  
 439      @data{qw(Name LocalName)} = qw(dsml:entry entry);
 440      %attr = ();
 441      $handler->end_element(\%data);
 442    }
 443  }
 444  
 445  sub write_schema {
 446    my ($self, $schema) = @_;
 447    my $handler = $self->{handler};
 448  
 449    $self->_dsml_context('dsml');
 450    my %attr;
 451    my %data = (
 452      NamespaceURI => 'http://www.dsml.org/DSML',
 453      Prefix       => 'dsml',
 454      Attributes   => \%attr,
 455    );
 456    @data{qw(Name LocalName)} = qw(dsml:directory-schema directory-schema);
 457    $handler->start_element(\%data);
 458    my %id;
 459  
 460    foreach my $attr ($schema->all_attributes) {
 461      $id{$attr->{name}} = 1;
 462      %attr = ( '{}id' => { Value => "#$attr->{name}", Name => 'id'});
 463  
 464      if (my $sup = $attr->{superior}) {
 465        my $sup_a = $schema->attribute($sup);
 466        $attr{"{}superior"} = {
 467      Value => "#" . ($sup_a ? $sup_a->{name} : $sup),
 468      Name  => 'superior'
 469        };
 470      }
 471      foreach my $flag (qw(obsolete single-value)) {
 472        $attr{"{}$flag"} = {
 473      Value => 'true', Name => $flag
 474        } if $attr->{$flag};
 475      }
 476      $attr{"{}user-modification"} = {
 477        Value => 'false',
 478        Name => 'user-modification',
 479      } unless $attr->{'user-modification'};
 480  
 481      @data{qw(Name LocalName)} = qw(dsml:attribute-type attribute-type);
 482      $handler->start_element(\%data);
 483      %attr = ();
 484      unless (($attr->{name} || '') eq ($attr->{oid} || '')) {
 485        @data{qw(Name LocalName)} = qw(dsml:name name);
 486        $handler->start_element(\%data);
 487        $handler->characters({Data => $attr->{name}});
 488        $handler->end_element(\%data);
 489      }
 490      if (my $aliases = $attr->{aliases}) {
 491        @data{qw(Name LocalName)} = qw(dsml:name name);
 492        foreach my $name (@$aliases) {
 493      $handler->start_element(\%data);
 494      $handler->characters({Data => $name});
 495      $handler->end_element(\%data);
 496        }
 497      }
 498      if (my $oid = $attr->{oid}) {
 499        @data{qw(Name LocalName)} = ("dsml:object-identifier","object-identifier");
 500        $handler->start_element(\%data);
 501        $handler->characters({Data => $oid});
 502        $handler->end_element(\%data);
 503      }
 504      foreach my $elem (qw(
 505      description
 506      equality
 507      ordering
 508      substring
 509      )) {
 510        defined(my $text = $attr->{$elem}) or next;
 511        @data{qw(Name LocalName)} = ("dsml:$elem",$elem);
 512        $handler->start_element(\%data);
 513        $handler->characters({Data => $text});
 514        $handler->end_element(\%data);
 515      }
 516      if (my $syn = $attr->{syntax}) {
 517        if (defined(my $bound = $attr->{max_length})) {
 518      $attr{'{}bound'} = {
 519        Value => $bound,
 520        Name => 'bound',
 521      };
 522        }
 523        @data{qw(Name LocalName)} = qw(dsml:syntax syntax);
 524        $handler->start_element(\%data);
 525        $handler->characters({Data => $syn});
 526        $handler->end_element(\%data);
 527      }
 528      @data{qw(Name LocalName)} = qw(dsml:attribute-type attribute-type);
 529      $handler->end_element(\%data);
 530    }
 531  
 532    foreach my $oc ($schema->all_objectclasses) {
 533      my $id = $oc->{name};
 534      $id = $oc->{'object-identifier'} if $id{$id};
 535  
 536      %attr = ( '{}id' => { Value => "#$id", Name => 'id'});
 537  
 538      if (my $sup = $oc->{superior}) {
 539        my $sup_a = $schema->objectclass($sup);
 540        $attr{"{}superior"} = {
 541      Value => "#" . ($sup_a ? $sup_a->{name} : $sup),
 542      Name  => 'superior'
 543        };
 544      }
 545      if (my $type = (grep { $oc->{$_} } qw(structural abstract auxilary))[0]) {
 546        $attr{"{}type"} = {
 547      Value => $type,
 548      Name  => 'type',
 549        };
 550      }
 551      if ($oc->{obsolete}) {
 552        $attr{"{}type"} = {
 553      Value => 'true',
 554      Name  => 'obsolete',
 555        };
 556      }
 557  
 558      @data{qw(Name LocalName)} = qw(dsml:objectclass-type objectclass-type);
 559      $handler->start_element(\%data);
 560      %attr = ();
 561  
 562      unless (($oc->{name} || '') eq ($oc->{'object-identifier'} || '')) {
 563        @data{qw(Name LocalName)} = qw(dsml:name name);
 564        $handler->start_element(\%data);
 565        $handler->characters({Data => $oc->{name}});
 566        $handler->end_element(\%data);
 567      }
 568      if (my $aliases = $oc->{aliases}) {
 569        @data{qw(Name LocalName)} = qw(dsml:name name);
 570        foreach my $name (@$aliases) {
 571      $handler->start_element(\%data);
 572      $handler->characters({Data => $name});
 573      $handler->end_element(\%data);
 574        }
 575      }
 576      foreach my $elem (qw(
 577      description
 578      object-identifier
 579      )) {
 580        defined(my $text = $oc->{$elem}) or next;
 581        @data{qw(Name LocalName)} = ("dsml:$elem",$elem);
 582        $handler->start_element(\%data);
 583        $handler->characters({Data => $text});
 584        $handler->end_element(\%data);
 585      }
 586      @data{qw(Name LocalName)} = qw(dsml:attribute attribute);
 587      foreach my $mm (qw(must may)) {
 588        %attr = (
 589      '{}required' => {
 590        Value => ($mm eq 'must' ? 'true' : 'false'),
 591        Name => 'required'
 592      },
 593      '{}ref' => {
 594        Name => 'ref'
 595      },
 596        );
 597        my $mmref = $oc->{$mm} or next;
 598        foreach my $attr (@$mmref) {
 599      my $a_ref = $schema->attribute($attr);
 600      $attr{'{}ref'}{Value} = $a_ref ? $a_ref->{name} : $attr;
 601      $handler->start_element(\%data);
 602      $handler->end_element(\%data);
 603        }
 604      }
 605  
 606      @data{qw(Name LocalName)} = qw(dsml:objectclass-type objectclass-type);
 607      $handler->end_element(\%data);
 608    }
 609  
 610    %attr = ();
 611    @data{qw(Name LocalName)} = qw(dsml:directory-schema directory-schema);
 612    $handler->end_element(\%data);
 613  }
 614  
 615  
 616  package Net::LDAP::DSML::pp;
 617  
 618  sub new {
 619    my $pkg = shift;
 620    bless { @_ }, $pkg;
 621  }
 622  
 623  sub start_element {
 624    my ($self, $data) = @_;
 625    my $handler = $self->{handler};
 626    $handler->start_element($data);
 627    unless ($data->{Name} =~ /^(?:dsml:)?(?:
 628       value
 629      |oc-value
 630      |name
 631      |syntax
 632      |equality
 633      |substring
 634      |object-identifier
 635      |description
 636      |ordering
 637      |attribute
 638      )$/ix
 639    ) {
 640      $handler->ignorable_whitespace({Data => "\n"});
 641    }
 642  }
 643  
 644  sub end_element {
 645    my $self = shift;
 646    my $handler = $self->{handler};
 647    $handler->end_element(@_);
 648    $handler->ignorable_whitespace({Data => "\n"});
 649  }
 650  
 651  sub xml_decl {
 652    my $self = shift;
 653    my $handler = $self->{handler};
 654    $handler->xml_decl(@_);
 655    $handler->ignorable_whitespace({Data => "\n"});
 656  }
 657  
 658  use vars qw($AUTOLOAD);
 659  
 660  sub DESTROY {}
 661  
 662  sub AUTOLOAD {
 663    (my $meth = $AUTOLOAD) =~ s/^.*:://;
 664    no strict 'refs';
 665    *{$meth} = sub { shift->{handler}->$meth(@_) };
 666    goto &$meth;
 667  }
 668  
 669  package Net::LDAP::DSML::output;
 670  
 671  sub new { bless {} }
 672  
 673  use vars qw($AUTOLOAD);
 674  
 675  sub DESTROY {}
 676  
 677  sub AUTOLOAD {
 678    (my $meth = $AUTOLOAD) =~ s/^.*:://;
 679    require XML::SAX::Writer;
 680    my $self = shift;
 681    $self->{handler} = XML::SAX::Writer->new;
 682    bless $self, 'Net::LDAP::DSML::pp';
 683    $self->$meth(@_);
 684  }
 685  
 686  1;
 687  
 688  __END__
 689  
 690  =head1 NAME
 691  
 692  NET::LDAP::DSML -- A DSML Writer for Net::LDAP
 693  
 694  =head1 SYNOPSIS
 695  
 696   For a directory entry;
 697  
 698   use Net::LDAP;
 699   use Net::LDAP::DSML;
 700   use IO::File;
 701  
 702  
 703   my $server = "localhost";
 704   my $file = "testdsml.xml";
 705   my $ldap = Net::LDAP->new($server);
 706  
 707   $ldap->bind();
 708  
 709  
 710   #
 711   # For file i/o
 712   #
 713   my $file = "testdsml.xml";
 714  
 715   my $io = IO::File->new($file,"w") or die ("failed to open $file as filehandle.$!\n");
 716  
 717   my $dsml = Net::LDAP::DSML->new(output => $io, pretty_print => 1 )
 718        or die ("DSML object creation problem using an output file.\n");
 719   #      OR
 720   #
 721   # For file i/o
 722   #
 723  
 724   open (IO,">$file") or die("failed to open $file.$!");
 725  
 726   my $dsml = Net::LDAP::DSML->new(output => *IO, pretty_print => 1)
 727       or die ("DSML object creation problem using an output file.\n");
 728  
 729   #      OR
 730   #
 731   # For array usage.
 732   # Pass a reference to an array.
 733   #
 734  
 735   my @data = ();
 736   $dsml = Net::LDAP::DSML->new(output => \@data, pretty_print => 1) 
 737       or die ("DSML object cration problem using an output array.\n");
 738  
 739  
 740    my $mesg = $ldap->search(
 741                             base     => 'o=airius.com',
 742                             scope    => 'sub',
 743                             filter   => 'ou=accounting',
 744                             callback => sub {
 745                       my ($mesg,$entry) =@_;
 746                       $dsml->write_entry($entry) 
 747                                            if (ref $entry eq 'Net::LDAP::Entry');
 748                         }
 749                              );  
 750  
 751   die ("search failed with ",$mesg->code(),"\n") if $mesg->code();
 752  
 753   For directory schema;
 754  
 755   A file or array can be used for output, in the following example
 756   only an array will be used.
 757  
 758   my $schema = $ldap->schema();
 759   my @data = ();
 760   my $dsml = Net::LDAP::DSML->new(output => \@data, pretty_print => 1 )
 761        or die ("DSML object creation problem using an output array.\n");
 762  
 763   $dsml->write_schema($schema);
 764  
 765   print "Finished printing DSML\n";
 766  
 767  =head1 DESCRIPTION
 768  
 769  Directory Service Markup Language (DSML) is the XML standard for
 770  representing directory service information in XML.
 771  
 772  At the moment this module only writes DSML entry and schema entities. 
 773  Reading DSML entities is a future project.
 774  
 775  Eventually this module will be a full level 2 consumer and producer
 776  enabling you to give you full DSML conformance.  Currently this 
 777  module has the ability to be a level 2 producer.  The user must 
 778  understand the his/her directory server will determine the 
 779  consumer and producer level they can achieve.  
 780  
 781  To determine conformance, it is useful to divide DSML documents into 
 782  four types:
 783  
 784    1.Documents containing no directory schema nor any references to 
 785      an external schema. 
 786    2.Documents containing no directory schema but containing at 
 787      least one reference to an external schema. 
 788    3.Documents containing only a directory schema. 
 789    4.Documents containing both a directory schema and entries. 
 790  
 791  A producer of DSML must be able to produce documents of type 1.
 792  A producer of DSML may, in addition, be able to produce documents of 
 793  types 2 thru 4.
 794  
 795  A producer that can produce documents of type 1 is said to be a level 
 796  1 producer. A producer than can produce documents of all four types is 
 797  said to be a level 2 producer.
 798  
 799  =head1 CALLBACKS
 800  
 801  The module uses callbacks to improve performance (at least the appearance
 802  of improving performance ;) and to reduce the amount of memory required to
 803  parse large DSML files. Every time a single entry or schema is processed
 804  we pass the Net::LDAP object (either an Entry or Schema object) to the
 805  callback routine.
 806  
 807  =head1 CONSTRUCTOR 
 808  
 809  =over 4
 810  
 811  =item new ()
 812  
 813  Creates a new Net::LDAP::DSML object.  There are 2 options
 814  to this method.
 815  
 816  C<output> is a reference to either a file handle that has already
 817  been opened or to an array.
 818  
 819  C<pretty_print> is an option to print a new line at the end of
 820  each element sequence.  It makes the reading of the XML output
 821  easier for a human.
 822  
 823  B<Example>
 824  
 825    my $dsml = Net::LDAP::DSML->new();  
 826    Prints xml data to standard out.
 827  
 828    my $dsml = Net::LDAP::DSML->new(output => \@array);  
 829    my $dsml = Net::LDAP::DSML->new(output => *FILE);  
 830    Prints xml data to a file or array.
 831  
 832    my $dsml = Net::LDAP::DSML->new(output => \@array, pretty_print => 1);  
 833    my $dsml = Net::LDAP::DSML->new(output => *FILE, pretty_print => 1);  
 834    Prints xml data to a file or array in pretty print style.
 835  
 836  =back
 837  
 838  
 839  =head1 METHODS
 840  
 841  =over 4
 842  
 843  =item start_dsml ()
 844  
 845  Start a DSML file.
 846  
 847  =item end_dsml ()
 848  
 849  End a DSML file.
 850  
 851  =item write_entry ( ENTRY )
 852  
 853  Entry is a Net::LDAP::Entry object. The write method will parse
 854  the LDAP data in the Entry object and put it into DSML XML
 855  format.
 856  
 857  B<Example>
 858  
 859    my $entry = $mesg->entry();
 860    $dsml->write_entry($entry);
 861  
 862  =item write_schema ( SCHEMA )
 863  
 864  Schema is a Net::LDAP::Schema object. The write_schema method will 
 865  parse the LDAP data in the Schema object and put it into DSML XML
 866  format.
 867  
 868  B<Example>
 869  
 870    my $schema = $ldap->schema();
 871    $dsml->write_schema($schema);
 872  
 873  =back
 874  
 875  =head1 AUTHOR
 876  
 877  Graham Barr   gbarr@pobox.com
 878  
 879  =head1 SEE ALSO
 880  
 881  L<Net::LDAP>,
 882  L<XML::SAX::Base>
 883  
 884  =head1 COPYRIGHT
 885  
 886  Copyright (c) 2002-2006 Graham Barr. All rights reserved. This program is
 887  free software; you can redistribute it and/or modify it under the same
 888  terms as Perl itself.
 889  
 890  =cut
 891  
 892  


Generated: Tue Mar 17 22:47:18 2015 Cross-referenced by PHPXref 0.7.1