Index: /trunk/prototype/config/Tonic.srv
===================================================================
--- /trunk/prototype/config/Tonic.srv	(revision 6528)
+++ /trunk/prototype/config/Tonic.srv	(revision 6559)
@@ -14,4 +14,7 @@
 ContactResource = /catalog/ContactResource.php
 
+[/sharedcontact/:id]
+SharedContactsResource = /catalog/SharedContactResource.php
+
 [/groups]
 GroupsResource = /catalog/GroupsResource.php
@@ -20,4 +23,7 @@
 GroupResource = /catalog/GroupResource.php
 
+[/sharedgroup/:id]
+SharedGroupsResource = /catalog/SharedGroupResource.php
+
 [/dynamiccontacts]
 DynamicContactsResource = /catalog/DynamicContactsResource.php
@@ -25,2 +31,5 @@
 [/dynamiccontact/:id]
 DynamicContactResource = /catalog/DynamicContactResource.php
+
+[/usercontacts]
+UserContactsResource = /catalog/UserContactsResource.php
Index: /trunk/prototype/rest/hypermedia/collection.php
===================================================================
--- /trunk/prototype/rest/hypermedia/collection.php	(revision 6528)
+++ /trunk/prototype/rest/hypermedia/collection.php	(revision 6559)
@@ -8,15 +8,16 @@
 include_once('error.php');
 /*
-Valores padrão
+  Valores padrão
 
-Números são enviados como números, sem aspas;
-Atributos não obrigatórios sem valor serão nulos;
-Strings vazias serão nulos;
-Todos os indices / chaves estarão sempre presentes na mensagem;
-Arrays vazios serão nulos;
-Objetos vazios serão nulos;
-Números sem valor serão nulos;
-valores booleanos são escritos como booleanos (sem aspas);
-*/
+  Números são enviados como números, sem aspas;
+  Atributos não obrigatórios sem valor serão nulos;
+  Strings vazias serão nulos;
+  Todos os indices / chaves estarão sempre presentes na mensagem;
+  Arrays vazios serão nulos;
+  Objetos vazios serão nulos;
+  Números sem valor serão nulos;
+  valores booleanos são escritos como booleanos (sem aspas);
+ */
+
 class Collection {
 
@@ -34,5 +35,5 @@
 	foreach ($config as $key => $value) {
 	    if ($value['class'] == $className) {
-		$uri = ($id ? (preg_replace('/\/[:][a-zA-Z-0-9]+/', '', $key).'/'.$id ) : $key);
+		$uri = ($id ? (preg_replace('/\/[:][a-zA-Z-0-9]+/', '', $key) . '/' . $id ) : $key);
 		break;
 	    }
@@ -41,13 +42,13 @@
     }
 
-	function addLink($link) {
+    function addLink($link) {
 	$this->links[] = $link;
     }
-	
+
     function addItem($item) {
 	$this->itens[] = $item;
     }
-	
-	function addData($data) {
+
+    function addData($data) {
 	$this->data[] = $data;
     }
@@ -56,5 +57,5 @@
 	return $this->data;
     }
-    
+
     function setTemplate($template) {
 	$this->template = $template;
Index: /trunk/prototype/rest/hypermedia/item.php
===================================================================
--- /trunk/prototype/rest/hypermedia/item.php	(revision 6528)
+++ /trunk/prototype/rest/hypermedia/item.php	(revision 6559)
@@ -4,4 +4,5 @@
 
     public $href;
+    public $dataType;
     public $data = array();
     public $links = array();
@@ -16,4 +17,13 @@
 	}
 	$this->href = $uri .'/'. $id;
+	$this->dataType = $uri;
+    }
+    
+    function setDataType($dataType) {
+	$this->dataType = $dataType;
+    }
+
+    function getDataType() {
+	return $this->dataType;
     }
 
Index: /trunk/prototype/rest/hypermedia/hypermedia.php
===================================================================
--- /trunk/prototype/rest/hypermedia/hypermedia.php	(revision 6528)
+++ /trunk/prototype/rest/hypermedia/hypermedia.php	(revision 6559)
@@ -16,17 +16,17 @@
     }
 
