######################################################################
##
## Copyright (c) LIFL 1999
## The GOODE team of the LIFL
## University of Lille, France
## All rights reserved
##
## The CorbaWeb script associated to the OMG IDL CORBA::Object interface.
##
######################################################################

# Each action must have two arguments: the first one refers to the
# current CORBA object and the second one refers to a CorbaWeb
# ActionContext instance.

######################################################################
## This action generates the specific view of a CORBA::Object.
######################################################################

proc view(object, ac)
{
  # by default, the 'view' action is equivalent to the 'interface' action.
  # can be specialized by action scripts named as OMG IDL interfaces.
  interface(object, ac)
}

######################################################################
## This action generates forms to execute CORBA::Object operations.
######################################################################

proc interface(object, ac)
{
  # generates all forms for the object and all its interfaces. 
  ac.all_forms(object, true)
}

######################################################################
## This action executes an operation on a CORBA::Object.
######################################################################

proc invoke(object, ac)
{
  # obtains the operation field.
  op_name = ac.getString("operation")

  # generates the operation name.
  ac.h1("Invokes the operation " + op_name)

  # searches the object interface into the IFR cache.
  interface = ac.getIFRcache().searchByType(object._type)

  # searches the CORBA::OperationDescription.
  op_descr = interface.searchOperationDescription(op_name)

  # obtains parameters.
  parameters = op_descr.parameters

  # will contain out and inout parameters.
  holders = {}

  # creates one string containing the invocation parameters
  # which will be evaluated.
  se = ""

  # iterates on all parameters.
  for p in parameters {
    # converts CORBA.String to string!
    name = p.name + ""
    se = se + ','
    if (p.mode == CORBA.ParameterMode.PARAM_IN) {
      v = ac.get_value(name, p.type)
      if (v._type == string) 
        se = se + '\"' + v + '\"'
      else
        se = se + v._toString()
    } else if (p.mode == CORBA.ParameterMode.PARAM_OUT) {
      holders[name] = Holder()
      se = se + "holders[\"" + name + "\"]"
    } else {
      holders[name] = Holder(ac.get_value(name, p.type))
      se = se + "holders[\"" + name + "\"]"
    }
  }

  if (se.length == 0) {
    se = "object." + op_name + "()"
  } else {
    se = "object." + op_name + '(' + se.substring(1) + ')'
  }

  ac.p()
  ac.println("Invokes " + se)

  try {
    # evaluates the invocation.
    result = eval(se)

    # displays the result.
    ac.p()
    ac.println("Result= ")
    ac.print_value(result)
    ac.p()

    # displays out and inout parameters.
    for h in holders.keys {
      ac.print(h + "= ")
      ac.print_value(holders[h].value)
      ac.p()
    }

  # if the invoked operation raises a CORBA exception
  } catch(CORBA.Exception e) {
    ac.p()

    ac.print("Raised exception: ")
    ac.print(e)
    ac.p()

  # if the evaluation raises a BadTypeCoerce
  # then these is an invalid parameter value!
  } catch(e) {
    ac.p()

    ac.println( "Error: Invalid parameter!")
    ac.println(e)
    ac.br()

    # iterates on all parameters.
    for p in parameters {
      # displays each parameter and the user input value.
      if (p.mode == CORBA.ParameterMode.PARAM_OUT)
        ac.println( name + ": an OUT parameter")
      else
        ac.println( name + ": " + ac.getString(name))
      ac.br()
     }
  }

  # does another action if needed.
  try {
    # obtains what must be done after invocation.
    after_invoke = ac.getString("after_invoke")
  } catch (e) {
    # if not found then do nothing!
    return
  }
  # apply the after_invoke action.
  ac.apply(after_invoke, object)
}

######################################################################
## This action gets an attribute of a CORBA::Object.
######################################################################

proc get(object, ac)
{
  # obtains the attribute field.
  attr_name = ac.getString("attribute")

  # generates the attribute name.  
  ac.h1("Gets the attribute " + attr_name)

  # searches the object interface into the IFR cache.
  interface = ac.getIFRcache().searchByType(object._type)

  # searches the CORBA::AttributeDescription.
  attr_descr = interface.searchAttributeDescription(attr_name)

  ac.println ( "object." + attr_name + " = ")

  # gets the attribute.
  result = eval("object." + attr_name)

  # displays it.
  ac.print_value ( result )

  # does another action if needed.
  try {
    # obtains what must be done after getting.
    after_get = ac.getString("after_get")
  } catch (e) {
    # if not found then do nothing!
    return
  }
  # apply the after_get action.
  ac.apply(after_get, object)
}

######################################################################
## This action sets a CORBA::Object attribute.
######################################################################

proc set(object, ac)
{
  # obtains the attribute field.
  attr_name = ac.getString("attribute")

  # generates the attribute name.  
  ac.h1("Sets the attribute " + attr_name)

  # searches the object interface into the IFR cache.
  interface = ac.getIFRcache().searchByType(object._type)

  # searches the CORBA::AttributeDescription.
  attr_descr = interface.searchAttributeDescription(attr_name)

  # creates a string representing the attribute setting.
  v = ac.get_value("value", attr_descr.type)
  if (v._type == string) 
    se = "object." + attr_name + " = \"" + v + '\"'
  else
    se = "object." + attr_name + " = " + v._toString()

  # prints it for debugging!
  ac.println(se)

  try {
    # evaluates the string.
    eval (se)

  # if the invoked operation raises a CORBA exception
  } catch(CORBA.Exception e) {
    ac.p()
    ac.print("Raised exception: ")
    ac.print(e)
    ac.p()

  # if the evaluation raises a BadTypeCoerce
  # then these is an invalid parameter value!
  } catch(e) {
    ac.p()

    ac.println( "Error: Invalid parameter!")
    ac.p()
  }

  # does another action if needed.
  try {
    # obtains what must be done after setting.
    after_set = ac.getString("after_set")
  } catch (e) {
    # if not found then do nothing!
    return
  }
  # apply the after_set action.
  ac.apply(after_set, object)
}

######################################################################
## Declaration of these actions into the CorbaWeb ActionRepository.
######################################################################

declareAction("view", view, "Views a CORBA Object")
declareAction("interface", interface, "Automatic HTML Forms Generation")
declareAction("invoke", invoke, "Invokes an operation")
declareAction("get", get, "Gets an attribute")
declareAction("set", set, "Sets an attribute")

######################################################################
# end of file 'CorbaWeb/actions/CORBA_Object'
######################################################################
