sexta-feira, 31 de outubro de 2008

Transferir bytes de um lado pro outro

Quando você quer transferir bytes de um lado pro outro via socket você pode utilizar várias estratégias, eu criei dois Iterators para facilitar esta tarefa.


Trecho da classe que envia

Socket s = new Socket("localhost", 8888);
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
byte[] nome = { 1, 2, 3, 4, 5, 6, 7 };

ByteArrayInputStream bytArrIn = new ByteArrayInputStream(nome);

SenderInputStreamIterator it = new SenderInputStreamIterator(in, out, bytArrIn);
while (it.hasNext()) {
byte[] b = (byte[]) it.next();
System.out.println(b[0]);
}



Trecho da classe que recebe

ServerSocket serv = new ServerSocket(8888);
Socket s = serv.accept();
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();

ByteArrayOutputStream byteArrOut = new ByteArrayOutputStream();
ReaderInputStreamIterator it = new ReaderInputStreamIterator(in, out);
while (it.hasNext()) {
byte[] b = (byte[]) it.next();
System.out.println(b[0]);

}





/**
* Classe criada para receber as informações enviadas pelo
* SenderInputStreamIterator.

*
* Oquê acontece na verdade é que esta classe pergunta diz: Tem mais? Então
* manda!
*
* @author Clayton.Passos
*
*/
public class ReaderInputStreamIterator implements Iterator {
private static final int BUFFER_SIZE = 1;
private DataInputStream dataIn;
private DataOutputStream dataOut;
private byte[] buffer = new byte[BUFFER_SIZE];

/**
*
* @param in
* Canal de comunicação de entrada de dados, utilizado para pedir
* mais informações para o SenderInputStreamIterator através do
* hasNext(). Também é utilizado pelo next() par ler as
* informações que o SenderInputStreamIterator está enviando.
*
* @param out
* Canal de comunicação utilizado para pedir mais informações ao
* SenderInputStreamIterator
*/
public ReaderInputStreamIterator(InputStream in, OutputStream out) {
this.dataIn = new DataInputStream(in);
this.dataOut = new DataOutputStream(out);
}

public boolean hasNext() {
try {
// Tem mais informações/bytes?
dataOut.writeByte(TransferProtocol.hasNext);
byte hasNext = dataIn.readByte();

switch (hasNext) {
case TransferProtocol.yesHasNext:
return true;
case TransferProtocol.noHasNext:
return false;
default:
throw new IllegalStateException("TransferProtocol unexpected");
}

} catch (Exception e) {
throw new IllegalStateException(e);
}
}

public Object next() {
try {
// Se tem mais informações/bytes? Então manda.
dataIn.readFully(buffer);
return buffer;
} catch (Exception e) {
throw new IllegalStateException(e);
}
}

/**
* Not implemented, and in real case... you don´t implement this method
*/
public void remove() {
throw new IllegalStateException("Not implemented");
}
}






/**
* Classe destinada a enviar as informações contida no InputStream para a saída
* de dados sob demanda.

* Oquê acontece na verdade é que esta classe fica esperando a
* ReaderInputStreamIterator perguntar: Tem mais?
*
*

* Dialogo:
* Reader: Tem alguma coisa ai pra mim? Tem mais?
* Sender: Tenho, Toma!
*

*
* @author Clayton.Passos
*
*/
public class SenderInputStreamIterator implements Iterator {
private static final int BUFFER_SIZE = 1;
private DataInputStream dataIn;
private DataOutputStream dataOut;
private int bytesRead;
private byte[] buffer = new byte[BUFFER_SIZE];
private ByteArrayInputStream byteArrIn;

/**
*
* @param in
* Canal de comunicação para que o hasNext saiba que o
* ReaderInputStreamIterator está pedindo mais informações
* @param out
* Canal de comunicação para que o next() possa enviar a
* informação
*
* @param byteArrIn
* informações a serem enviadas e recebidas pelo
* ReaderInputStreamIterator
*/
public SenderInputStreamIterator(InputStream in, OutputStream out,
ByteArrayInputStream byteArrIn) {
this.dataIn = new DataInputStream(in);
this.dataOut = new DataOutputStream(out);
this.byteArrIn = byteArrIn;
}

public boolean hasNext() {
try {
// Reader está pedindo mais informações/bytes?
byte hasNext = dataIn.readByte();
if (hasNext == TransferProtocol.hasNext) {
bytesRead = byteArrIn.read(buffer);
// Se tem, então avisa que tem
if (bytesRead != -1) {
dataOut.write(TransferProtocol.yesHasNext);
dataOut.flush();
return true;
// Se não tem, então avisa que não tem
} else {
dataOut.writeByte(TransferProtocol.noHasNext);
dataOut.flush();
return false;
}

} else {
throw new IllegalStateException("TransferProtocol unexpected");
}

} catch (Exception e) {
throw new IllegalStateException(e);
}
}

public Object next() {
try {
// Manda mais informações/bytes
dataOut.write(buffer);
dataOut.flush();
} catch (Exception e) {
throw new IllegalStateException(e);
}
return buffer;
}

/**
* Not implemented, and in real case... you don´t implement this method
*/
public void remove() {
throw new IllegalStateException("Not implemented");
}
}

