quinta-feira, 23 de maio de 2013

Tutorial sobre GIT




Esse video tutorial aborda aspectos básicos e avançados de GIT. Recomendado para quem está começando com controle de versão, com GIT ou migrando de Subversion para GIT. Ou mesmo quem já utiliza GIT.

O tutorial será dividido em 4 vídeos, a apresentação está disponível em: http://prezi.com/rpf-_xrinrzq/tutorial-git/?kw=view-rpf-_xrinrzq&rc=ref-34836321 e serve como base para os vídeos.

O primeiro vídeo apresenta um overview sobre GIT e seus comandos básicos que todo iniciante deve saber. A segunda parte apresenta como desfazer alterações com os comandos git revert e git reset. O terceiro vídeo apresenta branches e merges, e o quarto vídeo ensina como reescrever o histórico do GIT.

Para quem já utiliza o GIT recomendo ver a apresentação e escolher qual dos vídeos quer ver

Para acessar os vídeos vá em: http://www.youtube.com/playlist?list=PL3NGePwPGuvvnBO4tk---xNABmNVEpD2R

sábado, 20 de abril de 2013

Tutoriais e dicas de desenvolvimento

Alguns tutoriais e dicas de desenvolvimento estão disponíveis no link: https://wiki.atende.info/display/TD/Home

Vale a pena conferir. Pessoalmente eu contribuo nos dois lugares.

quinta-feira, 11 de abril de 2013

Apresentação Linux e Latex

Para ver as apresentações siga os links abaixo

Linux:


http://prezi.com/o3uyr1c16jsv/minicurso-linux/?auth_key=11dacb36a3035cd1cdfe78e90e9e488a5ef9866a&kw=view-o3uyr1c16jsv&rc=ref-34836321

Latex:


http://prezi.com/pkk0jeukhoym/minicurso-latex/?kw=view-pkk0jeukhoym&rc=ref-34836321

Sugiro fortemente que baixem o modelo em latex da regista abakos pois possue muitos exemplos de citações, figuras, tabelas, algoritmos e outros. O modelo está disponível em MODELO DE ARTIGO

quinta-feira, 1 de novembro de 2012

Json e Java

Para comunicação Ajax é necessário adotar um formato de dados para comunicação entre aplicação e interface.

As melhores alternativas são: Json e XML.

XML - É um formato de comunicação padrão entre sistemas diferentes. É muito difundido e pode ser utilizado para expressar quase qualquer tipo de dado. O XML possui um padrão complementar chamado XSD que tem como objetivo validar automaticamente a sintaxe do modelo XML, permitindo construir representações verificáveis.

JSON - Esse formato de dados consegue expressar de forma mais sucinta tudo o que XML consegue. Atualmente JSON não possui uma linguagem de validação com o XSD do XML.

Comparado ao XML o formato JSON é mais leve, pois com menos escrita se consegue expressar a mesma informação e mais eficiente para o processamento. JSON é um formato aberto com grande número de utilitários para troca de dados utilizando esse formato. Na comunicação entre uma interface em javascript e o servidor  o formato JSON parece ser uma melhor escolha, pois é a linguagem padrão de diversas bibliotecas como EXTJS

Ao programar em Java temos diversas alternativas para serialização em JSON, no JEE (Java Enterprise Edition) temos o padrão JAXB (Java Architecture for XML Binding) que permite a transformação de objetos em XML e também para JSON, no entanto essa biblioteca converte para XML para depois converter para JSON, o que tem performance reduzida e pode haver perda de informação devido a diferenças entre as linguagens.

Outra biblioteca muito utilizada é a chamada Jackson Mapper que não possui as desvantagens da biblioteca JAXB mencionadas acima, pois serializa diretamente para JSON.

Jackson e JEE


Utilizando-se JEE para configurar o Jackson basta tê-lo como um provider registrado. Utilizando-se RestEasy (padrão no servidor Jboss) como biblioteca JAXRS basta ter a biblioteca jackson-jaxrs-json-provider no ClassPath. Utilizando maven basta declarar as dependências:











<!-- Json -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-core</artifactId>

            <version>${jackson.version}</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-annotations</artifactId>

            <version>${jackson.version}</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-databind</artifactId>

            <version>${jackson.version}</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.datatype</groupId>

            <artifactId>jackson-datatype-hibernate4</artifactId>

            <version>2.0.2</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.jaxrs</groupId>

            <artifactId>jackson-jaxrs-json-provider</artifactId>

            <version>2.0.4</version>

        </dependency>

        <!-- para datas em Joda Time -->

        <dependency>

            <groupId>com.fasterxml.jackson.datatype</groupId>

            <artifactId>jackson-datatype-joda</artifactId>

            <version>2.0.4</version>

        </dependency>

<!--!Fim Json-->





Para habilitar webservices em REST crie um classe extendendo javax.ws.rs.core.Application:











package info.atende.erp.crm.config;

import javax.ws.rs.ApplicationPath;

import javax.ws.rs.core.Application;

/**

 * Adicionar configuração rest na aplicação

 * Criado por Giovanni Candido <giovanni@atende.info>.

 * Data: 29/10/12

 * Hora: 16:41

 */

@ApplicationPath("/rest")

public class RestConfig extends Application {

}





Isso deve ser suficiente para funcionar. No entanto o Jackson Mapper tem várias opções de customização. Para isso crie uma classe que provê um objeto ObjectMapper customizado. Por exemplo a classe JacksonContextResolver:











package info.atende.erp.crm.config;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.SerializationFeature;

import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module;

import com.fasterxml.jackson.datatype.joda.JodaModule;

import javax.ws.rs.Produces;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.ext.ContextResolver;

import javax.ws.rs.ext.Provider;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

/**

 * Customizar a implementacao do ObjectMapper do Jackson Json

 * Criado por Giovanni Candido <giovanni@atende.info>.

 * Data: 01/11/12

 * Hora: 18:04

 */

@Provider

@Produces(MediaType.APPLICATION_JSON)

public class JacksonContextResolver implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper;

    private String dateMask = "MM-dd-yyyy HH:mm:ss";

    public JacksonContextResolver() {

        this.objectMapper = new ObjectMapper();

        /**

         * Evita Hibernate Lazy Instantiation

         */

        Hibernate4Module hm = new Hibernate4Module();

        JodaModule jodaModule = new JodaModule();

        this.objectMapper.registerModule(hm);

        this.objectMapper.registerModule(jodaModule);

        /**

         * Configura Formato de data

         */

        this.objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        DateFormat dateFormat = new SimpleDateFormat(dateMask);

        this.objectMapper.setDateFormat(dateFormat);

    }

    @Override

    public ObjectMapper getContext(Class<?> aClass) {

        return objectMapper;

    }

}





Essa classe deve conter as anotações: @Provider @Produces(MediaType.APPLICATION_JSON) e implementar  ContextResolver<ObjectMapper>

ObjectMapper é o objeto que serializa objetos em JSON e vice versa. Na classe acima, adicionamos os módulos Hibernate4Module e JodaModule, depois configuramos o formato da data serializada.

Agora basta utilizar em conjunto com JAXRS por exemplo:











@Path("/cliente")

@Produces(MediaType.APPLICATION_JSON)

public class ClienteCtl {

    @EJB

    private CrudService clienteDAO;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

 

    @GET

    public ExtData listarTodosClientes(@QueryParam("nome") String nome, @QueryParam("page") Integer page,

                                       @QueryParam("start") Integer start, @QueryParam("limit") Integer limit) {

        ExtData dados = new ExtData();

        Collection clientes = clienteDAO.findAll(Cliente.class, start, limit);

        dados.add(clientes);

        return dados;

    }

}





Jackson e Spring Framework


Para utilizar com Spring Framework primeiramente não precisamos da dependência do jackson-jaxrs-json-provider o arquivo pom.xml pode ficar assim:











