Update of /cvsroot/net-script/netscript2/src/perl/NetScript/Libraries In directory usw-pr-cvs1:/tmp/cvs-serv4900 Modified Files: ControlStructuresLibrary.pm DebugLibrary.pm DefaultLibrary.pm FormsLibrary.pm Library.pm VariablesLibrary.pm Log Message: * added support for include/rinclude * various bugfixes * added mod_perl support Index: ControlStructuresLibrary.pm =================================================================== RCS file: /cvsroot/net-script/netscript2/src/perl/NetScript/Libraries/ControlStructuresLibrary.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** ControlStructuresLibrary.pm 9 Jun 2002 12:49:07 -0000 1.4 --- ControlStructuresLibrary.pm 7 Jul 2002 14:34:37 -0000 1.5 *************** *** 29,42 **** # </ns:while> # ! # <ns:for var="[counter variable]" from="[start value]" to="[end value]"> # [for-block here] # </ns:for> # # </pre> ! # # Also this library provides the library loading mechanism of NetScript. # You can load a library by using a processing instruction: # <pre> ! # <netscript use LIBNAME> # </pre> # The library must be named "LIBNAMELibrary.pm" and must be located --- 29,43 ---- # </ns:while> # ! # <ns:for <var="[counter variable]"|name="[counter variabe]"> ! # from="[start value]" to="[end value]" [step="[step]"]> # [for-block here] # </ns:for> # # </pre> ! # <p> # Also this library provides the library loading mechanism of NetScript. # You can load a library by using a processing instruction: # <pre> ! # <?netscript use LIBNAME?> # </pre> # The library must be named "LIBNAMELibrary.pm" and must be located *************** *** 48,51 **** --- 49,102 ---- # third-party-libraries in another place as the base libraries, # however this is just a recommendation, it is not needed. + # </p> + # <p> + # This library also provides an include mechanism for other netscript files. + # Currently the following include modes are supported: + # <pre> + # <?netscript import FILENAME or URL?> + # </pre> + # <p> + # This imports the file at the given URL and inserts its nodes in the source + # document after the processing instruction.If the URL has no protocol and + # starts with . or .. it is treated as relative URL to the currently executed + # script. The given document has to be an XML-compliant structure. + # Hence, it must have a document element. Since + # there are occasions, where you do not have or want a document element + # in imported files, there is a special netscript tag: + # </p> + # <pre> + # <ns:ignore>....</ns:ignore> + # </pre> + # <p> + # This tag can serve as your document element, but is ignored in processing. + # The tags within the <ns:ignore>-tag are moved up one level in the + # destination document, the <ns:ignore>-tag disappears. + # </p> + # <p> + # There are occasions when the import-facility is not enough. One thing is + # if you have a head and a foot for all your pages. Mostly this will be done + # by using tables. So the head and the foot themselves are not valid XML + # documents, and using <code>ns:ignore</code> will not help in these cases. + # For this, this library has a reature names reverse-import. It will not import + # another file into the current file, but will do the opposite of it, + # import the current file into a location of another file. + # The other file must have a "reverse-import point", or just rpoint. This + # is specified by using the following PI: + # </p> + # <pre> + # <?netscript ripoint {NAME}?> + # </pre> + # <p> + # In the source document, you have to specifiy the following PI: + # </p> + # <pre> + # <?netscript rimport {TARGETURL} {RIPOINT_NAME}?> + # </pre> + # <p> + # This PI has to be specified in the document root, before the root element. + # This serves speed purposes, since the interpreter has to search for this + # PI and it will not search the whole document. The sooner the PI occurs + # in the document, the faster the processing will be. + # </p> #*/ package NetScript::Libraries::ControlStructuresLibrary; *************** *** 53,57 **** - use NetScript::Libraries::DebugLibrary; use NetScript::Engine::EventListener; --- 104,107 ---- *************** *** 70,75 **** --- 120,127 ---- my %forLoops = (); my %forLoopsVarNames = (); + my %referencedDocuments = (); $this -> { m_forLoops } = \%forLoops; $this -> { m_forLoopsVarNames } = \%forLoopsVarNames; + $this -> { m_referencedDocuments } = \%referencedDocuments; $this; } *************** *** 81,84 **** --- 133,137 ---- # create event listeners for all events + my $eventListener1 = NetScript::Engine::EventListener -> new(); $eventListener1 -> init( *************** *** 96,103 **** --- 149,162 ---- "processingInstruction", $this ); + my $eventListener4 = NetScript::Engine::EventListener -> new(); + $eventListener4 -> init( + $NetScript::Engine::DOMWalker::DOCUMENT_START_EVENT, + "documentStart", $this ); + my $eventRelay = $this -> interpreter() -> getEventRelay(); $eventRelay -> addEventListener( $eventListener1 ); $eventRelay -> addEventListener( $eventListener2 ); $eventRelay -> addEventListener( $eventListener3 ); + $eventRelay -> addEventListener( $eventListener4 ); } *************** *** 108,112 **** sub elementStarted { my ( $this, $event ) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { --- 167,171 ---- sub elementStarted { my ( $this, $event ) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { *************** *** 127,130 **** --- 186,194 ---- 0; # consume event } + elsif( $node -> getLocalName() eq "ignore" ) { + # Walk over the node + $domWalker -> stepSourceIn(); + 0; #consume event + } else { 1; # do not consume event *************** *** 208,213 **** } else { ! # FIXME: DO NOT use DIE ! die "Else without IF" ; } } --- 272,277 ---- } else { ! $this -> interpreter() -> getEventRelay() -> createAndRaiseEvent( ! $NetScript::Interpreter::FATAL_EVENT, "else without if", undef ); } } *************** *** 334,337 **** --- 398,402 ---- # no it should not, skip node delete $this -> { m_forLoops } -> { $node }; + # delete $this -> { m_forLoopsVarNames } -> { $node }; $this -> interpreter() -> dropState(); $domWalker -> stepSourceNext(); *************** *** 372,376 **** sub elementFinished { my ( $this, $event ) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { --- 437,441 ---- sub elementFinished { my ( $this, $event ) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { *************** *** 393,396 **** --- 458,464 ---- 0; # consume event } + elsif ($node -> getLocalName() eq "ignore" ) { + 0; #consume event + } else { 1; # do not consume event *************** *** 408,419 **** sub processingInstruction { my ( $this, $event ) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getTarget() eq "netscript" ) { my $data = $node -> getData(); ! if ( $data =~ /\s*use\s*([^\s]*)/) { # check for "use LIBNAME" ! $this -> interpreter -> getLibLoader() -> loadLibrary( $1 ); ! $domWalker -> stepSourceIn(); return 0; # consume event } --- 476,513 ---- sub processingInstruction { my ( $this, $event ) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); + # Check for a NetScript-Related target if ( $node -> getTarget() eq "netscript" ) { my $data = $node -> getData(); ! warn "DATA: $data\n\n\n"; ! if ( $data =~ /^\s*use\s*([^\s]*)/) { # check for "use LIBNAME" ! $this -> interpreter() -> getLibLoader() -> loadLibrary( $1 ); ! $domWalker -> stepSourceNext(); ! return 0; # consume event ! } ! elsif ( $data =~ /^\s*import\s*([^\s]+)/ ) { #check for "import FILEURL" ! my $fileURL = $1; ! $fileURL = $this -> checkURL( $fileURL ); ! ! my $fileData = $this -> interpreter() -> getFileRetriever() -> ! retrieveFile( $fileURL ); ! my $document = $this -> interpreter() -> getDOMParser() -> ! parseString( $fileData ); ! $this -> importDocument( $document, $domWalker, $node ); ! return 0; # consume event ! } ! elsif ( $data =~ /^\s*ripoint\s*([^\s]+)/ ) { #check for "ripoint NAME" ! my $ripointName = $1; ! my $targetDoc = $domWalker -> sourceDocument(); ! my $document = $this -> getReferencedDocument( $ripointName, $targetDoc ); ! if ( defined( $document ) ) { ! $this -> importDocument( $document, $domWalker, $node ); ! } ! return 0; # consume event ! } ! elsif ( $data =~ /^\s*rimport\s+([^\s]+)\s+([^\s]+)\s*/ ) { # filter out "rimport"-PIs ! $domWalker -> stepSourceNext(); return 0; # consume event } *************** *** 422,426 **** } ! sub shutdown { --- 516,551 ---- } ! #/** ! # Imports the given document into the current source document of the ! # given DOMWalker at the location of the given node. The given node will ! # be removed. ! # @param the document to import ! # @param the DOMWalker ! # @param the reference node ! #*/ ! sub importDocument { ! my ( $this, $document, $domWalker, $node ) = @_; ! my $sourceDocument = $domWalker -> sourceDocument(); ! my $children = $document -> getChildNodes(); ! my $length = $children -> getLength() - 1; ! my $parent = $node -> getParentNode(); ! my $sibling = $node -> getNextSibling(); ! ! # Import all nodes of the document to the current source document ! for ( 0..$length ) { ! my $importedChild = $sourceDocument -> importNode( ! $children -> item( $_ ), 1 ); ! unless( defined( $sibling ) ) { ! $parent -> appendChild( $importedChild ); ! } ! else { ! $parent -> insertBefore( $importedChild, $sibling ); ! } ! } ! # move source pointer to next node ! $domWalker -> stepSourceNext(); ! # remove PI ! $parent -> removeChild( $node ); ! } sub shutdown { *************** *** 444,447 **** --- 569,709 ---- ); } + + #/** + # Called when the document starts. The Library searches for rinclude PIs + # in the document root. If there is one found, the current document will + # be included into the referenced document. If none is found, nothing will + # happen. + #*/ + sub documentStart { + my ( $this, $event ) = @_; + my $domWalker = $event -> getEventUnknown(); + my $sourceDocument = $domWalker -> currentSource(); + my $children = $sourceDocument -> getChildNodes(); + my $length = $children -> getLength() - 1; + + for ( 0..$length ) { + my $child = $children -> item( $_ ); + if ( $child -> getNodeType() == + $XML::DOM2::Node::PROCESSING_INSTRUCTION_NODE ) { + if ( $child -> getTarget() eq "netscript" ) { + my $data = $child -> getData(); + if ( $data =~ /^\s*rimport\s+([^\s]+)\s+([^\s]+)\s*/ ) { + my $fileURL = $1; + my $importPoint = $2; + $fileURL = $this -> checkURL( $fileURL ); + my $fileData = $this -> interpreter() -> getFileRetriever() -> + retrieveFile( $fileURL ); + my $document = $this -> interpreter() -> getDOMParser() -> + parseString( $fileData ); + warn "RIMPORT: Changing to $fileData ... > $document " ; + $domWalker -> resetDocument( $document ); + $this -> addDocumentReference( $importPoint, $document, $sourceDocument ); + $domWalker -> sourceAgain(); + return 0; # consume event; + } + } + } + } + return 1; # do not consume event + } + + #/** + # Adds a document reference. This can be used to retrieve the document which should + # be inserted into an import point. + # @param the name of the import point + # @param the document in which the import point must be located + # @param the document to mount into the import point + # @private + #*/ + sub addDocumentReference { + my ( $this, $name, $target, $source ) = @_; + $this -> { m_referencedDocuments } -> { $name.$target } = $source; + } + + #/** + # Returns a document for a import point name and document. + # @param the name of the import point + # @param the document in which the import point is located. + # @return the document to insert into the given mountpoint, or undef + # if no such document is currently known. + # @private + #*/ + sub getReferencedDocument { + my ( $this , $name, $target ) = @_; + $this -> { m_referencedDocuments } -> { $name.$target }; + } + + + #/** + # Checks the given URL for having a protocol and makes + # absolute URLs out of relative URLs. + # @param the URL to check + # @return the checked URL + #*/ + sub checkURL { + my ( $this, $fileURL ) = @_; + unless ( $fileURL =~ /^[A-Za-z]+:/ ) { # check for protocol + # no protocol, check for relative URL + if ( $fileURL =~ /^\./ ) { # is relativeUrl + $fileURL = $this -> calculateRelativeURL( $fileURL ); + } + else { + # no relative URL - assume "file:"-protocol + $fileURL = "file:".$fileURL; + } + } + return $fileURL; + } + + #/** + # Calculates the resulting URL out of the known URL of the currently executed + # script and the given relative URL. + # @public + # @param a relative URL + # @return an absolute URL + #*/ + sub calculateRelativeURL { + my ( $this, $relativeURL ) = @_; + my $scriptURL = $this -> interpreter() -> getScriptURL(); + + $scriptURL =~ /(.*)\/[^\/]+$/; + $scriptURL = $1; # strip filename + + # for each single point we stay here, for each double point + # we go one folder down... + while ($relativeURL =~ /^([^\/]+)\/(.*)$/ ) { + my $prefix = $1; + $relativeURL = $2; + if ( $prefix eq "." ) { + next; # stay in the same folder + } + elsif ( $prefix eq ".." ) { + $scriptURL =~ /(.*)\/[^\/]+$/; + $scriptURL = $1; # skip folder... + next; + } + else { # its a name + $scriptURL .= "/".$prefix; + next; + } + } + $scriptURL .= "/".$relativeURL; + return $scriptURL; + } + + sub getName { + "Control Structures Library"; + } + + sub getVersion { + 1.0; + } + + sub getDescription { + "This library provides control structures. Also it provides the library import facility."; + } + + 1; #make require happy Index: DebugLibrary.pm =================================================================== RCS file: /cvsroot/net-script/netscript2/src/perl/NetScript/Libraries/DebugLibrary.pm,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** DebugLibrary.pm 9 Jun 2002 12:49:07 -0000 1.5 --- DebugLibrary.pm 7 Jul 2002 14:34:37 -0000 1.6 *************** *** 73,77 **** my ( $this, $event ) = @_; if ( $this -> debugMessage() ne "" ) { ! my $domWalker = $event -> eventUnknown(); my $document = $domWalker -> sourceDocument(); my $comment = $document -> createComment( --- 73,77 ---- my ( $this, $event ) = @_; if ( $this -> debugMessage() ne "" ) { ! my $domWalker = $event -> getEventUnknown(); my $document = $domWalker -> sourceDocument(); my $comment = $document -> createComment( *************** *** 84,88 **** #/** # Called when a debug message has to be inserted. The message ! # must be in the eventMessage - field. The eventUnknown-field # should contain the sender of the event. Messages are # printed this way: --- 84,88 ---- #/** # Called when a debug message has to be inserted. The message ! # must be in the eventMessage - field. The getEventUnknown-field # should contain the sender of the event. Messages are # printed this way: *************** *** 95,99 **** sub debugEvent { my ( $this, $event ) = @_; ! my $sender = $event -> eventUnknown(); my $message = $event -> eventMessage(); $this -> { m_debug } .= "[$sender] $message\n"; --- 95,99 ---- sub debugEvent { my ( $this, $event ) = @_; ! my $sender = $event -> getEventUnknown(); my $message = $event -> eventMessage(); $this -> { m_debug } .= "[$sender] $message\n"; *************** *** 116,119 **** --- 116,131 ---- my ($this) = @_; $this -> SUPER::shutdown(); + } + + sub getName { + "Debug Library"; + } + + sub getVersion { + 1.0; + } + + sub getDescription { + "This library provides some basic debugging capabilities."; } Index: DefaultLibrary.pm =================================================================== RCS file: /cvsroot/net-script/netscript2/src/perl/NetScript/Libraries/DefaultLibrary.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** DefaultLibrary.pm 15 May 2002 18:22:18 -0000 1.3 --- DefaultLibrary.pm 7 Jul 2002 14:34:37 -0000 1.4 *************** *** 103,107 **** sub copyNode { my ($this, $event) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); $domWalker -> insertIntoTarget( $node, 1 ); --- 103,107 ---- sub copyNode { my ($this, $event) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); $domWalker -> insertIntoTarget( $node, 1 ); *************** *** 117,121 **** sub elementStarted { my ($this, $event) = @_; ! my $domWalker = $event -> eventUnknown(); $this -> copyNode( $event ); 0; # consume event --- 117,121 ---- sub elementStarted { my ($this, $event) = @_; ! my $domWalker = $event -> getEventUnknown(); $this -> copyNode( $event ); 0; # consume event *************** *** 129,133 **** sub elementFinished { my ($this, $event) = @_; ! my $domWalker = $event -> eventUnknown(); $domWalker -> stepTargetUp(); 0; # consume event --- 129,133 ---- sub elementFinished { my ($this, $event) = @_; ! my $domWalker = $event -> getEventUnknown(); $domWalker -> stepTargetUp(); 0; # consume event *************** *** 141,145 **** sub documentStarted { my ($this, $event) = @_; ! my $domWalker = $event -> eventUnknown(); $domWalker -> stepSourceIn(); } --- 141,145 ---- sub documentStarted { my ($this, $event) = @_; ! my $domWalker = $event -> getEventUnknown(); $domWalker -> stepSourceIn(); } *************** *** 150,153 **** --- 150,161 ---- my ($this) = @_; $this -> SUPER::shutdown(); + } + + sub getName { + "Default Library"; + } + + sub getDescription { + "This Library provides basic tag copying function. If no other library processes a tag, it will be finally processed by this library."; } Index: FormsLibrary.pm =================================================================== RCS file: /cvsroot/net-script/netscript2/src/perl/NetScript/Libraries/FormsLibrary.pm,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** FormsLibrary.pm 9 Jun 2002 12:49:07 -0000 1.3 --- FormsLibrary.pm 7 Jul 2002 14:34:37 -0000 1.4 *************** *** 65,71 **** # register the P-object ! $this -> interpreter() -> getState() -> setObjectValue( "P", $paramWrapper ); # register the C-object ! $this -> interpreter() -> getState() -> setObjectValue( "C", $cookieWrapper ); # register event listeners for the cookie-tag --- 65,71 ---- # register the P-object ! $this -> interpreter() -> getState() -> createObjectValue( "P", $paramWrapper ); # register the C-object ! $this -> interpreter() -> getState() -> createObjectValue( "C", $cookieWrapper ); # register event listeners for the cookie-tag *************** *** 91,95 **** sub elementStarted { my ( $this, $event ) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { --- 91,95 ---- sub elementStarted { my ( $this, $event ) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { *************** *** 113,117 **** sub elementFinished { my ( $this, $event ) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { --- 113,117 ---- sub elementFinished { my ( $this, $event ) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { *************** *** 201,204 **** --- 201,216 ---- "[Forms]" ); + } + + sub getName { + "Forms Library"; + } + + sub getVersion { + 1.0; + } + + sub getDescription { + "This Library adds functionality for processing forms. It adds the P and C variables and cookie-support."; } 1; #make require happy Index: Library.pm =================================================================== RCS file: /cvsroot/net-script/netscript2/src/perl/NetScript/Libraries/Library.pm,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Library.pm 2 Jun 2002 19:31:23 -0000 1.4 --- Library.pm 7 Jul 2002 14:34:37 -0000 1.5 *************** *** 72,75 **** --- 72,101 ---- } + #/** + # Returns the name of the library. + # @public + # @abstract + #*/ + sub getName { + undef; + } + + #/** + # Returns a description of the library. + # @public + # @abstract + #*/ + sub getDescription { + undef; + } + + #/** + # Returns the version of the library as float value. + # @public + # @abstract + #*/ + sub getVersion { + undef; + } 1; #make require happy Index: VariablesLibrary.pm =================================================================== RCS file: /cvsroot/net-script/netscript2/src/perl/NetScript/Libraries/VariablesLibrary.pm,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** VariablesLibrary.pm 9 Jun 2002 12:49:07 -0000 1.2 --- VariablesLibrary.pm 7 Jul 2002 14:34:37 -0000 1.3 *************** *** 14,18 **** # <pre> # ! # <ns:var var="[variable name]" value="[value]"/> # </pre> #*/ --- 14,18 ---- # <pre> # ! # <ns:var {var="[variable name]"|name="[variable name]"} value="[value]"/> # </pre> #*/ *************** *** 66,70 **** sub elementStarted { my ( $this, $event ) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { --- 66,70 ---- sub elementStarted { my ( $this, $event ) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { *************** *** 88,92 **** sub elementFinished { my ( $this, $event ) = @_; ! my $domWalker = $event -> eventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { --- 88,92 ---- sub elementFinished { my ( $this, $event ) = @_; ! my $domWalker = $event -> getEventUnknown(); my $node = $domWalker -> currentSource(); if ( $node -> getNamespaceURI() eq $NetScript::Interpreter::NAMESPACE_URI ) { *************** *** 150,153 **** --- 150,165 ---- "[Variables]" ); + } + + sub getName { + "Variables Library"; + } + + sub getVersion { + 1.0; + } + + sub getDescription { + "This Library adds functionality for creating and changing variables."; } 1; #make require happy |