All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zeidon.zruby.2.0.1.source-code.sinatra_framework.rb Maven / Gradle / Ivy

require 'rubygems'
require 'sinatra'
require 'haml'
require 'pp'
require 'fastercsv'
require "nokogiri"
require 'pathname'

load "zeidon.rb"
include_class 'com.quinsoft.zeidon.CursorPosition'
include_class 'java.util.jar.JarFile'

puts "Loaded sinatra_framework.rb from #{__FILE__}"
enable :sessions
set :port, ENV['SINATRA_PORT'].to_i || 4567

# ===== Generic methods =====

set :domain_mappings, {}

# This sets up a mapping between an entity name and the LOD that is used to retrieve a list.
set :lod_for_entity_list, {}

# The list of loddef's for each application.
@@app_loddef_list={}

def domain_mapping( domain_name, mapper )
  settings.domain_mappings[domain_name] = mapper
end

def lod_for_entity_list( lod_name, entity_name )
  settings.lod_for_entity_list[entity_name] = lod_name
end

# Retrieves the Zeidon task by task ID and returns a Ruby
# Task wrapper.
def get_task( args = { :create => true } )
  app_name = params[:application]
  application = Zeidon.get_object_engine.get_app app_name
  task_id = session[:zeidon_task_id]
  jtask = Zeidon.get_object_engine.getTaskById( task_id )
  if jtask.nil?
    return unless args[:create]
    raise "Must specify app name for :create" unless app_name
    task = Zeidon.get_object_engine.get_app( app_name ).create_task
    add_task_to_session task
    return application, task
  end

  app = Zeidon.get_object_engine.get_app( app_name )
  return application, task = Zeidon::Task.new( app, jtask )
end

def add_task_to_session( task )
  task_id = task.getTaskId
  session[:zeidon_task_id] = task_id
end

def input_field_for_attrib( attrib, args = {} )
  html = ''
  name="input[#{attrib.entity_name}][#{attrib.name}]"

  # Hidden attributes just get included as hidden fields.
  if attrib.hidden?
    return <<-code
    
code
  end

  jdomain = attrib.getDomain
  domain_type = jdomain.getDomainType.to_s
  domain_name = jdomain.getName

  # Check to see if there is a app-specific domain handler.
  if settings.domain_mappings[domain_name]
    return settings.domain_mappings[domain_name].input_field_for_attrib( attrib, name, args )
  end

  # Is this domain a table domain?  If so, then create a combo-box.
  if domain_type == 'TABLE'
    @list = jdomain.getTableEntries( @task.jtask, nil )
    puts "list for #{jdomain.getName} = #{@list}"
    return haml <<-code
%td
  %select{:name => '#{name}'}
    - @list.each do |entry|
      %option{:selected => (entry.getInternalValue == "#{attrib.to_s}") }
        = entry.getExternalValue
code
  end

  # If size is > 200 then use a text area.
  if attrib.getLength > 200
    str = attrib.to_s || ""
    lines = str.lines.count + 5
    lines = 20 if lines > 20
    return <<-code



code
  end

  type = 'text'
  html << <<-code
    
    \n"
  return html
end

def input_fields_for_entity( entity, args = {} )
#  puts "Entity methods = #{entity.methods.sort.join("\n").to_s}"
  args = args.clone # So we can add to the hash without changing original one.
  html = "\n"
  entity.attributes.each do |attrib|
    html << "\n\n" if ! attrib.hidden?
    html << input_field_for_attrib( attrib, args )
    html << "\n\n" if ! attrib.hidden?
  end
  html << "
