Migrando projetos de SVN para outro SVN

Este pequeno artigo tem o objetivo de auxiliar no processo de migração de projetos de um servidor SVN para outro também SVN.

Não levo em conta a migração de histórico de versão e outras funcionalidades, o objetivo é auxiliar iniciantes no processo de migração de servidor Subversion.

Possivelmente existem soluções mais completas e eficazes.

Como funciona o SVN

Um projeto é identificado como versionado por SVN quando possui uma para em cada diretório deste chamada “.svn”. Ali se encontram arquivos que informam a localização do serviço assim como outras configurações pertinentes.

Todos subdiretórios de um projeto SVN possuem sua própria pasta .svn com seu conjunto de configurações (muitas vezes essa pasta se encontra oculta pelo sistema operacional).

Migrando Projeto

Basicamente temos que efetuar o check-out de ambos os projetos, o antigo e o novo (que se encontra vazio).

Em seguida teremos que copiar o conteúdo de um repositório para outro e efetuar commit, porém o processo não é tão simples assim, primeiramente teremos que efetuar alguns procedimentos para evitar conflitos.

Removendo Conflitos

Como o serviço svn, assim como o cvs, se baseia em pastas ocultas, no caso chamadas  “.svn”, para registrar as informações de versionamento. antes de enviar para um novo servidor é necessário remover tais diretórios. O processo manual seria bastante cansativo, pois o projeto pode conter inúmeras subpastas dessa forma podemos utilizar as soluções a seguir:

* Certifique-se de ter realizado o commit todas as alterações no projeto antigo, pois a partir do momento que você remover os .svn você não mais conseguirá o fazer.

Removendo diretórios .svn no console do Linux

O comando a seguir irá remover todos os diretórios .svn do projeto localizado em “/home/alandaniel/workspace/projeto”:

$ find /home/alandaniel/workspace/projeto -iname .svn -exec rm -rf {} \;

Remover diretórios .svn utilizando o Eclipse

Para remover os diretórios no eclipse existem duas formas,  uma é pelo menu próprio para isso:

  • Botão direito no projeto: Team > Disconect > Marque “Also delete the svn meta…”

Outra solução, e mais recomendada, é exportar o projeto, assim você irá gerar uma cópia deste:

  • Botão direito no projeto: Export > Selecione File System > next  > Selecione o lugar a exportar > Next …

Passos Finais

Copie o novo conteúdo para o novo projeto e efetue o commit.

Habilitando servidor webdav usando Apache no Ubuntu Linux

Ferramentas: Ubuntu 9.04, apache2, ldap

WebDav é um tipo se serviço que permite a download e upload de arquivos de um servidor
de uma forma bastante transparente. É um padrão aberto e multiplataforma especificado na RFC 4510.
Permite o mapeamento de uma URL como se fosse um diretório local.

Esse artigo irá explicar como criar um servidor WebDav usando o servidor Web Apache 2 na distribuição Ubuntu Linux.
Esse artigo presume que você tenha conhecimento da instalar e configuração de servidor apache, no caso via pacotes debian,
porém se você souber extrair as informações aqui contidas poderá instalá-lo das outras diversas formas possíveis,
os locais de diretórios aqui abordados são do padrão debian-ubuntu.

1. PRIMEIRAS CONFIGURAÇÕES

Instale o apache e suas dependencias.

Iremos adicionar um novo host virtual, na porta 8080 para efetuar nossos testes, assegure-se que outra aplicação não está utilizando essa porta, senão escolha outra. Para criar um novo VirtualHost basta adicionar no arquivo “/etc/apache2/ports.conf” as seguintes linhas:

NameVirtualHost *:8080
Listen 8080

2. CONFIGURANDO O WEBDAV

Os diretórios a seguir são somente para organizar melhor a aplicação, você pode cria-los como desejar.
Crie a pasta /var/webdav/ e crie dentro as seguintes pastas:
*htdocs/ : será o local onde os arquivos serão inseridos, será o dav público;
*htdocs/basic/ : para exemplificar a autenticação basic;
*htdocs/digest/ : para exemplificar a autenticação digest;
*htdocs/ldap/ : para exemplificar a autenticação ldap;
*htdocs/ldap_grupo/ : para exemplificar o uso de ldap e grupos;
*config/ : pasta criada para conter o arquivo de senhas caso seja o caso, será visto depois.
altere o dono da pasta htdocs para www-data
sudo chown www-data /var/webdav/htdocs/