-    function getHypermedia($accept = 'json') {
+    function toUtf8($data) {
 
-	$data = get_object_vars($this);
+	if (!is_array($data))
+	    return  is_string($data) ? mb_convert_encoding($data, 'UTF-8', 'UTF-8 , ISO-8859-1') : $data;
 
-	switch ($accept) {
-	    case 'json':
-		return json_encode($data);
-		break;
-	    case 'xml':
-		return $this->generateValidXmlFromArray($data);
-	    default :
-		return json_encode($data);
+	$return = array();
+
+	foreach ($data as $i => &$v){
+	    if(is_object($v))
+		$v = get_object_vars($v);
+	    $return[$this->toUtf8($i)] = $this->toUtf8($v);
 	}
+	return $return;
     }
 
@@ -64,4 +64,19 @@
     }
 
+    function getHypermedia($accept = 'json') {
+
+	$data = $this->toUtf8(get_object_vars($this));
+
+	switch ($accept) {
+	    case 'json':
+		return json_encode($data);
+		break;
+	    case 'xml':
+		return $this->generateValidXmlFromArray($data);
+	    default :
+		return json_encode($data);
+	}
+    }
+
 }
 
Index: /trunk/prototype/rest/catalog/UserContactsResource.php
===================================================================
--- /trunk/prototype/rest/catalog/UserContactsResource.php	(revision 6559)
+++ /trunk/prototype/rest/catalog/UserContactsResource.php	(revision 6559)
@@ -0,0 +1,479 @@
+<?php
+
+if (!defined('ROOTPATH'))
+    define('ROOTPATH', dirname(__FILE__) . '/..');
+
+require_once(ROOTPATH . '/rest/hypermedia/hypermedia.php');
+
+use prototype\api\Config as Config;
+
+class UserContactsResource extends Resource {
+
+    /**
+     * Retorna uma lista de grupos
+     *
+     * @license    http://www.gnu.org/copyleft/gpl.html GPL
+     * @author     Consórcio Expresso Livre - 4Linux (www.4linux.com.br) e Prognus Software Livre (www.prognus.com.br)
+     * @sponsor    Caixa Econômica Federal
+     * @author     Adrino Coutinho da Silva. 
+     * @return     Retorna uma lista de Contatos Dinâmicos, Grupos, Contatos Pessoais, Grupos Compartilhados e Contatos Compartilhados
+     * @access     public
+     * */
+    function get($request) {
+
+	$this->secured();
+
+	$response = new Response($request);
+	$response->addHeader('Content-type', 'aplication/json');
+	$response->code = Response::OK;
+
+	$h = new Hypermedia();
+	$c = new Collection($request->resources, 'UserContactsResource');
+
+	try {
+
+	    $d = new Data();
+
+	    $d->setName('User Contacts');
+	    $d->setValue(null);
+	    $d->setPrompt('Contatos do usuário');
+	    $d->setDataType(null);
+	    $d->setMaxLength(null);
+	    $d->setMinLength(null);
+	    $d->setRequired(null);
+
+	    $c->addData($d);
+
+	    //Recupera os contatos dinâmicos do usuario
+	    $dynamicContacts = Controller::find(
+			    array('concept' => 'dynamicContact'), false, array('filter' => array('=', 'owner', Config::me("uidNumber")),
+			'order' => array('number_of_messages', 'name', 'mail'),
+			'orderDesc' => array(true, false, false))
+	    );
+
+	    if ($dynamicContacts) {
+		foreach ($dynamicContacts as $value) {
+		    $d = new Data();
+		    $i = new Item($request->resources, 'DynamicContactsResource', $value['id']);
+
+		    $d->setName('name');
+		    $d->setValue($value['name']);
+		    $d->setPrompt('Nome do Contato Recente');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('mail');
+		    $d->setValue($value['mail']);
+		    $d->setPrompt('Email do Contato Recente');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('number_of_messages');
+		    $d->setValue($value['number_of_messages']);
+		    $d->setPrompt('Quantidade de mensagens enviadas');
+		    $d->setDataType('integer');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(false);
+
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('id');
+		    $d->setValue($value['id']);
+		    $d->setPrompt('Id do contato dinamico');
+		    $d->setDataType('integer');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(false);
+
+		    $i->addData($d);
+
+		    $l = new Link();
+
+		    $l->setHref('');
+		    $l->setRel('delete');
+		    $l->setAlt('Remover');
+		    $l->setPrompt('Remover');
+		    $l->setRender('link');
+
+		    $i->addLink($l);
+
+		    $l = new Link();
+		    $l->setHref('');
+		    $l->setRel('put');
+		    $l->setAlt('Atualizar');
+		    $l->setPrompt('Atualizar');
+		    $l->setRender('link');
+
+		    $i->addLink($l);
+
+		    $l = new Link();
+		    $l->setHref('/dynamiccontact/' . $value['id']);
+		    $l->setRel('get');
+		    $l->setAlt('Buscar');
+		    $l->setPrompt('Buscar');
+		    $l->setRender('link');
+
+		    $i->addLink($l);
+		    $c->addItem($i);
+		}
+	    }
+
+	    $idS = array(Config::me("uidNumber"));
+	    $acl = array();
+
+	    //Recupera o uidNumber de todos os usuários que compartilham suas agendas com o usuário logado
+	    $shareds = Controller::service('PostgreSQL')->execResultSql('select acl_account as "uidNumber", acl_rights as "acl" from phpgw_acl where (acl_location =   \'' . Config::me("uidNumber") . '\' AND acl_appname =  \'contactcenter\' )');
+
+	    if (!empty($shareds) && $shareds)
+		foreach ($shareds as $s) {
+		    array_push($idS, $s['uidNumber']);
+		    $acl[$s['uidNumber']] = $this->decodeAcl(decbin($s['acl']));
+		}
+
+	    //Recupera os grupos do usuario
+	    $groups = Controller::find(array('concept' => 'contactGroup'), false, array('filter' => array('IN', 'user', $idS), 'order' => array('name')));
+
+	    if ($groups) {
+		foreach ($groups as $value) {
+
+		    $i = new Item($request->resources, ($value['user'] == Config::me("uidNumber") ? 'GroupsResource' : 'SharedGroupsResource'), $value['id']);
+
+		    $d = new Data();
+		    $d->setName('id');
+		    $d->setValue($value['id']);
+		    $d->setPrompt('Id do Grupo');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('owner');
+		    $d->setValue($value['user']);
+		    $d->setPrompt('Id Dono do Grupo');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('name');
+		    $d->setValue($value['name']);
+		    $d->setPrompt('Nome do Grupo');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('email');
+		    $d->setValue($value['email']);
+		    $d->setPrompt('Email do Grupo');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+		    $i->addData($d);
+
+		    if (Config::me("uidNumber") != $value['user']) {
+			/* Descomentar ao implementar os métodos
+			  if ($acl[$value['user']]['delete']) {
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('delete');
+			  $l->setAlt('Remover');
+			  $l->setPrompt('Remover');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			  }
+
+			  if ($acl[$value['user']]['update']) {
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('put');
+			  $l->setAlt('Atualizar');
+			  $l->setPrompt('Atualizar');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			  }
+
+			  if ($acl[$value['user']]['write']) {
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('post');
+			  $l->setAlt('Criar');
+			  $l->setPrompt('Criar novo');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			  }
+
+			  if ($acl[$value['user']]['read']) {
+			  $l = new Link();
+			  $l->setHref('/sharedgroup/' . $value['user'] . '/' . $value['id']);
+			  $l->setRel('get');
+			  $l->setAlt('Buscar');
+			  $l->setPrompt('Buscar');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			  }
+			 */
+		    } else {
+			/* Descomentar ao implementar métodos no recurso
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('delete');
+			  $l->setAlt('Remover');
+			  $l->setPrompt('Remover');
+			  $l->setRender('link');
+			  $i->addLink($l);
+
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('put');
+			  $l->setAlt('Atualizar');
+			  $l->setPrompt('Atualizar');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			 */
+
+			$l = new Link();
+			$l->setHref('/group/' . $value['id']);
+			$l->setRel('get');
+			$l->setAlt('Buscar');
+			$l->setPrompt('Buscar');
+			$l->setRender('link');
+
+			$i->addLink($l);
+		    }
+		    $c->addItem($i);
+		}
+	    }
+
+	    //Recupera os contatos pessoais do usuario
+	    $contacts = Controller::find(array('concept' => 'contact'), false, array('filter' => array('IN', 'user', $idS)));
+
+	    if ($contacts) {
+
+		foreach ($contacts as $value) {
+		    $d = new Data();
+		    $i = new Item($request->resources, (($value['user'] == Config::me("uidNumber")) ? 'ContactsResource' : 'SharedContactsResource'), $value['id']);
+		    $d->setName('id');
+		    $d->setValue($value['id']);
+		    $d->setPrompt('Id do Contato');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('owner');
+		    $d->setValue($value['user']);
+		    $d->setPrompt('Id Dono do Contato');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('name');
+		    $d->setValue($value['name']);
+		    $d->setPrompt('Nome do Contato');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('email');
+		    $d->setValue(isset($value['email']) ? $value['email'] : null);
+		    $d->setPrompt('Email do Contato');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+
+		    $i->addData($d);
+
+		    $d = new Data();
+		    $d->setName('telephone');
+		    $d->setValue(isset($value['telephone']) ? $value['telephone'] : null);
+		    $d->setPrompt('Telefone do Contato');
+		    $d->setDataType('string');
+		    $d->setMaxLength('100');
+		    $d->setMinLength(null);
+		    $d->setRequired(true);
+
+		    $i->addData($d);
+
+		    if (Config::me("uidNumber") != $value['user']) {
+			/* Descomentar ao criar recursos
+			  if ($acl[$value['user']]['read']) {
+			  $l = new Link();
+			  $l->setHref('/sharedcontact/' . $value['id']);
+			  $l->setRel('get');
+			  $l->setAlt('Buscar');
+			  $l->setPrompt('Buscar');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			  }
+
+			  if ($acl[$value['user']]['delete']) {
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('delete');
+			  $l->setAlt('Remover');
+			  $l->setPrompt('Remover');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			  }
+
+			  if ($acl[$value['user']]['put']) {
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('put');
+			  $l->setAlt('Atualizar');
+			  $l->setPrompt('Atualizar');
+			  $l->setRender('link');
+			  $i->addLink($l);
+			  }
+			 */
+		    } else {
+			/* Descomentar ao criar recursos
+			  $l = new Link();
+
+			  $l->setHref('');
+			  $l->setRel('delete');
+			  $l->setAlt('Remover');
+			  $l->setPrompt('Remover');
+			  $l->setRender('link');
+
+			  $i->addLink($l);
+
+			  $l = new Link();
+			  $l->setHref('');
+			  $l->setRel('put');
+			  $l->setAlt('Atualizar');
+			  $l->setPrompt('Atualizar');
+			  $l->setRender('link');
+
+			  $i->addLink($l);
+			 */
+			$l = new Link();
+			$l->setHref('/contact/' . $value['id']);
+			$l->setRel('get');
+			$l->setAlt('Buscar');
+			$l->setPrompt('Buscar');
+			$l->setRender('link');
+
+			$i->addLink($l);
+		    }
+		    $c->addItem($i);
+		}
+	    }
+
+
+	    if (!$contacts && !$dynamicContacts && !$groups) {
+		$this->createException($request, $response, Response::NOTFOUND, 'Bad request', 'Resource not found.');
+		return $response;
+	    }
+
+
+	    $t = new Template();
+
+	    $d = new Data();
+
+	    $d->setName('id');
+	    $d->setValue(null);
+	    $d->setPrompt('Id do Grupo');
+	    $d->setDataType('string');
+	    $d->setMaxLength('100');
+	    $d->setMinLength(null);
+	    $d->setRequired(true);
+
+	    $t->addData($d);
+
+	    $d = new Data();
+	    $d->setName('user');
+	    $d->setValue(null);
+	    $d->setPrompt('Id Dono do Grupo');
+	    $d->setDataType('string');
+	    $d->setMaxLength('100');
+	    $d->setMinLength(null);
+	    $d->setRequired(true);
+
+	    $t->addData($d);
+
+	    $d = new Data();
+	    $d->setName('name');
+	    $d->setValue(null);
+	    $d->setPrompt('Nome do Grupo');
+	    $d->setDataType('string');
+	    $d->setMaxLength('100');
+	    $d->setMinLength(null);
+	    $d->setRequired(true);
+
+	    $t->addData($d);
+	    $c->setTemplate($t);
+	    $h->setCollection($c);
+
+	    $response->body = $h->getHypermedia($request->accept[10][0]);
+	    return $response;
+	} catch (Exception $ex) {
+	    $this->createException($request, $response, Response::INTERNALSERVERERROR, 'Internal Server Error', $ex);
+	    return $response;
+	}
+    }
+
+    function decodeAcl($bin) {
+
+	$acl = array();
+	$bin = str_split($bin);
+	$acl['read'] = (isset($bin[0]) && $bin[0] == 1) ? true : false;
+	$acl['write'] = (isset($bin[1]) && $bin[1] == 1) ? true : false;
+	$acl['update'] = (isset($bin[2]) && $bin[2] == 1) ? true : false;
+	$acl['delete'] = (isset($bin[3]) && $bin[3] == 1) ? true : false;
+
+	return $acl;
+    }
+
+    private function createException($request, &$response, $code, $title, $description) {
+	$response->code = $code;
+
+	$h = new Hypermedia();
+	$c = new Collection($request->resources, 'DynamicContactResource');
+	$e = new Error();
+
+	$e->setCode($code);
+	$e->setTitle($title);
+	$e->setDescription($description);
+
+	$c->setError($e);
+	$h->setCollection($c);
+
+	$response->body = $h->getHypermedia($request->accept[10][0]);
+    }
+
+}
+
+?>