#{attrib.name}:
\n" return html end def list_entities( top_entity, args = {} ) args = args.clone # So we can add to the hash without changing original one. # Find children of 'entity' that have a max cardinality of 1. We will # display them all in one row. entity_list = [ top_entity ] jtop_view_entity = top_entity.getEntityDef if @command != 'list' # Only show children if we're aren't listing roots. jtop_view_entity.getChildren.each do | jchildentity | entity_list << @view.cursor( jchildentity.name ) if jchildentity.getMaxCardinality <= 1 end end # Add column headers. html = "\n" html << "" if jtop_view_entity.getAutoSeq != nil puts "class = #{top_entity.class}" entity_list.each do |entity| puts "name = #{entity.name}" html << "" if entity != top_entity entity.entityDef.attributes.each do |attrib| next if attrib.hidden? html << "" end end html << "\n" url_param = "&entity=#{top_entity.name}" url_param << "&viewname=#{@view_name}" if args[:viewname] top_entity.each do # For each top-level entity instance... html << "" links = [] # We'll create a list of edit links and then concat them at the end. if args[:include_only] # If true, then we're displaying a list of entities to include links << "Select" else links << "Edit" if jtop_view_entity.isUpdate links << "Exclude" if jtop_view_entity.isExclude links << "Delete" if jtop_view_entity.isDelete end html << "" # Add move up/down links. if jtop_view_entity.getAutoSeq != nil html << "" end entity_list.each do |entity| html << "" if entity != top_entity entity.entityDef.attributes.each do |attrib_def| next if attrib_def.hidden? if entity.isNull or entity.getAttribute( attrib_def ).is_null? html << "\n" else value = entity.getAttribute( attrib_def ).getString if value && value.length > 100 value = /^([^\n]*)/.match(value)[1][0..100] + "..." end html << "\n" end end end html << "\n" end html << "
#{entity.name}-->#{attrib.name}
" << links.join("
") << "
" html << "Move Up
" html << "Move Down" html << "
#{value}
\n" if ! args[:include_only] if top_entity.getEntityDef.isCreate html += haml <<-code %p %form{ :action => url('/#{@application}/new/#{@loddef}'), :method => 'get', :enctype => 'multipart/form-data', :name => 'New_#{top_entity.name}' } %input{:type => "hidden", :name => "viewname", :value => "#{@view_name}"} %input{:type => "hidden", :name => "entity", :value => "#{top_entity.name}"} %input{:type => "submit", :value => "New #{top_entity.name}", :class => "button" } code elsif top_entity.getEntityDef.isInclude html += haml <<-code %p %form{ :action => url('/#{@application}/include/#{@loddef}'), :method => 'get', :enctype => 'multipart/form-data', :name => 'Include_#{top_entity.name}' } %input{:type => "hidden", :name => "viewname", :value => "#{@view_name}"} %input{:type => "hidden", :name => "entity", :value => "#{top_entity.name}"} %input{:type => "submit", :value => "Include #{top_entity.name}", :class => "button" } code end end return html end def activate_for_edit( args = {} ) raise "ID not specified for edit" if params[:id].nil? jloddef = @application.getLodDef( @task.jtask, @loddef ) jroot = jloddef.getRoot jkey = jroot.getKeys[0] # We're assuming there is one and only one key. @view = @task.activate @loddef, jkey.getName => params[:id] @view_name = "Edit_#{params[:loddef]}" @view.set_name( @view_name ) return @view_name end def get_loddef_list app_name puts "Getting loddef_list from #{@@app_loddef_list}" return @@app_loddef_list[ app_name ] if @@app_loddef_list[ app_name ] @@app_loddef_list[ app_name ] = [] puts "classpath=" $CLASSPATH.each{|cp| puts "-> #{cp}"} oe = Zeidon.get_object_engine bindir = oe.get_app( app_name ).getObjectDir puts "bindir = #{bindir}" regex = /^#{bindir}.*\.(XOD|xod)$/ loader = oe.getClassLoader( "" ) urls = loader.getURLs urls.each do |url| begin jar = JarFile.new( url.getPath ) jar.entries.each do |entry| @@app_loddef_list[ app_name ] << File.basename( entry.toString, "." + $1) if entry.toString =~ regex end rescue puts "Error trying to load jar file #{url.getPath} protocol #{url.getProtocol}" end end @@app_loddef_list[ app_name ].sort! end # ===== Helper methods ===== helpers do def top_links html = "" # Add link to list of all LodDefs html << "" html << "" # Add link to list of root-level instances. if @loddef html << "" html << "" end # If we're editing/viewing a loddef, then check to see if we need a "to root" link. if @loddef and @entity jloddef = @application.getLodDef( @task.jtask, @loddef ) loddef_root = jloddef.getRoot.getName if loddef_root != @entity html << "" html << "" end jentityDef = jloddef.getEntityDef( @entity ) jparent = jentityDef.getParent if ! jparent.nil? and jparent.getName.to_s != loddef_root.to_s puts "jparent=#{jparent.getName}\nentity=#{@entity}" html << "" html << "" end end html << "" html << "
|#{@application} List|#{@loddef} Root List|Top of #{@loddef}|Up to #{jparent.getName}|

