qsos-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qsos-commits] qsos/apps/querysos/src querysos.rb querysos/Com...


From: Romain PELISSE
Subject: [Qsos-commits] qsos/apps/querysos/src querysos.rb querysos/Com...
Date: Wed, 30 Aug 2006 12:28:36 +0000

CVSROOT:        /sources/qsos
Module name:    qsos
Changes by:     Romain PELISSE <rpelisse>       06/08/30 12:28:36

Added files:
        apps/querysos/src: querysos.rb 
        apps/querysos/src/querysos: Command.rb CommandInterpreter.rb 
                                    FileManager.rb QuerySOSException.rb 
                                    Worker.rb XMLCommandConfigurator.rb 
                                    commands.xml 

Log message:
        QuerySOS, a ruby line command editor for QSOS Sheet ( initial commit )

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos.rb?cvsroot=qsos&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos/Command.rb?cvsroot=qsos&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos/CommandInterpreter.rb?cvsroot=qsos&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos/FileManager.rb?cvsroot=qsos&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos/QuerySOSException.rb?cvsroot=qsos&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos/Worker.rb?cvsroot=qsos&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos/XMLCommandConfigurator.rb?cvsroot=qsos&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/qsos/apps/querysos/src/querysos/commands.xml?cvsroot=qsos&rev=1.1

Patches:
Index: querysos.rb
===================================================================
RCS file: querysos.rb
diff -N querysos.rb
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos.rb 30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,37 @@
+#!/usr/bin/env ruby
+#require 'getoptlong'
+
+require 'querysos/CommandInterpreter'
+require 'querysos/XMLCommandConfigurator'
+require 'querysos/Worker'
+require 'querysos/FileManager'
+
+#options = GetoptLong.new(ARGV)
+#puts options.inspect
+
+puts "Welcome to QuerySOS 1.0 - A command line editor for QSOS Sheet"
+interpreter = QuerySOS::CommandInterpreter.new
+interpreter.configurator = QuerySOS::XMLCommandConfigurator.new
+w = QuerySOS::Worker.new
+w.filemanager= QuerySOS::FileManager.new
+interpreter.worker = w
+interpreter.init
+# improve by using getOptLong...
+# for the moment argument can only be a sheet to open
+if ARGV.size > 0 
+       file = ARGV[0]
+       if File.exists? file
+               interpreter.commands.each do |command|
+                       if command.id == "o"
+                               command.args = Array.new
+                               command.args.push file
+                               interpreter.current_cmd = command       
+                               interpreter.executeCurrentCmd
+                       end
+               end
+       else
+               puts "Can't open : " + file
+       end
+end
+# let's go...
+interpreter.run

Index: querysos/Command.rb
===================================================================
RCS file: querysos/Command.rb
diff -N querysos/Command.rb
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos/Command.rb 30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,38 @@
+#
+#      Created by RPELISSE
+#
+#      This class is a simple "bean", it contains all info related to a Command
+#
+#      
+#
+module QuerySOS
+
+class Command
+
+       attr_accessor   :id
+       attr_accessor   :name
+       attr_accessor   :doc
+       attr_accessor   :minArgs
+       attr_accessor   :maxArgs
+       attr_accessor   :args
+       attr_accessor   :code
+
+       #
+       #       This method allow to set any property of the bean. 
+       #       Use this method to set property, as it's ensure validtion
+       #
+       #               
+       def setMySelf(value,id)
+                if id.nil?
+                        throw QuerySOS::QuerySOSException.new("Can't set bean 
without a value (" + value + ").)")
+                end
+                if ! id.nil?
+                        if self.respond_to?(id)
+                                setter = self.method(id+"=")
+                                setter.call(value)
+                        end
+                end
+       end
+end
+
+end
\ No newline at end of file