segunda-feira, 20 de outubro de 2008

Campos de banco X Hibernate

Como saber o nome da coluna utilizada no banco de dados no mapeamento do hibernate, em tempo de execução?

Como saber o nome da tabela utilizada para persistir uma entidade?


Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();

// através do Configuration
PersistentClass classMapping =
cfg.getClassMapping("com.entity.Usuario");

String tableName = classMapping.getTable().getName();
System.out.println("Nome da tabela: " + tableName);

Column column2 = classMapping.getTable().getColumn(2);
System.out.println("Nome da 2ª coluna: " + column2.getName());

Chave primaria hibernate

Como saber qual é a propriedade referente a chave primária e um objeto utilizando hibernate?


Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();

//através do Configuration
PersistentClass classMapping =
cfg.getClassMapping("com.model.entity.Usuario");

System.out.println("chave: " +classMapping .getIdentifierProperty().getName());

KeyValue identifier = classMapping.getIdentifier();
Iterator columnIterator = identifier.getColumnIterator();
while(columnIterator.hasNext()){
Column cl = (Column) columnIterator.next();
System.out.println("chave: " +cl.getName());
}


//Através da Factory
ClassMetadata classMetadata =
factory.getClassMetadata("com.model.entity.Usuario");

System.out.println("chave: "
+ classMetadata.getIdentifierPropertyName());

sábado, 18 de outubro de 2008

Compactar e descompactar

Classe utilitária para compactar e descompactar arquivos zip apartir de um stream de dados



/**
* Compact and Unpack Zip files
*
* @author Clayton.Passos
*
*/
public class Zip implements ICompactOperation {
private static final int BUFFER_SIZE = 1024;

/**
* Compacta os arquivos da lista armazenando-os no output
*
* @param fileLst
* List
* @param dataOut
*
* @param pathComplete
* Se for verdadeiro guardará todo o caminho até o arquivo

* Se for falso armazenará apenas o arquivo, sem o caminho
* @throws IOException
*/
public static void compact(List fileLst, DataOutputStream dataOut,
boolean pathComplete) throws IOException {
ZipOutputStream out = new ZipOutputStream(dataOut);
out.setLevel(9);

// Create a buffer for reading the files
byte[] BUFFER = new byte[BUFFER_SIZE];

// Compress the files
FileInputStream in;
File file;
for (int i = 0; i < fileLst.size(); i++) {
file = (File) fileLst.get(i);
in = new FileInputStream(file);

// Add ZIP entry to output stream.
ZipEntry entry;
if (pathComplete) { // Complete path in zip file
entry = new ZipEntry(file.getPath());
} else {// only file in zip file, no path
entry = new ZipEntry(file.getName());
}

out.putNextEntry(entry);

// Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(BUFFER)) > 0) {
out.write(BUFFER, 0, len);
out.flush();
}

// Complete the entry
out.closeEntry();
in.close();
}

// Complete the ZIP file
out.close();
}

/**
* Descompacta o arquivo no local definido por outFilesPath
*
* @param dataIn
*
* @param outFilesPath
* Local onde ficarão os arquivos
* @throws IOException
*/
public static void unpack(DataInputStream dataIn, String outFilesPath)
throws IOException {
ZipInputStream zis = new ZipInputStream(dataIn);
ZipEntry zipEntry = null;
byte[] BUFFER = new byte[BUFFER_SIZE];
String path;
while ((zipEntry = zis.getNextEntry()) != null) {
path = outFilesPath + File.separator + zipEntry.getName();

// if don´t exist, create this path
new File(new File(path).getParent()).mkdirs();

FileOutputStream fileOut = new FileOutputStream(path);
int count;
while ((count = zis.read(BUFFER, 0, BUFFER_SIZE)) != -1) {
fileOut.write(BUFFER, 0, count);
}
fileOut.close();

}
zis.close();
}
}