" end def bottom_links puts "bottom_links" html = <<-code

Start Browser
code return html end def display_messages return "" if @messages.nil? || @messages.length == 0 return haml <<-code %table - @messages.each do |msg| %tr %td %font{:color => "red"} = msg %br code end def top_layout return top_links + display_messages end end # ===== Route methods ===== get '/startbrowser' do application = Zeidon.get_object_engine.startBrowser end # This method is called before the route methods are called and it sets up some standard # member variables. def setup_environment puts "===== setup_environment ======" puts Time.now pp params pp session # Set some standard variables. @command = params[:cmd] @loddef = params[:loddef] @view_name = params[:viewname] @entity = params[:entity] @application, @task = get_task @view = @task.get_view( @view_name ) if @view_name puts "view = #{@view}" @messages = session[:messages] session[:messages] = [] if @loddef jloddef = @application.getLodDef( @task.jtask, @loddef ) # Default entity to root of loddef if @entity.nil? @entity = jloddef.getRoot.getName @parent_entity = @entity @root_entity = @entity else jparent = jloddef.getEntityDef( @entity ).getParent @parent_entity = jparent.nil? ? @entity : jparent.getName @root_entity = jloddef.getRoot.getName end end end before '/:application/:cmd/:loddef' do setup_environment end get '/:application/list' do setup_environment @command = 'list' haml <<-code %title #{@application} List %h2 LodDef list for #{@application} = top_layout %table - get_loddef_list( @application.to_s ).each do |loddef| %tr %td %a{:href => url("/#{@application}/list/" + loddef )} = "List" = loddef = bottom_links code end get '/:application/list/:loddef' do @view = @task.activate @loddef, root_only_multiple:> true @view.setName @loddef + "_list" return haml <<-code %title #{@loddef} List %h2 #{@loddef} List = top_layout %table %tbody = list_entities( @view.cursor( "#{@entity}" ), :root_list => true ) code end # Create a new empty entity and redirect to edit it. get '/:application/new/:loddef' do # If the view doesn't exist create the OI. if @view.nil? @view = @task.activate_empty_object_instance @loddef @view_name = "New_#{@loddef}" @view.set_name( @view_name ) end @view.cursor( @entity ).createEntity u = url("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}&entity=#{@entity}") redirect u end get '/:application/edit/:loddef' do # If there is no named view then activate one using the URL params. activate_for_edit if @view.nil? cursor = @view.cursor( @entity ) key = cursor.get_key.getName cursor.setFirst(key, params[:id] ) # If the entity being edited is not the root then we won't have # a save button but an "accept". @save_button_text = ( @entity == @root_entity ) ? "Save" : "Accept" return haml <<-code %title #{@application} - Edit #{@loddef}.#{@entity} %h2 Edit #{@entity} = top_layout %form{ :action => url('/#{@application}/save/#{@loddef}'), :method => "post", :enctype => 'multipart/form-data', :name => 'New_#{@entity}'} %fieldset %input{:type => "hidden", :name => "viewname", :value => "#{@view_name}"} %input{:type => "hidden", :name => "entity", :value => "#{@entity}"} = input_fields_for_entity( @view.cursor( @entity ) ) %input{:type => "submit", :name => "save", :value => "#{@save_button_text}", :class => "button"} %input{:type => "submit", :name => "duplicate", :value => "Duplicate", :class => "button"} - @view.cursor( @entity ).each_child do |child_cursor| - cname = child_cursor.name %p %table{:border=>"1"} %tr %td= cname %tr %td= list_entities( child_cursor, :viewname => "#{@view_name}" ) code end get '/:application/delete/:loddef' do # If there is no named view then we are deleting the entire OI. if ! @view.nil? # We're deleting just an entity in the existing OI. puts "Deleting child entity" cursor = @view.cursor( @entity ) key = cursor.get_key.getName cursor.setFirst(key, params[:id] ) instance = cursor.getEntityInstance puts "Deleting #{instance}" session[:messages] << "Entity #{instance} has been deleted and will be committed when OI is saved." cursor.deleteEntity return redirect to("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}&entity=#{@parent_entity}") end return "Not supported yet" end get '/:application/exclude/:loddef' do return "No view found" if @view.nil? # We're deleting just an entity in the existing OI. puts "Excluding child entity" cursor = @view.cursor( @entity ) key = cursor.get_key.getName cursor.setFirst(key, params[:id] ) instance = cursor.getEntityInstance puts "Excluding #{instance}" session[:messages] << "Entity #{instance} has been excluded and will be committed when OI is saved." cursor.excludeEntity return redirect to("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}&entity=#{@parent_entity}") end get '/:application/moveup/:loddef' do puts "Moving child entity UP" cursor = @view.cursor( @entity ) key = cursor.get_key.getName cursor.setFirst(key, params[:id] ) temp = @view.new_view if temp.cursor( @entity ).setPrev == CursorResult::SET instance = cursor.getEntityInstance puts "Moving #{temp.cursor( @entity ).getEntityInstance} before #{instance}" temp.cursor( @entity ).moveSubobject( CursorPosition::PREV, instance ) else puts "Instance is first instance so nothing to move" end return redirect to("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}&entity=#{@parent_entity}") end get '/:application/movedown/:loddef' do puts "Moving child entity DOWN" cursor = @view.cursor( @entity ) key = cursor.get_key.getName cursor.setFirst(key, params[:id] ) temp = @view.new_view if temp.cursor( @entity ).setNext == CursorResult::SET instance = cursor.getEntityInstance puts "Moving up: #{instance}" cursor.moveSubobject( CursorPosition::NEXT, temp.cursor( @entity ).getEntityInstance ) else puts "Instance is last instance so nothing to move" end return redirect to("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}&entity=#{@parent_entity}") end post '/:application/save/:loddef' do raise ":viewname not specified" if @view_name.nil? # If 'duplicate' param is specified then we really want to duplicate the current # OI and send the user off to edit it. if ! params[ 'duplicate' ].nil? puts "Duplicating OI" session[:messages] << "OI Duplicated. Edit below." new_view = @view.duplicateOi new_view.setName @view_name return redirect to("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}") end input = params[:input] input.each_pair do |entity_name, values| cursor = @view.cursor( entity_name ) values.each_pair do |attrib_name, value| attrib = cursor.get_attribute( attrib_name ) attrib.setValue( value ) unless attrib.hidden? || attrib.isGenKey || ! attrib.isUpdate end end next_view_entity = "" if @entity == @root_entity @view.commit session[:messages] << "#{@loddef} OI saved." else session[:messages] << "#{@loddef}.#{@entity} updated." next_view_entity = "&entity=#{@parent_entity}" end return redirect to("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}#{next_view_entity}") end def activate_include_source list_view_name = "#{@entity}_List" # We can't cache the view list until we drop the cache if an # entity in the cache is updated/created/deleted. # @include_source = @task.get_view list_view_name # return if @include_source lod_name = settings.lod_for_entity_list[ @entity ] || @entity @include_source = @task.activate lod_name, root_only: true @include_source.set_name( list_view_name ) @select_entity = @include_source.getLodDef.getRoot.name end get '/:application/include/:loddef' do activate_include_source list_entities @include_source.cursor( @select_entity ), :include_only => true, :viewname => @view_name end # User selected an entity to be included. get '/:application/select/:loddef' do @select_entity = settings.lod_for_entity_list[ @entity ] || @entity list_view_name = "#{@entity}_List" @include_source = @task.get_view( list_view_name ) cursor = @include_source.cursor( @select_entity ) key = cursor.get_key.getName cursor.setFirst(key, params[:id] ) @view.cursor( @entity ).include_subobject( cursor ) return redirect to("/#{@application}/edit/#{@loddef}?viewname=#{@view_name}&entity=#{@parent_entity}") end get '/' do puts "Listing applications" haml <<-code %title Applications List %h2 List of Available Applications %table - Zeidon.get_object_engine.applications.each do |application| - if application != "ZeidonSystem" %tr %td %a{:href => url("/" + application + "/list" )} = "View" = application = bottom_links code end #============================================================== # Activate/Commit functions #============================================================== post '/:application/activate/:loddef' do end




© 2015 - 2025 Weber Informatics LLC | Privacy Policy