Index: querysos/CommandInterpreter.rb
===================================================================
RCS file: querysos/CommandInterpreter.rb
diff -N querysos/CommandInterpreter.rb
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos/CommandInterpreter.rb      30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,125 @@
+#
+#      Created by RPELISSE
+#
+#      This interpreter understant the following command
+#              - s[how] 'node' ( displays all the data on one node)
+#              - b[rowse] 'node' ( display childs )
+#              - a[dd] 'nodeA' 'nodeB' ( add nodeA as a child of nodeB
+#              - r[emove] nodeA ( remove the node&childs from the tree, ask 
for confirmation)
+#              - s[ave]
+#              - n[ew] 
+#              - o[pen] ( open file, close current file if any)
+#              - q[uit] ( quit the app )
+#
+require 'rexml/document'
+require 'querysos/QuerySOSException'
+
+module QuerySOS
+
+class CommandInterpreter
+
+       attr_accessor   :configFile
+       attr_accessor   :configurator
+       attr_accessor   :commands
+       attr_accessor   :current_cmd
+       attr_accessor   :worker
+
+
+       def initialize
+               @configFile= nil
+               @current_cmd = QuerySOS::Command.new
+               @current_cmd.id = "" 
+       end 
+       # building command interpreter, loading knowncommand from config file
+       def init
+               # find the conf file
+               if @configFile.nil? 
+                       # TODO: do this in a better way !
+                       @configFile= "querysos/commands.xml"
+               end 
+               conf = File.new(@configFile,"r")
+               # Configuring the interpreter
+               if @configurator.nil?
+                       throw QuerySOS::QuerySOSException.new("No configurator 
setted !")
+               end
+               @configurator.configFilePath= @configFile
+               # load the command and define the prompt
+               @commands = @configurator.load
+               @prompt = @configurator.prompt
+               if @prompt.nil? || @prompt != "" 
+                       @prompt  = "> "
+               end
+               # Checking that FileManager dependency has been setted
+               if @worker.nil? || @worker.class != QuerySOS::Worker
+                       throw QuerySOS::QuerySOSException.new("No worker setted 
!")
+               end
+               # init the current_command
+               @current_cmd = QuerySOS::Command.new
+       end
+       
+       def executeCurrentCmd
+               @worker.execute( @current_cmd )
+       end
+
+       def run
+               while @current_cmd.nil? || @current_cmd.id != 'q'
+                       @current_cmd = cmd_line = nil
+                       print @prompt
+                       cmd_line = gets
+                       puts cmd_line
+                       if ! cmd_line.nil? && cmd_line != "" 
+                               @current_cmd = 
cmdIdentification(cmd_line.downcase.split)
+                               if ! @current_cmd.nil?
+                                       self.executeCurrentCmd
+                               end
+                       end
+               end 
+       end
+       public  :run
+
+       def cmdIdentification(tab)
+               # check arguments
+               if tab.nil? || tab.class != Array
+                       throw Exception.new("Invalid argument, argument 1 can't 
be null and should be an instance of Array")
+               end
+               # First item should be the command or one of it's abreviated 
version
+               @commands.each do |command|
+                       # start with the id...
+                       if ( tab[0].index(command.id) == 0 )
+                               # build the appropriate array
+                               command.args = tab[1,tab.length]
+                               return prepare(command)
+                       end
+               end
+       end
+
+       def prepare(command)
+               if command.nil? || command.class != QuerySOS::Command
+                       throw Exception.new("Invalid argument, argument 1 can't 
be null and should be an instance of Command")
+               end
+               invalid = false
+               # can the args's array be empty ?
+               if command.minArgs == 0 || command.maxArgs == 0 
+                       if command.args.size == 0
+                               return command
+                       else
+                               invalid = true
+                       end     
+               end
+               # validating arguments
+               if      command.args.length > command.maxArgs.to_i || 
+                       command.args.length < command.minArgs.to_i
+                       invalid = true
+               end
+               # dealing with invalid input
+               if invalid 
+                       puts "Error : Wrong numbers of arguments..."
+                       puts command.doc
+                       return nil
+               else
+                       return command
+               end
+       end
+
+end
+end

Index: querysos/FileManager.rb
===================================================================
RCS file: querysos/FileManager.rb
diff -N querysos/FileManager.rb
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos/FileManager.rb     30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,149 @@
+require 'rubygems'
+require_gem 'qsos'
+
+require 'querysos/QuerySOSException'
+
+module QuerySOS
+class FileManager
+
+       public
+       attr_accessor   :current_sheet
+       attr_reader     :filename
+       attr_accessor   :lib
+       attr_reader     :filelock
+
+       #
+       #       Basic constructor : simply load the qsos library.
+       #
+       #
+       def initialize
+               self.init
+               @lib = QSOS::Document.new               
+       end
+
+       def init
+               @filename = ""
+               @current_sheet = nil
+       end
+
+
+       def sheetValid?(filename)
+               # Is the filename nil ?
+               if filename.nil? 
+                       throw QuerySOSException.new("Filename provided is 
'nil'")
+               end
+               # Is the filename a proper String ?
+               if filename.class != String
+                       throw QuerySOSException.new("Filename provided must be 
a String,not a " + filename.class.to_s)
+               end
+               # Does the file already exists ?
+               if ! File.exists? filename 
+                       throw QuerySOSException.new("File : " + filename + " 
does not exists.") 
+               end
+               # TODO : Add more validation ( valid xml ? ...)
+               # Ok, valid file
+               return true             
+       end
+
+       #       
+       #       Creates new a qsos file. Check for the extention .qsos, and add 
it if missing
+       #
+       #       @param: filename, string containing the new filename ( plus 
possible path)
+       def new(filename)
+               if filename.nil?
+                       throw QuerySOSException.new("Argument 1 must not be nil 
!")
+               end
+               if filename.class != String
+                       throw QuerySOSException.new("Argument 1 expected is to 
be a String, not a " + filename.class.to_s)
+               end
+               if  File.exists? filename
+                       throw QuerySOSException.new("The file " + filename + " 
already exists.")
+               end     
+       end
+
+       #
+       #       Open the file passed as argument : check if the file exists, if 
its an url ,try to download it.
+       #       then, it put a lock on it. 
+       #
+       #       @exception : Raise an QuerySOSException if the file exists ( or 
has been successfully downloaded), but
+       #                       failed to open it.
+       def open(filename)
+               if self.sheetValid? filename
+                       @filename = filename
+                       # Create a lock on the file
+                       self.lock
+                       # attempt to load the file 
+                       begin
+                               @current_sheet = @lib.load filename
+                       rescue
+                               # load file, cleaning resources and object 
properties
+                               self.init
+                               self.unlock
+                               throw QuerySOS::QuerySOSException.new("Loading 
file '" + filename + "' has failed !")
+                       end
+               end
+       end
+       public :open
+
+       def lock
+               if @filelock.nil?
+                       @filelock = File.new(@filename,File::RDWR)
+                       if ! @filelock.flock(File::LOCK_EX)
+                               throw QuerySOS::QuerySOSException("File " + 
@filename + " already locked")
+                       end
+               else
+                       throw QuerySOS::QuerySOSException.new("Trying to lock a 
file without releasing this file :" + @firelock.pathname + @firelock.basename + 
".")
+               end
+       end
+       
+       def unlock
+               if ! @filelock.nil?
+                       if ! @filelock.flock(File::LOCK_UN)
+                               throw QuerySOS::QuerySOSException("Trouble 
unlocking file: " + @firelock.basename)
+                       end
+                       @filelock = nil
+               else
+                       throw QuerySOS::QuerySOSException.new("Trying to unlock 
a file, without previous lock.")
+               end
+       end
+
+
+       #
+       #       Close the current file : unlock it, and reset itself.
+       #
+       #
+       def close
+               if self.loaded?
+                       # TODO a file is loaded, try to unlock it...
+                       self.init
+                       self.unlock
+               else
+                       throw QuerySOSException.new("Try to close file as no 
file was loaded.")
+               end
+       end
+       public :close
+
+       #
+       # check if a file is already loaded. Return false if no file is loaded, 
otherwise true
+       #
+       def loaded?
+               ! @current_sheet.nil? && ! @filename.nil? && @filename != ""    
+       end
+       
+
+
+       def save
+               if self.loaded?
+                       lib.write @filename
+               else
+                       throw QuerySOS::QuerySOSException.new("Trying to save 
while no file opened")
+               end
+       end
+       public :save
+
+       def getSheet(path)
+               # TODO: check for url, download in case of url
+       end
+       private :getSheet
+end
+end
\ No newline at end of file

Index: querysos/QuerySOSException.rb
===================================================================
RCS file: querysos/QuerySOSException.rb
diff -N querysos/QuerySOSException.rb
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos/QuerySOSException.rb       30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,5 @@
+module QuerySOS
+class QuerySOSException < Exception
+
+end
+end
\ No newline at end of file

Index: querysos/Worker.rb
===================================================================
RCS file: querysos/Worker.rb
diff -N querysos/Worker.rb
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos/Worker.rb  30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,82 @@
+#
+#      Created by RPELISSE
+#
+#
+#
+#
+#
+module QuerySOS
+
+require 'querysos/Command'
+
+class Worker
+       
+       attr_accessor   :filemanager
+
+       def execute(command)
+               # Validating the argument
+               if command.nil? || command.class != QuerySOS::Command
+                       throw Exception.new("Invalid argument, argument 1 can't 
be nil and must be an instance of Command")
+               end
+               # 
+               if command.id == "q"
+                       if ! @filemanager.current_sheet.nil? 
+                               @filemanager.close
+                       end
+                       puts "Bye..."
+                       exit
+               elsif command.id == "o"
+                       file = command.args[0]
+                       puts "Opening : " + file
+                       if ! @filemanager.current_sheet.nil?
+                               @filemanager.close
+                       end
+                       begin
+                               @filemanager.open file
+                       rescue
+                               puts $!.message
+                               return
+                       end
+                       # displaying some basic info about the opened sheet
+                       puts "Product:" + @filemanager.current_sheet.getAppname
+                       puts "Lang:"    + @filemanager.current_sheet.getLanguage
+                       puts "Release:" + @filemanager.current_sheet.getRelease
+                       puts "Website:" + @filemanager.current_sheet.getUrl
+                       puts "Demo:"    + @filemanager.current_sheet.getDemoUrl
+                       puts ""
+               elsif command.id == "n"
+                       puts "Creating a new file..."
+                       @filemanager.new command.args[0]
+               elsif command.id == "w"
+                       puts "saving..."
+                       if ! @filemanager.current_sheet.nil?
+                               @filemanager.save
+                       else
+                               puts "No file opened : abort saving."
+                       end
+               elsif command.id == "b"
+                       puts "Browsing node " + command.args[0].to_s + "..."
+                       if @filemanager.current_sheet
+                               @filemanager.current_sheet.
+                       else
+                               puts "No sheet open !"
+                       end
+               elsif command.id == "s"
+                       puts "Displaying data on node " + command.args[0].to_s 
+ "..."
+                       if ! @filemanager.current_sheet.nil?
+                               node = command.args[0].to_s
+                               puts "Field: " + node 
+#                              puts 
@filemanager.current_sheet.getDescByName(node,0)
+#                              puts 
@filemanager.current_sheet.getDescByName(node,1)
+#                              puts 
@filemanager.current_sheet.getDescByName(node,2)
+                               puts "Comment: " + 
@filemanager.current_sheet.getCommentByName(node)
+                               puts "Score: " + 
@filemanager.current_sheet.getScoreByName(node)
+                       else
+                               puts "No sheet open !"
+                       end
+               end
+
+
+       end
+end
+end
\ No newline at end of file

Index: querysos/XMLCommandConfigurator.rb
===================================================================
RCS file: querysos/XMLCommandConfigurator.rb
diff -N querysos/XMLCommandConfigurator.rb
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos/XMLCommandConfigurator.rb  30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,97 @@
+#
+#      Created by RPELISSE
+#
+#
+#
+#
+#
+module QuerySOS
+require 'rexml/document'
+require 'querysos/Command'
+
+class XMLCommandConfigurator
+
+       attr_accessor   :configFilePath
+       attr_accessor   :prompt
+       
+       def initialize
+               @DOCUMENTATION = "Documentation"
+               @ARGS = "args"
+               @PROMPT = "prompt"
+
+               @ID = "id"
+               @NAME = "name"
+               @MIN = "min"
+               @MAX = "max"
+       end
+
+       #
+       #       Main method, allow to load the configuration of the command 
interpreter from the XML file.
+       #
+       #       @return: an instance of Array that containes each commands
+       def load
+               if @configFilePath.nil? || ! File.exists?(@configFilePath)
+                       throw QuerySOS::QuerySOSException.new("Missing 
configuration file for the command interpreter")
+               end
+               file = File.new @configFilePath 
+                doc = REXML::Document.new file
+               return getCommands(doc.root)
+       end
+       #
+       #       Setter for configFilePath. Check that the argument is a not nil 
and it's an instance of String 
+       #       
+       #       @param : file, configuration filename ( may include  the path)
+       #
+       def configFilePath=(file)
+               if file.nil? || file.class != String
+                       throw QuerySOS::QuerySOSException.new("Invalid 
configuration file for the command interpreter: " + file.to_s)
+               end
+               @configFilePath=file
+       end
+
+       def getCommands(root)
+               # validating argument 
+               if root.nil? || root.class != REXML::Element 
+                       throw QuerySOS::QuerySOSException("Invalid argument, 
argument 1 must be an instance of REXML::Element")
+               end
+               # getting the prompt
+               if ! root.attribute(@PROMPT).nil?
+                       @prompt = root.attribute(@PROMPT).value
+               end
+               # getting all the known commands
+               commands = Array.new
+               if root.has_elements?
+                       root.elements.each do |command|
+                               c = QuerySOS::Command.new
+                               c.setMySelf(command.attribute(@ID).value,@ID)
+                               
c.setMySelf(command.attribute(@NAME).value,@NAME)
+                               if command.has_elements?
+                                       command.elements.each do |property|
+                                               extractCommandChilds(c,property)
+                                       end
+                               end
+                               commands.push c
+                       end
+               end             
+               return commands
+       end
+
+       def extractCommandChilds(c,property)
+               # extracting documentation ( if any)
+               if property.name == @DOCUMENTATION && property.has_text?
+                       c.doc = property.get_text       
+               end                             
+               # extracting Args property
+               if property.name == @ARGS 
+                       c.minArgs = property.attribute(@MIN).value
+                       c.maxArgs = property.attribute(@MAX).value
+               end
+               # extracting script code !
+               if property.name == @SCRIPT && property.has_text?
+                       c.code = property.get_text
+               end
+       end
+
+end
+
+end

Index: querysos/commands.xml
===================================================================
RCS file: querysos/commands.xml
diff -N querysos/commands.xml
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ querysos/commands.xml       30 Aug 2006 12:28:36 -0000      1.1
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+     id : abrieved command name , ex : n[ew], so 'n' is the id
+     name : full name, same example : 'new'
+     <command  id=""
+               name="">
+            <documentation>
+                    this tag contents the documentation for the command.
+            </documentation>
+            min: positive integer, the min number of args [0,N]
+            max: positive integer, the max number of args [0,N]
+            note : min <= max, unless an exception is thrown
+            <args      min=""
+                       max="">
+                    Maybe more stuff to validate the command ?
+            </args>
+            <script>
+               ruby code including here to get the work done !
+            </script>
+     </command>
+-->
+<querysos-interpreter prompt="QuerySOS> ">
+       <command        id="o"
+                       name="open">
+               <documentation>usage: type "open", no args 
needed.</documentation>
+               <args   min="1"
+                       max="1">
+               </args>
+               <script>
+                       puts "bye..."
+                       exit
+               </script>
+       </command>
+       <command        id="q"
+                       name="quit">
+               <documentation>usage : type "quit", no args need</documentation>
+               <args   min="0"
+                       max="0">
+               </args>
+               <script>
+                       puts "bye..."
+                       exit
+               </script>
+       </command>      
+       <command        id="s"
+                       name="show">
+               <documentation>usage : type "show line", one args needed ( a 
valid node)</documentation>
+               <args   min="1"
+                       max="1">
+               </args>
+               <script/>
+       </command>      
+       <command        id="n"
+                       name="new">
+               <documentation>usage : type "new filename", one args needed ( a 
valid filename)</documentation>
+               <args   min="1"
+                       max="1">
+               </args>
+               <script/>
+       </command>      
+       
+       <command        id="w"
+                       name="write">
+               <documentation>usage : type "write", no args 
needed.</documentation>
+               <args   min="0"
+                       max="0">
+               </args>
+               <script/>
+       </command>      
+       #               - b[rowse] 'node' ( display childs )
+       #               - a[dd] 'nodeA' 'nodeB' ( add nodeA as a child of nodeB
+       #               - r[emove] nodeA 
+
+       
+       <command        id="b"
+                       name="browser">
+               <documentation>usage : type "browse node", one args needed ( 
the node to browse).</documentation>
+               <args   min="1"
+                       max="1">
+               </args>
+               <script/>
+       </command>      
+       
+       <command        id="a"
+                       name="add">
+               <documentation>usage : type "add nodeToAdd 
parentNode".</documentation>
+               <args   min="0" 
+                       max="0">
+               </args>
+               <script/>
+       </command>      
+</querysos-interpreter>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]