<!-- Json -->

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-core</artifactId>

            <version>${jackson.version}</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-annotations</artifactId>

            <version>${jackson.version}</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.core</groupId>

            <artifactId>jackson-databind</artifactId>

            <version>${jackson.version}</version>

        </dependency>

        <dependency>

            <groupId>com.fasterxml.jackson.datatype</groupId>

            <artifactId>jackson-datatype-hibernate4</artifactId>

            <version>2.0.2</version>

        </dependency>

        <!-- para datas em Joda Time -->

        <dependency>

            <groupId>com.fasterxml.jackson.datatype</groupId>

            <artifactId>jackson-datatype-joda</artifactId>

            <version>2.0.4</version>

        </dependency>

<!--!Fim Json-->





Para habilitar serialização REST no Spring Framework configure o arquivo de configuração do spring:











<?xml version="1.0" encoding="UTF-8"?>





    <mvc:resources mapping="/**.html" location="/**.html"/>

    <mvc:resources mapping="/app.js" location="/app.js"/>

    <mvc:resources mapping="/app/**" location="/app/**"/>

    <mvc:resources mapping="/recursos/**" location="/recursos/**"/>

    <mvc:resources mapping="/library/**" location="/library/**"/>

    <context:component-scan base-package="info.atende.erp.crm.controller">

        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>

    </context:component-scan>

    <!-- Habilita e customiza o Jackson Mapper -->

    <mvc:annotation-driven>

        <mvc:message-converters register-defaults="false">

            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">

                <property name="objectMapper" ref="jacksonObjectMapper"/>

            </bean>

            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>

        </mvc:message-converters>

    </mvc:annotation-driven>

    <!-- ObjectMapper customizado -->

    <bean id="jacksonObjectMapper" class="info.atende.erp.crm.spring.CustomObjectMapper">

    </bean>

</beans>





Crie a classe CustomObjectMapper:











package info.atende.erp.crm.spring;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**

 * Object Mapper para customizar a serialização do Json

 * Criado por Giovanni Candido <giovanni@atende.info>.

 * Data: 29/08/12

 * Hora: 17:51

 */

@Component("jacksonDateMapper")

public class CustomObjectMapper extends ObjectMapper {

    private String dateMask = "MM-dd-yyyy HH:mm:ss";

    @PostConstruct

    public void afterPropertiesSet() throws Exception {

    

        /**

         * Evita Hibernate Lazy Instantiation

         */

        Hibernate4Module hm = new Hibernate4Module();

        JodaModule jodaModule = new JodaModule();

        registerModule(hm);

        registerModule(jodaModule);

        /**

         * Configura Formato de data

         */

        configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        DateFormat dateFormat = new SimpleDateFormat(dateMask);

        setDateFormat(dateFormat);

    }

    public void setDateMask(String dateMask) {

        this.dateMask = dateMask;

    }

}





Uma diferença entre os controladores Spring e as classe JAXRS é que o spring só serializará em Json se isso for negociado entre a requisição e controlador. No controlador deve-se anotar o método com @ResponseBody exemplo











package info.atende.erp.crm.controller;

import info.atende.erp.crm.controller.extjs.ExtData;

import info.atende.erp.crm.controller.extjs.ExtResponse;

import info.atende.erp.crm.dao.ClienteDAO;

import info.atende.erp.crm.entidades.*;

import org.joda.time.LocalDate;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Scope;

import org.springframework.dao.DataIntegrityViolationException;

import org.springframework.data.domain.Page;

import org.springframework.data.domain.PageRequest;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;

import java.util.HashMap;

/**

 * Controlador para clientes

 * Criado por giovanni.

 * Data: 17/04/12

 * Hora: 17:03

 */

@Controller

@Scope("prototype")

@RequestMapping("/cliente")

public class ClienteCtl {

    @Autowired

    private ClienteDAO clienteDAO;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

 

    @RequestMapping(method = RequestMethod.GET)

    @ResponseBody