Agora é necessario adicionar o módulo de webdav, execute o comando a seguir (Apache2 deverá estar instalado):

# a2enmod dav
# a2enmod dav_fs

Esse comando simplesmente criará um link dos módulos desejados de /etc/apache/mod-avaliable/… para /etc/apache/mod-enable/…

Agora criaremos o seguinte arquivo “/etc/apache/site-enabled/webdav” com o conteúdo a seguir:

<VirtualHost *:8080>
	DocumentRoot /var/webdav/htdocs/
        <Directory /var/webdav/htdocs/>
		DAV On
	</Directory>
</VirtualHost>

Agora reinicie o servidor e teste o endereço http://localhost:8080

# /etc/init.d/apache2 restart

3. ACESSANDO WEBDAV NO UBUNTU USANDO NAUTILUS

Para utilizar uma url webdav no linux você pode utilizar o Nautilus, para isso faça os seguintes passos:
*Abri um navegador de arquivos (nautilus)
*Clique em arquivo > conectar ao servidor…
*Selecione Webdav, e informe as configurações do nosso servidor (localhost|8080)

4. AUTENTICAÇÃO POR ARQUIVO: BASIC

Uma das formas de restringir o acesso ao nosso servidor webdav é criar um arquivo de senhas.

Adicione os módulos necessários executando o comando:

# a2enmod auth_basic
# a2enmod auth_file

Agora iremos criar um arquivo de usuários e senhas.
Execute o comando a seguir, onde teste é o nome do usuário que você deseja criar:

# htpasswd -c /var/webdav/config/passwd_basic.dav teste

O parametro “-c” significa create, caso o arquivo já exista irá ser substituido.

Agora modificaremos novamente o arquivo “/etc/apache/site-enabled/webdav” e adicionaremos dentro de <VirtualHost…>:

 	Alias /basic /var/webdav/htdocs/basic
	<Location /basic>
		AuthType Basic
		AuthName webdav
		AuthBasicProvider file
		AuthUserFile /var/webdav/config/passwd_basic.dav
		Require valid-user
	</Location>

Reinicie o servidor e teste.

5. AUTENTICAÇÂO POR ARQUIVO: DIGEST

A autenticação Digest é bastante similar à Basic, a diferença está somente na forma com que o password é enviado ao servidor,
no formato MD5 que o torna mais seguro para transmissão via internet e também que esse obedece o realm especificado em AuthName.

Adicione os módulos necessários executando o comando:

# a2enmod auth_digest

Execute o comando a seguir, onde webdav é o nome do realm e teste o nome do usuário que você deseja criar:

# sudo htdigest -c /var/webdav/config/passwd_digest.dav webdav teste

Vamos ao  “/etc/apache/site-enabled/webdav” e adicionamos dentro de <VirtualHost…>:

	Alias /digest /var/webdav/htdocs/digest
	<Location /digest>
		AuthType Digest
		AuthName webdav
		AuthUserFile /var/webdav/config/passwd_digest.dav
		Require valid-user
	</Location>

6. AUTENTICACAO EM SERVICO LDAP

Adicione os módulos necessários executando o comando:

# a2enmod ldap
# a2enmod authnz_ldap

Adicionaremos em “/etc/apache/site-enabled/webdav” dentro de <VirtualHost…>:

	Alias /ldap /var/webdav/htdocs/ldap
	<Location /ldap>
		AuthType Basic
		AuthBasicProvider ldap
		AuthName webdav
		AuthLDAPURL "ldaps://ldap.servidor.com:636/ou=EMPRESA,dc=pr,dc=gov,dc=br"
	</Location>

7. AUTENTICACAO EM SERVICO LDAP

