///
/// file   : service.tks
/// author : Bastian Spiegel <bs@tkscript.de>
/// descr. : example file a RIO service configuration.
/// license: 
/// Copyright 2005 The Bali Project. All rights reserved.
/// 
/// Redistribution and use in source and binary forms, with or without modification, are permitted provided that 
/// the following conditions are met:
/// 
///    1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 
///       following disclaimer.
///    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 
///       the following disclaimer in the documentation and/or other materials provided with the distribution.
/// 
/// THIS SOFTWARE IS PROVIDED BY THE BALI PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
/// BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
/// IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
/// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
/// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
/// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/// 
/// The views and conclusions contained in the software and documentation are those of the authors and should not be
/// interpreted as representing official policies, either expressed or implied, of the Bali Project.
/// 
/// created: 27Aug2005
/// changed: 11Sep2005 / 12Sep2005
///
///

module "MDefaultService";


class TestVO {
   String key;
   String value;
 }
 
 
TestVO vo;
 
class TestDAO : RIO_Namespace {
   getName { return "TestDAO"; }
   getProcedures { return 
                      "ap 10"
                      " create 2 key s value s : TestVO"
                      " find 1 key s : TestVO"
                      " echoBooleanArray 1 array ab : ab"
                      " echoIntArray 1 array ai : ai"
                      " echoLongArray 1 array al : al"
                      " echoFloatArray 1 array af : af"
                      " echoDoubleArray 1 array ad : ad"
                      " echoStringArray 1 array as : as"
                      " echoClassArray 1 array aTestVO : aTestVO"
                      " echoHashArray 1 array ah : ah"
                      ; 
   }

   create(String key, value) { vo.key=key; vo.value=value; return vo; }

   echoBooleanArray(Boolean array[]):ObjectArray {
      print "echoBooleanArray: array = "+#(array)+" numElements="+array.numElements;
      Boolean b;
      int i=0;
      foreach b in array
      {
         print "[...] TestDAO::echoBooleanArray: Boolean["+i+"] = " + b;
         i++;
      }
      return deref array;
   }

   echoIntArray(IntArray array):IntArray {
      print "echoIntArray: array = "+#(array)+" numElements="+array.numElements;
      int v;
      int i=0;
      foreach v in array
      {
         print "[...] TestDAO::echoIntArray: IntArray["+i+"] = " + v;
         i++;
      }
      return deref array;
   }

   echoLongArray(Long array[]):ObjectArray {
      print "echoLongArray: array = "+#(array)+" numElements="+array.numElements;
      Long l;
      int i=0;
      foreach l in array
      {
         print "[...] TestDAO::echoLongArray: Long["+i+"] = " + l;
         i++;
      }
      return deref array;
   }

   echoStringArray(String array[]):StringArray {
      print "echoStringArray: array = "+#(array)+" numElements="+array.numElements;
      String s;
      int i=0;
      foreach s in array
      {
         print "[...] TestDAO::echoStringArray: Long["+i+"] = \"" + s + "\"";
         i++;
      }
      return deref array;
   }

   echoFloatArray(FloatArray array):FloatArray {
      print "echoFloatArray: array = "+#(array)+" numElements="+array.numElements;
      int v;
      int i=0;
      foreach v in array
      {
         print "[...] TestDAO::echoFloatArray: FloatArray["+i+"] = " + v;
         i++;
      }
      return deref array;
   }

   echoDoubleArray(Double array[]):ObjectArray {
      print "echoDoubleArray: array = "+#(array)+" numElements="+array.numElements;
      Double d;
      int i=0;
      foreach d in array
      {
         print "[...] TestDAO::echoDoubleArray: Double["+i+"] = " + d;
         i++;
      }
      return deref array;
   }

   echoClassArray(TestVO array[]):ClassArray {
      TestVO c;
      int i=0;
      foreach c in array
      {
         print "[...] TestDAO::echoClassArray: TestVO["+i+"] = (key=\""+c.key+"\" value=\""+c.value+"\").";
         i++;
      }
      return deref array;
   }

   echoHashArray(HashTable array[]):ObjectArray {
      HashTable c;
      int i=0;
      foreach c in array
      {
         print "[...] TestDAO::echoHashArray: array["+i+"] = "+#(c)+".";
         i++;
      }
      return deref array;
   }

   find(String key) { if(vo.key==key) return vo; else return null; }
}


class IdVO {
   Long id;
}