    public ExtData listarTodosClientes(String nome, Integer page, Integer start, Integer limit) {

        PageRequest pageRequest = new PageRequest(page - 1, limit);

        ExtData dados = new ExtData();

        Page pagina;

        if (nome != null) {

            pagina = clienteDAO.findLikeNome(nome + "%", pageRequest);

        } else {

            pagina = clienteDAO.findAll(pageRequest);

        }

        dados.add(pagina.getContent());

        dados.setTotal(pagina.getTotalElements());

        return dados;

    }

}





O cliente (javascript) deve setar corretamente os cabeçalhos HTTP: Content-Type e Accept  para que funcione a troca de contexto.

quarta-feira, 1 de agosto de 2012

Importar base de dados mysql problemas de acentuação e o Table doesn't exist when using LOCK TABLES

Vou tentar resumir aqui um problema de horas.

Tentei fazer backup de uma base de dados grande em mysql. Fiz o backup pelo phpmyadmin e restaurei pelo terminal do linux usando o comando mysql. Restaurou tranquilo, no entanto a acentuação estava incorreta.

Para resolver o problema tentei criar um backup usando mysqldump, eu estava certo com relação a acentuação mas não consegui fazer o backup por causa de uma tabela que gerava o erro "Table xxx doesn't exist when using LOCK TABLES"

Tentei várias soluções para resolver esse problema o único que funcionou foi fazer o mysqldump com a opção --skip-lock-tables, no entanto eu perdia informação ao fazer isso pois ele ignora as tabelas com esse problema. Ao restaurar o backup a acentuação estava ok mais eu havia perdido dados.

Então após horas, voltei ao meu problema original e tentei uma nova abordagem. Deletei a base de dados e criei ela novamente usando explicitamente codificação UTF-8, eu já havia usado o comando do mysql para trocar o charset do banco, mas foi necessário criá-lo novamente (o que me fez perder algumas horas também). Então voltei o backup do phpmyadmin e tudo funcionou como deveria.

Coisas da vida.

quinta-feira, 31 de maio de 2012

Habilitar Suporte a Trim no Mac OSX Lion

HD's SSD's de terceiros no Mac OSX não possuem suporte a TRIM habilitado. Para contornar use o método abaixo. NÃO USE O TRIM ENABLER POIS ELE VAI AVACALHAR O SEU SISTEMA use o método abaixo:

1. Backup the file we’re patching
sudo cp /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage.original

2. Patch the file to enable TRIM support
sudo perl -pi -e 's|(\x52\x6F\x74\x61\x74\x69\x6F\x6E\x61\x6C\x00{1,20})[^\x00]{9}(\x00{1,20}\x51)|$1\x00\x00\x00\x00\x00\x00\x00\x00\x00$2|sg' /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

3. Clear the system kernel extension cache
sudo kextcache -system-prelinked-kernel

sudo kextcache -system-caches

4. Now Reboot!

a) If in the future you want to disable TRIM support
sudo perl -pi -e 's|(\x52\x6F\x74\x61\x74\x69\x6F\x6E\x61\x6C\x00).{9}(\x00\x51)|$1\x41\x50\x50\x4C\x45\x20\x53\x53\x44$2|sg' /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

sudo kextcache -system-prelinked-kernel

sudo kextcache -system-caches

b) If something goes horribly wrong, restore the backup
sudo cp /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage.original /System/Library/Extensions/IOAHCIFamily.kext/Contents/PlugIns/IOAHCIBlockStorage.kext/Contents/MacOS/IOAHCIBlockStorage

Retirado de: http://digitaldj.net/2011/07/21/trim-enabler-for-lion/

sábado, 26 de maio de 2012

Procura recursiva em linux e copia de chave ssh



Achei esse post na internet: http://tuxers.com/main/ssh-copy-id-and-why-i-read-the-man-pages/

Muito bom, fazer um grep -r PATTERN diretorio procura recursivamente pelo padrão no conteúdo de arquivos do diretório. Muito útil.

Outra dica é o ssh-copy-id usuario@ip que copia a chave publica de ssh do seu usuário para o usuario da outra máquina