Adicionaremos em “/etc/apache/site-enabled/webdav” dentro de <VirtualHost…>:

	Alias /ldap_grupo /var/webdav/htdocs/ldap_grupo
	<Location /ldap_grupo>
		Order deny,allow
  		Deny from All
		AuthType Basic
		AuthBasicProvider ldap
		AuthName webdav
		AuthzLDAPAuthoritative on
		AuthLDAPURL ldaps://ldap.servidor:636/ou=EMPRESA,dc=pr,dc=gov,dc=br?uid?sub
		Require valid-user
		AuthLDAPGroupAttribute memberUid
		AuthLDAPGroupAttributeIsDN off
		Require ldap-group cn=nome-do-grupo,ou=EMPRESA,dc=pr,dc=gov,dc=br
		satisfy any
	</Location>

8. WARNINGS

O warning “client used wrong authentication scheme: /basic”, parece ser normal quando temos multiplas validações em um mesmo domínio, acredito ser um bug do navegador ou uma associação ao realm.

9. CONCLUSÃO

Configurar um webdav no apache é bastante simples e pode ser bastante útil.

O resultado final do arquivo “/etc/apache/site-enabled/webdav” é:

#Para ignorar certificados SSL inválidos
LDAPVerifyServerCert off

<VirtualHost *:8080>
        ServerAdmin medianeira@gmail.com

        DocumentRoot /var/webdav/htdocs/
        <Directory /var/webdav/htdocs/>
		DAV On
	</Directory>
	
	Alias /basic /var/webdav/htdocs/basic
	<Location /basic>
		AuthType Basic
		AuthName webdav
		AuthBasicProvider file
		AuthUserFile /var/webdav/config/passwd_basic.dav
		Require valid-user
	</Location>

	Alias /digest /var/webdav/htdocs/digest
	<Location /digest>
		AuthType Digest
		AuthName webdav
		AuthUserFile /var/webdav/config/passwd_digest.dav
		Require valid-user
	</Location>
	
	Alias /ldap /var/webdav/htdocs/ldap
	<Location /ldap>
		AuthType Basic
		AuthBasicProvider ldap
		AuthName webdav
		AuthLDAPURL "ldaps://ldap.servidor.com:636/ou=EMPRESA,dc=pr,dc=gov,dc=br"
	</Location>
	
	Alias /ldap_grupo /var/webdav/htdocs/ldap_grupo
	<Location /ldap_grupo>
		Order deny,allow
  		Deny from All
		AuthType Basic
		AuthBasicProvider ldap
		AuthName webdav
		AuthzLDAPAuthoritative on
		AuthLDAPURL ldaps://ldap.servidor.com:636/ou=EMPRESA,dc=pr,dc=gov,dc=br?uid?sub
		Require valid-user
		AuthLDAPGroupAttribute memberUid
		AuthLDAPGroupAttributeIsDN off
		Require ldap-group cn=nome-do-grupo,ou=EMPRESA,dc=pr,dc=gov,dc=br
		satisfy any
	</Location>
</VirtualHost>

Referências:

http://httpd.apache.org/docs/2.2/howto/auth.html

http://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html

Criando pacotes Debian (.deb)

S.O: Ubuntu Linux Karmic

Esse pequeno artigo tem o intuito de ensinar a criar um pacote debian,
não entro em detalhes complexos do formato.

O que é um arquivo .deb?