class NameIdVO extends IdVO {
   String name;
}

// The Role value object is defined by "RoleVO 3 id l name s granted_procedures as"
class RoleVO extends NameIdVO {
   StringArray granted_procedures;
}

// The Person value object is defined by "PersonVO 7 id l name s birthdate t forename s surname s role RoleVO role_id l "
class PersonVO extends NameIdVO {
   Time birthdate;
   String forename;
   String surname;
   RoleVO role;
   Long role_id;
}


// The "Person" namespace and data access object class (DAO)
class PersonDAO extends RIO_Namespace {
   Long next_id;

   getProcedures { return
                      "ap 7"
                      " findById 1 id l : aPersonVO "
                      " findByName 1 name s : aPersonVO "
                      
                      " create 1 person PersonVO : PersonVO "
                      " remove 1 person PersonVO : b "
                      " find 1 person PersonVO : aPersonVO "
                      " findBySurname 1 surname s : aPersonVO "
                      " findByMinMaxBirthdate 2 min t max t : aPersonVO"
                      ;
   }
   
   nextId():Long {
      return ++next_id;
   }

   // Implementation for RIO procedure "Person create 1 person PersonVO : PersonVO"
   create(PersonVO person):PersonVO {
      print "service: PersonDAO.create(person="+#(person)+")";
      print "[...] RIO<Person create>: create person name=\""+person.name+"\" forename=\""+person.forename+"\" surname=\""+person.surname+"\".";
      person.id=nextId();
      person.name=person.forename+" "+person.surname;
      person.role_id=1;
      RoleVO role <= person.role;
      role.id=person.role_id;
      role.name="User";
      return person;
   }

   // Implementation for RIO procedure "new : b"
   _new():PersonVO {
      print "[...] RIO<Person new>: return new PersonVO";
      local PersonVO vo;
      vo.id=nextId();
      return deref vo;
   }

   // Implementation for RIO procedure "remove 1 person PersonVO : b"
   remove(PersonVO person):Boolean {
      print "[...] RIO<Person remove>: name=return new PersonVO";
      return 0;
   }

   // Implementation for RIO procedure "find 1 person PersonVO : aPersonVO"
   find(PersonVO person):ClassArray {
      print "[...] RIO<Person find>: ";
      error(#["name"="n/a", "details"="no implementation"]);
   }

   // Implementation for RIO procedure "findById 1 id l : aPersonVO"
   findById(Long id):ClassArray {
      print "[...] RIO<Person findById>: id="+id;
      local PersonVO ca[]; 
      return deref ca;
   }

   // Implementation for RIO procedure "findByName 1 name s : aPersonVO"
   findByName(String name):ClassArray {
      print "[...] RIO<Person findByName>: name="+name;
      local PersonVO ca[];
      return deref ca;
   }

   // Implementation for RIO procedure "findBySurname 1 name s : aPersonVO"
   findBySurname(String surname):ClassArray {
      print "[...] RIO<Person findBySurname>: surname="+surname;
      local PersonVO ca[];
      return deref ca;
   }

   // Implementation for RIO procedure "findByMinMaxBirthdate 2 min t max t : aPersonVO"
   findByMinMaxBirthdate(Time min, Time max):ClassArray {
      print "[...] RIO<Person findByMinBirthdate>: min="+min+" max="+max;
      local PersonVO ca[]; 
      return deref ca;
   }
}

// The "Role" namespace and data access object class (DAO)
class RoleDAO extends RIO_Namespace {
   getProcedures() { return
                        "ap 2"
                        " findById 1 id l : RoleVO"
                        " findByName 1 name s : RoleVO"
                        ;
   }

   // Implementation for RIO procedure "Role findById 1 id l : RoleVO"
   findById(Long id):RoleVO {
      print "[...] RIO<Role findById>: id="+id;
      return null;
   }

   // Implementation for RIO procedure "Role findByName 1 id s : RoleVO"
   findByName(String name):RoleVO {
      print "[...] RIO<Role findByName>: name="+name;
      return null;
   }
}


class DefaultService : RIO_ServiceProvider {
   public init() returns boolean {
      
      return RIO_ServiceProvider::init() 
        
         && addClass(TestVO)
         && addClass(RoleVO)
         && addClass(PersonVO)

         && addNamespace(TestDAO)
         && addNamespace(PersonDAO)
         && addNamespace(RoleDAO)
         ;
   }
         
}