Um pacote debian é um arquivo compactado em um formato específico (ar http://en.wikipedia.org/wiki/Ar_%28Unix%29), bastante similar a um tar.gz ou um .zip, resumindo podemos facilmente descompactá-lo.
dentro desse arquivo você encontra outros 3 arquivos, 2 deles compactados:
* debian-binary: um arquivo gerado automaticamente com o formato do deb.
* control.tar.gz: informações do pacote, como dependência, e scripts pré e pós instalação.
* data.tar ou data.tar.gz ou data.tar.bz2 ou data.tar.lzma: os arquivos da aplicação disponibilizados em endereço absoluto, exemplo: /etc/programa/arquivos/…

Exemplo prático:

Iremos criar um pacote .deb que instala um aplicação que simplesmente irá escrever “Hello World!” no nosso console ao digitarmos o comando exemplo.sh no console.
Para nosso exemplo criaremos a seguinte estrutura de pastas:
/ : pode ser criado em qualquer lugar do seu disco, não precisa ser na raiz do sistema de arquivos.
/source/
/source/usr/
/source/usr/bin/

/source/usr/bin/exemplo.sh : arquivo contendo o código da aplicação, não esqueça de dar direitos de execução nesse arquivo (chmod +x exemplo.sh)
/source/DEBIAN/
/source/DEBIAN/control : arquivo que conterá informações (metadados) sobre o nosso pacote Debian, dependências, etc.

Conteúdo de exemplo.sh:

#!/bin/sh
echo "Hello World!";

Conteúdo de control:

Package: exemplo
Priority: optional
Version: 0.1
Architecture: i386
Maintainer: Alan Daniel Weiss (webcentro)
Depends: dash
Description: Exemplo de criação de um pacote debian que irá instalar o aplicativo /usr/bin/exemplo.sh que escreve "Hello World!" no terminal.

O conteúdo do arquivo control é auto explicativo,
nele estão as informações necessárias para efetuar a instalação do seu pacote,
observe que o campo Depends irá informar as dependências desse pacote, caso possua várias dependecias essas deverão ser separadas com virgula (,).

Criar o pacote

Agora que temos a estrutura do nosso pacote completa devemos executar o comando que irá empacotar tudo isso em um archive .deb,
vá nas raiz do projeto (pasta que contém o diretório source) e digite o seguinte comando:

$ dpkg-deb -b ./source/ .

será criado um arquivo com o nome exemplo_0.1_i386.deb, se quiser você pode abrir esse arquivo com o Gerenciador de Pacotes (compactados) e verificar a estrutura que foi criada.

Instalando, Usando e Removendo a Aplicação

Para instalar seu pacote você pode usar a aplicação gráfica GDEB, ou então executar o comando a seguir:

$ sudo dpkg -i exemplo_0.1_i386.deb

Agora teste a aplicação executando o comando no console em qualquer diretório do seu sistema de arquivos o comando a seguir:

$ exemplo.sh

Para remover use o apt:

$ sudo apt-get remove exemplo

Conclusão:

Criar pacotes debian é muito simples e versátil,
Empacotar um programa torna muito fácil para o usuário final instalá-lo.

Existem outras funcionalidades, como por exemplo scripts de pré instalação e pós, que ficam para um post futuro.

Caso tenha dúvidas fique a vontade em postar comentários, tentarei disponibilizar o código do exemplo caso o wordpress permitir.

ps: Aviso que somente tenho conhecimento do funcionamento de tudo que explico aqui na distribuição Ubuntu, desconheço as características das demais.

No space left bug?

Hoje me deparei com um problema nada agradavel. Meu sistema acusa que eu não tenho mais espaço livre na partição /
porém rodando um df mostra que ainda sobram 25%.

Estou rodando a distro Ubuntu Karmic e minha partição raiz está em ext4.

resultado de df:

alandaniel@sefa56866:~$ df
Sist. Arq.           1K-blocos      Usad Dispon.   Uso% Montado em
/dev/sda5             48062440  34035024  11585940  75% /

o engraçado é que criei um arquivo de 10GB usando o comando:

dd if=/dev/zero of=file_to-create bs=1k count=10000000

e esse foi criado perfeitamente, ocupou o restante do espaço sem problemas.

Li o seguinte post http://bbs.archlinux.org/viewtopic.php?id=62958 , e parece que o EXT4 ainda não está 100% estável.

A causa pode ser uma queda na luz que ocorreu ontem 12/04/2010, irei executar o comando:

fsck.ext4 -f /dev/sda5

porém esse diz que podem ocorrer problemas caso executado em uma partição montada,
conforme os resultados irei reportar aqui.

GTD: Automatizando sua Agenda diária usando Google Calendar e Gnome


S.O: Ubuntu 9.10
Ferramentas abordadas: Mozilla Sunbird, Gnome Evolution, Google Calendar, iCalendar, Gnome Clock

Esse post foi feito especialmente para aqueles que adoram utilizar o gnome como shell gráfica e que adoram concentrar sua agenda em um ponto específico, no caso o google calendar.

Já vou começar avisando que o motivo de toda essa parafernalha, é que o plugin do Gnome Evolution para conectar com os serviços da google não funciona 100% então tive que adotar esse workaround.

O google calendar já é um velho conhecido, nele podemos manter em um só local nossos apontamentos e compromissos.

O gnome evolution é a ferramenta default de PIM (Gerenciamento de Informações Pessoais) adotada como padrão no Ubuntu. Agora, por que eu acho legal usar o evolution?

  • O Gnome Evolution possui integração com o Gnome Clock, assim no calendário padrão é possível visualizar seus compromissos, também  quando clicando duas vezes em uma data será aberto automaticamente a agenda em tal dia.
  • Também o alarme integrado é legal:

Porém o mais legal seria o Gnome Evolution fazer Read/Write no Google Calendar. Atualmente existe um plugin no repositório que promete fazer isso, porém eu não tive boas experiências com este e não consegui fazê-lo funcionar. Fui obrigado a tomar a seguinte alternativa:

  • Instale o Sunbird (ferramenta de calendário da mozilla)
  • Configure sua conta google, caso tenha dúvidas: http://www.google.com/support/calendar/bin/answer.py?hl=en&answer=99358#sunbird
  • Faça o download e instale o plugin do sunbird: Automatic Exporter (https://addons.mozilla.org/pt-BR/sunbird/addon/3740)
  • Configure o plugin para exportar o google calendar para um arquivos iCal clicando em Ferramentas > Complementos > Automatic Exporter > Preferencias.
    • Marque a opção exportar ao fechar;
    • Selecione o local em que deseja que seu arquivo .ics seja salvo;
    • Selecione o formato iCalendar;
    • Marque a opção Ativo na área Iniciar uma aplicação depois de exportar, e preencha os campos da seguinte forma:
      • Caminho da aplicação: evolution
      • Parametros da aplicação –force-shutdown
  • Agora abra o Evolution
  • Agendas > Clique direito na listagem das agendas > Nova Agenda
    • Tipo: Neste Computador
    • Marque: Personalizar Opções
    • Selecione o arquivo *.ics gerado pelo sunbird (assegure-se de fechá-lo antes para que o export ocorra)
    • Marque a opção Atualizar Periodicamente

Agora vou explicar o motivo disso tudo: O arquivo .ics será nossa ponte entre o Google Calendar -> Sunbird -> Gnome Evolution, o comando “evolution –force-shutdown” irá forçar o evolution a atualizar o calendário do gnome e fechar automaticamente.

Único empecilho é que você deverá utilizar sempre o Sunbird para controlar sua agenda.

Assim termina o nosso workaround, caso tenham alguma duvida sintam-se a vontade de questionarem.

Sql para selecionar nomes de tabelas e colunas no postgres

Um simples sql para quem quer buscar colunas e tabelas no Postgres

select 
c.relname,
a.attname as "Column",
pg_catalog.format_type(a.atttypid, a.atttypmod) as "Datatype"
 
from pg_catalog.pg_attribute a 
inner join pg_stat_user_tables c on a.attrelid = c.relid
WHERE
a.attnum > 0 AND
NOT a.attisdropped
order by c.relname, a.attname

Linux: Comando for no console – Exibir encoding de multiplos arquivos

O código a seguir é um exemplo de como usar loop no console do linux (bash), funciona como um foreach em uma lista
(the following code shows how to use loop/foreach/for on linux console)

$ for i in `find *`; do file "$i" --mime-encoding ; done

O resultado será uma listagem com o encoding de todos arquivos a partir do diretório atual·

exemplo de resultado: webroot/js/jquery.meio.mask.min.js: utf-8

outro exemplo usando if aninhado

for i in `find *`; do if ! echo $i|grep svn --quiet; then file "$i" --mime-encoding; fi; done

p.s: uma forma mais simples de executar o comando acima seria usar o comando “grep svn –revert-match” ou então negar svn no grep, porém não tive sucesso em alguns testes, exemplo:

$ for i in `find *|grep svn --invert-match`; do file "$i" --mime-encoding ; done

Referência:

http://www.vias.org/linux-knowhow/bbg_sect_09_01.html

http://www.vias.org/linux-knowhow/bbg_sect_07_02.html

Comandos essenciais do Eclipse para Java

Tentarei listar nesse post os comandos mais básicos da ferramenta eclipse,
os que eu julgo essenciais.

Sintam-se a vontade para postar outros que você também julgue necessários.

[Ctrl][Shift]+R
Usado para buscar um arquivo (você pode usar wildcards ? qualquer caracter, qualquer string)

[Ctrl][Shift]+T
Buscar um tipo/classe (também possibilita usar wildcards)

[Ctrl]+[Espaço]
Autocompleta um texto (metodo, classe, snippet, anottation, etc).
Existem diversos snippets (blocos de código prontos) que pode ser acessados dessa forma,
um exemplo é digitar “Syso” e pressionar [Ctrl]+[Espaco] assim ele escreverá automaticamente “System.out.println();”

[Ctrl]+A
Selecionar todo o conteúdo do arquivo em questão.

[Ctrl]+I
Identa o código selecionado.

[Shift]+[Tab]
Retrocede identação do bloco selecionado

[Tab]
Caso haja um bloco selecionado irá avança-lo.

[Ctrl][Shift]+O
(letra O)
Irá automaticamente organizar os imports da sua classe Java, removendo os não utilizados.

[Ctrl]+Z [Ctrl]+Y
O bom e velho [Ctrl]+Z que desfaz as ultimas alterações e o [Ctrl]+Y que refaz.

[Ctrl]+Q
Retorna ao ponto da sua ultima alteração (caso você tenha fechado o arquivo ele o abrirá novamente)

[Ctrl]+Click ou F3
Vai até o local onde o elemento clicado, ou com o cursos sobre tiver sido declarado

F2
Exibe as informações do elemento na qual o cursor estiver posicionado

F4
Exibe a Hierarquia da classe em questão, conforme o local onde o cursos estiver posicionado

Por hora são somente estes, sei que muitos devem pensar: “todo mundo sabe disso!”. Criei esse post com o intuito de que fosse utilizado por pessoas em treinamento inicial/estágiarios, muitos materiais relativos e de melhor qualidade podem ser encontrados na internet.
Saber desses comandos pode facilitar e muito o trabalho, aumentar a produtividade além de ajudar a padronização (como exemplo do CTRL+I que onde eu trabalho é pouco usado).

Code: /dev/null ‘s like implementation for java

(This title is weird)

Just to remember, a implementation that send to garbage all the System.out.println messages:

//Java implementation for /dev/null
System.setOut(new java.io.PrintStream(new java.io.OutputStream() {public void write(int b) {}}));
System.out.println("This goes to the void");

Source: http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2006-11/msg03469.html

ArrayStringBuilder makes StringBuilder acts as an array

String concat is something that we need to do a lot when creating SQLs but there is a problem by using string-plus-string concatenation (“string”+”"string”): Every couple of quotations java will create and alocate one String class, this can be a trigger for memory problems.

The orientation (at Celepar) is to use StringBuffer that is faster than simple concat. Searching the web i found that StringBuilder is a bit faster than StringBuffer.

Now let me go to the point, i needed to make an join and use a separator at a group of strings, but memory was something i was worried, then i tried to simulate an array over StringBuilder,  the result was the following class.

p.s: I really doen’t feel that there aren’t a better and faster way to do this, but i didn’t found anything at this time;

package com.br.webcentro.utils;

import java.util.Arrays;

/**
 * This class works using the java.lang.StringBuilder,
 * but this simulates an array to implement a joinable splitable string
 *
 * may be better extend the class AbstractStringBuilder but for now it will only work using it;
 *
 * feel free to post implementations
 *
 * If you have some advice please contact me at webcentro(at)gmail.com
 * @author alandanielweiss
 * @since 2010-01-22
 */

public class ArrayStringBuilder implements java.io.Serializable{

	private StringBuilder builder;

	private boolean isMultiEnabled = false;
	private boolean isEmptyAllowed = true;

	private int start[];
	private int len[];
	private int counter=0;
	private int totalLen=0;

	private static final long serialVersionUID = -2443226579329551214L;

	/**
     * Constructs a string builder with no characters in it and an
     * initial capacity of 16 characters.
     */

	public ArrayStringBuilder() {
		this.builder = new StringBuilder();
		this.start   = new int[16];
		this.len     = new int[16];
    }

	/**
	 * Sets the initial StringBuilder capacity
	 * @param capacity
	 */
	public ArrayStringBuilder(int capacity) {
		this.builder = new StringBuilder(capacity);
		this.start   = new int[capacity];
		this.len     = new int[capacity];
    }

	/**
	 * Create class and append string
	 * @param string
	 */
    public ArrayStringBuilder(String string) {
    	this();
    	this.add(string);
    }

	/**
	 * Create class and the the StringBuilder
	 * @param string
	 */
    public ArrayStringBuilder(StringBuilder builder) {
		this.start   = new int[16];
		this.len     = new int[16];

		this.counter = 1;
    	this.start[0] = 0;
    	this.len[0] = builder.toString().length();
    	this.totalLen = this.len[0];

    	this.builder = builder;
    }

    /**
     * Append a string
     * @param str
     * @return
     */
	public ArrayStringBuilder add(String str){
		if (str == null)
			str = "null";
	    int len = str.length();
		if (len == 0 && !isEmptyAllowed)
			return this;

		//multi-line don't increment counter
		if(!this.isMultiEnabled)
			this.counter ++;

		if (this.counter > start.length)
		    expandCapacity(this.counter);

		if(!this.isMultiEnabled)
			this.start[this.counter-1] = this.totalLen;

		if(this.isMultiEnabled)
			len +=this.len[this.counter-1];

		this.len[this.counter-1]   = len;

		this.totalLen += str.length();
		this.builder.append(str);
		return this;
	}

	/**
	 * start multiline array
	 * when done use the method end()
	 * @return
	 */
	public ArrayStringBuilder start(String str){
		this.isMultiEnabled = false;
		this.add(str);
		this.isMultiEnabled = true;
		return this;
	}

	/**
	 * finish multiline array
	 * @return
	 */
	public ArrayStringBuilder finish(String str){
		this.add(str);
		this.isMultiEnabled = false;
		return this;
	}

	void expandCapacity(int minimumCapacity) {
		int newCapacity = (start.length + 1) * 2;
        if (newCapacity < 0) {
        	newCapacity = Integer.MAX_VALUE;
        } else if (minimumCapacity > newCapacity) {
        	newCapacity = minimumCapacity;
		}
        this.start = Arrays.copyOf(this.start, newCapacity);
        this.len = Arrays.copyOf(this.len, newCapacity);
    }

	/**
	 * Joins the StringBuilder using the passed separator
	 * @param separator
	 * @return
	 */
	public String join(String separator){
		StringBuilder str = new StringBuilder();
		for (int idx=0; idx<this.counter;idx++){
			str.append(this.builder.substring(this.start[idx], this.start[idx]+this.len[idx]));
			if(idx+1<this.counter)
				str.append(separator);
	    }
		return str.toString();
	}

	public String[] toArray(){
		String[] str = new String[this.counter];
		for (int idx=0; idx<this.counter;idx++){
			str[idx] = this.builder.substring(this.start[idx], this.start[idx]+this.len[idx]);
	    }
		return str;
	}

	/**
	 * To string...
	 * @return String
	 */
    public String toString() {
    	return this.builder.toString();
    }

    /**
     * Creates a StringBuilder with the actual object values
     * @return builder:StringBuilder
     */
    public StringBuilder getStringBuilder(){
    	return this.builder;
    }

    /**
     * when true every time you use add/start/finish with an empty string it will add a new array
     * if false the command add/start/finish empty has no effect
     */
    public void setEmptyAllowed(boolean isMultiEnabled){
    	this.isMultiEnabled = isMultiEnabled;
    }

    public static void main(String[] args) {
		//Sample 1
    	StringBuilder strb = new StringBuilder();
    	strb.append("to be");
    	ArrayStringBuilder arrb = new ArrayStringBuilder(strb);
    	arrb.start(" or ");
    	arrb.add("not ");
    	arrb.add("to ");
    	arrb.finish("be");
		ArrayStringBuilder arrb2 = new ArrayStringBuilder(arrb.join(","));
		System.out.println(arrb2.add(": that's").add("the").add("question").join(" "));

		//Sample 2
		ArrayStringBuilder fields = new ArrayStringBuilder();
		fields.add("id");
		if(1==1)
			fields.add("name");
		if(1==2)
			fields.add("profession");
		StringBuilder sql = new StringBuilder();
		sql.append("select ").append(fields.join(" , ")).append(" from table ");
		System.out.println(sql.toString());
	}
}

A good comparision between StringBuilder and StringBuffer can be found at: StringBuilder vs StringBuffer vs String.concat – done right

Please feel free to send comments, to improve this class.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.