UM SISTEMA DE GERÊNCIA DE ESTAÇÕES REMOTAS … · rabalhoT de conclusão de curso apresentado...

303

Transcript of UM SISTEMA DE GERÊNCIA DE ESTAÇÕES REMOTAS … · rabalhoT de conclusão de curso apresentado...

UNIVERSIDADE FEDERAL DE SANTA CATARINA

UM SISTEMA DE GERÊNCIA DEESTAÇÕES REMOTAS UTILIZANDO

RFB SOBRE VNC

Anderson Bu�on BertoGilberto Torrezan Filho

Florianópolis - SC 2006/2

UNIVERSIDADE FEDERAL DE SANTA CATARINADEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA

CURSO DE CIÊNCIAS DA COMPUTAÇÃO

UM SISTEMA DE GERÊNCIA DEESTAÇÕES REMOTAS UTILIZANDO

RFB SOBRE VNC

Anderson Bu�on BertoGilberto Torrezan Filho

Trabalho de conclusão decurso apresentado comoparte dos requisitos paraa obtenção do grau deBacharel em Ciências daComputação.

Florianópolis - SC 2006/2

Anderson Bu�on BertoGilberto Torrezan Filho

UM SISTEMA DE GERÊNCIA DEESTAÇÕES REMOTAS UTILIZANDO

RFB SOBRE VNC

Trabalho de conclusão de curso apresentado como parte dosrequisitos para a obtenção do grau de Bacharel em Ciências daComputação.

Orientador: Prof. Dr. Leandro José Komosinski

Banca Examinadora

Prof. Dr. José Mazzucco Jr.

Prof. Dr. Mário Antônio Ribeiro Dantas

Agradecimentos

Agradeço à minha mãe por ter dado apoio e condições para que eu �zesseo curso de ciências da computação.

Anderson Bu�on Berto

Agradeço à minha namorada por ter me aturado durante a elaboraçãodesse trabalho, à todos os meus amigos que entederam a minha ausência, àminha mãe por ter me dado apoio (tanto moral quanto proteico, a�nal elacozinha muito bem) e ao meu pai que mesmo distante ajudou muito.

Gilberto Torrezan Filho

Resumo

Esse trabalho se destina à construção de um software de gerenciamentoremoto de estações de trabalho via dispovitivos móveis. Os requisitos nãofuncionais de�nidos são: usabilidade, con�abilidade e desempenho.

Foi realizada a análise de projetos correlatos, os mesmos foram análisadossegundo o código, navegabilidade, portabilidade e desempenho. Fizemos umservidor bridge para a comunicação entre o cliente e o servidor VNC. Nesseservidor bridge foi feita a construção da persistência das tarefas e a execuçãodas mesmas, podendo mostrar o uso da CPU, espaço em disco, memórialivre, entre outros. Foi implementado uma �casca� no cliente (wrapper) coma função de receber as tarefas do servidor, as informações pertinentes a cadatarefa e o envio de comandos para que as tarefas possam ser executadasatravés do dispositivo móvel.

Com o servidor e o cliente �nalizados, podemos testar o projeto e con-�rmar que é possível que se faça um gerenciamento remoto de estações detrabalho sem que se exija muito processamento do dispositivo cliente.

Palavras-chave: Telefone Celular, VNC, RFB, Computação Remota,Ferramentas de Gerência.

Abstract

This work focus on the constrution of a remote management software ofworkstations through mobile devices. The non-functional requirements are:usability, trustworthiness and performance.

We made the analisys of the correlated projects, taking as paramters somemeasures like quality of code, navegability, portability and performance. Onthe server side, we made the persistence of the tasks, as the execution pathof them. With the execution of the tasks, measures like CPU use, free diskspace, free memory and so on can be stored and analised. On the mobile clientside, we extended the protocol to support the task selection and executionfeatures.

With the �nished project, we conclude that is possible to make a remotemanagement of workstations without the demanding of a big processing onthe client device.

Key Words: Cell Phone, VNC, RFB, Remote Computing, ManagementTools.

Sumário

1 Introdução 11.1 De�nição do Problema . . . . . . . . . . . . . . . . . . . . . . 11.2 Objetivo Geral . . . . . . . . . . . . . . . . . . . . . . . . . . 21.3 Objetivos Especí�cos . . . . . . . . . . . . . . . . . . . . . . . 3

2 VNC e o Protocolo RFB 52.1 VNC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Introdução ao RFB . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.1 Interface com o usuário através do Protocolo RFB . . . 62.2.2 Codi�cações do Protocolo . . . . . . . . . . . . . . . . 72.2.3 Extensões do Protocolo . . . . . . . . . . . . . . . . . . 82.2.4 Novas Codi�cações . . . . . . . . . . . . . . . . . . . . 82.2.5 Falsa Codi�cação . . . . . . . . . . . . . . . . . . . . . 82.2.6 Segurança . . . . . . . . . . . . . . . . . . . . . . . . . 92.2.7 Mensagens . . . . . . . . . . . . . . . . . . . . . . . . . 92.2.8 Inicialização do Cliente . . . . . . . . . . . . . . . . . . 102.2.9 Inicialização do Servidor . . . . . . . . . . . . . . . . . 112.2.10 Mensagens do Cliente para o Servidor . . . . . . . . . . 112.2.11 Mensagens do Servidor para o Cliente . . . . . . . . . . 12

3 Trabalhos Correlatos 133.1 Trabalhos analisados . . . . . . . . . . . . . . . . . . . . . . . 13

3.1.1 VNC2Go . . . . . . . . . . . . . . . . . . . . . . . . . . 133.1.2 PocketVNC . . . . . . . . . . . . . . . . . . . . . . . . 143.1.3 .NET VNC Viewer: . . . . . . . . . . . . . . . . . . . . 153.1.4 J2ME VNC . . . . . . . . . . . . . . . . . . . . . . . . 163.1.5 JNC Mobile . . . . . . . . . . . . . . . . . . . . . . . . 173.1.6 VNC Viewer . . . . . . . . . . . . . . . . . . . . . . . . 183.1.7 Imhotek VNC . . . . . . . . . . . . . . . . . . . . . . . 18

3.2 Comparação entre os projetos . . . . . . . . . . . . . . . . . . 193.2.1 Código . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

iii

3.2.2 Navegabilidade . . . . . . . . . . . . . . . . . . . . . . 203.2.3 Portabilidade . . . . . . . . . . . . . . . . . . . . . . . 203.2.4 Desempenho . . . . . . . . . . . . . . . . . . . . . . . . 20

4 Projeto e Desenvolvimento do Sistema Proposto 214.1 Projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214.2 Desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . 22

4.2.1 Servidor Bridge . . . . . . . . . . . . . . . . . . . . . . 224.2.2 Wrapper do Cliente . . . . . . . . . . . . . . . . . . . . 344.2.3 Discussão Dos Resultados . . . . . . . . . . . . . . . . 47

5 Conclusão 515.1 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515.2 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . 52

A Lista de Acrônimos 57

B Ferramentas Utilizadas 59B.1 Eclipse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59B.2 J2ME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60B.3 Antenna . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61B.4 Hibernate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61B.5 HSQLDB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62B.6 JCon�g . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63B.7 GPL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63B.8 CVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64B.9 Quartz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

C Anexos 66C.1 Código Fonte da Aplicação Cliente (J2ME VNC com Wrapper) 66C.2 Código Fonte do Servidor Bridge . . . . . . . . . . . . . . . . 162

D Artigo 279D.1 Resumo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280D.2 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280

D.2.1 Objetivo Geral . . . . . . . . . . . . . . . . . . . . . . 281D.2.2 Objetivos Especí�cos . . . . . . . . . . . . . . . . . . . 281

D.3 VNC e RFB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281D.3.1 VNC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281D.3.2 RFB . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282

D.4 Trabalhos Correlatos Analisados . . . . . . . . . . . . . . . . . 282D.4.1 Comparação entre os projetos . . . . . . . . . . . . . . 282

iv

D.5 Projeto e Desenvolvimento . . . . . . . . . . . . . . . . . . . . 283D.5.1 Projeto . . . . . . . . . . . . . . . . . . . . . . . . . . 283D.5.2 Desenvovimento . . . . . . . . . . . . . . . . . . . . . . 283

D.6 Discussão dos Resultados . . . . . . . . . . . . . . . . . . . . . 287D.7 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288D.8 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . 289

v

Lista de Figuras

2.1 Modelo cliente-servidor. . . . . . . . . . . . . . . . . . . . . . 6

4.1 Estrutura do projeto. . . . . . . . . . . . . . . . . . . . . . . . 224.2 Entidades. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234.3 Sequência da execução de uma task. . . . . . . . . . . . . . . . 254.4 Extensão do RFB no cliente. . . . . . . . . . . . . . . . . . . . 274.5 Extensão do RFB no servidor RFB. . . . . . . . . . . . . . . . 284.6 Fluxo de execução no sentido cliente para servidor. . . . . . . 284.7 Fluxo de execução no sentido servidor para cliente. . . . . . . 294.8 Pacote transmitido contendo as tarefas cadastradas. . . . . . . 304.9 Pacote transmitido contendo o resultado da execução de uma

tarefa. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304.10 Tela inicial do servidor bridge com tarefas cadastradas. . . . . 314.11 Inicialização do servidor bridge. . . . . . . . . . . . . . . . . . 324.12 Tela de adição de nova tarefa. . . . . . . . . . . . . . . . . . . 334.13 Seqüência de execução para cadastro de novas tarefas. . . . . . 344.14 Seqüência de execução para a geração de grá�cos. . . . . . . . 354.15 Tela inicial. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364.16 Acessando o menu Ctrl Alt Del. . . . . . . . . . . . . . . . . . 364.17 Tela após o ctrl alt del executado. . . . . . . . . . . . . . . . . 374.18 Acessando Modo no menu. . . . . . . . . . . . . . . . . . . . . 374.19 Tela com os modos. . . . . . . . . . . . . . . . . . . . . . . . . 384.20 Zoom in e zoom out. . . . . . . . . . . . . . . . . . . . . . . . 384.21 Escrita com SMS. . . . . . . . . . . . . . . . . . . . . . . . . . 394.22 Menu apertar enter. . . . . . . . . . . . . . . . . . . . . . . . . 404.23 Menu repintar. . . . . . . . . . . . . . . . . . . . . . . . . . . 404.24 Menu opções. . . . . . . . . . . . . . . . . . . . . . . . . . . . 414.25 Opções dentro do menu opções. . . . . . . . . . . . . . . . . . 424.26 Menu chamar mouse e após executado. . . . . . . . . . . . . . 424.27 Menu Entrar com Texto. . . . . . . . . . . . . . . . . . . . . . 434.28 Digintando texto no celular. . . . . . . . . . . . . . . . . . . . 434.29 Texto inserido no bloco de notas. . . . . . . . . . . . . . . . . 44

vi

4.30 Menu Segurar Control, Alt, Meta. . . . . . . . . . . . . . . . . 444.31 Menu Tarefas. . . . . . . . . . . . . . . . . . . . . . . . . . . . 454.32 Tarefas que estão cadastradas no servidor. . . . . . . . . . . . 454.33 Estatítiscas da tarefa seleciona, Tarefa 3 no caso. . . . . . . . 46

D.1 Estrutura do projeto. . . . . . . . . . . . . . . . . . . . . . . . 284D.2 Entidades. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 285D.3 Extensão do RFB no cliente. . . . . . . . . . . . . . . . . . . . 286D.4 Extensão do RFB no servidor RFB. . . . . . . . . . . . . . . . 286

vii

Lista de Tabelas

2.1 Tabela Versões do Protocolo . . . . . . . . . . . . . . . . . . 92.2 Tabela Desa�o enviado pelo servidor. . . . . . . . . . . . . . 102.3 Tabela resposta do cliente ao desa�o do servidor. . . . . . . . 102.4 Tabela Evento de Tecla . . . . . . . . . . . . . . . . . . . . . 112.5 Tabela Evento do Mouse . . . . . . . . . . . . . . . . . . . . 12

3.1 Tabela Comparativa Entre Trabalhos Correlatos . . . . . . . . 19

4.1 Tabela Comparativa Entre Trabalhos Correlatos . . . . . . . 48

viii

Capítulo 1

Introdução

1.1 De�nição do Problema

Com a crescente velocidade com que a informação é gerada e transmi-tida, fazem-se necessárias cada vez mais tecnologias para expandir e agilizaros processos de gerência, manutenção e assistência de produtos e serviçosatravés dos diversos meios pelos quais a informação é gerada, transmitidae armazenada. Não se pode mais perder tempo entre a ocorrência de umproblema e a tomada de decisão que inicie o processo de solução do mesmo.

O que as tecnologias de informação mais prezam é o fator agilidade.Quanto mais rápido um sistema opera, mais e�caz ele tende a ser. As tec-nologias móveis ou sem �o são um exemplo: ter um dispositivo receptor deinformação disponível em qualquer lugar independente de fonte de alimen-tação ou ponto de comunicação �xos é um grande trunfo dessa tecnologia, oque a faz ser e�caz e, no caso de telefones celulares, massivamente popular.

Com a evolução dos telefones celulares para "smart-phones"(telefones in-teligentes), que além de fazerem ligações telefônicas também incorporam fun-ções de um computador pessoal (PC), a tecnologia móvel deu um grandepasso. A união entre a funcionalidade do PC e a popularidade do celularabriram as portas para in�nitas possibilidades de agilização de processos emelhoria de serviços na área da informação.

Porém, tanta mobilidade e praticidade têm um custo. Um dispositivomóvel isolado possui capacidade de armazenamento e processamento muitoinferiores aos dispositivos ditos �xos (não-móveis). Isso limita o alcance datecnologia móvel de certa maneira, mas instiga a procura de soluções viáveis

1

para o uso adequado de suas funcionalidades.Uma das soluções é justamente o ponto forte da tecnologia móvel: a

comunicação. Se um dispositivo isolado não é capaz de executar determi-nada função, ele pode se comunicar com outros dispositivos para diminuiro impacto da execução da tarefa, delegando responsabilidades. É o famosoprincípio da "Divisão e Conquista".

Outra abordagem similar é a comunicação com os dispositivos �xos, cujascapacidades de armazenamento e processamento são maiores. Uma tarefapode ser delegada por um dispositivo móvel a um dispositivo �xo, e esteretornar os resultados da tarefa para aquele. A grosso modo, sob a óptica datarefa concluída, o dispositivo móvel é quem a executou.

Um exemplo prático dessa abordagem é o acesso remoto de um computa-dor via um aparelho celular. O celular pode enviar comandos para o compu-tador, este executar a tarefa, e enviar os resultados de volta para o celular.Tarefas simples como reiniciar um computador, executar um programa remo-tamente ou simplesmente veri�car se tudo corre bem num servidor podemser facilmente delegáveis por um dispositivo móvel via internet, poupandotempo e obviamente sendo mais cômodo ao usuário.

É nesse contexto que esse trabalho se insere: promover a delegação detarefas de um dispositivo móvel para um computador �xo, via internet. Oprincípio de delegação de funções de um dispositivo para outro não é novi-dade, já que há muito que a internet é uma realidade. O que é relativamentenovo é a possibilidade de comunicação e delegação de tarefas entre disposi-tivos de diferentes "naturezas", como é o caso de um aparelho celular e umcomputador pessoal.

Um famoso método de acesso entre dois computadores pessoais é via VNC(Virtual Network Computing), que é um programa que permite acessar asfunções de um computador remotamente como se não o fosse remoto.

1.2 Objetivo Geral

Esse trabalho originalmente se propôs a estender e aprimorar o trabalhoJNC Mobile - Sistema de Acesso Remoto para Dispositivos Móveis[JNC ],desenvolvido por Andrei Luciano Krause e Rafael Augusto da Silva, imple-mentando requisitos descritos como trabalhos futuros pelos autores, além deoutros novos requisitos.

Porém, com a análise feita no trabalho JNC Mobile, descobriu-se váriosproblemas que estavam além da implementação de novos requisitos. Entreeles:

• Código de difícil interpretação e manutenção, dado o alto acoplamento

2

e baixa coesão das classes;

• Falta de documentação no código;

• Baixo desempenho, a ponto de tornar o uso prático inviável;

• Problemas com a navegabilidade por parte do cliente.

Dados esses problemas, decidiu-se então que seria melhor estender umprojeto open-source correlato ao JNC Mobile, onde esses problemas não setornassem uma barreira ao desenvolvimento. Dessa maneira o foco será uni-camente voltado ao desenvolvimento e pesquisa dos novos requisitos, e não areformulação de um projeto todo (ou, utilizando o famoso jargão da compu-tação, "não reinventar a roda").

O projeto adotado como base foi o J2ME VNC. A discussão dos pontosfortes desse projeto com relação aos outros analisados, inclusive com relaçãoao projeto original, está descrita no capítulo 3.

Portanto, o objetivo passou a ser a implementação dos requisitos aponta-dos como trabalhos futuros no projeto JNC Mobile, além de outros requisitosdescritos a seguir, tendo como base de desenvolvimento o projeto J2ME VNC.

É esperado que ao �nal do desenvolvimento seja possível alcançar níveisde operabilidade bons o su�ciente para que o sistema seja eventualmenteutilizado por empresas e até por pessoas comuns em seu dia-a-dia.

1.3 Objetivos Especí�cos

Objetivos Principais:

• Implementação de um servidor bridge que recebe e gerencia as novasrequisições feitas pelo cliente;

• Cadastro de Tarefas (desligar, reiniciar, ativar desfragmentador dedisco, rotinas de trabalho, rodar antivírus, entre outras) no servidorbridge, além da correspondente interface no cliente;

• Estudo do protocolo RFB (Remote Framebu�er) utilizado no sistemaVNC;

• Implementação da função de zoom panorâmico.

Objetivos Secundários:

• Implementação de um sistema de monitoramento via web, utilizando amesma tecnologia adotada no sistema VNC;

3

• Internacionalização da interface grá�ca para português (pt_BR).

4

Capítulo 2

VNC e o Protocolo RFB

2.1 VNC

VNC[VNC a] (Virtual Network Computing) é um sistema criado parapossibilitar o acesso a computadores remotos. Com o VNC o usuário podeacessar todas as funcionalidades do computador (controlar o mouse, o te-clado, executar programas, etc) como se estivesse na frente do mesmo, in-dependendo do sistema operacional. Para usuários comuns o VNC pode serusado para ajudar um amigo ou familiar que esteja com algum problema enão entenda de computadores, para as empresas, o administrador do sistemapode reparar erros sem sair da sua sala. Também possui �ns educacionais,por exemplo, um instrutor ensinar um grupo de estudantes ao mesmo tempo.

O VNC foi um projeto desenvolvido pela ORL (Olivetti Research Labo-ratory), e comprado em 1999 pela AT&T. Uma das características do VNC éser um software livre, e para que continue assim, ele está sob a licença GPL.Utiliza o modelo cliente servidor.

2.2 Introdução ao RFB

O RFB (Remote FrameBu�er)[RFB ] é um protocolo construído para oacesso remoto em interfaces grá�cas. Aplicável a todos os sistemas de janelas(X11, Windows e Macintosh).

Esse protocolo funciona no modelo cliente-servidor, �gura 2.1. O compu-tador remoto, computador o qual possui o sistema operacional e as aplicações

5

que poderão ser usadas, é chamado de servidor RFB. O cliente RFB é o com-putador (ou qualquer outro dispositivo que possa fazer esse tipo de conexão,no caso desse trabalho, é utilizado um dispositivo móvel) que se conectaao servidor RFB e após a conexão feita �possui� o sistema de janelas e asaplicações desse servidor.

Figura 2.1: Modelo cliente-servidor.

O RFB foi desenvolvido para ser leve e com sua implementação o maissimples possível, de tal maneira que se exija quase nada do dispositivo cliente.Assim vários dispositivos podem ser usados, inclusive os aparelhos celularesque possuem uma capacidade muito menor de processamento. O protocolotambém é capaz de gerênciar os estados do cliente. Esses estados guardama interface do usuário e as aplicações que estavam sendo usadas.

2.2.1 Interface com o usuário através do Protocolo RFB

O protocolo trata a interface com o usuário de um modo muito simples.Basicamente é: desenha-se um retângulo de pixels na posição x, y indicada.Apesar de parecer um modo muito simples, ele foi o escolhido, pois ofereceuma grande �exibilidade nas questões de velocidade com que o cliente pintaa tela, o menor uso de tráfego de dados entre o cliente-servidor e usandomais a capacidade de processamento do servidor. Para diminuir ainda maiso tráfego e o processamento no cliente as atualizações de tela são feitas deacordo com a demanda do cliente, o servidor só irá mandar uma atualizaçãose a mesma for uma resposta a uma requisição do cliente.

6

Desenhar um retângulo de pixels envolve outras questões, como qual for-mato e codi�cação de pixel usar. Para isso ser resolvido existe uma negocia-ção entre o cliente e o servidor. A escolha sempre será a que deixe o trabalhodo cliente o mais simples. Os formatos mais comuns para a representação dascores são: 8-bit, 16-bit e 24-bit. A codi�cação se refere a como o retângulo(tela) de pixels será enviado. As codi�cações oferecidas pelo protocolo RFBsão: Raw, CopyRect, RRE, CoRRE, Hextile e ZRLE.

2.2.2 Codi�cações do Protocolo

Raw

A codi�cação do tipo Raw é a mais simples de todas. Ela consiste emaltura do retângulo x largura do retângulo x bytes por pixel e um array depixels e deve ser desenhado da esquerda para a direita.

Todos os clientes devem conhecer essa codi�cação e o servidor não irá usá-la somente se o cliente especi�car que outra codi�cação deverá ser usada.

CopyRect

A CopyRect é usada quando o cliente já possui no seu framebu�er oretângulo a ser desenhado, ou seja, o servidor somente mandará ao clientea posição x, y do retângulo que deve ser copiado e a posição x, y onde oretângulo copiado deverá ser desenhado.

RRE

A codi�cação RRE (rise-and-run-length encoding), transforma a tela aser desenhada em sub-retângulos. O cliente pode renderizar o retângulo aser pintado, desenhando todos os seus sub-retângulos.

CoRRE

O Compact RRE apenas garante que o tamanho do retângulo não ultra-passe 255x255 pixels.

7

Hextile

É uma variação do CoRRE. Ela usa tiles de 16x16. Tiles são pequenosquadrados que quando unidos formam a tela inteira. Se a tela não for múltiplade 16 os últimos tiles enviados serão do tamanho necessário para preenchero restante que falta para pintar. Por padrão esse tiles devem ser desenhadosna tela da esquerda para direita e de cima para baixo (top-left). E em cadatile é usada a codi�cação Raw ou outra codi�cação (BackgroundSpeci�ed,ForegroundSpeci�ed, AnySubrects, SubrectsColoured).

ZRLE

Os dados do ZRLE quando descomprimidos equivalem ao Hextile de tilede 64x64. O ZRLE usa o CPIXEL (compressed Pixel).

2.2.3 Extensões do Protocolo

Extensão do protocolo signi�ca adicionar novas codi�cações no mesmo.Para que essas novas codi�cações funcionem, uma das exigências do protocoloRFB é que tanto o cliente quanto o servidor devem implementar essa novacodi�cação.

2.2.4 Novas Codi�cações

O protocolo RFB permite que sejam feitas novas codi�cações mantendoa compatibilidade entre os clientes e servidores. Porém certos servidores quenão suportam essa nova codi�cação irão ignorar a requisição feita com ela.E os clientes que não conhecerem a mesma nunca farão uma requisição comessa nova codi�cação.

2.2.5 Falsa Codi�cação

Acontece quando o cliente requisita a execução de uma codi�cação quenão esteja implementada no servidor. Se o servidor suportar essa codi�caçãoele irá atendê-la, senão irá ignorá-la. Como cliente não sabe se o servidor su-porta ou não a extensão, o cliente deve assumir que o servidor não reconhecea mesma, até ter uma resposta positiva do servidor.

8

1. Cursor

Clientes que requisitam essa pseudo-codi�cação indicam que são capa-zes de desenhar um cursor localmente.

2. Tamanho do Desktop

Cliente é capaz de aceitar mudanças de altura e largura do framebu�er.

2.2.6 Segurança

Para a segurança o cliente e servidor devem entra em acordo no que seráusado.

2.2.7 Mensagens

Mensagens de Conexão

• Versão do Protocolo

O inicio da conexão se da quando o servidor manda ao cliente umamensagem com a versão mais atual do protocolo que ele suporta. Entãoé requisitado a versão do protocolo que será usada. O cliente deveresponder qual versão usará, mas essa versão não pode ser superiorà versão do servidor. Exemplo de como é mandada a mensagem deescolha da versão do protocolo 3.3, 3.7, 3.8 respectivamente:

N◦ de bytes Valor Mensagem12 �RFB 003.003\n� (hex 52 46 42 20 30 30 33 2e 30 30 33 0a)

N◦ de bytes Valor Mensagem12 �RFB 003.007\n� (hex 52 46 42 20 30 30 33 2e 30 30 37 0a)

N◦ de bytes Valor Mensagem12 �RFB 003.008\n� (hex 52 46 42 20 30 30 33 2e 30 30 38 0a)

Tabela 2.1: Tabela Versões do Protocolo

9

• Segurança

Nesse momento é escolhido o tipo de segurança que será usada naconexão. O servidor lista os tipos possíveis, então o cliente deve escolherum deles. Caso o cliente não suporte nenhum da lista enviada peloservidor a conexão irá falhar.

Tipos de Segurança:

1. Nenhuma

Nenhuma segurança na conexão, todos os dados são mandados emaberto.

2. Autenticação do VNC

A autenticação serve somente para con�rmar se o cliente tem di-reito de se conectar no servidor. Para que isso ocorra o servidorenvia um número aleatório de 16 bytes para o cliente. O clientedeve cifrar esse número com o cifrador DES e uma chave inse-rida pelo usuário, após isso, o cliente deve responder ao servidorenviando o resultado da cifragem do número aleatório (desa�o /resposta).

N◦ de bytes Tipo Descrição16 U8 desa�o

Tabela 2.2: Tabela Desa�o enviado pelo servidor.

N◦ de bytes Tipo Descrição16 U8 resposta

Tabela 2.3: Tabela resposta do cliente ao desa�o do servidor.

2.2.8 Inicialização do Cliente

O cliente envia ao servidor uma �ag. Se essa �ag tiver o valor �verdade�isso signi�ca que o cliente se conectará ao servidor e permitirá que outrosclientes continuem conectados. Mas caso essa �ag tenha o valor �falso� oservidor desconectará os outros clientes e dará acesso exclusivo a esse novocliente.

10

2.2.9 Inicialização do Servidor

Na inicialização do servidor é enviado ao cliente informações como: alturae largura do framebu�er, seu formato de pixel e o nome do computador. Issoocorre depois da mensagem de inicialização do cliente.

2.2.10 Mensagens do Cliente para o Servidor

• Formato do Pixel

Escolhe-se o formato do pixel que deve ser mandado ao FrameBu�ernas mensagens de atualização. Se o cliente não especi�car um formatoo servidor irá mandar o formato original que ele possui.

• Codi�cações

O cliente especi�ca qual codi�cação será usada na conexão (Raw, Copy-Rect, RRE, CoRRE, Hextile e ZRLE.). Caso não seja escolhida ne-nhuma codi�cação a opção padrão é a codi�cação Raw.

• Atualização do FrameBu�er

O cliente noti�ca o servidor que necessita de uma atualização enviandoa posição x, y e a altura e largura (FrameBu�erUpdateRequest). Oservidor manda somente a área que o cliente solicitou, a menos que ocliente envie uma requisição que não seja incremental, ou seja, o clientenecessita que seja enviado todo o framebu�er do servidor.

• Evento de Tecla

Se a Down-�ag possuir for �verdadeiro� signi�ca que a tecla esta pres-sionada, caso o valor seja �falso� a tecla não está pressionada.

N◦ de bytes Tipo Descrição1 U8 tipo da mensagem1 U8 Down-�ag2 padding4 U32 tecla

Tabela 2.4: Tabela Evento de Tecla

11

• Evento do Mouse

Indica o movimento do mouse e se algum botão do mesmo foi pressio-nado.

N◦ de bytes Tipo Descrição1 U8 tipo da mensagem1 U8 máscara do botão2 U16 posição (x)2 U16 posição (y)

Tabela 2.5: Tabela Evento do Mouse

A máscara para o botão do mouse especi�ca qual dos botões foi pressi-onado (botão da esquerda (1), botão do meio (2), botão da direita (3),scroll para frente (4), scroll para trás (5)).

2.2.11 Mensagens do Servidor para o Cliente

• Atualização do FrameBu�er

Uma atualização só é enviada pelo servidor quando existe uma requisi-ção de atualização por parte do cliente. É enviado ao cliente o númerode retângulos desejado com a codi�cação escolhida.

• Mapa de Entrada de Cores

Se o formato de pixel usa o mapa de cores o servidor manda essa men-sagem indicando como dever ser mapeados os pixels para se obter aintensidade de RGB (vermelho, verde, azul).

• Bell

Soa um sinal no cliente caso o mesmo tenha um.

12

Capítulo 3

Trabalhos Correlatos

3.1 Trabalhos analisados

Nessa seção discutimos a análise de alguns projetos correlatos a esse tra-balho segundo os seguintes critérios:

1. Código: Segundo esse critério é analisada a estrutura do código fontedo projeto (se disponível), levando em consideração a legibilidade, oscomentários e a documentação.

2. Navegabilidade: É analisada a interface grá�ca do programa cliente,levando em consideração a facilidade de uso, existência ou não de teclasde atalho e se a interface é de fácil compreensão ou não.

3. Portabilidade: Segundo esse critério é analisada a gama de disposi-tivos que podem executar o projeto, além da gama de servidores VNCaos quais eles podem se conectar.

4. Desempenho: Analisado o tráfego de dados e o processamento noservidor devido ao uso do projeto.

3.1.1 VNC2Go

Descrição

O VNC2Go[VNC c] é uma ferramenta gratuita que se propõe a fazer asfunções básicas de um visualizador VNC. Ela é uma ferramenta madura deacesso e gerenciamento de terminais remotos via dispositivos móveis, porém

13

não possui atalhos para funcionalidades, ou seja, tudo tem que ser feito viamouse (o que é horrível de se fazer por um celular, por exemplo).

Análise

A análise foi feita em um computador Pentium 4 2.4GHz, 768 megabytesde memória RAM. No emulador Java Wireless Toolkit 2.2.

• Código

O VNC2Go é um programa freeware e não possui o código aberto.

• Navegabilidade

Possui uma interface grá�ca pobre, pouco intuitiva e de difícil manipu-lação. Um ponto positivo na navegação do VNC2Go é a navegação como mouse, por ser rápida e com boa atualização. Outro ponto positivosão os atalhos programados, os quais facilitam o acesso a determinadasfunções do computador, como por exemplo, o CTRL-ESC para abrir omenu iniciar.

• Portabilidade

Pelo falo de ser feito em Java (J2ME) o VNC2Go pode ser rodadoem vários aparelhos celulares de várias marcas. Também funciona comdiferentes servidores de VNC. Com isso o usuário tem muita liberdadede escolha e não �ca �preso� a determinadas marcas de aparelhos ouservidores de VNC.

• Desempenho

O VNC2Go teve um bom desempenho. Rápido na conexão e na atua-lização da tela quando necessário. Possui um pequeno tráfego na redee não exige grande processamento do servidor.

3.1.2 PocketVNC

Descrição

O PocketVNC[Poc ] é um VNC desenvolvido para plataforma PocketPC.Foi criado para dispositivos rodando WindowsCE (WindowsCE.NET), e nãoé gratuito.

14

Análise

Não pode ser testado, pois não rodou no emulador de PocketPC (WindowsMobile 5.0).

• Código

O PocketVNC é um software proprietário, sendo assim não possui ocódigo aberto.

3.1.3 .NET VNC Viewer:

Descrição

O .NET VNC Viewer[NET ] é um projeto open-source que permite oacesso de um dispositivo móvel rodando WindowsCE a um terminal rodandoWindows. Funciona em PocketPCs e smart-phones.

Análise

A análise foi feita em um computador Pentium 4 2.4GHz, 768 megabytesde memória RAM. No emulador para PocketPC (Windows Mobile 5.0).

• Código

O .NET VNC Viewer é um software proprietário, sendo assim nãopossui o código aberto.

• Navegabilidade

Tem uma boa navegabilidade, fácil e rápida, rápida porque possui atela toda do computador remoto. A navegação se torna mais lentaquando ocorrem mudanças na tela. Possui navegação discreta e algu-mas opções que podem torná-la mais fácil (modo tela), um problemana navegabilidade é o fato de não possuir um botão de desconexão.

• Portabilidade

A portabilidade é um ponto fraco do .NET VNC Viewer, pois ele foifeito para a plataforma PocketPC que usa o Windows CE e nos testesfeitos ele funcionou somente com o servidor de VNC UltraVNC, com oReal VNC a conexão falhava.

15

• Desempenho

O .NET VNC Viewer no geral não teve um bom desempenho, exite neleuma falha que em a qualquer momento ele se desconectava sem acusarqualquer erro. Quando o cliente caia o servidor ainda mostrava-o comoativo. Na questão de navegação pela tela quando não há mudançasno servidor, o desempenho foi muito bom. Porém para estabelecera conexão e para qualquer mudança ocorrida ele é bastante lento emrelação aos outros projetos. Enquanto �cava ocioso deixava o servidorcom aproximadamente 10% de processamento.

3.1.4 J2ME VNC

Descrição

O J2ME VNC[J2M b] é um projeto open-source que está em fase beta dedesenvolvimento. Roda sobre a plataforma Java e possui as funcionalidadesbásicas de um visualizador VNC. Sua navegabilidade é muito boa, além deter um bom desempenho, tanto por parte de tráfego de rede quanto emsobrecarga de processamento no servidor.

Análise

A análise foi feita em um computador Pentium 4 2.4GHz, 768 megabytesde memória RAM. No emulador Java Wireless Toolkit 2.2.

• Código

O código do J2ME VNC é aberto (protegido pela licensa GPL) e defácil acesso via um repositório público de versões (CVS). Além disso, aestruturação do código é agradável, bem comentado e inteligível.

• Navegabilidade

A navegabilidade do J2ME VNC é muito boa, possuindo várias funçõesde navegação direta (deslocando o mouse para um ponto especí�co datela, por exemplo, sem ter que mover o mouse via celular até o pontodesejado) e vários menus com funções de ajuda.

• Portabilidade

O projeto J2ME VNC se sobressai, por funcionar com uma vasta gamade servidores VNC e em vários aparelhos celulares, inclusive nos com-plicados aparelhos da Nokia, e por ser feito 100% em Java (J2ME).

16

• Desempenho

O desempenho do projeto J2ME VNC é satisfatório, tanto em nívelde tráfego de rede quanto em nível de processamento no cliente e noservidor. O fato do cliente operar sobre as áreas da tela alteradas noservidor, o que é mérito da implementação adotada do protocolo RFB,é o que possibilita esse bom desempenho.

3.1.5 JNC Mobile

Descrição

O JNC Mobile[JNC ] é um projeto de trabalho de conclusão de cursodesenvolvido em Java por Andrei Luciano Krause e Rafael Augusto da Silva.

Análise

A análise foi feita em um computador Pentium 4 2.4GHz, 768 megabytesde memória RAM. No emulador Java Wireless Toolkit 2.2.

• Código

Código de difícil interpretação e manutenção, dado o alto acoplamentoe baixa coesão das classes. Falta de documentação no código.

• Navegabilidade

O cliente tem problemas na navegabilidade, por exemplo, o usuárioem certas ocasiões aperta uma tecla e essa não responde ao comando.Também pouco intuitivo e sem um bom menu de ajuda.

• Portabilidade

Por ser feito em Java ele é um projeto com alta portabilidade, tantoem aparelhos celulares quanto em servidores VNC.

• Desempenho

O projeto teve um desempenho muito ruim. Grande parte desse pro-blema se deve ao fato do cliente requisitar a tela do servidor num in-tervalo de tempo �xo, com isso o cliente requisita a mesma tela váriasvezes caso o servidor esteja ocioso.

17

3.1.6 VNC Viewer

Descrição

O VNC Viewer[VNC b] é um cliente VNC desenvolvido especi�camentepara o celular Sony Ericsson P800. Desenvolvido em Personal Java, possibi-lita a comunicação via internet, cabos, bluetooth ou infravermelho.

Análise

Não pode ser testado, pois não rodou no emulador UIQ Symbian OS 7.0.

• Código

O VNC Viewer é um software proprietário, sendo assim não possui ocódigo aberto.

3.1.7 Imhotek VNC

Descrição

O Imhotek VNC[Imh ] é um cliente gratuito desenvolvido em Java e em-pacotado para sistemas baseados em Symbian. Sua navegação dispõe debarras de rolagem e possui suporte ao armazenamento de per�s de usuáriospara permitir um uso mais cômodo.

Análise

Não pode ser testado, devido ao fato do link para download do softwareestar fora do ar.

• Código

O Imhotek VNC é um software proprietário, sendo assim não possui ocódigo aberto.

18

3.2 Comparação entre os projetos

Comparação feita entre os projetos correlatos encontrados que rodam emdiversas plataformas.

.NET Viewer J2ME VNC VNC2Go JNC MobileTempo (segundos)Iniciar Conexão 24 12 5 10Movimento pela Tela 1 2 6 3Abrir Arquivo (txt) 15 5 5 3Abrir Menu Iniciar 15 5 7 3

Servidor N◦ Pacotes Env. Rec. Env. Rec. Env. Rec. Env. Rec.Iniciar Conexão 29 , 11 2 , 2 2 , 2 10 , 5Movimento pela Tela 1 , 1 1 , 1 1 , 1 5 , 5Abrir Arquivo (txt) 5 , 5 5 , 5 1 , 1 5 , 5Abrir Menu Iniciar 5 , 5 2 , 2 1 , 1 5 , 5

Processamento noServidor ( % pico)Iniciar Conexão 100 100 100 100Movimento pela Tela 100 80 80 100Abrir Arquivo (txt) 100 85 100 100Abrir Menu Iniciar 100 85 100 100Cliente Ocioso 10 2 2 100

Tabela 3.1: Tabela Comparativa Entre Trabalhos Correlatos

A análise foi feita em um computador Pentium 4 2.4GHz, 768 megabytesde memória RAM, com sitema operacional Windows em emuladores especí-�cos para cada programa.

Na comparação feita entre os projetos correlatos decediu-se adotar comoprojeto base para esse trabalho o J2ME VNC devido as seguintes caracterís-ticas:

3.2.1 Código

O código do J2ME VNC é aberto (protegido pela licensa GPL) e de fácilacesso via um repositório público de versões (CVS). Além disso, a estrutu-ração do código é agradável, bem comentado e inteligível.

19

Essa característica foi a determinante para que os projetos proprietáriosfossem descartados, como o Pocket VNC, e a inteligibilidade do código foi adeterminante para o descarte de�nitivo do JNC Mobile como projeto basepara este trabalho.

3.2.2 Navegabilidade

A navegabilidade do J2ME VNC é muito boa, possuindo várias funçõesde navegação direta (deslocando o mouse para um ponto especí�co da tela,por exemplo, sem ter que mover o mouse via celular até o ponto desejado) evários menus com funções de ajuda.

Essa característica descartou os projetos cuja interface grá�ca do clientefosse pobre ou de difícil manipulação, como o VNC2Go.

3.2.3 Portabilidade

A portabilidade de um sistema de gerência é fundamental. Não se podeprever que tipo de servidor deverá ser gerenciado, e nem que tipo de cliente(no caso, o aparelho celular) irá gerenciar o servidor. Portanto, o projetoJ2ME VNC se sobressai, por funcionar com uma vasta gama de servidoresVNC e em vários aparelhos celulares, inclusive nos complicados aparelhos daNokia, e por ser feito 100% em Java (J2ME).

Essa característica determinou o descarte dor projetos VNC Viewer, .NETVNC Viewer e Imhotek VNC como candidatos a projeto base desse trabalho.

3.2.4 Desempenho

O desempenho do projeto J2ME VNC é satisfatório, tanto em nível detráfego de rede quanto em nível de processamento no cliente e no servidor.O fato do cliente operar sobre as áreas da tela alteradas no servidor, o que émérito da implementação adotada do protocolo RFB, é o que possibilita essebom desempenho.

Os demais projetos não foram testados por não terem emuladores paraos mesmos ou por não executarem nos emuladores indicados.

Dada a análise feita dos projetos correlatos, decidiu-se adotar o projetoJ2ME VNC como base para este trabalho.

20

Capítulo 4

Projeto e Desenvolvimento do

Sistema Proposto

4.1 Projeto

Um sistema de acesso remoto baseia-se em dois programas distintos: oprograma cliente (visualizador), e o programa servidor (máquina acessada).

O cliente é responsável por pedir informações ou solicitar serviços aoservidor através do envio de comandos. O servidor, por sua vez, espera sernoti�cado pelo cliente para enviar informações (esse modo de operação doservidor é conhecido como modo passivo).

Portanto, para desenvolver um sistema VNC completo, é necessário desen-volver um programa cliente e um programa servidor. Dado que o programaservidor é basicamente o mesmo, independente de plataforma (sistema ope-racional ou natureza dos dispositivos conectados), e que há vários servidoresgratuitos e de fácil acesso na internet, esse projeto será focado na construçãode um wrapper de um cliente VNC móvel (como discutido no capítulo 3 essecliente é o J2ME VNC), e a construção de um servidor bridge entre o clientee o servidor VNC, como visto na �gura D.5.1:

Como objetivos temos:

1. Possibilitar o cadastro de tarefas automáticas no servidor bridge: aoinstalar o servidor bridge na estação de trabalho a ser controlada re-motamente, o usuário poderá cadastrar tarefas junto a esta máquinaque posteriormente poderão ser executadas pela aplicação cliente dis-ponível no dispositivo móvel. Assim, tarefas como desligar, reiniciar,

21

Figura 4.1: Estrutura do projeto.

ativar desfragmentador de disco, uma rotina de trabalho, rodar anti-vírus, entre outras, poderá ser facilmente executada com uma simplesseleção em um menu de tarefas da aplicação cliente.

2. Permitir um zoom panorâmico, possibilitando uma visão geral do sis-tema pela aplicação cliente. Essa função é útil quando o objetivo domonitoramento remoto é, por exemplo, somente saber se determinadoprograma está rodando ou se o sistema operacional está exibindo al-guma mensagem de erro.

4.2 Desenvolvimento

O desenvolvimento da solução proposta se divide em duas áreas, que são:Servidor Bridge e o Wrapper do cliente.

4.2.1 Servidor Bridge

O servidor Bridge é ao mesmo tempo cliente e servidor. Ele é o servidorno qual o cliente do sistema (o celular) se conecta via RFB, e o cliente do ser-vidor VNC nativo do sistema. É nele que o protocolo RFB será expandido,dando suporte às funcionalidades descritas no capítulo 1. Dentro do servidorBridge, há uma nova divisão no problema. Um problema é a adição de no-vas codi�cações ao protocolo RFB, permitindo a conexão do cliente. Outroproblema é o modelo de dados, algoritmos e persistência das entidades relaci-onadas às funções desejadas, como por exemplo as entidades relacionadas aocadastro de tarefas pré-de�nidas no servidor para acesso futuro via cliente.

Entidades

22

Nessa sessão serão discutidos os modelos conceituais e o desenvolvimentodas entidades e algoritmos relativos ao domínio do problema.

• Modelo

O modelo das entidades é representado segundo diagrama UML daimagem D.2.

Figura 4.2: Entidades.

A classe Task é a super classe de todas as tarefas a serem cadastradas noservidor. Dela derivam duas classes: CommandTask e ScheduledTask.

A CommandTask representa uma tarefa que deve ser executada comouma linha de comando. Por essa característica, ela pode ter diversostipos de retorno, inclusive nenhum. A execução de comando pode re-tornar um valor útil ao usuário, como o espaço livre no HD, ou simples-mente executar uma ação desejada, como matar um processo ou resetara máquina. Por esse motivo, essa classe possui o atributo waitForRe-turn, que indica se o servidor deve esperar por um valor de retorno ounão.

A ScheduledTask representa uma tarefa que é periodicamente execu-tada, armazenando valores obtidos para futura consulta, possivelmentegerando grá�cos. Os tipos predeterminados de tarefas agendadas são:

� Avaliação do uso de CPU por todos os processos;

23

� Avaliação do uso de CPU por um processo especí�co;

� Avaliação do espaço em disco;

� Avaliação da memória livre;

� Avaliação do uso de memória por todos os processos;

� Avaliação do uso de memória por um processo especí�co;

� Avaliação do uso de memória virtual por um processo especí�co.

O atributo scheduleExpression de�ne a periodicidade de execução datarefa. Ela é um CronExpression de�nida pelo Quartz[Qua ].

A classe TaskValue representa um valor adquirido via a execução deuma ScheduledTask. Portanto, cada ScheduledTask possui uma listade TaskValue associados. É através dessa lista que é possível gerargrá�cos e analisar o comportamento da máquina do servidor segundoo tipo da ScheduledTask.

• Persistência

Para que as Tasks cadastradas não precisem ser recadastradas entre asexecuções do servidor, e para que os valores obtidos pelas Scheduled-Tasks não se percam, é necessário persistir as informações de algumamaneira. A maneira mais convencional é utilizar um banco de dadosrelacional.

Para utilizar um banco desse tipo, é necessário fazer um mapeamentoentre os modelos orientado a objetos e o modelo relacional. Para tal, foiutilizada a tecnologia do Hibernate[Hib ], que é capaz de gerar o modelorelacional automaticamente através do modelo orientado a objetos.

Portanto, cada objeto a ser persistido recebeu a anotação Entity, re-presentando uma Entity Bean. O esquema escolhido para representara herança existente entre Task, CommandTask e ScheduledTask foi ode gerar uma tabela para cada tipo, simpli�cando a visualização dosdados no banco. Essa abordagem resulta num pior desempenho, poispara cada seleção é necessário fazer um Join entre tabelas, porém émais fácil de encontrar eventuais problemas.

Na lista de TaskValue das ScheduledTask foi adicionada a anotaçãoOneToMany, indicando que cada ScheduledTask pode ter várias Task-Value. No atributo task da classe TaskValue foi adicionada a anotaçãoManyToOne, indicando que cada TaskValue se associa com uma únicaScheduledTask.

24

O Hibernate é capaz de gerenciar qualquer banco que possua um driverJDBC. Para testes, o banco escolhido foi o HSQLDB.

• Execução

O �uxo de cada tarefa é totalmente dependente do tipo dessa tarefa.As CommandTasks são executadas, e dependendo do valor do atributowaitForReturn, a aplicação espera ou não um valor de retorno, paraposteriormente retornar esse valor ao cliente. A interpretação dos da-dos retornados cabe ao usuário. Já as ScheduledTasks são executadasperiodicamente, segundo a expressão Quartz associada. Cada execuçãoresulta em um valor numérico, que por sua vez é associado a um Task-Value, que por sua vez é persistido no banco. O diagrama de seqüênciada imagem 4.3 ilustra essas situações.

Figura 4.3: Sequência da execução de uma task.

Fora as entidades já descritas, aqui aparecem as classes de controle deexecução. São elas:

� TaskExecuter: Essa é a classe responsável pela execução das

25

tarefas, independente de suas naturezas. Ela identi�ca o tipo datarefa, executa os comandos necessários, e retorna ou persiste osvalores obtidos. Nela se assinam listeners que são noti�cados todavez que uma tarefa é executada.

� HibernateUtil: Essa é a classe responsável pela persistência dosdados. Ela não acessa diretamente o banco, só gerencia as sessõese as instâncias dos TaskDAO. Serve de fachada para os serviçosde persistência.

� TaskDAO: Essa é uma interface que provê serviços de persistên-cia. Sua implementação depende de como se deseja que os dadossejam persistidos, seja em arquivos xml, bancos de dados orienta-dos a objeto, bancos de dados relacionais, etc. É implementadapela classe TaskDAOImp, que utiliza Hibernate para persistir econsultar entidades num banco relacional.

� QuartzScheduler: Essa é a classe responsável por agendar edisparar os agendamentos das ScheduledTask. O disparo de umatarefa agendada implica na sua execução pela classe TaskExecuter.

� SistemInfo: Essa é uma interface que provê os dados necessáriospara a execução das ScheduledTasks, como por exemplo desvendaro uso de CPU por determinado processo. A implementação dessainterface é dependente do sistema operacional, pois vários dadosnão podem ser pegos via puro Java.

• Extensão do Protocolo RFB

Como descrito no capítulo 2, extensão do protocolo RFB é a adiçãode novas codi�cações para a execução de novas tarefas. Para que oservidor bridge exerça a verdadeira função de ponte, ele deve permitirque todas as funções normais de um servidor VNC sejam executadas,tratando somente as tags especiais (novas tags). Ou seja, o servidorbridge deve analisar tudo o que chega do cliente, e se o que chegar nãocorresponder a uma tag nova, deve repassar todo o comando para oservidor VNC.

Então, para que o servidor bridge exerça essa função, ele deve compre-ender o protocolo RFB, e as extensões de�nidas.

Ao realizar o estudo descrito no capítulo 2, descobre-se que para ex-tender o protocolo basta utilizar uma tag não reservada, e dar umsigni�cado lógico para ela, tanto no servidor quanto no cliente. Sendoassim, é necessário analisar quais as novas funções que deseja-se agregarao protocolo, para daí então escolher as novas tags.

26

• Novas funções do protocolo

Para desenvolver a solução proposta no capítulo 4, necessita-se de 4funções:

1. Comando que indica o pedido da lista de tarefas cadastradas nobridge: Adotou-se o código 129;

2. Comando que indica a execução de uma determinada tarefa ca-dastrada: Adotou-se o código 130;

3. Comando que indica, no cliente, que a lista de tarefas chegou:Adotou-se o código 4;

4. Comando que indica, no cliente, que o resultado da execução deuma tarefa chegou: Adotou-se o código 5;

A escolha dos códigos não tem restrições, além da de que o código nãopode estar sendo utilizado para outras funções no protocolo. As �gurasD.3 e D.4 ilustram a convenção adotada.

Figura 4.4: Extensão do RFB no cliente.

Implementação da função de bridge

A função de ponte do servidor bridge está encapsulada numa classe decontrole chamada de BridgeServer. Ela controla todo o tráfego no sen-tido cliente para servidor quanto no sentido servidor para cliente. Ela

27

Figura 4.5: Extensão do RFB no servidor RFB.

analisa o conteúdo das mensagens enviadas do cliente para o servidor a�m de descobrir se o comando executado é um comando novo ou não.O �uxo de execução é descrito nas �guras 4.6 e 4.7.

Figura 4.6: Fluxo de execução no sentido cliente para servidor.

A classe BridgeServer é composta por duas threads de execução, que seexecutam de forma assíncrona. Uma thread ouve o que o cliente tem adizer, e outra ouve o que o servidor VNC tem a dizer. A comunicaçãoé feita via leitura e escrita em sockets. Em Java, a leitura e escrita

28

Figura 4.7: Fluxo de execução no sentido servidor para cliente.

de bytes é feita via streams (�uxos) de dados. Em cada socket aberto,portanto, há dois streams: InputStream (para leituras) e OutputStream(para escritas).

No �uxo normal, desconsiderando as novas tags empregadas, o que élido no InputStream do socket do sentido cliente para servidor é dire-tamente escrito no OutputStream do socket do sentido servidor paracliente. Da mesma forma, o que é lido no InputStream do socket dosentido servidor para cliente é escrito diretamente no OutputStream dosocket do sentido cliente para servidor.

Agora, considerando-se as novas tags, não se pode deixar as novas men-sagens chegar no servidor VNC, o que causaria um erro. Portanto, antesde se escrever um comando vindo do cliente diretamente no socket doservidor VNC, deve-se analisar o cabeçalho da mensagem. Se o cabe-çalho contém uma das novas tags de�nidas, então quem deve tratar ocomando é o próprio servidor bridge.

No caso de o cabeçalho conter a tag 129, o servidor acessa o bancode dados buscando todas as tarefas cadastradas. Para cada tarefa, elemonta uma descrição curta da mesma, que é o que aparecerá no displaydo cliente. O pacote de resposta gerado por essa requisição é descritona �gura 4.8.

O campo inicial, conforme estipulado pelo protocolo RFB, deve possuir8 bits de tamanho. Os campos seguintes �cam a cargo de quem projetoua nova função. Nesse pacote o campo que de�ne o número de tarefas

29

Figura 4.8: Pacote transmitido contendo as tarefas cadastradas.

possui 16 bits, assim como o campo que de�ne o número de caracteresda descrição. O campo da descrição de cada tarefa possui 16 vezes otamanho de�nido no campo anterior, já que cada caracter, em Java,ocupa 16 bits.

No caso de o cabeçalho conter a tag 130, o corpo da mensagem deve serlido, pois os 16 bits subseqüentes ao cabeçalho contém o código iden-ti�cador da tarefa selecionada. Após a leitura desses bits, o servidoracessa o banco, buscando a tarefa desejada. Com a tarefa em mãos, éanalisado o tipo dessa tarefa: se tarefa de comando ou tarefa agendada.Caso seja tarefa de comando, ela é executada via classe TaskExecuter,que retorna o texto informando o resultado da execução da tarefa, quepor sua vez é passado ao cliente. No caso de uma tarefa agendada,estatísticas como média, menor e maior valores etc. são coletadas viaclasse TaskValuesController, que monta o relatório pronto para ser pas-sado para o cliente. O pacote de resposta gerado por essa requisição édescrito na �gura 4.9.

Figura 4.9: Pacote transmitido contendo o resultado da execução de umatarefa.

Novamente, seguindo a padrão de�nido pelo RFB, o campo inicial pos-sui 8 bits de tamanho. O campo seguinte, que de�ne o tipo da tarefaexecutada, assume os valores 0 para tarefas de comando e 1 para tare-fas agendadas. Para manter compatibilidade com a leitura no cliente epara permitir que hajam novos tipos de tarefas no futuro, esse campofoi de�nido com tamanho de 8 bits. O campo seguinte, de 16 bits,de�ne o número de caracteres do texto que vem a seguir, que comono pacote anterior, possui 16 vezes o tamanho de�nido no campo denúmero de caracteres.

Utilização

30

O projeto, acima de tudo, é uma aplicação desktop. Portanto, para me-lhor utilização, é requerida uma interface grá�ca com o usuário (GUI). Eladeve ser simples e funcional, permitindo cadastrar, acessar e remover tarefas.Além disso, ela deverá ser capaz de renderizar grá�cos dos valores geradospelas ScheduledTasks, ou seja, os TaskValues. Esses grá�cos, posteriormente,serão transmitidos para o cliente móvel.

A tecnologia adodata para a geração da interface grá�ca foi a Swing,padrão para aplicações desktop em Java. Para a geração dos grá�cos, foiutilizado o JFreeChart[JFr ].

• Inicialização

A imagem 4.10 mostra a tela inicial do servidor bridge. A abertura doprograma implica a execução de várias classes, como mostra o diagramade seqüência da imagem 4.11.

Figura 4.10: Tela inicial do servidor bridge com tarefas cadastradas.

Ao abrir o programa, a persistência é inicializada e as tasks cadastradassão automaticamente carregadas. Logo em seguida, a classe QuartzS-cheduler cadastra as ScheduledTasks para serem disparadas em seusdevidos tempos. Então a interface grá�ca é noti�cada para mostrar astasks cadastradas.

31

Figura 4.11: Inicialização do servidor bridge.

• Cadastro de novas tasks

O botão �Adicionar Tarefa. . . � abre a tela mostrada na �gura 4.12.Nela é possível con�gurar o tipo da tarefa a ser cadastrada, e todos osparâmetros requeridos para a execução da tarefa, seja ela agendada oude comando.

Uma vez criada a Task, ela é salva no banco. Se, além disso, a Taskfor do tipo ScheduledTask, ela é cadastrada no QuartzScheduler paraagendamento de disparos, como mostra a imagem 4.13.

• Atualização de tasks

O botão �Alterar Tarefa. . . � abre a mesma tela mostrada na �gura4.12. Nessa tela os valores da task selecionada podem ser alterados,e a task então é modi�cada. Após a modi�cação, ocorre um processosemelhante ao cadastro de novas tasks, com a diferença de que a açãoa ser feita no banco é uma atualização e não uma inserção.

• Remoção de tasks

32

Figura 4.12: Tela de adição de nova tarefa.

O botão �Remover Tarefa� exclui a task selecionada e todos os seusvalores associados, caso seja uma ScheduledTask. A operação feita napersistência, portanto, é a remoção do objeto. Além disso, se o tipo datask é ScheduledTask, ela é descadastrada do QuartzScheduler, paraque não seja mais disparada.

• Execução manual de tasks

O botão �Executar Tarefa� executa a tarefa selecionada imediatamente.Essa execução tem como objetivos receber o valor de retorno de umatarefa cadastrada (por ser de difícil execução fora do programa), ousimplemente testar a tarefa cadastrada. A seqüência de execução segueo diagrama da imagem 4.3.

• Geração de grá�cos

O botão �Valores Medidos. . . � mostra uma tela com todos os valoresmedidos de uma dada ScheduledTask. Desses valores é possível gerar3 tipos de grá�cos, que são linha, barras e pizza.

Cada tipo grá�co representa melhor ou pior determinado tipo de task,dependendo dos dados que são obtidos e da freqüência de execuçãodessa task. Por exemplo, grá�cos de linha são bons para mostrar dadosde uma task que é executada muito freqüentemente, o que não é o caso

33

Figura 4.13: Seqüência de execução para cadastro de novas tarefas.

de grá�co em pizza. Já o grá�co em pizza é bom para mostrar aproporcionalidade entre os valores medidos.

A seqüência de execução segue o diagrama da imagem 4.14.

4.2.2 Wrapper do Cliente

Wrapper do cliente é uma �casca� implementada no cliente J2ME VNCque estará rodando no aparelho celular. Ele contém as funcionalidades docliente J2ME VNC e mais a extensão do protocolo RFB para que possa secomunicar com o servidor Bridge, e assim usufruir das funções que o mesmooferece.

Funcionalidades

O cliente J2ME VNC possui várias funcionalidades para comandar o com-putador via celular, entre elas podemos citar: Ctrl Alt Del, Modo, ApertarEnter, Repintar, Opções, Chamar o mouse, Entrar com texto, Segurar Ctrl,

34

Figura 4.14: Seqüência de execução para a geração de grá�cos.

Segurar Alt, Segurar Meta. A essas funcionalidades foi adicionado a opçãoTarefas, que é a comunicação do cliente VNC com o servidor Bridge, para queo mesmo execute ou envie ao cliente as informações das tarefas previamentecadastradas no servidor.

Ao estar conectado com o servidor, o cliente J2ME pode executar suasfunções. Para executar as funções deve-se acessar o menu, na �gura 4.15mostra-se a tela inicial.

• Função Ctrl Alt Del

Acessando o menu e selecionando a opção Ctrl Alt Del, como mostraa �gura 4.16, o cliente envia ao computador que o comando Ctrl AltDel deve ser executado, assim o computador mostrará na sua tela oGerenciador de Tarefas do Windows. Com as funçoes de comandaro mouse e entrar com textos pelo cliente pode-se via celular �nalizarprocessos, conferir o desempenho do computador, executa nova tarefa,ou seja, tudo o que se pode fazer no gerenciador de tarefas, na �gura4.17 pode-se ver a tela do gerenciador.

• Modo

35

Figura 4.15: Tela inicial.

Figura 4.16: Acessando o menu Ctrl Alt Del.

Na função de modo é onde se escolhe o modo de visão e o modo defuncão das teclas, �guras 4.18 e 4.19.

� Visão: No modo visão pode-se escolher como a tela do computadorserá mostrada no celular.

36

Figura 4.17: Tela após o ctrl alt del executado.

Figura 4.18: Acessando Modo no menu.

1. Visão Normal: a tela do computador é mostrada em tamanhoreal. Como a tela do celular é muito menor que a do compu-tador o usuário verá somente a parte do desktop onde ele seencontra, para ter visão do resto ele precisará se locomoverpela tela.

37

Figura 4.19: Tela com os modos.

2. Visão Tela Cheia: é uma visão panorâmica do desktop (zoomout), como na �gura 4.20.

Figura 4.20: Zoom in e zoom out.

� Função Das Teclas: as funções que a teclas do aparelho celularpodem assumir para controlar o compurtardor ou exercer a funçãode celular.

38

1. Navegação: As teclas do cliente possuem a função de navega-ção pela tela do computador quando a visão estiver no modonormal.

2. Modo Mouse: Ao se escolher essa opção as teclas do celularpassa a comandar os movimentos do mouse.

3. Modo SMS: As teclas do celular comportam-se com teclas decelulares, por exemplo, ao se apertar a tecla 2 ela irá mostrarna tela as letra A, B, C e o número 2 conforme quantidade devezes que a tecla for pressionada, na �gura 4.21 pode-se vera letra no canto inferior da tela quando se pressiona a tecla 2uma vez.

Figura 4.21: Escrita com SMS.

• Função Apertar Enter

Envia ao computador o comando de pressionar a tecla enter, �gura4.22.

• Repintar

Repinta a tela do celular, serve como uma atualização para o estadoatual da tela do computador, �gura 4.23.

• Opções

39

Figura 4.22: Menu apertar enter.

Figura 4.23: Menu repintar.

� Scroll Amount: quantidade de movimentação da tela no modo mo-vimentação, quanto maior o nível de scroll maior o deslocamentona tela no modo de navegação. Os níveis de scroll vão de 0 até 4.

� Quantidade de Movimento do Mouse: é a quantidade de movi-mentação do mouse no modo mouse, assim como o scroll amount

40

quanto maior o nível de movimento maior o movimento. Como omouse é mais sensível a movimentos os níveis vão de 0 até 20.

� Modo Ativo de Repintura: dispara o repintar a cada ciclo detempo, assim a tela do celular sempre estará atualizada em re-lação a tela do computador. Porém essa opções consome muitotrafego de dados já que a todo momento é enviada o desktop parao celular.

� Cursor Local: Caso não esteja setada a opção de cursor localquando o maouse é chamado, implica que a cada movimento domouse é movido o mouse do servidor e é dado um repintar emtodas as movimentações.

Quando o cursor é local, o cliente �simula� um cursor de mouse.É como se o mouse estivesse no celular, então quando é feita amovimentação do mouse não é feita uma chamada ao repintar.Assim que ocorreer um click é movido o cursor remoto para ondeo cursor local está. Muito útil para otimizar a repintura, pois acada movimento do mouse não é necessário uma repintura.

Conforme as �guras 4.24 e 4.25.

Figura 4.24: Menu opções.

• Chamar o mouse

Chama o mouse pra o centro da tela do celular, �gura 4.26.

41

Figura 4.25: Opções dentro do menu opções.

Figura 4.26: Menu chamar mouse e após executado.

• Entrar com Texto

Entra com algum texto no computador através do celular. Seleciona-se a aplicação onde se deseja inserir o texto, com o modo Entrar comTexto digita-se o texto e envia o mesmo para a aplicação, nas �guras4.27, 4.28 e 4.29 pode-se ver os passos para inserir um texto no bloco

42

de notas.

Figura 4.27: Menu Entrar com Texto.

Figura 4.28: Digintando texto no celular.

• Segurar Control, Alt, Meta

Ao selecionar uma dessas opções é enviado ao computador a função demanter a respectiva tecla pressionada, �gura 4.30.

43

Figura 4.29: Texto inserido no bloco de notas.

Figura 4.30: Menu Segurar Control, Alt, Meta.

• Tarefas

Acessando o menu tarefas, �gura 4.31, é enviado ao servidor uma re-quisição para que o mesmo mande as tarefas existentes como mostraa �gura 4.32. Assim que é escolhida qual tarefa se deseja obter asinformações o servidor envia as informações da mesma, �gura 4.33.

44

Figura 4.31: Menu Tarefas.

Figura 4.32: Tarefas que estão cadastradas no servidor.

Extensão do Protocolo no Cliente

Para que as novas funcionalidades implementadas no servidor Bridge se-jam entendidas pelo cliente, este também deve extender o protocolo RFB eassim ter suporte as novas tags existentes.

45

Figura 4.33: Estatítiscas da tarefa seleciona, Tarefa 3 no caso.

As quatro funçoes são as seguintes:

1. Comando que indica o pedido da lista de tarefas cadastradas no bridge:Adotou-se o código 129;

2. Comando que indica a execução de uma determinada tarefa cadastrada:Adotou-se o código 130;

3. Comando que indica, no cliente, que a lista de tarefas chegou: Adotou-se o código 4;

4. Comando que indica, no cliente, que o resultado da execução de umatarefa chegou: Adotou-se o código 5;

Foi implementado na classe RFBProto do cliente os seguintes métodospara que o celular pudesse saber quais as tarefas existentes no servidor, exe-cutar as mesmas e também informações sobre os dados (valor máximo, valormínimo, média, quantas vezes a tarefa foi executada) dessas mesmas tarefas.

1. serverReceiveTasks(): recebe as tarefas cadastradas no servidor pri-meiro é lido o número de tarefa cadastradas no servidor, depois é �mon-tado� a descrições de cada tarefa.

2. requestTasks(): requisita as tarefas (código 129).

46

3. executeTask(int id): envia o �id� da tarefa a ser executada pelo servidor,assim que o comando executar e o id chegam no servidor ele executaráa tarefa especi�cada (código 130).

4. receiveTaskReturn(): recebe o retorno ta tarefa executada.

4.2.3 Discussão Dos Resultados

A análise foi feita seguindo os seguintes critérios:

1. Tempo.

2. Número de pacotes enviados e recebidos no servidor.

3. Pico de processamento no servidor.

Em cada um dos itens acima foram analisados os seguintes critérios: iniciode conexão, movimento simples pela tela do cliente, abertura de um arquivocom extensão txt e a ação de abrir o menu iniciar. No item, Pico de proces-samento do servidor, foi analisado também a porcentagem do processamentoenquanto o cliente estava ocioso.

Todos os projetos foram testados em um computador Pentium 4 2.4GHzcom 768 megabytes de memória RAM e placa de vídeo GForce FX5200 de128 megabytes usando o sistema operacional Windows XP SP2 R©. Os dis-positivos cliente e servidor rodaram localmente.

No desenvolvimento deste trabalho foram analisados diferentes clientesVNC. Na tabela 4.1 temos um comparativo dos trabalhos correlatos analisa-dos e o projeto feito nesse trabalho de conclusão de curso.

47

.NET Viewer J2ME VNC VNC2Go JNC Mobile TCCTempo (seg)Iniciar Conexão 24 12 5 10 10Movimento pela Tela 1 2 6 3 2Abrir Arquivo (txt) 15 5 5 3 5Abrir Menu Iniciar 15 5 7 3 6

N◦ Pacotes Env. Rec. Env. Rec. Env. Rec. Env. Rec. Env. Rec.Iniciar Conexão 29 , 11 2 , 2 2 , 2 10 , 5 14 , 15Movimento pela Tela 1 , 1 1 , 1 1 , 1 5 , 5 3 , 3Abrir Arquivo (txt) 5 , 5 5 , 5 1 , 1 5 , 5 5 , 4Abrir Menu Iniciar 5 , 5 2 , 2 1 , 1 5 , 5 3 , 2

Processamento( % pico)Iniciar Conexão 100 100 100 100 100Movimento pela Tela 100 80 80 100 88Abrir Arquivo (txt) 100 85 100 100 43Abrir Menu Iniciar 100 85 100 100 16Cliente Ocioso 10 2 2 100 2

Tabela 4.1: Tabela Comparativa Entre Trabalhos Correlatos

Análise:

• Tempo (segundos):

1. Iniciar Conexão: O critério Iniciar Conexão refere-se ao tempo deinicio da conexão do cliente com o servidro VNC. Na análise feita amédia de tempo de conexão foi de 12,2 segundos. O projeto .NETViewer foi o mais lento, isso pode ter ocorrido devido ao fato doemulador desse projeto ser bastante lento e assim prejudicando nahora do teste.

2. Movimento Pela Tela: Aqui foi analisado um simples movimentopela tela (todos foram analisados com um simples movimento parabaixo). Nesse quesito o .NET Viewer foi o mais rápido. O J2MEVNC teve um bom desempenho, isso acontece por que em ummovimento de tela o que é enviado é somente o �pedaço� da telarequisitado e não a a tela inteira.

3. Abrir Arquivo (txt): Estilo o movimento da tela, porém nesseitem existe a execução da tarefa de abrir um arquivo (como a ta-

48

refa não exige muito processamento o que realmente foi avaliadofoi a capacidade de repintura da tela). Entre os trabalhos anali-sados todos, exceto o .NET Viewer, tiveram um resultado muitoparecido. Deve-se lembrar que o .NET Viwer pode ter sido o maislento pelo fato do seu emulador ser pesado.

4. Abrir Menu Iniciar: o critério abrir menu iniciar é avaliado desdeo clique do mouse para abrir o menu até o menu aparecer comple-tamente na tela do cliente. Os resultados foram muito parecidosentre os projetos e o .NET Viewer novamente sendo o mais lentoentre todos.

• Número de Pacotes enviados e recebidos: Para cada um dos itens jácitados, analisou-se o número de pacotes enviados e recebidos. Comoo cliente e o servidor estavam rodando localmente esse número foi namaioria das vezes abaixo do esperado. Exceto o projeto .NET Viewerque teve muitos pacotes enviados quando se avaliou o inicio de conexão.

A análise dos pacotes enviados e recebidos no projeto deste TCC nãofoi feita localmente e sim remotamente, por isso os valores encontradospara ele são mais reais. Com isso pode-se perceber que o projeto .NETViewer tem algum problema quanto a conexão, por que enquanto umprojeto que rodou remotamente usou cerca de 14 pacotes para o envio o.NET Viewer rodando localmente teve um total de 29 pacotes enviados.

• Pico do processamento do servidor: Foi feita a análise do máximo quechegou o processamento no servidor para cada critério e colocado maiso item cliente ocioso.

1. Iniciar Conexão: Como era de se esperar no inicio da conexãoentre o cliente e o servidor todos os projetos chegaram aos seus100% de processamento. Já que o cliente e o servidor trocavamdados para fazer o handshake inicial.

2. Movimento Pela Tela: Na movimentação pela tela três projetoschegaram a cerca de 80% de processamento, o VNC2Go, o J2MEVNC e o nosso trabalho.

3. Abrir Arquivo (txt): Para abrir um arquivo de texto, mesmo queseja pouco processamento, foi-se exigido um pouco mais do ser-vidor, para fazer essa tarefa simples alguns projetos chegaram a100%.

4. Abrir Menu Iniciar: Assim como o item abrir arquivo, abrir menuiniciar teve na sua maioria um processamente chegando a 100%.

49

Os únicos trabalhos que não chegaram ao máximo de processa-mento foram o J2ME VNC e o nosso trabalho.

5. Cliente Ocioso: Com o cliente ocioso pode-se perceber que o pro-jeto JNC Mobile possui algum problema, a�nal, quando o clientenão exigia nenhum processamento o servidor �cou em seus 100%constantemente.

Os outros projetos se comportaram normalmente. Lembrando queo .NET Viewer teve acima dos outros (com 10%) pelo seu emula-dor ser muito mais pesado que o emulador dos outros projetos.

Discussão Geral:

Esse trabalho de conclusão de curso foi desenvolvido em cima do projetoJ2ME VNC, por isso os resultados obtidos entre os dois foram muito pareci-dos, o que era de se esperar. A maior diferença entre os dois projetos foi naquestão de envio e recebimento de pacotes, essa diferença não se deve a umamudança na nossa implementação mas sim no fato que o projeto J2ME VNCter sido testado localmente e o nosso TCC testado remotamente (cliente eservidor em rede não local).

50

Capítulo 5

Conclusão

5.1 Conclusão

A Integração de dispositivos de diferentes �naturezas�, como aparelhoscelulares e computadores pessoais é um tema em alta num mundo onde cadavez mais as pessoas precisam se comunicar, cada vez mais e�cientemente eprodutivamente.

Tecnologias como a J2ME VNC são de grande valia em setores onde otempo de resposta à uma requisição é precioso, e onde o acesso a um terminal�xo de trabalho é limitado. Do mesmo modo, desenvolver um produto focadonessa tecnologia, além de inovador, é desa�ante.

Como esse trabalho foi feito em cima do cliente J2ME pode-se perceberna discussão dos resultados, que os valores medidos dos dois trabalhos sãomuito parecidos. Isso mostra a grande vantagem do J2ME em relação aosoutros projetos, já que ele faz as mesmas funções em menor tempo e commenor uso do processador no servidor.

No desenvolvimento tivemos alguns problemas:

• Na adição de novas codi�cações ao protocolo RFB foi encontrada umapequena di�culdade. Quais tags poderiam ser usadas para as novascodi�cações?. Como a especi�cação do protocolo não esclarece quais astags que são usadas pelo mesmo, a solução foi escolher uma tag qualquere testar todas as funcionalidades para saber se essa tag escolhida já erausada por outra função. Para as novas codi�cações foram adotadas asseguintes tags:

51

1. Comando que indica o pedido da lista de tarefas cadastradas nobridge: Adotou-se o código 129;

2. Comando que indica a execução de uma determinada tarefa ca-dastrada: Adotou-se o código 130;

3. Comando que indica, no cliente, que a lista de tarefas chegou:Adotou-se o código 4;

4. Comando que indica, no cliente, que o resultado da execução deuma tarefa chegou: Adotou-se o código 5;

• Após o wrapper do cliente terminado e funcionando no emulador, foihora de testarmos num aparelho celular real. Como o cliente é feitoem Java, e Java tem como característica ser portável, era de se espe-rar que o cliente funcionasse na primeira tentativa, porém no J2ME aportabilidade de Java não funciona muito bem, e o projeto não rodoude primeira no aparelho celular. Após modi�cações para que o projetofuncionasse num celular Nokia especí�co (aparelho usado para testes),o projeto funcionou corretamente nesse telefone, mas se o projeto forexecutado em algum celular de outra marca ele não iria funcionar di-reto, para que o projeto funcione deve ser feitas modi�cações de acordocom o aparelho.

Ao �nal, concluímos que é possível e fácil adicionar novas codi�cações aoprotocolo RFB para que o mesmo possa �entender� a uma variada gama defunções. E com a criação de um servidor que faça o processamento local épossível adicionar muitas funcionalidades em um dispositivo móvel que nãotenha poder para processar tal, tarefas que exijam muito processamento, porexemplo. E com isso criar funções inovadoras.

5.2 Trabalhos Futuros

Como aperfeiçoamento desse trabalho de conclusão de curso pode serfeito:

• Envio ao aparelho celular dos grá�cos que resultam da execução dastarefas no servidor:

O servidor bridge possui geração de grá�cos para as tarefas que sãoexecutadas periódicamente, porém esses são mostrados somente no ser-vidor. O que pode ser feito é o envio desses grá�cos para o celular oua geração dos mesmos no próprio aparelho móvel.

52

• Implementação de um sistema de monitoramento via web, utilizando amesma tecnologia adotada no sistema VNC:

Criação de um sistema de gerenciamento pela web, assim como o clientede celular faz hoje, se conectando ao servidor bridge e executando astarefas existentes no mesmo.

• Implementação de um conjunto mais complexo e útil de tarefas:

Criação de novas tarefas, no sentido de possibilitar a execução em sérieou em paralelo de tarefas distintas, por exemplo, ou mesmo permitira execução de tarefas mais complexas que não podem ser executadassomente via linha de comando.

53

Referências Bibliográ�cas

[Ant ] Antenna. Antenna.

Disponível em <http://antenna.sourceforge.net/>. Acesso em:Outubro, 2006.

[CVS ] CVS. Concurrent Version System.

Disponível em <http://focalinux.cipsga.org.br/guia/avancado/ch-s-cvs.htm>. Acesso em: Julho, 2006.

[Ecl ] IDE Eclipse. IDE Eclipse.

Disponível em <http://www.eclipse.org/>. Acesso em: Outubro,2006.

[GPL ] GPL. General Public License.

Disponível em <http://www.gnu.org/licenses/gpl.html>. Acessoem: Julho, 2006.

[Hib ] Hibernate. Tecnologia de mapeamento automático entre modelosrelacional e orientado a objetos.

Disponível em <http://www.hibernate.org/>. Acesso em: Julho,2006.

[HSQ ] HSQLDB. HSQLDB.

Disponível em <http://www.hsqldb.org>. Acesso em: Outubro,2006.

[Imh ] Imhotek VNC. Imhotek VNC.

Disponível em <http://www.imhotek.com/html/vnc.html>.Acesso em: Julho, 2006.

[J2M a] J2ME. J2ME.

Disponível em <http://java.sun.com/javame/index.jsp>. Acessoem: Outubro, 2006.

54

[J2M b] J2ME VNC. J2ME VNC.

Disponível em <http://j2mevnc.sourceforge.net/>. Acesso em: Ju-lho, 2006.

[JCo ] JCon�g. JCon�g.

Disponível em <http://tolstoy.com/samizdat/jcon�g.html>.Acesso em: Novembro, 2006.

[JFr ] JFreeChart. Biblioteca avançada para desenho de grá�cos.

Disponível em <http://www.jfree.org/jfreechart/>. Acesso em:Julho, 2006.

[JNC ] JNC Mobile. JNC Mobile.

Disponível em<http://projetos.inf.ufsc.br/arquivos_projetos/projeto_79/Relatório_Final_TCC.pdf>. Acesso em: Novembro, 2005.

[NET ] .NET VNC Viewer. .NET VNC Viewer.

Disponível em <http://dotnetvnc.sourceforge.net/>. Acesso em:Julho, 2006.

[Poc ] PocketVNC. PocketVNC.

Disponível em <http://www.pocketvnc.com/pocketVNC.aspx>.Acesso em: Julho, 2006.

[Qua ] Quartz. Agendador avançado de tarefas.

Disponível em <http://www.opensymphony.com/quartz/>.Acesso em: Julho, 2006.

[RFB ] RFB. Remote Framebu�er.

Disponível em <http://realvnc.com/docs/rfbproto.pdf>. Acessoem: Julho, 2006.

[VNC a] VNC. Real VNC.

Disponível em <http://www.realvnc.com/>. Acesso em: Julho,2006.

[VNC b] VNC Viewer. VNC Viewer.

Disponível em <http://www.p800.info/app.php?app_id=13>.Acesso em: Julho, 2006.

55

[VNC c] VNC2Go. VNC2Go.

Disponível em <http://www.freeutils.net/vnc2go/index.jsp>.Acesso em: Julho, 2006.

56

Apêndice A

Lista de Acrônimos

1. RFB: (Remote FrameBu�er), protocolo construído para o acesso re-moto em interfaces grá�cas.

2. VNC: (Virtual Network Computing), sistema criado para possibilitaro acesso a computadores remotos.

3. VNC2Go: Trabalho correlato feito em Java.

4. PocketVNC: Trabalho correlato feito para WindowsCE.

5. .NET VNC Viewer: Trabalho correlato feito para WindowsCE.

6. J2ME VNC: Trabalho correlato feito em Java.

7. JNC Mobile: Trabalho correlato feito em Java.

8. Imhotek VNC: Trabalho correlato feito para Symbian.

9. WindowsCE: Sistema operacional de dispositivos móveis.

10. Servidor Bridge: Servidor que tem função de ponte entre o cliente e oservidor VNC.

11. Wrapper do Cliente: ��Casca� implementada no cliente.

12. Eclipse: IDE utilizada na programação do cliente e servidor.

13. Java: Linguagem de programação para desktop.

14. J2ME: Linguagem de programação para celulares.

57

15. Antenna: Usado para e compilar, empacotar, ofuscar o código e rodaras aplicações de celulares.

16. Hibernate: Ferramenta de mapeamento objeto/relacional para Java.

17. HSQLDB: Banco de dados livre. Feito em Java.

18. JCon�g: API que fornece espaço em disco.

19. Quartz: Agendador de Tarefas.

20. GPL: Licença para software livre.

21. CVS: Sistema de controle de versão.

22. JDBC: Driver para conexão com o banco de dados.

23. Raw: Codi�cações do protocolo RFB.

24. CopyRect: Codi�cações do protocolo RFB.

25. RRE: Codi�cações do protocolo RFB.

26. CoRRE: Codi�cações do protocolo RFB.

27. Hextile: Codi�cações do protocolo RFB.

28. ZRLE: Codi�cações do protocolo RFB.

29. Pixel: A menor unidade grá�ca de uma imagem matricial, e que sópode assumir uma única cor por vez.

30. Task: Tarefas do servidor.

31. MIDP: (Mobile Information Device Pro�le), versão do J2ME para ce-lular.

32. Tiles: Pequenos quadrados que são um pedaço da tela do celular equando unidos formam a tela inteira.

33. Flag: Variável com valor verdadeiro ou falso.

34. UltraVNC: Servidor VNC.

35. Real VNC: Servidor VNC.

36. Entity Bean: Representa um registro de uma tabela em um banco dedados.

58

Apêndice B

Ferramentas Utilizadas

B.1 Eclipse

Eclipse[Ecl ] é um software gratuito e independente de plataforma. Atu-almente o eclipse é bastante usado como IDE (Integrated Development En-vironments, Ambiente de Desenvolvimento Integrado), por exemplo, paradesenvolvimento de aplicativos feitos com a linguagem Java (JDT, Java De-velopment Toolkit). Porém também pode ser usado para outros tipos deaplicação cliente. E distribuído com a Eclipse Public License.

Inicialmente o eclipse foi desenvolvido pela IBM para ser o sucessor dafamília de aplicações do VisualAge (com o VisualAge podia-se programar emvárias linguagens, como por exemplo, COBOL, C, C++, Fortran, Smalltalk,entre outras). Hoje em dia o eclipse tornou-se uma ferramenta open-sourcee é dirigida pela Fundação Eclipse que além da IDE eclipse possui muitosoutros projetos.

Uma das grandes vantagens do eclipse é o seu suporte a plugins. Com apossibilidade de criação de plugins foi possível programar em várias outraslinguagens no eclipse. Nativamente o eclipse já vem com os plugins do Ant edo CVS. CDT (C/C++), CFEclipse (ColdFusion Markup Language), Pho-tran (Fortran), LDT (Lua), PHPeclipse (PHP), EPIC (Perl), RDT (Ruby),TeXlipse (LaTeX), EclipseME (J2ME) são alguns exemplos de lingusgens quepossuem plugins para eclipse.

Dentre os plugins existêntes para eclipse foram usados para a confecçãodesse TCC o EclipseME para mudanças no cliente J2MEVNC e para testes,o TeXlipse para a criação desse documento em LaTeX assim como o JDTpara o desenvolvimento do Servidor Bridge.

59

B.2 J2ME

O J2ME (Java Plataform Micro Edition)[J2M a] é uma linguagem quepossibilita o desenvolvimento de aplicações para sistemas embarcados. É umJava para dispositivos como celulares, PDAs, dispositivos pequenos em geralcom transparência ao desenvolvedor os detalhes do fabricante do aparelho.O J2ME certas vantagens para programação em dispositivos móveis:

• Dinamismo: pode-se baixar aplicações pela rede e instalá-las no dispo-sitivo em qualquer momento.

• Segurança: o J2ME garante a proteção de informações que estejam nodispositivo. Os dados de uma aplicação são acessados somente pelaaplicação.

• Portabilidade: aplicações rodam em vários dispositivos de vários fabri-cantes.

• Con�abilidade: com a proteção e gerência de memória o J2ME nãocausa resets em dispositivos embarcados, isso torna o J2ME con�áveljá que reboots não são tolerados nesses tipos de dispositivos.

Quanto a sua con�guração a tecnologia J2ME foi dividida da seguintemaneira:

• CDC (Connected Device Con�guration): conjunto de tecnologias o qualo destino é a utilização em dispositivos mais potentes. Com o CDCpode-se construir interfaces grá�cas melhores e aplicações que utilizemmais processamento computacional.

• CLDC (Connected Limited Device Con�guration): de�ne um conjuntode APIs para ambientes com capacidade muito baixa de processamento,fonte de energia limitada. Por exemplo, os celulares.

Para que não se torne especí�ca a programação em cada aparelho celularcriou-se per�s. As duas con�gurações estão divididas em vários per�s, porémpara aparelhos celulares CLDC existe somente o per�l MIDP (Mobile Infor-mation Device Pro�le). Para que um determinado aparelho possa suportarum per�l ele deve possuir uma série de requisitos de software e de hardwareos quais são de�nidos nas especi�cações dos per�s.

J2ME também possui a JSR (Java Speci�cation Request) que são docu-mentos submetidos por membros que propõe o desenvolvimento de uma novaespeci�cação. Atualmente existe várias JSR, dentre elas podemos citar:

• JSR1: Especi�cação de tempo real.

60

• JSR5: Especi�cação de parsing XML.

• JSR15: Especi�cação de I/O de Imagens.

• JSR30: Especi�cação CLDC.

• JSR36: Especi�cação CDC.

• JSR37: Especi�cação MIDP.

• JSR54: Especi�cação JDBC 3.0.

• JSR68: Especi�cação da plataforma J2ME.

• JSR74: Especi�cação de PKCS (Public Key Cryptography Standards).

• JSR184: Especi�cação para grá�cos 3D em aparelhos móveis.

• JSR189: Java 3D API 1.4.

• JSR924: Especi�cação da Maquina Virtual Java.

• Entre outras.

B.3 Antenna

O Antenna[Ant ] é uma ferramenta que fornece Task Ant apropriadaspara desenvolvimento de aplicações Java MIDP (Mobile Information DevicePro�le). Usando o Antenna se pode compilar, empacotar, ofuscar o códigoe rodar as aplicações MIDP, assim como manipular os arquivos de descriçãoJAD (Java Application Descriptor). Para ofuscar o código é necessário quese tenha instalado no computador o ofuscador RetroGuard e/ou o ofuscadorProGuard.

B.4 Hibernate

O Hibernate[Hib ] é uma ferramenta de mapeamento objeto/relacionalpara Java. Tem como objetivo facilitar a construção de aplicações Java de-pendentes de bases de dados relacionais sendo apenas responsável pelo mape-amento das tabelas do modelo. Com o uso do Hibernate não há a necessidadede se escrever muito código em SQL, tornando assim uma ferramenta que

61

aumenta a velocidade do desenvolvimento. O Hibernate é indicado paraaplicações onde a maior parte da lógica está na própria aplicação Java.

O Hibernate é um projeto open-source licensiado pela LGPL (Lesser Ge-neral Public License).

• Hibernate Core: o objetivo do Hibernate é diminuir ao máximo o tra-balho do programador em relação a programação em linguagem SQL,assim o núcleo gera o SQL para o programador. Porém deixa o pro-gramador livre para escrever instruções em SQL ou HQL (HibernateQuery Language).

• Hibernate Annotations: assim como todas as ferramentas de mapea-mento objeto/relacional, o hibernate requer metadatas.

• Hibernate EntityManager: o desenvolvedor pode usar as APIs nativasdo Hibernate, do SQL e do JDBC sempre que achar necessário. Apersistência fornecida pelo Hibernate é a persistência padrão do JBossEJB 3.

• Hibernate Tools: possui plugins para Eclipse, tasks Ant para integraçãodurante o ciclo de compilação.

• NHibernate: Hibernate para desenvolvimento com .NET.

B.5 HSQLDB

Hypersonic SQL Database (HSQLDB)[HSQ ] é um banco de dados livrefeito em Java. Possui uma arquitetura cliente-servidor ou standalone paraa manipulação do banco. O HSQLDB é um banco multiplataforma e coma possibilidade de manipulçao de banco de dados em memória, em arquivostextos ou em disco. É uma solução simples que utiliza poucos recursos epossui um bom desempenho.

Componentes:

• HSQLDB JDBC Driver: possui um driver padrão JDBC para conexãode aplicações com o Sistema de Gerenciamento.

• Database Manager: ferramenta grá�ca do HSQLDB, uma versão feitacom AWT e outra com Swing.

• Query Tool e SQL Tool: ferramenta para o envio de instruções SQLpor linha de comando.

62

• HSQLDB RDBMS: módulo gerenciador do banco de dados.

B.6 JCon�g

O JCon�g [JCo ] é uma lib cross-platform para Java. Com ela pode-seter informações sobre processos que estão sendo executados no computador,tipos de arquivos, e muitas funcionalidades a nível de sistema. Funciona emvárias plataformas como: Windows, MacOS, Linux, Unix. Porém para o fun-cionamente no sistema operacional windows são necessários os usos de DLLsespecí�cas. Nesse trabalho o JCon�g foi usado para se obter as informaçõesde espaço em disco (capacidade total do disco, espaço livre, espaço usado).

B.7 GPL

GNU General Public License[GPL ] é uma licença para software livrecriada por Richard Stallman publicada em janeiro de 1989 e em 1991 foi pu-blicada a versão 2.0 da licença para sanar os vários problemas que a primeiraversão possuía, também em 1991 foi lançada a LGPL (Lesser General PublicLicense). Atualmente foi publicado um esboço da GPLv3.

Generalizando, a GPL é baseada em quatro liberdades.

1. Todos são livres para executar o programa para qualquer propósito.

2. Todos têm a liberdade de entender como o programa funciona e podemfazer adaptações a esse programa.

3. Podem-se distribuir cópias do programa de modo que você possa ajudarao próximo.

4. A liberdade de fazer aperfeiçoamentos no programa, e liberar essesaperfeiçoamentos a �m de bene�ciar toda a comunidade.

O código fonte ser aberto é um requisito para que as liberdades dois equatro possam acontecer.

Apesar de todas as liberdades, a GPL mantém os direitos do autor nãopermitindo que a informação seja usada de forma que limite às liberdadesoriginais. A licença também não permite que o código seja apoderado poroutra pessoa, ou se criem restrições que impeçam o código de ser distribuído

63

da mesma maneira a qual foi adquirido, ou seja, se alguém usar um pro-grama sob a licença GPL a �m de criar um novo programa/função, esse novoprograma/função obrigatoriamente deverá estar sob a licença GPL.

A principal diferença entre a GPL e a LGPL é que a LGPL permite queprogramas sejam ligados com programas ou módulos que não são necessa-riamente GPL ou LGPL, por exemplo, podem ser programas ou módulosproprietários.

B.8 CVS

CVS[CVS ] (Concurrent Version System) é um sistema de controle deversão, o qual se trabalha com várias versões dos arquivos mantendo as ver-sões antigas e logs de quem e quando modi�cou os arquivos. Pode ser usadolocal ou remotamente.

O CVS foi criado a partir do RCS (Revision Control System), criadodevido ao fato do RCV possuir dois grandes problemas:

• Um método de bloqueio dos arquivos: o que acaba impedindo o desen-volvimento em paralelo do projeto.

• O sistema não permite uma hierarquia de diretórios no repositório.

É recomendado o uso do CVS para qualquer desenvolvimento de projetoque tenha vários envolvidos e possam trabalhar ao mesmo tempo.

No modo remoto o CVS utiliza o modelo cliente servidor. O servidorse encarrega de armazenar as versões e os logs do projeto. Os clientes seconectam ao servidor e obtém uma cópia completa do projeto, apos trabalharem cima dessa cópia pode-se enviar ao servidor as modi�cações feitas. Váriosclientes podem editar o mesmo projeto de forma concorrente, quando osclientes tentarem enviar as suas modi�cações o servidor irá tentar concatenartodas as alterações. Caso não seja possível, se dois clientes modi�caram amesma área do código, o servidor executa a primeira alteração e informa aocliente da segunda alteração que houve con�ito.

Limitação do CVS:

• Os diretórios ou arquivos que estão em um repositório não podem serrenomeados, precisa-se remover e adicionar um novo.

B.9 Quartz

64

Quartz[Qua ] é um framework open-source para implementar agendamen-tos de tarefas. É um framework escrito em Java que pode ser usado tantoem J2EE como em J2SE. Ele oferece grande �exibilidade sem perder a sim-plicidade. Pode-se criar agendamentos simples ou complexos para executarqualquer tarefa.

Com o Quartz, por exemplo, é possível criar agendamentos para que umatarefa seja executada todo o dia num determinado horário, ou que essa tarefaseja executada a cada intervalo de tempo.

65

Apêndice C

Anexos

C.1 Código Fonte da Aplicação Cliente (J2ME

VNC com Wrapper)

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003 Michael Lloyd Lee5 ∗6 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify7 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by8 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or9 ∗ ( a t your opt ion ) any l a t e r ve r s i on .10 ∗11 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,12 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f13 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 ∗ GNU General Pub l i c License f o r more d e t a i l s .15 ∗16 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License17 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware18 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA19 ∗/2021 package tk . wetnet . j2me . vnc ;2223 import javax . m i c roed i t i on . mid let . MIDlet ;24 import javax . m i c roed i t i on . mid let . MIDletStateChangeException ;2526 import javax . m i c roed i t i on . l c du i .Command;27 import javax . m i c roed i t i on . l c du i . Form ;28 import javax . m i c roed i t i on . l c du i . A le r t ;

66

29 import javax . m i c roed i t i on . l c du i . CommandListener ;30 import javax . m i c roed i t i on . l c du i . Image ;31 import javax . m i c roed i t i on . l c du i . Display ;32 import javax . m i c roed i t i on . l c du i . D i sp layab l e ;33 import javax . m i c roed i t i on . l c du i . AlertType ;34 import javax . m i c roed i t i on . l c du i . TextFie ld ;3536 import javax . m i c roed i t i on . rms . RecordStore ;37 import javax . m i c roed i t i on . rms . RecordEnumeration ;3839 /∗∗ The About and Advanced S e t t i n g s MIDlet .40 ∗ To reduce the run−t ime memory requirements o f the main MIDlet ,41 ∗ the about screen and the advanced s e t t i n g s are combined in t o a42 ∗ s epara t e MIDlet .43 ∗ @author Michael Lloyd Lee44 ∗ @version 1 . 0 . 045 ∗ @todo Rewrite Macro Maker46 ∗/4748 public class About extends MIDlet49 implements CommandListener {50 private Command ex i t = new Command( "#ex i t#" , Command.EXIT,

0 ) ;51 private Command de l e t e = new Command( "#rese t_host s#" , Command.SCREEN, 1 ) ;52 private Command gpl = new Command( "#gpl#" , Command.SCREEN, 1 ) ;53 private Command mit = new Command( "#mit#" , Command.SCREEN, 1 ) ;54 private Command t r a n l a t o r s = new Command( "#t r a n s l a t o r s#" , Command.SCREEN,55 0 ) ;56 private Command buts = new Command( "#buts#" ,Command.SCREEN, 1 ) ;5758 private Command editCmds = new Command( "#edit_cmds#" , Command.SCREEN, 1 ) ;5960 private Command back = new Command( "#back#" , Command.BACK, 0 ) ;6162 private Command update = new Command( "#update#" , Command.ITEM, 0 ) ;63 private Command add = new Command( "#add#" , Command.OK, 0 ) ;6465 /∗∗ For ge tHe i gh t ()/ getWidth ( )66 ∗/67 private VNCCanvas c = new VNCCanvas ( ) ; // why ohh why arn ' t they s t a t i c ?6869 private Form about = new Form( "#about#" ) ;70 private Image ab = null ;7172 private Aler t gp lA l e r t = null ;73 private Aler t mitAlert = null ;74 private Aler t t ranAle r t = null ;75 private Aler t butsAle r t = null ;76

67

77 private Form commandForm = null ;7879 private RecordStore r s ;8081 /∗∗ The name o f the Macro ∗/82 private TextFie ld name = new TextFie ld ( "#name#" , "" , 255 , TextFie ld .ANY ) ;83 /∗∗ The Macro s t r i n g ∗/84 private TextFie ld macro = new TextFie ld ( "#macro#" , "" , 255 ,85 TextFie ld .ANY ) ;8687 private HostCommand currentID = null ;8889 public About ( ) {90 super ( ) ;9192 try {93 ab = Image . createImage ( "/VNC. png" ) ;94 about . append ( ab ) ;95 } catch ( java . i o . IOException t ) {96 }97 about . append ( "#abouts t r#\n#http#\n#sprocketcog#\n#mark#\n#konrad#\n#me#" ) ;9899 gp lA l e r t = new Aler t ( "#gpl#" , "#gp l s t r#" , ab , AlertType . INFO ) ;100 butsAle r t = new Aler t ( "#buts#" ,101 "#up#" + c . getKeyName( c . getKeyCode ( c .UP) )102 + "\n#down#" + c . getKeyName103 ( c . getKeyCode ( c .DOWN))104 + "\n#l e f t#" + c . getKeyName105 ( c . getKeyCode ( c .LEFT) )106 + "\n#r i gh t#" + c . getKeyName107 ( c . getKeyCode ( c .RIGHT) )108 + "\n#f i r e#" + c . getKeyName109 ( c . getKeyCode ( c . FIRE) )110 + "\n#game_a#" + c . getKeyName111 ( c . getKeyCode ( c .GAME_A))112113 , ab , AlertType . INFO ) ;114 mitAlert = new Aler t ( "#mit#" , "#mit s t r#" , ab , AlertType . INFO ) ;115 t ranAle r t = new Aler t ( "#t r a n s l a t o r s#" , "#thanks#\n"116 + " S t e f f e n Menne\n"117 + " f o r the German ve r s i on \n"118 + "Angela Antoniou\n"119 + " f o r the Greek ve r s i on \n"120 + "Nythi l \n"121 + " f o r the Po l i sh ve r s i on \n"122 + "Emeric Laroche\n"123 + " f o r the French ve r s i on " ,124 ab , AlertType . INFO ) ;125

68

126 gp lA l e r t . setTimeout ( Ale r t .FOREVER ) ;127 mitAlert . setTimeout ( Ale r t .FOREVER ) ;128 t ranAle r t . setTimeout ( Ale r t .FOREVER ) ;129 butsAle r t . setTimeout ( Aler t .FOREVER ) ;130131 commandForm = new Form( "#edit_cmds_tit le#" ) ;132 commandForm . append ( name ) ;133 commandForm . append ( macro ) ;134 commandForm . setCommandListener ( this ) ;135136 commandForm . addCommand( back ) ;137 commandForm . addCommand( add ) ;138139 // TODO: Fix excep t i on hand l ing !140 try {141 r s = RecordStore . openRecordStore ( "cmds" , true ) ;142 i f ( r s . getNumRecords ( ) == 0 ) {143 byte [ ] s = "Ctr l Alt Del |<\\c<\\a !\\d>\\a>\\c" . getBytes ( ) ;144 r s . addRecord ( s , 0 , s . l ength ) ;145 }146147148 RecordEnumeration re = r s . enumerateRecords ( null , null , fa l se ) ;149 while ( re . hasNextElement ( ) ) {150 int id = re . nextRecordId ( ) ;151 St r ing cur rent = new St r ing ( r s . getRecord ( id ) ) ;152 St r ing t i t l e = current ;153 i f ( cur r ent . indexOf ( " | " ) > 0 ) {154 t i t l e = current . sub s t r i ng (0 , cur r ent . indexOf ( " | " ) ) ;155 }156 HostCommand cm = new HostCommand( t i t l e ,157 Command.ITEM, 10 , id ) ;158 commandForm . addCommand( cm ) ;159 }160 } catch ( javax . m i c roed i t i on . rms . RecordStoreException t ) {161 System . e r r . p r i n t l n ( "VNC( ) : t " + t . t oS t r i ng ( ) ) ;162 t . pr intStackTrace ( ) ;163 }164165 /∗∗∗166 ∗ My bad haiku167 ∗ Memory o f Net Po s i t i v e168 ∗ i t i s in .169 ∗∗∗/170 about . addCommand( e x i t ) ;171 about . addCommand( gpl ) ;172 about . addCommand( buts ) ;173 about . addCommand( mit ) ;174 about . addCommand( editCmds ) ;

69

175 about . addCommand( t r a n l a t o r s ) ;176 about . addCommand( d e l e t e ) ;177 about . setCommandListener ( this ) ;178179 }180181 public void commandAction (Command c , Di sp layab l e d) {182 i f ( d == commandForm ) {183 // TODO: Fix excep t i on hand l ing !184 try {185 i f ( c == back ) {186 Display . ge tDisp lay ( this ) . se tCurrent ( about ) ;187 } else i f ( c == add ) {188 byte [ ] s = (name . g e tS t r i ng ( ) . r ep l a c e ( ' | ' , ' p ' )189 + " | "190 + macro . g e tS t r i ng ( ) . r ep l a c e ( ' | ' , ' p ' ) )191 . getBytes ( ) ;192 int id = r s . addRecord ( s , 0 , s . l ength ) ;193 HostCommand hc = new HostCommand( name . g e tS t r i ng ( )194 . r ep l a c e ( ' | ' , ' p ' ) ,195 Command.ITEM, 10 , id ) ;196 commandForm . addCommand( hc ) ;197 commandForm . removeCommand( add ) ;198 commandForm . addCommand( update ) ;199 currentID = hc ;200 } else i f ( c == update ) {201 byte [ ] s = (name . g e tS t r i ng ( ) . r ep l a c e ( ' | ' , ' p ' )202 + " | "203 + macro . g e tS t r i ng ( ) . r ep l a c e ( ' | ' , ' p ' ) )204 . getBytes ( ) ;205 r s . setRecord ( currentID . id , s , 0 , s . l ength ) ;206 commandForm . removeCommand( currentID ) ;207 currentID = new HostCommand( name . g e tS t r i ng ( )208 . r ep l a c e ( ' | ' , ' p ' ) ,209 Command.ITEM, 10 ,210 currentID . id ) ;211 commandForm . addCommand( currentID ) ;212213 } else i f ( c instanceof HostCommand ) {214 St r ing tmp = new St r ing ( r s . getRecord ( ( (HostCommand) c )215 . id ) ) ;216 name . s e t S t r i n g ( tmp . sub s t r i ng (0 , tmp . indexOf ( " | " ) ) ) ;217 macro . s e t S t r i n g ( tmp . sub s t r i ng218 ( tmp . indexOf ( " | " ) + 1 ,219 tmp . l ength ( ) ) ) ;220 commandForm . removeCommand( add ) ;221 commandForm . addCommand( update ) ;222 currentID = (HostCommand) c ;223 }

70

224 } catch ( Throwable t ){225 System . e r r . p r i n t l n ( t ) ;226 Display . getDi sp lay ( this ) . se tCurrent227 ( new Aler t ( "Error " , t . t oS t r i ng ( ) , null ,228 AlertType .ERROR ) , commandForm ) ;229230 }231 } else i f ( d == about ) {232 i f ( c == ex i t ) {233 not i fyDes t royed ( ) ;234 } else i f ( c == gpl ) {235 Display . getDi sp lay ( this ) . se tCurrent ( gp lA l e r t ) ;236 } else i f ( c == mit ) {237 Display . getDi sp lay ( this ) . se tCurrent ( mitAlert ) ;238 } else i f ( c == t r an l a t o r s ) {239 Display . getDi sp lay ( this ) . se tCurrent ( t ranAle r t ) ;240 } else i f ( c == editCmds ) {241 Display . getDi sp lay ( this ) . se tCurrent ( commandForm ) ;242 } else i f ( c == t r an l a t o r s ) {243 Display . getDi sp lay ( this ) . se tCurrent ( t ranAle r t ) ;244 } else i f ( c == buts ) {245 Display . getDi sp lay ( this ) . se tCurrent ( butsAle r t ) ;246 } else i f ( c == de l e t e ) {247 try {248 RecordStore . de l e t eRecordStore ( " hos t s " ) ;249 } catch ( javax . m i c roed i t i on . rms . RecordStoreException t ) {}250 }251 }252 }253254 protected void pauseApp ( ) {255 }256257 protected void destroyApp (boolean parm1) throws

258 MIDletStateChangeException {259 try {260 r s . c l o s eRecordStore ( ) ;261 } catch ( javax . m i c roed i t i on . rms . RecordStoreException t ) {262263 }264265 }266267 protected void startApp ( )268 throws javax . m i c roed i t i on . mid let . MIDletStateChangeException {269270 Display . ge tDisp lay ( this ) . se tCurrent ( about ) ;271 }272 }

71

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003 Michael Lloyd Lee5 ∗6 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify7 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by8 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or9 ∗ ( a t your opt ion ) any l a t e r ve r s i on .10 ∗11 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,12 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f13 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 ∗ GNU General Pub l i c License f o r more d e t a i l s .15 ∗16 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License17 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware18 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA19 ∗/2021 package tk . wetnet . j2me . vnc ;2223 import javax . m i c roed i t i on . l c du i . ∗ ;2425 public class HostCommand extends Command {26 int id ;27 public HostCommand( St r ing l , int f , int p , int i ) {28 super ( l , f , p ) ;29 id = i ;30 }31 }

72

1 /∗ −∗−mode : java ; c−bas ic−o f f s e t : 2 ; −∗− ∗/2 /∗3 ∗ This f i l e i s par t o f J2ME VNC.4 ∗5 ∗ Copyright ( c ) 2005 ymnk , JCraft , Inc . A l l r i g h t s r e s e rved .6 ∗7 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify8 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by9 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or10 ∗ ( a t your opt ion ) any l a t e r ve r s i on .11 ∗12 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,13 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f14 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15 ∗ GNU General Pub l i c License f o r more d e t a i l s .16 ∗17 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License18 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware19 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA20 ∗/2122 package tk . wetnet . j2me . vnc ;2324 //#i f d e f JHTTP_TUNNEL2526 import javax . m i c roed i t i on . i o . ∗ ;27 import java . i o . ∗ ;28 import com . j c r a f t . j h t tp tunne l . ∗ ;2930 class JHttpTunnelStreamConnection implements StreamConnection{31 private InputStream in=null ;32 private OutputStream out=null ;33 private boolean c l o s ed=fa l se ;34 private JHttpTunnelClient j h t c=null ;35 JHttpTunnelStreamConnection ( St r ing host , int port ) throws IOException{36 try{37 jh t c=new JHttpTunnelClient ( host , port ) ;38 j h t c . setInBound (new InBoundConnector ( ) ) ;39 j h t c . setOutBound (new OutBoundConnector ( ) ) ;40 j h t c . connect ( ) ;41 in=jh t c . getInputStream ( ) ;42 out=jh t c . getOutputStream ( ) ;43 }44 catch ( Exception e ){45 throw new IOException ( e . t oS t r i ng ( ) ) ;46 }47 }48 public void c l o s e ( ) throws IOException {

73

49 i f ( c l o s ed ) throw new IOException ( "Closed Stream" ) ;50 try{51 i f ( j h t c !=null ){52 jh t c . c l o s e ( ) ; j h t c=null ;53 }54 }55 catch ( Exception e ){}56 c l o s ed=true ;57 }58 public DataInputStream openDataInputStream ( ) throws IOException {59 // i f ( c l o s ed ) throw new IOException (" Closed Stream ") ;60 return new DataInputStream ( in ) ;61 }62 public InputStream openInputStream ( ) throws IOException {63 // i f ( c l o s ed ) throw new IOException (" Closed Stream ") ;64 return in ;65 }66 public DataOutputStream openDataOutputStream ( ) throws IOException {67 // i f ( c l o s ed ) throw new IOException (" Closed Stream ") ;68 return new DataOutputStream ( out ) ;69 }70 public OutputStream openOutputStream ( ) throws IOException {71 // i f ( c l o s ed ) throw new IOException (" Closed Stream ") ;72 return out ;73 }74 }75 //#e l s e76 // Used so I can s t i l l compi le . Removed by WtkSmartLink77 //# c l a s s JHttpTunnelStreamConnection {}78 //#end i f

74

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003 Michael Lloyd Lee5 ∗6 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify7 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by8 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or9 ∗ ( a t your opt ion ) any l a t e r ve r s i on .10 ∗11 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,12 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f13 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 ∗ GNU General Pub l i c License f o r more d e t a i l s .15 ∗16 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License17 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware18 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA19 ∗/2021 /∗ This has to be the u g l i e s t code in e x i s t e n c e !22 ∗/2324 package tk . wetnet . j2me . vnc ;2526 /∗∗ Runs the " t i c k " method in VNCCanvas27 ∗ @see VNCCanvas . t i c k ( )28 ∗ @see java . u t i l . Timer29 ∗/30 class Ticker extends java . u t i l . TimerTask {3132 /∗∗ The VNCCanvas to " t i c k " ∗/33 private VNCCanvas vnc ;3435 /∗∗ Constructor36 ∗ @param v the VNCCanvas to t i c k .37 ∗/38 public Ticker ( VNCCanvas v ) {39 vnc = v ;40 }4142 /∗∗ Ticks the VNC Canvas ∗/43 public void run ( ) {44 vnc . t i c k ( ) ;45 }46 }

75

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003−2005 Michael Lloyd Lee5 ∗6 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify7 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by8 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or9 ∗ ( a t your opt ion ) any l a t e r ve r s i on .10 ∗11 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,12 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f13 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 ∗ GNU General Pub l i c License f o r more d e t a i l s .15 ∗16 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License17 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware18 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA19 ∗/2021 package tk . wetnet . j2me . vnc ;2223 import java . u t i l . Vector ;2425 import java . i o . InputStream ;26 import java . i o . OutputStream ;27 import java . i o . IOException ;282930 import javax . m i c roed i t i on . mid let . MIDlet ;31 import javax . m i c roed i t i on . mid let . MIDletStateChangeException ;3233 import javax . m i c roed i t i on . l c du i .Command;34 import javax . m i c roed i t i on . l c du i . Form ;35 import javax . m i c roed i t i on . l c du i . A le r t ;36 import javax . m i c roed i t i on . l c du i . CommandListener ;37 import javax . m i c roed i t i on . l c du i . Image ;38 import javax . m i c roed i t i on . l c du i . Display ;39 import javax . m i c roed i t i on . l c du i . D i sp layab l e ;40 import javax . m i c roed i t i on . l c du i . AlertType ;41 import javax . m i c roed i t i on . l c du i . ChoiceGroup ;42 import javax . m i c roed i t i on . l c du i . Gauge ;43 import javax . m i c roed i t i on . l c du i . TextFie ld ;44 import javax . m i c roed i t i on . l c du i . TextBox ;45 import javax . m i c roed i t i on . l c du i . Choice ;4647 import javax . m i c roed i t i on . rms . RecordStore ;48 import javax . m i c roed i t i on . rms . RecordEnumeration ;

76

4950 import javax . m i c roed i t i on . i o . StreamConnection ;51 import javax . m i c roed i t i on . i o . Connector ;52 import javax . m i c roed i t i on . i o . ConnectionNotFoundException ;53 import javax . m i c roed i t i on . i o . InputConnection ;54 import javax . m i c roed i t i on . i o . HttpConnection ;555657 import tk . wetnet . vnc . RFBProto ;58 import tk . wetnet . vnc . DrawToable ;5960 /∗∗ The main MIDlet61 ∗ This has a form fo r the connect ion in f o ( s e r v e r IP/ por t e t c )62 ∗ Then i t c r e a t e s the socke t connect ion between the dev i c e and the server ,63 ∗ passes the IO streams to a newly crea t ed RFBProto , and c r ea t e s a VNC Canvas ,64 ∗ and passes the RFB to the canvas .65 ∗/6667 public class VNC extends MIDlet implements CommandListener , Runnable {68 /∗∗ The record s t o r e ho l d ing the "Quick Links " ∗/69 private RecordStore r s = null ;70 /∗∗ The record s t o r e ho l d ing the opt ions , such as i s NCM enab led ∗/71 private RecordStore opt ions = null ;72 /∗∗ A vec to r o f Host Commands ( the i n t e r n a l r e p r e s en t a t i on o f Quick Links73 ∗ @see HostCommand74 ∗/75 private Vector hostCmds = new Vector ( ) ;7677 /∗∗ The mid l e t s Disp lay o b j e c t ∗/78 protected Display me ;79 /∗∗ The VNC Canvas ∗/80 protected VNCCanvas canvas ;81 /∗∗ Our r f b proto ∗/82 protected RFBProto r fb ;83 /∗∗ The current Stream Connection ∗/84 private StreamConnection con ;85 /∗∗ A tempory thread used to s e t up the i n i t i a l connect ion ∗/86 private Thread run ;878889 //#i f d e f DEBUG90 //# Command l o g = new Command( "Log" , Command.OK, 0 ) ;91 //# pr i v a t e Command uploadLog = new Command( "Upload" , Command.OK, 0 ) ;92 //# pr i v a t e Command backLog = new Command( "Back" , Command.OK, 0 ) ;93 //#94 //# pr i v a t e D i sp l a yab l e backDi sp l ayab l e = nu l l ;95 //#end i f9697

77

98 private Form connectionForm = new Form( "VNC" ) ;99 private Form connectingForm = new Form( "VNC − #connect ing#" ) ;100 private TextFie ld u r l = new TextFie ld ( "#host#" , "" , 25 , TextFie ld .ANY ) ;101 private TextFie ld password = new TextFie ld ( "#password#" , "" ,102 14 , TextFie ld .PASSWORD ) ;103 private Command connect = new Command( "#connect#" , Command.OK, 20 ) ;104105 private Command add = new Command( "#add#" , Command.ITEM, 9 ) ;106 private Command manage = new Command( "#manage#" , Command.ITEM, 11 ) ;107108 private Command de l e t e = new Command( "#de l e t e#" , Command.OK, 0 ) ;109 private Command back = new Command( "#back#" , Command.BACK, 1 ) ;110 private Command ex i t = new Command( "#ex i t#" , Command.EXIT, 1 ) ;111112 private ChoiceGroup host s = null ;113 private St r ing host = "" ;114 private int port = 5900 ;115116 private Gauge connect ionDisp lay = new Gauge ( "#connect ing#" , false , 5 , 0 ) ;117118 /∗∗ Tick boxes f o r each o f the op t i ons ( l i k e NCM, shared desktop , use HTTP)119 ∗/120 private ChoiceGroup shared = new ChoiceGroup ( "" , Choice .MULTIPLE ) ;121122 /∗∗ The connect ion s tage , between 0 & 4∗/123 private int conD = 0 ;124125 /∗∗ Increase the conD by one , and updates the connect ion d i s p l a y gauge126 ∗ @see connec t ionDisp lay127 ∗ @see conD128 ∗/129 protected void incConnect ionStatus ( ) {130 conD++;131 connect ionDisp lay . setValue ( conD ) ;132 }133134 /∗∗135 ∗ Then i t c r e a t e s the socke t connect ion between the dev i c e and the server ,136 ∗ passes the IO streams to a newly crea t ed RFBProto , and c r ea t e s a137 ∗ VNC Canvas , and passes the RFB to the canvas , o c c a s i ona l l y c a l l i n g138 ∗ inc Connection S ta tus139 ∗ @see me140 ∗ @see incConnect ionSta tus141 ∗/142 public void run ( ) {143 i f ( u r l . g e tS t r i ng ( ) == null | |144 ( u r l . g e tS t r i ng ( ) != null

145 && ur l . g e tS t r i ng ( ) . l ength ( ) < 1 ) ) {146 Aler t a = new Aler t ( "#no_host#" , "#host_box_blank#" ,

78

147 null , AlertType .ERROR ) ;148 a . setTimeout ( a .FOREVER ) ;149 me . setCurrent ( a , connectionForm ) ;150 return ;151 }152153 /∗∗154 ∗ @random_idea Add an animated c l o c k wh i l e i t connects155 ∗/156 Thread . currentThread ( ) . y i e l d ( ) ;157 incConnect ionStatus ( ) ;158 host = ur l . g e tS t r i ng ( ) ;159 //#i f d e f JHTTP_TUNNEL160 port = 8888 ;161 //#end i f162163 i f ( host . indexOf ( " : " ) >= 0 ) {164 try {165 i f ( host . charAt ( host . indexOf ( " : " )+1 ) != ' : ' ) {166 port = In t eg e r . pa r s e In t ( host . s ub s t r i ng167 ( host . indexOf ( " : " )+1 ,168 host . l ength ( ) ) ) ;169170 //#i f n d e f JHTTP_TUNNEL171 //# i f ( por t < 5900 ) por t += 5900;172 //#end i f173 } else {174 port = In t eg e r . pa r s e In t ( host . s ub s t r i ng175 ( host . indexOf ( " : " )+2 ,176 host . l ength ( ) ) ) ;177 }178 } catch ( NumberFormatException nfe ) {179 Aler t a = new Aler t ( "#problem_connecting#" ,180 "#format_is_wrong#"181 + host . sub s t r i ng ( host . indexOf ( " : " )+1 ,182 host . l ength ( ) )183 + "#is_not_a_number#" ,184 null , AlertType .ERROR ) ;185 a . setTimeout ( a .FOREVER ) ;186 me . setCurrent ( a , connectionForm ) ;187 return ;188 }189 host = host . sub s t r i ng ( 0 , host . indexOf ( " : " ) ) ;190 }191192 //#i f d e f DEBUG193 //# lo g ( "Connecting" ) ;194 //#end i f195

79

196 try {197 //#i f d e f JHTTP_TUNNEL198 i f ( shared . i s S e l e c t e d ( 2 ) ) {199 //#i f d e f DEBUG200 //# lo g ( "Use JHttpTunnel " ) ;201 //#end i f202 con=new JHttpTunnelStreamConnection ( host , /∗8888∗/ port ) ;203 } else {204 //#end i f205 con = ( StreamConnection ) Connector .206 open ( " socket : // " + host + " : " + port ,207 Connector .READ_WRITE ) ;208 //#i f d e f JHTTP_TUNNEL209 }210 //#end i f211 incConnect ionStatus ( ) ;212 //#i f d e f DEBUG213 //# lo g ( "Connection Open" ) ;214 //#end i f215 } catch ( I l l ega lArgumentExcept ion uae ) {216 Aler t a = new Aler t ( "#problem_connecting#" ,217 "#format_is_wrong"218 + "#please_double_check#"219 + "\n" + uae . t oS t r i ng ( ) , // todo debug var ?220 null , AlertType .ERROR ) ;221 a . setTimeout ( a .FOREVER ) ;222 me . setCurrent ( a , connectionForm ) ;223 return ;224 } catch ( ConnectionNotFoundException cn f e ) {225 Aler t a = new Aler t ( "#problem_connecting#" ,226 "#unable_to_connect#"227 + ( cn f e . getMessage ( ) == null ?228 " I s the host c o r r e c t ?" :229 cn f e . getMessage ( ) )230 + "?" ,231 null , AlertType .ERROR ) ;232 a . setTimeout ( a .FOREVER ) ;233 me . setCurrent ( a , connectionForm ) ;234 return ;235 } catch ( IOException i o e ) {236 Aler t a = new Aler t ( "#problem_connecting#" ,237 "#unknown_problem#" + io e . t oS t r i ng ( ) ,238 null , AlertType .ERROR ) ;239 a . setTimeout ( a .FOREVER ) ;240 me . setCurrent ( a , connectionForm ) ;241 return ;242 } catch ( Throwable t ) {243 Aler t a = new Aler t ( "#problem_connecting#" ,244 "#unknown_problem#" + t . t oS t r i ng ( ) ,

80

245 null , AlertType .ERROR ) ;246 a . setTimeout ( a .FOREVER ) ;247 me . setCurrent ( a , connectionForm ) ;248 return ;249 }250251 byte [ ] tmp = password . g e tS t r i ng ( ) . getBytes ( ) ;252 byte [ ] b = new byte [ ( tmp . l ength+1>8?tmp . l ength +1 : 8 ) ] ;253 System . arraycopy ( tmp , 0 , b , 0 , tmp . l ength ) ;254 //#i f d e f DEBUG255 //# lo g ( "Creat ing VNC Canvas" + b . l e n g t h + " " + tmp . l en g t h ) ;256 //#end i f257 canvas = new VNCCanvas( this ) ;258 incConnect ionStatus ( ) ;259 //#i f d e f DEBUG260 //# lo g ( "Canvas Created" ) ;261 //#end i f262263 try {264 //#i f d e f DEBUG265 //# lo g ( "Creat ing RFBProto" ) ;266 //#end i f267 r fb = new RFBProto ( ( ( InputConnection ) con )268 . openDataInputStream ( ) ,269 con . openOutputStream ( ) ,270 b , canvas , shared . i s S e l e c t e d ( 0 ) ,271 shared . i s S e l e c t e d ( 1 ) ) ;272 //#i f d e f DEBUG273 //# lo g ( "RFBProto Created" ) ;274 //#end i f275 } catch ( IOException i o e ) {276 Aler t a = new Aler t ( "#problem_connecting#" ,277 "#unknown_problem#" + io e . t oS t r i ng ( ) ,278 null , AlertType .ERROR ) ;279 a . setTimeout ( a .FOREVER ) ;280 me . setCurrent ( a , connectionForm ) ;281 return ;282 } catch ( Throwable t ) {283 Aler t a = new Aler t ( "#problem_connecting#" ,284 "#unknown_problem#" + t . t oS t r i ng ( ) ,285 null , AlertType .ERROR ) ;286 a . setTimeout ( a .FOREVER ) ;287 me . setCurrent ( a , connectionForm ) ;288 return ;289 }290 run = new Thread ( r fb ) ;291 run . s t a r t ( ) ;292 cleanUp ( ) ;293 incConnect ionStatus ( ) ;

81

294 try {295 r s . c l o s eRecordStore ( ) ;296 } catch ( Throwable t ){}297 }298299 public void commandAction (Command c , Di sp layab l e d) {300 i f ( c == connect ) {301 me . setCurrent ( connectingForm ) ;302 (new Thread ( this ) ) . s t a r t ( ) ;303 } else i f ( c == add ) {304 try {305 St r ing tmp = ur l . g e tS t r i ng ( ) + " | " + password . g e tS t r i ng ( ) ;306 HostCommand cm = new HostCommand( u r l . g e tS t r i ng ( ) ,307 Command.ITEM, 10 ,308 r s . addRecord309 ( tmp . getBytes ( ) , 0 ,310 tmp . l ength ( ) ) ) ;311 hostCmds . addElement ( cm ) ;312 connectionForm . addCommand( cm ) ;313 } catch ( Throwable t ){314 System . e r r . p r i n t l n ( "Save : " + t ) ;315 }316 } else i f ( c == manage ) {317 Form manageForm = new Form( "#manage_hosts#" ) ;318 hos t s = new ChoiceGroup ( "#host_#" , ChoiceGroup .EXCLUSIVE ) ;319 try {320 int s i z e = hostCmds . s i z e ( ) ; ;321 //System . out . p r i n t l n ( s i z e ) ;322 for ( int i = 0 ; i < s i z e ; i++ ) {323 HostCommand current = (HostCommand) hostCmds . elementAt ( i ) ;324 //System . out . p r i n t l n ( i + " " + current . i d + " "325 // + current . g e tLabe l ( ) ) ;326 hos t s . append ( cur rent . id + " " + current . getLabe l ( ) ,327 null ) ;328 }329 } catch ( Throwable t ) { System . e r r . p r i n t l n ( t ) ; }330 manageForm . setCommandListener ( this ) ;331 manageForm . append ( hos t s ) ;332 manageForm . addCommand( d e l e t e ) ;333 manageForm . addCommand( back ) ;334 me . setCurrent ( manageForm ) ;335 } else i f ( c == de l e t e ) {336 St r ing removes = host s . g e tS t r i ng ( hos t s . g e tSe l e c t ed Index ( ) ) ;337 int remove = In t eg e r . pa r s e In t ( removes . sub s t r i ng338 ( 0 , removes . indexOf ( " " ) ) ) ;339 //System . out . p r i n t l n ( remove ) ;340 hos t s . d e l e t e ( hos t s . g e tSe l e c t ed Index ( ) ) ;341 try {342 r s . de le teRecord ( remove ) ;

82

343 } catch ( Throwable t ) {344 System . e r r . p r i n t l n ( " d e l e t e " + t ) ;345 }346 for ( int i = hostCmds . s i z e ()−1; i >=0; i−−){347 i f ( ( (HostCommand) hostCmds . elementAt ( i ) ) . id == remove ) {348 connectionForm . removeCommand( ( (HostCommand) hostCmds349 . elementAt ( i ) ) ) ;350 hostCmds . removeElementAt ( i ) ;351 }352 }353 } else i f ( c == ex i t ) {354 not i fyDes t royed ( ) ;355356 //#i f d e f DEBUG357 //# } e l s e i f ( c == lo g ) {358 //# Form l = new Form( l a s t_ l i n e ) ;359 //# l . append ( complete_log ) ;360 //# l . setCommandListener ( t h i s ) ;361 //# l . addCommand( backLog ) ;362 //# l . addCommand( uploadLog ) ;363 //# backDi sp l ayab l e = d ;364 //# me. se tCurrent ( l ) ;365 //# } e l s e i f ( c == backLog ) {366 //# me. se tCurrent ( backDi sp l ayab l e ) ;367 //# } e l s e i f ( c == uploadLog ) {368369 //# InputStream i s = nu l l ;370 //# OutputStream os = nu l l ;371 //# HttpConnection c1 = nu l l ;372 //# t ry {373 //# con . c l o s e ( ) ;374375 //# c1 = ( HttpConnection ) Connector .376 //# open ( " h t t p :// j2mevnc . source f o r g e . net / cgi−b in /upload . p l " ,377 //# Connector .READ_WRITE, t rue ) ;378379 // Set the r e que s t method and headers380 //# c1 . setRequestMethod ( HttpConnection .POST ) ;381 // Get t ing the output stream may f l u s h the headers382 //# c1 . se tReques tProper ty383 //# ( " I f−Modified−Since " ,384 //# "29 Oct 1999 19 :43 :31 GMT") ;385 //# c1 . se tReques tProper ty386 //# ("User−Agent " ,387 //# "Upload " ) ;388 //# c1 . se tReques tProper ty ("Content−Language " ,389 //# "en−gb " ) ;390391 //# os = c1 . openOutputStream ( ) ;

83

392 //# os . wr i t e ( complete_log . ge tBy te s ( ) ) ;393 //# os . c l o s e ( ) ;394 //#395 // Opening the InputStream w i l l open the connect ion396 // and read the HTTP headers . They are s t o r ed u n t i l397 //# // reque s t ed .398 //# i s = c1 . openInputStream ( ) ;399400 // Get the ContentType401 //# St r ing type = c1 . getType ( ) ;402 //#403 //# St r ing s ;404405 //# i f ( c1 . getResponseCode () != c1 .HTTP_OK ) {406 //# s = c1 . getResponseCode () + " : "407 //# + c1 . getResponseMessage ( ) ;408 //# } e l s e {409 //# // Get the l en g t h and process the data410 //# in t l en = ( i n t ) c1 . ge tLength ( ) ;411 //# i f ( l en > 0) {412 //# by te [ ] data = new by t e [ l en ] ;413 //# in t a c t ua l = i s . read ( data ) ;414 //# s = new S t r ing ( data ) ;415 //# } e l s e {416 //# in t ch ;417 //# St r in gBu f f e r r e s u l t = new S t r in gBu f f e r ( ) ;418 //# whi l e ( ( ch = i s . read ( ) ) != −1) {419 //# r e s u l t . append ( ( char ) ch ) ;420 //# }421 //# s = r e s u l t . t oS t r i n g ( ) ;422 //# }423 //# }424 //# Aler t a = new Aler t ( "Uploaded Log" ,425 //# s , nu l l , n u l l ) ;426 //# a . setTimeout ( A le r t .FOREVER ) ;427 //# me. se tCurrent ( a , d ) ;428 //# } catch ( IOException e ) {429 //# Aler t a = new Aler t ( "Upload Fa i l ed " ,430 //# e . t oS t r i n g ( ) , nu l l , n u l l ) ;431 //# a . setTimeout ( A le r t .FOREVER ) ;432 //# me. se tCurrent ( a , me. ge tCurrent ( ) ) ;433 //# } f i n a l l y {434 //# i f ( i s != nu l l )435 //# t ry { i s . c l o s e ( ) ; } catch ( IOException e ) {}436 //# i f ( os != nu l l )437 //# t ry { os . c l o s e ( ) ; } catch ( IOException e ) {}438 //# i f ( c1 != nu l l )439 //# t ry { c1 . c l o s e ( ) ; } catch ( IOException e ) {}440 //# }

84

441 //#442 //#end i f443444 } else i f ( c == back ) {445 me . setCurrent ( connectionForm ) ;446 } else i f ( c instanceof HostCommand ) {447 try {448 me . setCurrent ( connectingForm ) ;449 HostCommand cmd = (HostCommand) c ;450 St r ing tmp = new St r ing ( r s . getRecord ( cmd . id ) ) ;451 u r l . s e t S t r i n g ( tmp . sub s t r i ng (0 , tmp . indexOf ( " | " ) ) ) ;452 password . s e t S t r i n g ( tmp . sub s t r i ng453 ( tmp . indexOf ( " | " ) + 1 ,454 tmp . l ength ( ) ) ) ;455 (new Thread ( this ) ) . s t a r t ( ) ;456 } catch ( Throwable t ){457 System . e r r . p r i n t l n ( t ) ;458 }459460 }461 }462463 /∗∗ Our "about " image , t h i s doub l e s as the s tandard VNC icon ∗/464 // p ro t e c t ed Image aboutImage = nu l l ;465466467 /∗∗ Constructor468 ∗ Se t s up the UI , adds command l i s t e n e r s , reads the ho s t s469 ∗ Record Store , and s e t s up the Quick Links . Reads the op t i ons470 ∗ record s tore , and s e t s the d e f a u l t op t i ons .471 ∗/472 public VNC() {473 me = Display . getDi sp lay ( this ) ;474475 connectionForm . append ( u r l ) ;476 connectionForm . append ( password ) ;477 connectionForm . append ( shared ) ;478 connectionForm . addCommand( connect ) ;479 connectionForm . addCommand( e x i t ) ;480 connectionForm . addCommand( add ) ;481 connectionForm . addCommand( manage ) ;482 //#i f d e f DEBUG483 //# connectionForm . addCommand( l o g ) ;484 //#end i f485486 connectionForm . setCommandListener ( this ) ;487488 shared . append ( "#shareddesktop#" , null ) ;489 shared . append ( "#ncm#" , null ) ;

85

490 //#i f d e f JHTTP_TUNNEL491 shared . append ( "#use jh t tp#" , null ) ;492 //#end i f493 try {494 r s = RecordStore . openRecordStore ( " hos t s " , true ) ;495 RecordEnumeration re = r s . enumerateRecords ( null , null , fa l se ) ;496 while ( re . hasNextElement ( ) ) {497 int id = re . nextRecordId ( ) ;498 St r ing cur rent = new St r ing ( r s . getRecord ( id ) ) ;499 St r ing t i t l e = current ;500 i f ( cur r ent . indexOf ( " | " ) > 0 ) {501 t i t l e = cur rent . sub s t r i ng (0 , cur r ent . indexOf ( " | " ) ) ;502 }503 HostCommand cm = new HostCommand( t i t l e ,504 Command.ITEM, 10 , id ) ;505 connectionForm . addCommand( cm ) ;506 hostCmds . addElement ( cm ) ;507 }508509510 opt ions = RecordStore . openRecordStore ( " opt ions " , true ) ;511 re = opt ions . enumerateRecords ( null , null , fa l se ) ;512 i f ( re . hasNextElement ( ) ) {513 r i d = re . nextRecordId ( ) ;514 byte [ ] opts = opt ions . getRecord ( r i d ) ;515 i f ( opts != null && opts . l ength > 0) {516 // System . out . p r i n t l n ( op t s . l e n g t h ) ;517 shared . s e tS e l e c t ed Index ( 0 , ( opts [ 0 ] & 1)==1 ) ;518 shared . s e tS e l e c t ed Index ( 1 , ( opts [ 0 ] & 2)==2 ) ;519 }520 } else {521 r i d = −100;;522 }523524 //aboutImage = Image . createImage ( "/VNC. png" ) ;525 //#i f d e f DEBUG526 //# connectingForm .addCommand( l o g ) ;527 //#end i f528 connectingForm . setCommandListener ( (CommandListener ) this ) ;529 // connectingForm . append ( aboutImage ) ;530 connectingForm . append ( connect ionDisp lay ) ;531532533 } catch ( Throwable t ) {534 System . e r r . p r i n t l n ( "VNC( ) : t " + t . t oS t r i ng ( ) ) ;535 t . pr intStackTrace ( ) ;536 }537 }538 /∗∗ The record s t o r e ID fo r the op t i ons ∗/

86

539 private int r i d = 0 ;540541542 /∗∗543 ∗ @todo pause app544 ∗/545 protected void pauseApp ( ) {546547 }548549 /∗∗ Saves the opt ions ,550 ∗ @todo Rework . The op t i ons shou ld be saved on change .551 ∗/552 protected void destroyApp (boolean parm1) throws

553 javax . m i c roed i t i on . mid let . MIDletStateChangeException {554 i f ( canvas != null )555 canvas . c l o s e ( ) ;556 try {557558 byte [ ] b = new byte [ 1 ] ;559 b [ 0 ] = (byte ) ( ( shared . i s S e l e c t e d ( 0 ) ? 1 : 0 )560 + ( shared . i s S e l e c t e d ( 1 ) ? 2 : 0 ) ) ;561 i f ( r i d != −100 ){562 opt ions . setRecord ( r id , b , 0 , b . l ength ) ;563 } else {564 opt ions . addRecord ( b , 0 , b . l ength ) ;565 }566567 r s . c l o s eRecordStore ( ) ;568 opt ions . c l o s eRecordStore ( ) ;569 // op t i ons . de l e t eRecordS tore ( " op t i ons " ) ;570 } catch ( Throwable t ){571 System . e r r . p r i n t l n ( t . t oS t r i ng ( ) ) ;572 }573 }574575 /∗∗ Cal l ed on un−pause or app s t a r t .576 ∗ Se t s the curren t d i s p l a y to e i t h e r the connect ion form i f we are not577 ∗ connected to a server , or the VNC Canvas i f we are connected to a s e r v e r578 ∗ @see MIDlet . s tar tApp579 ∗/580 protected void startApp ( )581 throws javax . m i c roed i t i on . mid let . MIDletStateChangeException {582 i f ( canvas == null )583 me . setCurrent ( connectionForm ) ;584 else

585 me . setCurrent ( canvas ) ;586 }587

87

588 /∗∗ Releases system resources , by n u l l ' ing a l l r e f e rence s , and c a l l i n g589 ∗ GC.590 ∗ None o f the f o l l ow i n g are going to be used again .591 ∗/592 private void cleanUp ( ) {593 connectionForm = null ;594 connectingForm = null ;595596 u r l = null ;597 password = null ;598599 connect = null ;600601 add = null ;602 manage = null ;603604 d e l e t e = null ;605 back = null ;606607 hos t s = null ;608609 System . gc ( ) ;610 }611612 //#i f d e f DEBUG613 //# s t a t i c S t r ing complete_log = "";614 //# s t a t i c S t r ing l a s t_ l i n e = "NOT STARTED TO LOG! " ;615616 //# pub l i c s t a t i c vo id l o g ( S t r ing l o g ) {617 //# System . out . p r i n t l n ( l o g + "\n" ) ;618 //# l a s t_ l i n e = l o g ;619 //# complete_log+=lo g + "\n" ;620 //# }621 //#end i f622623 }624625626 // LocalWords : modeOKCmd keyPressed ASAIK connectionForm useh t t p HostCommand

88

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003 Michael Lloyd Lee5 ∗6 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify7 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by8 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or9 ∗ ( a t your opt ion ) any l a t e r ve r s i on .10 ∗11 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,12 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f13 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 ∗ GNU General Pub l i c License f o r more d e t a i l s .15 ∗16 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License17 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware18 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA19 ∗/2021 package tk . wetnet . j2me . vnc ;2223 import javax . m i c roed i t i on . l c du i . Canvas ;24 import javax . m i c roed i t i on . l c du i . Image ;25 import javax . m i c roed i t i on . l c du i . Graphics ;26 import javax . m i c roed i t i on . l c du i .Command;27 import javax . m i c roed i t i on . l c du i . CommandListener ;28 import javax . m i c roed i t i on . l c du i . ChoiceGroup ;29 import javax . m i c roed i t i on . l c du i . Gauge ;30 import javax . m i c roed i t i on . l c du i . Form ;31 import javax . m i c roed i t i on . l c du i . AlertType ;32 import javax . m i c roed i t i on . l c du i . A le r t ;33 import javax . m i c roed i t i on . l c du i . TextFie ld ;34 import javax . m i c roed i t i on . l c du i . TextBox ;35 import javax . m i c roed i t i on . l c du i . D i sp layab l e ;3637 import javax . m i c roed i t i on . rms . RecordStore ;38 import javax . m i c roed i t i on . rms . RecordEnumeration ;3940 import java . i o . IOException ;4142 import tk . wetnet . vnc . RFBProto ;43 import tk . wetnet . vnc . DrawToable ;44 import tk . wetnet . u t i l . Queue ;4546 /∗∗ The VNC Canvas , r e c e i v e s draw r e qu e s t s from the VNC serve r v ia RFBProto47 ∗ c l a s s , and the end user can the use t h i s to communicated back to the s e r v e r48 ∗ key presses , and mouse movements .

89

49 ∗/50 public f ina l class VNCCanvas extends Canvas51 implements CommandListener , DrawToable , Runnable {52 /∗∗ The VNC c l a s s t ha t c rea t ed me ∗/53 private VNC midlet ;5455 /∗∗ Timeout f o r SMS key pre s s . Af ter X seconds t h i s i s c a l l e d ,56 ∗ sending the cu r r en t l y s e l e c t e d l e t t e r to the s e r v e r .57 ∗ @category SMS Key System58 ∗/59 private class Timeout extends java . u t i l . TimerTask {6061 public void run ( ) {62 nextLet te r ( ) ;63 r epa in t ( ) ;64 s e rv i c eRepa in t s ( ) ;65 }66 }676869 /∗∗ Our timer , used f o r SMS time outs , and Act ive Refresh .70 ∗ @category SMS Key System71 ∗ @category Act ive Refresh72 ∗/73 private java . u t i l . Timer t imer = new java . u t i l . Timer ( ) ;7475 /∗∗ The current Timeout Object .76 ∗ @category SMS Key System77 ∗/78 private Timeout timeout = null ;7980 /∗∗ I s Act ive Refresh cu r r en t l y enab led81 ∗ @category Act ive Refresh82 ∗/83 private boolean ac t i v eRe f r e sh = fa l se ;8485 /∗∗ The "working" icon ∗/86 private Image redraw = null ;87 /∗∗ The mouse icon ∗/88 private Image mouse = null ;89 /∗∗ The SMS icon ∗/90 private Image sms = null ;91 /∗∗ The Nav mode icon ∗/92 private Image nav = null ;9394 /∗∗ I f a c t i v e r e f r e s h i s enabled , and the s e r v e r i s not c u r r en t l y sending95 ∗ data to the c l i e n t , r e f r e s h the screen .96 ∗ @category Act ive Refresh97 ∗/

90

98 protected void t i c k ( ) {99 i f ( a c t i v eRe f r e sh && ! update ) {100 try {101 midlet . r f b . requestUpdate ( o f fx , o f fy ,102 getWidth ( ) ,103 getHeight ( ) ,104 true ) ;105 } catch ( IOException t ) {106 e r r o r ( "Active Refresh : " + t . t oS t r i ng ( ) ) ;107 }108 }109 }110111 /∗∗ The amount to move the screen by ∗/112 private int s c r o l l b y = ( getWidth ( ) / 5 ) ;113 /∗∗ The amount to move the screen by ∗/114 private int s c ro l lbyY = ( getHeight ( ) / 5 ) ;115116 /∗∗ A tempory copy o f the curren t screen used when the screen i s117 ∗ s c r o l l e d .118 ∗/119 private Image tmpImg = Image . createImage ( getWidth ( ) , getHeight ( ) ) ;120 /∗∗ The back b u f f e r used by the i n t e r n a l doub le b u f f e r i n g ∗/121 private Image bu f f e r = Image . createImage ( getWidth ( ) , getHeight ( ) ) ;122 /∗∗ The zoomed out image , c rea t ed by draw ( i n t x l o t s ) ∗/123 private Image zoomOut = Image . createImage ( getWidth ( ) , getHeight ( ) ) ;124125 /∗∗ The back−b u f f e r s g raph i c s o b j e c t126 ∗ @todo Maybe rename?127 ∗/128 private Graphics g = bu f f e r . getGraphics ( ) ;129 /∗∗ The zoomed out g raph i c s o b j e c t ∗/130 private Graphics gzoomout = zoomOut . getGraphics ( ) ;131132 /∗∗ The current X o f f s e t s ∗/133 private int o f fx ,134 /∗∗ The current Y o f f s e t s ∗/135 o f f y ;136137 /∗∗ The number o f p i x e l s to move the mouse cursor by ∗/138 private int mouseMoveBy = 1 ;139140 /∗∗ The current view mode141 ∗ @category view mode142 ∗/143 private int viewMode = NORMAL;144 /∗∗ Normal , none−zoomed out view mode145 ∗ @category view mode146 ∗ @value 0

91

147 ∗/148 private stat ic f ina l int NORMAL = 0 ;149 /∗∗ Zoomed out view mode150 ∗ @category view mode151 ∗ @value 1152 ∗/153 private stat ic f ina l int ZOOM_OUT = 1 ;154155 /∗∗ The current number pad mode156 ∗ @category number pad mode157 ∗/158159 /∗∗ SMS Mode160 ∗ Arrow keys send l e f t / r i g h t /up/down161 ∗ Number keys send SMS162 ∗ Number keys come f i r s t163 ∗ @category Input mode164 ∗ @value 1165 ∗/166 private stat ic f ina l int SMS_MODE = 2 ;167168 /∗∗ Type Mode169 ∗ Arrow keys send l e f t / r i g h t /up/down170 ∗ None−arrow keys come f i r s t171 ∗ @category INPUT mode172 ∗ @value 2173 ∗/174 private stat ic f ina l int TYPE_MODE = 3 ;175176177 /∗∗ Move the screen178 ∗ None−arrow keys " type "179 ∗ @category Input Mode180 ∗ @value 0181 ∗/182 private stat ic f ina l int NAV_MODE = 0 ;183184 /∗∗ Move the mouse cursor185 ∗ @category Input Mode186 ∗ @value 1187 ∗/188 private stat ic f ina l int MOUSE_MODE = 1 ;189190 /∗∗191 ∗ @category Input Mode192 ∗/193 private int inputMode = NAV_MODE;194195 private Command modeCmd = new Command( "#mode#" , Command.SCREEN, 1 ) ;

92

196 private Command refreshCmd = new Command( "#r e f r e s h#" , Command.SCREEN, 2 ) ;197 private Command moveMouseCmd = new Command( "#call_mouse#" ,198 Command.SCREEN, 3 ) ;199 private Command textCmd = new Command( "#enter_text#" , Command.SCREEN, 4 ) ;200 private Command modeOKCmd = new Command( "#ok#" , Command.OK, 1 ) ;201 private Command exitCmd = new Command( "#ex i t#" , Command.EXIT, 10 ) ;202 private Command optionsCmd = new Command( "#opt ions#" , Command.SCREEN, 2 ) ;203204 private Command cancelCmd = new Command( "#cance l#" , Command.BACK, 1 ) ;205206 private Command altCmd = new Command( "#a l t#" , Command.SCREEN, 5 ) ;207 private Command metaCmd = new Command( "#meta#" , Command.SCREEN, 6 ) ;208 private Command ctrlCmd = new Command( "#con t r o l#" , Command.SCREEN, 5 ) ;209210 private Command caseCmd = new Command( "#case#" , Command.SCREEN, 1 ) ;211 private Command enterCmd = new Command( "#ente r#" , Command.SCREEN, 1 ) ;212213 // Comando para pegar as t a r e f a s cadas t radas214 private Command tasksCmd = new Command( "Tare fas " , Command.SCREEN, 7 ) ;215216 /∗∗ Are the ALT, Contro l or Meta keys pres sed ∗/217 private boolean a l t = false , meta = false , c t r l = fa l se ;218219 private St r ing [ ] viewModes = {"#normal#" , "#fu l l_ s c r e en#" } ;220221 private St r ing [ ] inputModes = { "#nav igat ion#" ,222 "#mouse_mode#" ,223 "#sms_mode#" ,224 "#type#" } ;225226 private ChoiceGroup viewCh = new ChoiceGroup ( "#view#" ,227 ChoiceGroup .EXCLUSIVE,228 viewModes , null ) ;229230 private ChoiceGroup inputModeChoice = new ChoiceGroup ( "#game_keys#" ,231 ChoiceGroup .EXCLUSIVE,232 inputModes , null ) ;233234 //componente para s e l e ç ão das t a s k s235 private ChoiceGroup tasksChoice ;236237 // t e l a para s e l e ção das t a s k s238 private Form task s = new Form( "Tare fas " ) ;239240 // u l t imas t a s k s capturadas241 private St r ing [ ] l a s tTasks ;242243 // t e l a para mostrar o r e su l t a do da execução de uma ta s k244 private Form messageForm = new Form( "Tarefa executada " ) ;

93

245246247 private TextBox sendStringBox = new TextBox ( "#send#" , "" , 255 ,248 TextFie ld .ANY ) ;249250 private Form opt ions = new Form( "#opt i on s t#" ) ;251 private Gauge s c r o l lX = new Gauge ( "#scrol l_amount#" , true , 4 , 0 ) ;252 // p r i v a t e Gauge s c r o l lY = new Gauge ( "#s c r o l l y #", true , 4 , 0 ) ;253254 private Gauge mouseMove = new Gauge ( "#mouse_move#" , true , 20 , 1 ) ;255256 private ChoiceGroup aR = new ChoiceGroup ( "" , ChoiceGroup .MULTIPLE ) ;257258 private Form modeForm = new Form( "#mode#" ) ;259260 /∗∗ The out−of−the−event−thread event thread ∗/261 private Thread worker = new Thread ( this ) ;262 /∗∗ I s the system cu r r en t l y running ∗/263 private boolean running = true ;264265 /∗∗ I s the l o c a l cursor mode enab led266 ∗ When enabled , on ly mouse p r e s s e s are sen t to the server ,267 ∗ a l l o t h e r s on ly change the mouseX and mouseY v a r i a b l e s268 ∗ @see mouseX269 ∗ @see mouseY270 ∗/271 private boolean l o ca lCur so r = fa l se ;272273 /∗∗ Number o f ou t s tand ing GUI ac t i on s to be processed , or s t i l l b e ing274 ∗ processed . Used by the pa in t method , to show the "working" icon .275 ∗/276 private int r eque s t s = 0 ;277278 /∗∗ The record s t o r e ho l d ing the Macros . ∗/279 private RecordStore r s ;280281 /∗∗ Empty cons t ruc t o r used by the About screen f o r d e t a i l s about the canvas282 ∗/283 VNCCanvas ( ) { }284285286 /∗∗ Creates a VNC Canvas f o r normal use .287 ∗/288 VNCCanvas( VNC m ) {289 midlet = m;290 addCommand( metaCmd ) ;291 addCommand( ctrlCmd ) ;292 addCommand( altCmd ) ;293 addCommand( modeCmd ) ;

94

294 addCommand( moveMouseCmd ) ;295 addCommand( refreshCmd ) ;296 addCommand( textCmd ) ;297 addCommand( exitCmd ) ;298 addCommand( optionsCmd ) ;299 addCommand( enterCmd ) ;300 addCommand( tasksCmd ) ;301302 //#i f d e f DEBUG303 addCommand( m. log ) ;304 //#end i f305306 greyOut (g , 0 , 0 , getWidth ( ) , getHeight ( ) ) ;307 greyOut ( gzoomout , 0 , 0 , getWidth ( ) , getHeight ( ) ) ;308309 aR . append ( "#a c t i v e r e f r e s h#" , null ) ;310 aR . append ( "#loca l_cur so r#" , null ) ;311312 opt ions . append ( s c r o l lX ) ;313 // op t i ons . append ( s c r o l lY ) ;314 opt ions . append ( mouseMove ) ;315 opt ions . append ( aR ) ;316 opt ions . addCommand( modeOKCmd ) ;317 opt ions . addCommand( modeOKCmd ) ;318319 sendStringBox . addCommand( modeOKCmd ) ;320 sendStringBox . addCommand( enterCmd ) ;321 sendStringBox . addCommand( cancelCmd ) ;322 sendStringBox . setCommandListener ( this ) ;323324325 //Adicionando comandos às t e l a s326 ta sk s . addCommand(modeOKCmd) ;327 ta sk s . addCommand( cancelCmd ) ;328 ta sk s . setCommandListener ( this ) ;329330 messageForm . addCommand( modeOKCmd ) ;331 messageForm . addCommand( exitCmd ) ;332 messageForm . setCommandListener ( this ) ;333334335336 setCommandListener ( this ) ;337338 modeForm . append ( viewCh ) ;339 modeForm . append ( inputModeChoice ) ;340 modeForm . addCommand( modeOKCmd ) ;341 sendStringBox . addCommand( cancelCmd ) ;342

95

343 modeForm . setCommandListener ( this ) ;344345 opt ions . setCommandListener ( this ) ;346347 for ( int i = 0 ; i <5; i++) {348 eventCashe . push ( new Event ( ) ) ;349 }350351 try {352 redraw = Image . createImage ( "/ redraw . png" ) ;353354 mouse = Image . createImage ( "/mouse . png" ) ;355 sms = Image . createImage ( "/key . png" ) ;356 nav = Image . createImage ( "/nav . png" ) ;357 } catch ( IOException t ) {358 System . e r r . p r i n t l n ( "Create Image : key : " + t ) ;359 }360361 t imer . s chedu le ( new tk . wetnet . j2me . vnc . Ticker ( this ) , 2000 , 1500 ) ;362363 //#i f d e f DEBUG364 //# VNC. l o g ( " hasRepeatEvents ( ) " + hasRepeatEvents ( ) ) ;365 //#end i f366367 try {368 r s = RecordStore . openRecordStore ( "cmds" , true ) ;369 i f ( r s . getNumRecords ( ) == 0 ) {370 byte [ ] s = "Ctr l Alt Del |<\\c<\\a !\\d>\\a>\\c" . getBytes ( ) ;371 r s . addRecord ( s , 0 , s . l ength ) ;372 }373374 RecordEnumeration re = r s . enumerateRecords ( null , null , fa l se ) ;375 while ( re . hasNextElement ( ) ) {376 int id = re . nextRecordId ( ) ;377 St r ing cur rent = new St r ing ( r s . getRecord ( id ) ) ;378 St r ing t i t l e = current ;379 i f ( cur r ent . indexOf ( " | " ) > 0 ) {380 t i t l e = current . sub s t r i ng (0 , cur r ent . indexOf ( " | " ) ) ;381 }382 HostCommand cm = new HostCommand( t i t l e , Command.ITEM,383 10 , id ) ;384 addCommand( cm ) ;385 }386 //TODO: Bet t e r Error Handling Code !387 } catch ( javax . m i c roed i t i on . rms . RecordStoreException t ) {388 System . e r r . p r i n t l n ( "VNC( ) : t " + t . t oS t r i ng ( ) ) ;389 t . pr intStackTrace ( ) ;390 }391 worker . s t a r t ( ) ;

96

392 }393394 /∗∗ The Mouse X l o c a t i o n ∗/395 private int mouseX = 0 ,396 /∗∗ The mouse Y l o c a t i o n ∗/397 mouseY = 0 ;398399 /∗∗ Processes the commands even t s out s i d e o f the event queue .400 ∗ @see commandAction401 ∗ @see even t s402 ∗ @see eventsCashe403 ∗ @see Event404 ∗ @see run ()405 ∗ @todo redo excep t i on hand l ing406 ∗ @todo move to mu l t i p l y sma l l e r methods?407 ∗/408 private void commandRunner ( Command c , Di sp layab l e d ) {409 //#i f d e f DEBUG410 //# VNC. l o g ( "commandAction" + c . g e tLabe l ( ) ) ;411 //#end i f412413 i f ( c == refreshCmd ) {414 try {415 i f ( viewMode == ZOOM_OUT ) {416 midlet . r f b . requestUpdate ( 0 , 0 ,417 midlet . r f b . x ,418 midlet . r f b . y ,419 fa l se ) ;420 } else {421 midlet . r f b . requestUpdate ( o f fx , o f fy ,422 getWidth ( ) ,423 getHeight ( ) ,424 fa l se ) ;425 }426 } catch ( Throwable t ){427 e r r o r ( "cmd Refresh " + t ) ;428 }429 r epa in t ( ) ;430 s e rv i c eRepa in t s ( ) ;431 } else i f ( c == optionsCmd ) {432 midlet .me . setCurrent ( opt ions ) ;433 } else i f ( c == metaCmd ) {434 meta = ! meta ;435 try {436 midlet . r f b . key ( 0 x f f e7 , meta ) ;437 } catch ( Throwable t ) {438 e r r o r ( t . t oS t r i ng ( ) ) ;439 }440 } else i f ( c == altCmd ) {

97

441 a l t = ! a l t ;442 try {443 midlet . r f b . key ( 0 x f f e9 , a l t ) ;444 } catch ( Throwable t ) {445 e r r o r ( t . t oS t r i ng ( ) ) ;446 }447 } else i f ( c == ctrlCmd ) {448 c t r l = ! c t r l ;449 try {450 midlet . r f b . key ( 0 x f f e3 , c t r l ) ;451 } catch ( Throwable t ) {452 e r r o r ( t . t oS t r i ng ( ) ) ;453 }454 } else i f ( c == exitCmd ) {455 c l o s e ( ) ;456 midlet . not i fyDes t royed ( ) ;457 } else i f ( c == textCmd ) {458 midlet .me . setCurrent ( sendStringBox ) ;459 } else i f ( c == modeCmd ) {460 midlet .me . setCurrent ( modeForm ) ;461 } else i f ( c == cancelCmd ) {462 // Reset s e t t i n g s .463 sendStringBox . setChars ( null , 0 , 0 ) ;464 inputModeChoice . s e tS e l e c t ed Index ( inputMode , true ) ;465 viewCh . s e tS e l e c t ed Index ( viewMode , true ) ;466467 i f (d == tasks ){468 la s tTasks = null ; //apaga t a s k s469 ta sk s . d e l e t e ( 0 ) ;470 }471472 midlet .me . setCurrent ( this ) ;473 } else i f ( c == caseCmd ) {474 uppercase = ! uppercase ;475 } else i f ( c == enterCmd ) {476 try {477 i f ( d == sendStringBox ) {478 midlet . r f b . s endStr ing ( sendStringBox . g e tS t r i ng ( ) + "\n" ) ;479 } else {480 midlet . r f b . s endStr ing ( "\n" ) ;481 }482 } catch ( Throwable t ) {483 e r r o r ( "Sending Enter : " + t . t oS t r i ng ( ) ) ;484 }485 midlet .me . setCurrent ( this ) ;486 } else i f ( c == modeOKCmd ) {487 i f ( d == modeForm ) {488 inputMode = inputModeChoice . g e tSe l e c t ed Index ( ) ;489

98

490 viewMode = viewCh . ge tSe l e c t ed Index ( ) ;491492493 i f ( inputMode == SMS_MODE ) {494 addCommand( caseCmd ) ;495 } else {496 removeCommand( caseCmd ) ;497 }498 } else i f ( d == sendStringBox ) {499 try {500 midlet . r f b . s endStr ing ( sendStringBox . g e tS t r i ng ( ) ) ;501 } catch ( Throwable t ){502 e r r o r ( "modeOK: sendStr ing : " + t ) ;503 }504 } else i f ( d == opt ions ) {505 s c r o l l b y = ( s c r o l lX . getValue ( ) + 1 ) ∗ ( getWidth ( ) / 5 ) ;506 sc ro l lbyY = ( s c r o l lX . getValue ( ) + 1 ) ∗ ( getHeight ( ) / 5 ) ;507 mouseMoveBy = mouseMove . getValue ( ) ;508 i f (mouseMoveBy==0) {509 mouseMoveBy=1;510 }511512 ac t i v eRe f r e sh = aR . i s S e l e c t e d ( 0 ) ;513 l o ca lCur so r = aR . i s S e l e c t e d ( 1 ) ;514 }515 else i f (d == tasks ){ // ta s k f o i s e l e c i onada ! ! !516 try {517 St r ing s = la s tTasks [ tasksChoice . g e tSe l e c t ed Index ( ) ] ;518 s = s . sub s t r i ng (0 , s . indexOf ( "−" ) ) ;519 la s tTasks = null ; //apaga t a s k s520 ta sk s . d e l e t e ( 0 ) ;521 System . out . p r i n t l n ( "ID s e l e c i onado : "+s ) ;522523 this . s tartUpdate ( ) ;524 midlet . r f b . executeTask ( In t eg e r . pa r s e In t ( s ) ) ;525 }526 catch ( Throwable t ){527 e r r o r ( "Nao f o i p o s s i v e l executar a t a r e f a : " + t ) ;528 }529 }530 else i f (d == messageForm ){531 messageForm . d e l e t e ( 0 ) ;532 }533534 midlet .me . setCurrent ( this ) ;535 } else i f ( c == tasksCmd ){ // execução do comando para capturar as t a s k s cadas t radas536 try {537 System . out . p r i n t l n ( "Capturando ta sk s . . . " ) ;538 this . s tartUpdate ( ) ;

99

539 midlet . r f b . requestTasks ( ) ;540 }541 catch ( Throwable t ){542 e r r o r ( "Nao f o i p o s s i v e l capturar as t a r e f a s cadast radas : " + t ) ;543 }544545 } else i f ( c == moveMouseCmd ) {546 try {547 mouseX = o f f x + ( getWidth ( ) / 2 ) ;548 mouseY = o f f y + ( getHeight ( ) / 2 ) ;549 midlet . r f b . mouse ( mouseX ,550 mouseY ,551 0 ) ;552 midlet . r f b . requestUpdate ( mouseX , mouseY , 32 , 32 , true ) ;553 } catch ( Throwable t ) {554 e r r o r ( "cmd Refresh " + t ) ;555 }556 //#i f d e f DEBUG557 } else i f ( c == midlet . l og ) {558 midlet . commandAction ( midlet . log , d ) ;559 //#end i f560 } else i f ( c instanceof HostCommand ) {561 HostCommand cmd = (HostCommand) c ;562 St r ing tmp ;563 try {564 tmp = new St r ing ( r s . getRecord ( cmd . id ) ) ;565 } catch ( Throwable t ) {566 tmp = " | " ;567 }568 try {569 stringToKeys ( tmp . sub s t r i ng570 ( tmp . indexOf ( " | " ) + 1 ,571 tmp . l ength ( ) ) ) ;572 } catch ( Throwable t ) {573 e r r o r ( "Custom Command: " + t ) ;574 }575 }576 reques t s −−;577 i f ( r eque s t s <= 0 ) {578 r eque s t s = 0 ;579 }580 r epa in t ( ) ;581 s e rv i c eRepa in t s ( ) ;582 }583584 /∗∗ Places and Event r ep r e s en t i n g the current command ac t i on in the585 ∗ event queue .586 ∗ @see even t s587 ∗ @see Event

100

588 ∗ @see CommandListener . commandAction (Command, D i sp l a yab l e )589 ∗/590 public void commandAction (Command co , Di sp layab l e d i ) {591 Event e = null ;592593 r eque s t s++;594 r epa in t ( ) ;595596 i f ( eventCashe . isEmpty ( ) ) {597 e = new Event ( ) ;598 } else {599 e = (Event ) eventCashe . pop ( ) ;600 }601602 boolean no t i f y = events . isEmpty ( ) ;603 e .mode = e .COMMAND_ACTION;604 e . d = di ;605 e . c = co ;606607 events . push ( e ) ;608 i f ( n o t i f y ) {609 try {610 worker . n o t i f yA l l ( ) ;611 } catch ( I l l e ga lMon i t o rS ta t eExcep t i on i ) {612 System . e r r . p r i n t l n ( i . t oS t r i ng ( ) ) ;613 }614 }615 }616617 /∗∗ Upper or lower case618 ∗ @category SMS Key System619 ∗/620 private boolean uppercase = true ;621622 /∗∗ The number/#∗ key pres sed l a s t .623 ∗ @category SMS Key System624 ∗/625 private byte l a s tP r e s s ed = −1;626627 /∗∗ The number o f t imes the current number key has been pres sed % by the628 ∗ number o f va l u e s t h i s key can be .629 ∗ @category SMS Key System630 ∗/631 private byte keyCounter = −1;632633 /∗∗ The key/number o f t imes keyboard l ayou t .634 ∗ e . g . i f key '1 ' has been pres sed tw ice you ge t 'B ' .635 ∗ @category SMS Key System636 ∗/

101

637 private char [ ] [ ] keys = { { ' 0 ' , ' ' } ,638 { ' . ' , ' , ' , ' ! ' , ' 1 ' } ,639 { 'A ' , 'B ' , 'C ' , ' 2 ' } ,640 { 'D ' , 'E ' , 'F ' , ' 3 ' } ,641 { 'G' , 'H ' , ' I ' , ' 4 ' } ,642 { ' J ' , 'K ' , 'L ' , ' 5 ' } ,643 { 'M' , 'N ' , 'O ' , ' 6 ' } ,644 { 'P ' , 'Q ' , 'R ' , ' S ' , ' 7 ' } ,645 { 'T ' , 'U ' , 'V ' , ' 8 ' } ,646 { 'W' , 'X ' , 'Y ' , 'Z ' , ' 9 ' } ,647 { '#' } ,648 { ' ∗ ' } } ;649650651 /∗∗ Cleans up & l e a v e s the s e r v e r in a reasonab l e s t a t e .652 ∗ Close the open record s t o r e s .653 ∗ Unpress any meta keys (Meta/Al t /Cntr l )654 ∗ Ends the event−proce s s ing thread .655 ∗ Ends the RFB Protos thread .656 ∗ Closes the RFB IO streams657 ∗/658 protected void c l o s e ( ) {659 try {660 r s . c l o s eRecordStore ( ) ;661 } catch ( Throwable t ) {}662663 try {664 running = fa l se ;665 worker . n o t i f y ( ) ;666667 i f ( meta ) {668 try {669 midlet . r f b . key ( 0 x f f e7 , fa l se ) ;670 } catch ( Throwable t ) {671 e r r o r ( t . t oS t r i ng ( ) ) ;672 }673 }674 i f ( a l t ) {675 try {676 midlet . r f b . key ( 0 x f f e9 , fa l se ) ;677 } catch ( Throwable t ) {678 e r r o r ( t . t oS t r i ng ( ) ) ;679 }680 }681 i f ( c t r l ) {682 try {683 midlet . r f b . key ( 0 x f f e3 , fa l se ) ;684 } catch ( Throwable t ) {685 e r r o r ( t . t oS t r i ng ( ) ) ;

102

686 }687 }688689690 midlet . r f b . running = fa l se ;691 midlet . r f b . s i n . c l o s e ( ) ;692 midlet . r f b . sout . c l o s e ( ) ;693 } catch ( Throwable t ) { }694 }695696697 /∗∗ Sends the curren t l e t t e r ( in SMS mode) to the server , and r e f r e s h e s698 ∗ the screen .699 ∗ @todo Rename method !700 ∗ @category SMS Key System701 ∗/702 private void nextLet te r ( ) {703 try {704 i f ( uppercase ) {705 midlet . r f b . key ( keys [ l a s tP r e s s ed ] [ keyCounter ] , true ) ;706 midlet . r f b . key ( keys [ l a s tP r e s s ed ] [ keyCounter ] , fa l se ) ;707 } else {708 midlet . r f b . key ( Character . toLowerCase709 ( keys [ l a s tP r e s s ed ] [ keyCounter ] ) , true ) ;710 midlet . r f b . key ( Character . toLowerCase711 ( keys [ l a s tP r e s s ed ] [ keyCounter ] ) , fa l se ) ;712 }713 } catch ( Throwable t t ){714 e r r o r ( " keyPressed : t t : " + t t ) ;715 }716 keyCounter = −1;717 l a s tP r e s s ed = −1;718 try {719 midlet . r f b . requestUpdate ( o f fx , o f fy ,720 getWidth ( ) ,721 getHeight ( ) ,722 true ) ;723 } catch ( Throwable thr ) {724 e r r o r ( " keyPressed : thr : " + thr ) ;725 }726 }727728 /∗∗ The input even t s ( key p r e s s e s and command−even t s ) add Event i tems729 ∗ i n t o the even t s queue , to reduce the amount o f time spent in the730 ∗ event thread .731 ∗ @see eventCashe732 ∗ @see run ()733 ∗ @see keyPressed ()734 ∗ @see Event

103

735 ∗/736 private Queue events = new Queue ( ) ;737738 /∗∗ To prevent memory a l l o c a t i o n s , a cashe o f Event o b j e c t s i s kep t .739 ∗ @see even t s740 ∗ @see run ()741 ∗ @see keyPressed ()742 ∗ @see Event743 ∗/744 private Queue eventCashe = new Queue ( ) ;745746 /∗∗ Processes even t s . This i s done ou t s i d e o f the system event thread747 ∗ as the IO oppera t ions might take a very long time to complete ,748 ∗ or even b l o c k a l l t oge ther , and we do not want UI to f r e e z e up749 ∗ on the user .750 ∗ whi l e I have even t s to process , and I 'm running751 ∗ pop the event , and proces s i t .752 ∗ Push the event back onto the cashe .753 ∗ S leep f o r 1s , or u n t i l new even t s are d i spa t ched .754 ∗/755 public void run ( ) {756 while ( running ) {757 while ( ! events . isEmpty ( ) && running ) {758 Event e = (Event ) events . pop ( ) ;759 switch ( e .mode ) {760 case Event .KEY_PRESSED:761 kp ( e . keyCode ) ;762 break ;763 case Event .COMMAND_ACTION:764 commandRunner ( e . c , e . d ) ;765 e . c = null ;766 e . d = null ;767 break ;768 }769770 eventCashe . push ( e ) ;771 }772773 try {774 synchronized ( worker ) {775 worker . wait ( 1000 ) ;776 }777 } catch ( Inter ruptedExcept ion i e ) {778779 } catch ( I l l e ga lMon i t o rS ta t eExcep t i on emse ) {780781 }782 }783 }

104

784785 /∗∗ The input even t s ( key p r e s s e s and command−even t s ) add Event i tems786 ∗ i n t o the even t s queue , to reduce the amount o f time spent in the787 ∗ event thread .788 ∗/789 private class Event extends tk . wetnet . u t i l . Queue . QueueEntry {790 private stat ic f ina l int KEY_PRESSED = 0 ;791 private stat ic f ina l int COMMAND_ACTION = 1 ;792 private int mode = KEY_PRESSED;793794 private int keyCode = 0 ;795 private Command c = null ;796 private Disp layab l e d = null ;797 }798799800 /∗∗ Simply adds the event in t o the event queue , and n o t i f i e s the event801 ∗ thread .802 ∗ @random_idea Add s c r o l l mode , where i t grays out screen , then adds803 ∗ A smal l box to r ep re s en t the current l o ca t i on , and804 ∗ you move t ha t then i t r e f r e s h the screen to t ha t l o c a t i o n .805 ∗ @random_idea Fish eye mode?806 ∗ WAS: keyPressed807 ∗/808 public void keyReleased ( int keyCode ) {809 Event e = null ;810811 r eque s t s++;812 r epa in t ( ) ;813814 i f ( eventCashe . isEmpty ( ) ) {815 e = new Event ( ) ;816 } else {817 e = (Event ) eventCashe . pop ( ) ;818 }819820 boolean no t i f y = events . isEmpty ( ) ;821 e .mode = e .KEY_PRESSED;822 e . keyCode = keyCode ;823 events . push ( e ) ;824 i f ( n o t i f y ) {825 try {826 worker . n o t i f yA l l ( ) ;827 } catch ( I l l e ga lMon i t o rS ta t eExcep t i on i ) {828 System . e r r . p r i n t l n ( i . t oS t r i ng ( ) ) ;829 }830 }831 }832

105

833 /∗∗ i f the mode i s the Mouse Mode , repea ted keys move the l o c a l mouse834 ∗ pointer , but does not send t h i s to the s e r v e r .835 ∗/836 public void keyRepeated ( int keyCode ) {837 i f ( inputMode == MOUSE_MODE ) {838 switch ( getGameKeyPriorityGames ( keyCode ) ) {839 case DOWN:840 mouseY+=mouseMoveBy ;841 break ;842 case UP:843 mouseY−=mouseMoveBy ;844 break ;845 case LEFT:846 mouseX−=mouseMoveBy ;847 break ;848 case RIGHT:849 mouseX+=mouseMoveBy ;850 break ;851 }852 i f (mouseX < 0) {853 mouseX=0;854 } else i f (mouseX > midlet . r f b . x ) {855 mouseX=midlet . r f b . x ;856 }857 i f (mouseY < 0) {858 mouseY=0;859 } else i f (mouseY > midlet . r f b . y ) {860 mouseY=midlet . r f b . y ;861 }862 }863 r epa in t ( ) ;864 s e rv i c eRepa in t s ( ) ;865 }866867 private void sendKey ( int keyCode ) {868 // Add a ha sh t a b l e to l e t uses change keycodes .869870 try {871 midlet . r f b . key ( keyCode , true ) ;872 midlet . r f b . key ( keyCode , fa l se ) ;873 midlet . r f b . requestUpdate ( o f fx , o f fy , getWidth ( ) ,874 getHeight ( ) , true ) ;875 } catch ( Throwable t1 ){876 e r r o r ( " keyPressed : t1 : " + t1 ) ;877 }878 }879880 private boolean sendSMS( int keyCode ) {881 byte t = −1;

106

882 i f ( keyCode >= 48 && keyCode <= 57 ) {883 t = (byte ) ( keyCode − 48 ) ;884 } else i f ( keyCode == KEY_STAR ) {885 t = 11 ;886 } else i f ( keyCode == KEY_POUND ) {887 t = 10 ;888 }889 i f ( t == −1 ) return fa l se ;890 i f ( t != l a s tP r e s s ed && la s tP r e s s ed != −1 ) {891 try {892 i f ( uppercase ) {893 midlet . r f b . key ( keys [ l a s tP r e s s ed ] [ keyCounter ] ,894 true ) ;895 midlet . r f b . key ( keys [ l a s tP r e s s ed ] [ keyCounter ] ,896 fa l se ) ;897 } else {898 midlet . r f b . key ( Character . toLowerCase899 ( keys [ l a s tP r e s s ed ] [ keyCounter ] ) ,900 true ) ;901 midlet . r f b . key ( Character . toLowerCase902 ( keys [ l a s tP r e s s ed ] [ keyCounter ] ) ,903 fa l se ) ;904 }905 } catch ( Throwable t t ){906 e r r o r ( " keyPressed : t t : " + t t ) ;907 }908 keyCounter = −1;909 } else {910 i f ( t imeout != null ) {911 timeout . cance l ( ) ;912 }913 timeout = new Timeout ( ) ;914 t imer . s chedu le ( timeout , 2000 ) ;915 }916 l a s tP r e s s ed = t ;917 keyCounter++;918 i f ( keyCounter == keys [ l a s tP r e s s ed ] . l ength ) {919 keyCounter = 0 ;920 }921 return true ;922 }923924 private boolean sendMouse ( int keyCode ) {925 int buts = 0 ;926 boolean doneSomething = fa l se ;927928 switch ( getGameKeyPriorityGames ( keyCode ) ) {929 case DOWN:930 doneSomething = true ;

107

931 mouseY+=mouseMoveBy ;932 break ;933 case UP:934 doneSomething = true ;935 mouseY−=mouseMoveBy ;936 break ;937 case LEFT:938 doneSomething = true ;939 mouseX−=mouseMoveBy ;940 break ;941 case RIGHT:942 doneSomething = true ;943 mouseX+=mouseMoveBy ;944 break ;945 case FIRE :946 doneSomething = true ;947 buts = 1 ;948 break ;949 case GAME_A:950 doneSomething = true ;951 buts = 2 ;952 break ;953 }954955 i f ( ! doneSomething ) return doneSomething ;956957 i f (mouseX < 0) {958 mouseX=0;959 } else i f (mouseX > midlet . r f b . x ) {960 mouseX=midlet . r f b . x ;961 }962 i f (mouseY < 0) {963 mouseY=0;964 } else i f (mouseY > midlet . r f b . y ) {965 mouseY=midlet . r f b . y ;966 }967 i f ( ! l o ca lCur so r | | buts > 0 ) {968 //#i f d e f DEBUG969 //# VNC. l o g ( "mousex : " + mouseX + "mouseY"+ mouseX ) ;970 //#end i f971 try {972 midlet . r f b . mouse ( mouseX ,973 mouseY ,974 ( buts > 0 ? 1 : 0) ) ;975 i f ( buts != 0 ) {976 midlet . r f b . mouse ( mouseX ,977 mouseY ,978 0 ) ;979 i f ( buts == 2 ) {

108

980 midlet . r f b . mouse ( mouseX ,981 mouseY ,982 1 ) ;983 midlet . r f b . mouse ( mouseX ,984 mouseY ,985 0 ) ;986 }987988 }989990 midlet . r f b . requestUpdate ( o f fx , o f fy , getWidth ( ) ,991 getHeight ( ) , true ) ;992993 } catch ( Throwable t7 ) {994 e r r o r ( "MouseMove : " + t7 ) ;995 }996 }997 return doneSomething ;998 }9991000 private boolean sendNav ( int keyCode ){1001 int sb = 0 ;10021003 tmpImg . getGraphics ( ) . drawImage ( bu f f e r , 0 , 0 , g .TOP| g .LEFT ) ;1004 //Image i = Image . createImage ( b u f f e r ) ;1005 switch ( getGameKeyPriorityGames ( keyCode ) ) {1006 case LEFT:1007 i f ( viewMode == NORMAL )1008 sb = s c r o l l b y ;1009 else i f ( viewMode == ZOOM_OUT )1010 sb = getWidth ( ) ;1011 i f ( o f f x − sb < 0 ) {1012 sb = o f f x ;1013 }1014 o f fx−=sb ;10151016 g . drawImage ( tmpImg , sb , 0 , g .TOP| g .LEFT ) ;10171018 greyOut ( g , 0 , 0 , sb , getHeight ( ) ) ;1019 try {1020 midlet . r f b . requestUpdate ( o f fx , o f fy ,1021 sb ,1022 getHeight ( ) , fa l se ) ;1023 } catch ( Throwable t4 ){1024 e r r o r ( " keyPressed : t4 : " + t4 ) ;1025 }1026 return true ;1027 // break ;1028

109

1029 case RIGHT:1030 i f ( viewMode == NORMAL )1031 sb = s c r o l l b y ;1032 else i f ( viewMode == ZOOM_OUT )1033 sb=getWidth ( ) ;10341035 i f ( o f f x + sb > ( midlet . r f b . x − getWidth ( ) ) ) {1036 sb = ( midlet . r f b . x − getWidth ( ) ) − o f f x ;1037 System . out . p r i n t l n ( sb ) ;1038 }10391040 o f f x+=sb ;1041 g . drawImage ( tmpImg , −sb , 0 , g .TOP| g .LEFT ) ;10421043 greyOut ( g , getWidth ( ) − sb , 0 ,1044 s c r o l l b y , getHeight ( ) ) ;1045 try {1046 midlet . r f b . requestUpdate ( o f f x + getWidth ( )1047 − sb , o f fy ,1048 sb ,1049 getHeight ( ) , fa l se ) ;1050 } catch ( Throwable t5 ){1051 e r r o r ( " keyPressed : t5 : " + t5 ) ;1052 }1053 return true ;1054 // break ;1055 case UP:1056 i f ( viewMode == NORMAL )1057 sb = scro l lbyY ;1058 else i f ( viewMode == ZOOM_OUT )1059 sb=getHeight ( ) ;10601061 i f ( o f f y − sb < 0) {1062 sb = o f f y ;1063 }10641065 o f fy−=sb ;1066 g . drawImage ( tmpImg , 0 , sb , g .TOP| g .LEFT ) ;10671068 greyOut ( g , 0 , 0 , getWidth ( ) , sb ) ;1069 try {1070 midlet . r f b . requestUpdate ( o f fx , o f fy ,1071 getWidth ( ) ,1072 sb , fa l se ) ;1073 } catch ( Throwable t6 ){1074 e r r o r ( " keyPressed : t6 : " + t6 ) ;1075 }1076 return true ;1077 // break ;

110

10781079 case DOWN:1080 i f ( viewMode == NORMAL )1081 sb = scro l lbyY ;1082 else i f ( viewMode == ZOOM_OUT )1083 sb=getHeight ( ) ;10841085 i f ( o f f y + sb > ( midlet . r f b . y − getHeight ( ) ) ) {1086 System . out . p r i n t l n ( sb ) ;1087 sb = ( midlet . r f b . y − getHeight ( ) ) − o f f y ;1088 System . out . p r i n t l n ( sb + " " + o f f y + " "1089 + ( midlet . r f b . y − getHeight ( ) )1090 + " " + ( o f f y+sb ) ) ;1091 }10921093 o f f y+=sb ;1094 g . drawImage ( tmpImg , 0 , −sb , g .TOP| g .LEFT ) ;10951096 greyOut ( g , 0 , getHeight ( ) − sb ,1097 getWidth ( ) , sb ) ;1098 try {1099 midlet . r f b . requestUpdate ( o f fx , o f f y + getHeight ( )1100 − sb ,1101 getWidth ( ) ,1102 sb , fa l se ) ;1103 } catch ( Throwable t1 ){1104 e r r o r ( " keyPressed : t1 : " + t1 ) ;1105 }1106 return true ;1107 // break ;1108 }1109 return fa l se ;1110 }11111112 private f ina l int _KEY_UP = 0 ,1113 _KEY_DOWN = 1 ,1114 _KEY_LEFT = 2 ,1115 _KEY_RIGHT = 3 ,1116 _KEY_FIRE = 4 ,1117 _KEY_SNDFIRE = 5 ,1118 _KEY_CHANGE_MODE = 6 ;11191120 // TODO: READ FROM FILE !1121 int [ ] act ionKeys = new int [ ] { KEY_NUM2,1122 KEY_NUM8,1123 KEY_NUM4,1124 KEY_NUM6,1125 KEY_NUM5,1126 KEY_POUND,

111

1127 KEY_STAR } ;11281129 /∗∗ p r i o r i t y ∗/1130 private int getGameKeyPriorityGames ( int keyCode ) {1131 i f ( getGameAction ( keyCode ) != 0 )1132 return getGameAction ( keyCode ) ;1133 i f ( keyCode == actionKeys [ _KEY_DOWN ] )1134 return DOWN;1135 else i f ( keyCode == actionKeys [ _KEY_LEFT ] )1136 return LEFT;1137 else i f ( keyCode == actionKeys [ _KEY_RIGHT ] )1138 return RIGHT;1139 else i f ( keyCode == actionKeys [ _KEY_UP ] )1140 return UP;1141 else i f ( keyCode == actionKeys [ _KEY_FIRE ] )1142 return FIRE ;1143 else i f ( keyCode == actionKeys [ _KEY_SNDFIRE ] )1144 return GAME_A;1145 return 0 ;1146 }11471148 /∗∗ The KeyPressed implementat ion1149 ∗/1150 private void kp ( int keyCode ) {1151 boolean doneSomething = fa l se ;1152 i f ( keyCode == actionKeys [ _KEY_CHANGE_MODE ] ) {1153 inputMode++;1154 i f ( inputMode > TYPE_MODE ) inputMode = NAV_MODE;1155 doneSomething = true ;1156 inputModeChoice . s e tS e l e c t ed Index ( inputMode , true ) ;1157 } else i f ( inputMode == TYPE_MODE ) {1158 i f ( keyCode > 0 ) {1159 sendKey ( keyCode ) ;1160 doneSomething = true ;1161 } // e l s e sw i t ch gamekey move1162 } else i f ( inputMode == MOUSE_MODE ) {1163 doneSomething = sendMouse ( keyCode ) ;1164 } else i f ( inputMode == SMS_MODE ) {1165 doneSomething = sendSMS( keyCode ) ;1166 } else i f ( inputMode == NAV_MODE ) {1167 doneSomething = sendNav ( keyCode ) ;1168 }11691170 i f ( ! doneSomething ) {1171 i f ( keyCode > 0 )1172 sendKey ( keyCode ) ;1173 }11741175 reques t s −−;

112

1176 i f ( r eque s t s <= 0 ) {1177 r eque s t s = 0 ;1178 }11791180 r epa in t ( ) ;1181 s e rv i c eRepa in t s ( ) ;1182 }118311841185 /∗∗ grays out an image .1186 ∗ @param gr The graph i c s o b j e c t to grey out1187 ∗ @param x the x o f f s e t1188 ∗ @param y the y o f f s e t1189 ∗ @param w the width1190 ∗ @param h the h e i g h t1191 ∗/1192 private void greyOut ( Graphics gr , int x , int y , int w, int h ) {1193 g . s e tCo lo r ( 0 x f f f f f f ) ;1194 g . f i l l R e c t ( x , y , w, h ) ;1195 for ( int i = w−1; i >0; i−=2 ) {1196 for ( int f = h−1; f >0; f−=2 ) {1197 gr . s e tCo lo r ( 100 , 100 , 100 ) ;1198 gr . f i l l R e c t ( x+i , y+f , 1 , 1 ) ;1199 }1200 }1201 }12021203 /∗∗ I s the s e r v e r cu r r en t l y sending an update ∗/1204 private boolean update = fa l se ;12051206 /∗∗ The se r v e r has s t a r t e d an update1207 ∗ @see DrawOnMe. s tar tUpdate ( )1208 ∗/1209 public void startUpdate ( ){1210 update=true ;1211 r epa in t ( ) ;1212 s e rv i c eRepa in t s ( ) ;1213 }12141215 /∗∗ The se r v e r has f i n i s h e d sending an update .1216 ∗ @see DrawOnMe. endUpdate ( )1217 ∗/1218 public void endUpdate ( ){1219 update=fa l se ;1220 r epa in t ( ) ;1221 s e rv i c eRepa in t s ( ) ;1222 }12231224 /∗∗ S t a r t s an alarm on the s e r v e r s r e que s t

113

1225 ∗ @see DrawOnMe. r i n gBe l l ( )1226 ∗/1227 public void r i n gBe l l ( ) {1228 AlertType .ALARM. playSound ( midlet .me ) ;1229 }12301231 /∗∗ Nul l implementat ion1232 ∗ @todo remove a l l t o g e t h e r to save space ?1233 ∗ @see DrawOnMe. copyRect ( )1234 ∗/1235 public void copyRect ( int x , int y , int w, int h , int srcx , int s r cy ){1236 //#i f d e f DEBUG1237 //# VNC. l o g ( "copyRect " ) ;1238 //#end i f1239 /∗ i f ( ( x > o f f x ) && ( x < o f f x+getWidth ( ) )1240 && (y > o f f y ) && (y < o f f y+ge tHe i gh t ( ) )){1241 Image i = Image . createImage ( w, h ) ;1242 i . ge tGraphics ( ) . drawImage ( bu f f e r , x−o f f x , y−o f f y ,1243 g .TOP| g .LEFT ) ;1244 gr . drawImage ( i , srcx , srcy , g .TOP| g .LEFT ) ;1245 }∗/1246 }12471248 /∗∗ Cashes the l o c a l screen width / remote screen width1249 ∗ This i s used by the s c a l i n g system1250 ∗ @note t h i s uses the l owe s t o f t h i s and d ivy1251 ∗ @todo remove one o f the two/have a nasty s c a l e op t ion ?1252 ∗/1253 private int divx = 0 ;1254 /∗∗ Cashes the l o c a l screen h e i g h t / remote screen h e i g h t1255 ∗ This i s used by the s c a l i n g system1256 ∗ @note t h i s uses the l owe s t o f t h i s and d i vx1257 ∗ @todo remove one o f the two/have a nasty s c a l e op t ion ?1258 ∗/1259 private int divy = 0 ;12601261 /∗∗ Draws a square on the back b u f f e r1262 ∗ Also draws a s ca l e d square on the zoomed out image i f i t i s a square1263 ∗ l a r g e r than or equa l to the number o f p i x e l s covered by one s ca l e d p i x e l1264 ∗ or i f x and y are exca l y on the top r i g h t p i x e l o f a zoomed out s e c t i on1265 ∗ @todo move the c r ea t i n g o f RGB to RFBProto , so on ly sends one1266 ∗ i n t ?1267 ∗ @todo b e t t e r s ca l e d image .1268 ∗ @todo p lay wi th wi th e l s e statement , && or | |1269 ∗ @see DrawOnMe. draw ()1270 ∗/1271 public void draw ( int red , int green , int blue , int x , int y ,1272 int w, int h) {1273

114

12741275 gzoomout . s e tCo lo r ( red , green , b lue ) ;12761277 i f ( w >= divx | | h >= divy ) {1278 gzoomout . f i l l R e c t ( ( x==0 ? 0 : x/divx ) ,1279 ( y==0 ? 0 : y/divy ) ,1280 ( w==0 ? 1 : (w/divx ) + 1 ) ,1281 ( h==0 ? 1 : (h/divy ) + 1 ) ) ;1282 } else i f ( ( x % divx == 0 ) && ( y % divy == 0 ) ) {1283 gzoomout . f i l l R e c t ( ( x==0 ? 0 : x/divx ) ,1284 ( y==0 ? 0 : y/divy ) ,1285 1 , 1 ) ;1286 }12871288 g . s e tCo lo r ( red , green , b lue ) ;1289 g . f i l l R e c t ( x−o f fx , y−o f f y , w, h ) ;1290 }12911292 /∗∗1293 ∗ @see Canvas . po in t e rPres sed ( int , i n t )1294 ∗/1295 protected void po in t e rPre s s ed ( int x , int y ) {1296 mouseX = o f f x + x ;1297 mouseY = o f f y + y ;1298 try {1299 midlet . r f b . mouse ( mouseX ,1300 mouseY ,1301 1 ) ;1302 midlet . r f b . mouse ( mouseX ,1303 mouseY ,1304 0 ) ;1305 midlet . r f b . requestUpdate ( mouseX , mouseY , 32 , 32 ,1306 true ) ;1307 } catch ( Throwable t ) {1308 e r r o r ( "MouseMove : " + t ) ;1309 }1310 }13111312 /∗∗ Paints e i t h e r the zoomed out image , or normal image ( depending on1313 ∗ mode ) , the "working" icon i f the system i s cu r r en t l y working1314 ∗ p lu s any mode icons .1315 ∗ @see r e qu e s t s1316 ∗ @see update1317 ∗ @param gr The Object to pa in t on1318 ∗/1319 public void pa int ( Graphics gr ) {1320 try{1321 switch ( viewMode ) {1322 case ZOOM_OUT:

115

1323 gr . drawImage (zoomOut , 0 , 0 , g .TOP| g .LEFT ) ;1324 gr . s e tCo lo r ( 0 , 255 , 0 ) ;13251326 gr . drawRect ( ( o f f x ==0?0:( o f f x / divx ) ) ,1327 ( o f f y ==0?0:( o f f y / divy ) ) ,1328 getWidth ( ) / divx ,1329 getHeight ( ) / divy ) ;1330 break ;1331 default :1332 gr . drawImage ( bu f f e r , 0 , 0 , g .TOP| g .LEFT ) ;1333 i f ( inputMode == MOUSE_MODE ){1334 gr . s e tCo lo r ( 255 , 0 , 0 ) ;1335 gr . drawRect ( mouseX − o f fx −1, mouseY − o f fy −1, 2 , 2 ) ;1336 }1337 break ;1338 }1339 i f ( update | | r e que s t s > 0 ) {1340 gr . drawImage ( redraw , getWidth ( ) , getHeight ( ) ,1341 gr .BOTTOM | gr .RIGHT ) ;1342 }1343 i f ( inputMode == MOUSE_MODE ) {1344 gr . drawImage ( mouse , getWidth ()−16 , getHeight ( ) ,1345 gr .BOTTOM | gr .RIGHT ) ;1346 } else i f ( inputMode == SMS_MODE ) {1347 gr . drawImage ( sms , getWidth ()−16 , getHeight ( ) ,1348 gr .BOTTOM | gr .RIGHT ) ;1349 } else i f ( inputMode == NAV_MODE ) {1350 gr . drawImage ( nav , getWidth ()−16 , getHeight ( ) ,1351 gr .BOTTOM | gr .RIGHT ) ;1352 }1353 i f ( inputMode == SMS_MODE && la s tP r e s s ed != −1 ) {1354 gr . s e tCo lo r ( 0 ) ;1355 gr . f i l l R e c t ( 0 , getHeight ()− gr . getFont ( ) . getHeight ( ) ,1356 gr . getFont ( ) . charWidth ( keys [ l a s tP r e s s ed ] [ keyCounter ] ) ,1357 gr . getFont ( ) . getHeight ( ) ) ;1358 gr . s e tCo lo r ( 0xFFFFFF ) ;1359 i f ( uppercase ) {1360 gr . drawChar ( keys [ l a s tP r e s s ed ] [ keyCounter ] , 0 ,1361 getHeight ()− gr . getFont ( ) . getHeight ( ) ,1362 gr .TOP| gr .LEFT ) ;13631364 } else {1365 gr . drawChar ( Character . toLowerCase1366 ( keys [ l a s tP r e s s ed ] [ keyCounter ] ) , 0 ,1367 getHeight ()− gr . getFont ( ) . getHeight ( ) ,1368 gr .TOP| gr .LEFT ) ;1369 }1370 }1371 }

116

1372 catch ( Throwable t ){13731374 }1375 }13761377 /∗∗ An error has ocoured , so d i s p l a y an error message , and only on1378 ∗ but ton "Exi t " , which when pres sed w i l l c a l l " c l o s e " , and c l ean up .1379 ∗/1380 public void e r r o r ( S t r ing e r r o r ) {1381 System . out . p r i n t ( e r r o r ) ;1382 Form form = new Form( "#e r r o r#" ) ;1383 /∗ t r y {1384 form . append ( mid l e t . aboutImage ) ;1385 } catch ( Throwable t ) {}∗/13861387 form . append ( e r r o r ) ;1388 form . addCommand( exitCmd ) ;1389 //#i f d e f DEBUG1390 form . addCommand( midlet . l og ) ;1391 //#end i f1392 form . setCommandListener ( this ) ;1393 midlet .me . setCurrent ( form ) ;1394 }13951396 /∗∗ The VNC serv e r i s ready f o r us , so change from the connect ion screen1397 ∗ to the canvas , pre−c a l c u l a t e va l u e s needed , then r e que s t an update .1398 ∗/1399 public void ready ( ) {1400 midlet .me . setCurrent ( this ) ;1401 divx = ( midlet . r f b . x / getWidth ( ) ) + 1 ;1402 divy = ( midlet . r f b . y / getHeight ( ) ) + 1 ;1403 i f ( divx < divy ) divx = divy ;1404 i f ( divy < divx ) divy = divx ;1405 try {1406 midlet . r f b . requestUpdate ( 0 , 0 ,1407 getWidth ( ) ,1408 getHeight ( ) , fa l se ) ;1409 } catch ( Throwable t ){1410 e r r o r ( " ready : " + t ) ;1411 }1412 }14131414 /∗∗ The RFB serv e r has go t a s t a g e c l o s e r to be ing connected1415 ∗ @see VNC. incConnect ionStatus ( )1416 ∗/1417 public void incConnect ionStatus ( ) {1418 midlet . incConnect ionStatus ( ) ;1419 }1420

117

14211422 /∗∗ I n t r e p t s a s t r i n g as a Macro , and runs i t .1423 ∗ ?move t h i s too the About box ( wi th the " hidden" op t i ons )1424 ∗ ?and on t h i s s i d e have a machine f r i e nd l y , human unreadab le format?1425 ∗ ? harder to then parse back f o r e d i t i n g .1426 ∗1427 ∗1428 ∗ cmd ( ac t i on )1429 ∗ i . e .1430 ∗ ! h ! e ! l ! l ! e − sends h e l l o .1431 ∗ <\c<\a !\ d>\a>\c − c t r l a l t d e l e t e .1432 ∗1433 ∗1434 ∗ l e t t e r combos :1435 ∗ x l i t e r a l .1436 ∗ \d De le te1437 ∗ \a Al t1438 ∗ \m Meta1439 ∗ \c Contro l1440 ∗ \n newl ine1441 ∗ \\ \1442 ∗ \p |1443 ∗1444 ∗1445 ∗ cmds :1446 ∗ < − key down1447 ∗ > − key up1448 ∗ ! − key down then up ( i e pre s s )1449 ∗ mXXXX,XXXX − Mouse Move To , must be four d i g i t s1450 ∗ c − Cl i c k ( primary mouse but ton )1451 ∗ MXXXX,XXXX − Move Screen To , f o l l ow s the same standard as 'm'14521453 ∗ @param s The S t r ing1454 ∗ @todo Rename?1455 ∗ @todo Rewrite !1456 ∗ @todo Add miss ing con t r o l l e t t e r s1457 ∗ @throws Throwable1458 ∗/145914601461 private void str ingToKeys ( S t r ing s ) throws Throwable {1462 boolean incUpdate = true ; // When the macro i s over , can I ge t away1463 // wi th j u s t doing a incrementa l update .1464 try {1465 int l en = s . l ength ( ) ;14661467 for ( int i = 0 ; i<l en ; i++ ) {1468 i f ( s . charAt ( i ) == ' ! ' | | s . charAt ( i ) == '> '1469 | | s . charAt ( i ) == '< ' ) {

118

1470 char cmd = s . charAt ( i ) ;1471 i++;1472 int send = ( int ) s . charAt ( i ) ;1473 i f ( s . charAt ( i ) == ' \\ ' ) {1474 i++;1475 switch ( s . charAt ( i ) ) {1476 case ' \\ ' : send = ' \\ ' ; break ; // s l a s h1477 case ' n ' : send = ' \n ' ; break ; // newl ine1478 case ' p ' : send = ' | ' ; break ; // pine1479 case ' d ' : send = 0xFFFF; break ; // d e l e t e1480 case ' a ' : send = 0xFFE9 ; break ; // a l t1481 case 'm' : send = 0xFFE7 ; break ; // meta1482 case ' c ' : send = 0xFFE3 ; break ; // con t r o l1483 case ' 1 ' : send = 0xFFbe ; break ; // F11484 case ' 2 ' : send = 0xFFbf ; break ; // F21485 case ' 3 ' : send = 0xFFb0 ; break ; // F31486 case ' 4 ' : send = 0xFFc1 ; break ; // F41487 case ' 5 ' : send = 0xFFc2 ; break ; // F51488 case ' 6 ' : send = 0xFFc3 ; break ; // F61489 case ' 7 ' : send = 0xFFc4 ; break ; // F71490 case ' 8 ' : send = 0xFFc5 ; break ; // F81491 case ' 9 ' : send = 0xFFc6 ; break ; // F91492 case ' 0 ' : send = 0xFFc7 ; break ; // F101493 case 'A ' : send = 0xFFc8 ; break ; // F111494 case 'B ' : send = 0xFFc9 ; break ; // F1214951496 // TODO the r e s t ! :>1497 default : send = s . charAt ( i ) ;1498 }1499 }1500 switch ( cmd ) {1501 case ' ! ' : mid let . r f b . key ( send , true ) ;1502 midlet . r f b . key ( send , fa l se ) ;1503 break ;1504 case '> ' : mid let . r f b . key ( send , fa l se ) ; break ;1505 case '< ' : mid let . r f b . key ( send , true ) ; break ;1506 }1507 } else i f ( s . charAt ( i ) == 'm' ) {1508 switch ( s . charAt ( i+1 ) ) {1509 case ' u ' : i++; sendMouse ( UP ) ; break ;1510 case ' d ' : i++; sendMouse ( DOWN ) ; break ;1511 case ' l ' : i++; sendMouse ( LEFT ) ; break ;1512 case ' r ' : i++; sendMouse ( RIGHT ) ; break ;1513 case '#' : i++;1514 //#i f d e f DEBUG1515 //# VNC. l o g ( "Move Move : Going : " + s ) ;1516 //#end i f1517 mouseX += Int eg e r . pa r s e In t ( s . s ub s t r i ng ( i +1, i+5 ) ) ;1518 //#i f d e f DEBUG

119

1519 //# VNC. l o g ( "Move Move : mouseX" + s . s u b s t r i n g ( i +1,1520 //# i+5 ) ) ;1521 //#end i f1522 mouseY += Int eg e r . pa r s e In t ( s . s ub s t r i ng ( i +6, i+10 ) ) ;1523 //#i f d e f DEBUG1524 //# VNC. l o g ( "Move Move : mouseY : " + s . s u b s t r i n g ( i +6,1525 //# i+10 ) ) ;1526 //#end i f1527 i f ( mouseX < 0 ) mouseX = 0 ;1528 i f ( mouseY < 0 ) mouseY = 0 ;1529 i f ( mouseX > midlet . r f b . x ) mouseX = midlet . r f b . x ;1530 i f ( mouseX > midlet . r f b . y ) mouseX = midlet . r f b . y ;1531 //#i f d e f DEBUG1532 //# VNC. l o g ( "Move Move : " + mouseX + "x" + mouseY ) ;1533 //#end i f1534 midlet . r f b . mouse ( mouseX , mouseY , 0 ) ;1535 i=+9;1536 break ;1537 case '%' : i++;1538 //#i f d e f DEBUG1539 //# VNC. l o g ( "Move Mouse %: Going : " + s ) ;1540 //#end i f1541 // Get 1 percent1542 int xp = ( midlet . r f b . x ) / 100 ;1543 int yp = ( midlet . r f b . y ) / 100 ;1544 //#i f d e f DEBUG1545 //# VNC. l o g ( "Move Move : mouseX" + s . s u b s t r i n g ( i +1,1546 //# i+4 ) ) ;1547 //#end i f1548 int de l taxp= In t eg e r . pa r s e In t ( s . sub s t r i ng1549 ( i +1, i+4 ) ) ;1550 //#i f d e f DEBUG1551 //# VNC. l o g ( "Move Move : mouseY : " + s . s u b s t r i n g ( i +5,1552 //# i+8 ) ) ;1553 //#end i f1554 int de l tayp= In t eg e r . pa r s e In t ( s . sub s t r i ng1555 ( i +5, i+8 ) ) ;15561557 mouseX=deltaxp ∗xp ;1558 mouseY=deltayp ∗yp ;1559 // Should never happen .1560 i f ( mouseX < 0 ) mouseX = 0 ;1561 i f ( mouseY < 0 ) mouseY = 0 ;1562 i f ( mouseX > midlet . r f b . x ) mouseX = midlet . r f b . x ;1563 i f ( mouseX > midlet . r f b . y ) mouseX = midlet . r f b . y ;1564 //#i f d e f DEBUG1565 //# VNC. l o g ( "Move Move : " + mouseX + "x" + mouseY ) ;1566 //#end i f1567 midlet . r f b . mouse ( mouseX , mouseY , 0 ) ;

120

1568 i=+7;1569 break ;1570 default :1571 //#i f d e f DEBUG1572 //# VNC. l o g ( "Move Move : Going : " + s ) ;1573 //#end i f1574 mouseX = Int eg e r . pa r s e In t ( s . sub s t r i ng ( i +1, i+5 ) ) ;1575 //#i f d e f DEBUG1576 //# VNC. l o g ( "Move Move : mouseX" + s . s u b s t r i n g ( i +1,1577 //# i+5 ) ) ;1578 //#end i f1579 mouseY = In t eg e r . pa r s e In t ( s . s ub s t r i ng ( i +6, i+10 ) ) ;1580 //#i f d e f DEBUG1581 //# VNC. l o g ( "Move Move : mouseY : " + s . s u b s t r i n g ( i +6,1582 //# i+10 ) ) ;1583 //#end i f1584 i f ( mouseX < 0 ) mouseX = 0 ;1585 i f ( mouseY < 0 ) mouseY = 0 ;1586 i f ( mouseX > midlet . r f b . x ) mouseX = midlet . r f b . x ;1587 i f ( mouseX > midlet . r f b . y ) mouseX = midlet . r f b . y ;1588 //#i f d e f DEBUG1589 //# VNC. l o g ( "Move Move : " + mouseX + "x" + mouseY ) ;1590 //#end i f1591 midlet . r f b . mouse ( mouseX , mouseY , 0 ) ;1592 i=+9;1593 break ;1594 }1595 } else i f ( s . charAt ( i ) == 'M' ) {1596 switch ( s . charAt ( i+1 ) ) {1597 case ' u ' : i++; sendNav ( UP ) ; break ;1598 case ' d ' : i++; sendNav ( DOWN ) ; break ;1599 case ' l ' : i++; sendNav ( LEFT ) ; break ;1600 case ' r ' : i++; sendNav ( RIGHT ) ; break ;1601 case '#' : i++;1602 // TODO: I n v a l i d a t e screen !1603 o f f x += Int eg e r . pa r s e In t ( s . s ub s t r i ng ( i +1, i+5 ) ) ;1604 o f f y += Int eg e r . pa r s e In t ( s . s ub s t r i ng ( i +6, i+10 ) ) ;16051606 i f ( o f f x < 0 ) o f f x = 0 ;1607 i f ( o f f y < 0 ) o f f y = 0 ;1608 i f ( o f f x > midlet . r f b . x − getWidth ( ) )1609 o f f x = midlet . r f b . x − getWidth ( ) ;1610 i f ( o f f y > midlet . r f b . y − getHeight ( ) )1611 o f f x = midlet . r f b . y − getHeight ( ) ;1612 incUpdate = fa l se ;1613 i =+9;1614 break ;1615 case '%' : i++;1616 // TODO: I n v a l i d a t e screen !

121

1617 //#i f d e f DEBUG1618 //# VNC. l o g ( "Move Screen %: \"" + s . s u b s t r i n g ( i +1, i+4 ) + "\" − \"" + s . s u b s t r i n g ( i +5, i+8 ) + "\"" ) ;1619 //# VNC. l o g ( "Move Screen %: Going : " + s + " " + i ) ;1620 //#end i f1621 int xp = ( midlet . r f b . x − getWidth ( ) ) / 100 ;1622 int yp = ( midlet . r f b . y − getHeight ( ) ) / 100 ;16231624 int de l taxp = In t eg e r . pa r s e In t ( s . s ub s t r i ng1625 ( i +1, i+4 ) ) ;1626 int de l tayp = In t eg e r . pa r s e In t ( s . s ub s t r i ng1627 ( i +5, i+8 ) ) ;16281629 o f f x=de l taxp ∗xp ;1630 o f f y=de l tayp ∗yp ;16311632 i f ( o f f x < 0 ) o f f x = 0 ;1633 i f ( o f f y < 0 ) o f f y = 0 ;1634 i f ( o f f x > midlet . r f b . x − getWidth ( ) )1635 o f f x = midlet . r f b . x − getWidth ( ) ;1636 i f ( o f f y > midlet . r f b . y − getHeight ( ) )1637 o f f y = midlet . r f b . y − getHeight ( ) ;16381639 incUpdate = fa l se ;16401641 i=+9;1642 break ;1643 default :1644 // TODO: I n v a l i d a t e screen !1645 //#i f d e f DEBUG1646 //# VNC. l o g ( "Move Screen : Going : " + s ) ;1647 //#end i f1648 int mX = Int eg e r . pa r s e In t ( s . sub s t r i ng ( i +1, i+5 ) ) ;1649 //#i f d e f DEBUG1650 //# VNC. l o g ( "Move Screen : X" + s . s u b s t r i n g ( i +1, i+5 ) ) ;1651 //#end i f1652 int mY = Int eg e r . pa r s e In t ( s . sub s t r i ng ( i +6, i+10 ) ) ;1653 //#i f d e f DEBUG1654 //# VNC. l o g ( "Move Screen : Y: " + s . s u b s t r i n g ( i +6, i+10 ) ) ;1655 //#end i f1656 i f ( mX < 0 ) mX = 0 ;1657 i f ( mY < 0 ) mY = 0 ;1658 i f ( mX > midlet . r f b . x − getWidth ( ) )1659 mX = midlet . r f b . x − getWidth ( ) ;1660 i f ( mY > midlet . r f b . y − getHeight ( ) )1661 mY = midlet . r f b . y − getHeight ( ) ;1662 //#i f d e f DEBUG1663 //# VNC. l o g ( "Move Screen : " + mX + "x" + mY ) ;1664 //#end i f1665 incUpdate = fa l se ;

122

1666 o f f x = mX;1667 o f f y = mY;1668 i=+9;1669 }16701671 } else i f ( s . charAt ( i ) == ' c ' ) {1672 //#i f d e f DEBUG1673 //# VNC. l o g ( "Move c l i c k " ) ;1674 //#end i f1675 midlet . r f b . mouse ( mouseX , mouseY , 1 ) ;1676 midlet . r f b . mouse ( mouseX , mouseY , 0 ) ;1677 }1678 }1679 } catch ( IndexOutOfBoundsException i o ) {1680 //#i f d e f DEBUG1681 //# VNC. l o g ( io . t oS t r i n g ( ) ) ;1682 //#end i f1683 AlertType .ERROR. playSound ( midlet .me ) ;1684 midlet .me . setCurrent ( new Aler t ( "#index_out_tit le#" ,1685 "#index_out_start#"1686 + io . getMessage ( )1687 + "#index_out_end#" , null ,1688 AlertType .ERROR) , this ) ;16891690 }1691 midlet . r f b . requestUpdate ( o f fx , o f fy ,1692 getWidth ( ) , getHeight ( ) ,1693 incUpdate ) ;1694 }169516961697 /∗∗1698 ∗ @author G i l b e r t o Torrezan Fi lho1699 ∗/1700 public void showTasks ( S t r ing [ ] newTasks ) {1701 System . out . p r i n t l n ( "Recebeu as ta sk s ! ! ! Tamanho : "+newTasks . l ength ) ;1702 this . endUpdate ( ) ;1703 la s tTasks = newTasks ;1704 tasksChoice = new ChoiceGroup ( " S e l e c i on e a Tarefa " ,1705 ChoiceGroup .EXCLUSIVE,1706 newTasks , null ) ;17071708 ta sk s . append ( tasksChoice ) ;1709 midlet .me . setCurrent ( ta sk s ) ;1710 }171117121713 /∗∗1714 ∗ @author G i l b e r t o Torrezan Fi lho

123

1715 ∗/1716 public void message ( S t r ing message ) {1717 this . endUpdate ( ) ;1718 messageForm . append ( message ) ;1719 midlet .me . setCurrent ( messageForm ) ;1720 }1721 }172217231724 //LocalWords : drawImage sb mouseX mouseY

124

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003 Michael Lloyd Lee5 ∗6 ∗ Copyright (C) 1999 AT&T Labora tor i e s Cambridge . A l l Righ ts Reserved .7 ∗8 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify9 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by10 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or11 ∗ ( a t your opt ion ) any l a t e r ve r s i on .12 ∗13 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,14 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f15 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16 ∗ GNU General Pub l i c License f o r more d e t a i l s .17 ∗18 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License19 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware20 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA21 ∗/2223 package tk . wetnet . u t i l ;2425 /∗∗ A simple Queue implementated as a Doubly−Linked−L i s t26 ∗ @author Michael Lloyd Lee27 ∗ @version 1 . 0 . 028 ∗ @threadsa fe ty This c l a s s and i t s methods shou ld be thread sa f e .29 ∗/3031 public class Queue {32 /∗∗ Ins t ead o f con ta in ing i tems which a Object Data , i tems us ing t h i s c l a s s33 ∗ shou ld extend QueueEntry .34 ∗/35 stat ic public class QueueEntry {36 public QueueEntry ( ) {}37 private QueueEntry next ;38 private QueueEntry prev ;39 }4041 public Queue ( ) { }4243 private QueueEntry f i r s t = null ;44 private QueueEntry l a s t = null ;4546 /∗∗ I s the queue empty47 ∗ @returns i f the queue empty48 ∗/

125

49 public synchronized boolean isEmpty ( ) {50 return f i r s t==null ;51 }5253 /∗∗ Returns the s i z e o f the queue54 ∗ @returns s i z e o f the queue55 ∗ @warning l oops through the queue , thus s low .56 ∗/57 public synchronized int s i z e ( ) {58 i f ( isEmpty ( ) ) return 0 ;59 QueueEntry e = f i r s t ;60 int c = 0 ;61 while ( e != null ) {62 c++;63 e = e . next ;64 }65 return c ;66 }6768 /∗∗ Pushes an item onto the Queue69 ∗ @param o Object to push onto the Queue70 ∗/71 public synchronized void push ( QueueEntry o ) {72 i f ( f i r s t == null ) {73 f i r s t = o ;74 o . next = null ;75 o . prev = null ;76 l a s t = o ;77 return ;78 }79 o . next = f i r s t ;80 f i r s t . prev = o ;81 o . prev = null ;82 f i r s t = o ;83 }8485 /∗∗ Pops an item from the Queue86 ∗ @returns the popped item87 ∗/88 public synchronized QueueEntry pop ( ) {89 QueueEntry r = l a s t ;90 i f ( r != null ) {91 i f ( l a s t == f i r s t ) {92 f i r s t = null ;93 l a s t = null ;94 return r ;95 }96 l a s t = r . prev ;97 r . prev = null ;

126

98 }99 return r ;100 }101102 }

127

1 package tk . wetnet . vnc ;23 //4 // This DES c l a s s has been e x t r a c t e d from package Acme. Crypto f o r use in VNC.5 // The b y t e b i t [ ] array has been reve r s ed so t ha t the most s i g n i f i c a n t b i t6 // in each by t e o f the key i s ignored , not the l e a s t s i g n i f i c a n t .Also the

7 // unnecessary odd pa r i t y code has been removed .8 //9 // These changes are :10 // Copyright (C) 1999 AT&T Labora tor i e s Cambridge . A l l Right s Reserved .11 //12 // This so f tware i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,13 // but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.15 //1617 // DesCipher − the DES encryp t ion method18 //19 // The meat o f t h i s code i s by Dave Zimmerman <dzimm@widget . com>, and i s :20 //21 // Copyright ( c ) 1996 Widget Workshop , Inc . A l l Righ ts Reserved .22 //23 // Permission to use , copy , modify , and d i s t r i b u t e t h i s so f tware24 // and i t s documentation f o r NON−COMMERCIAL or COMMERCIAL purposes and25 // wi thout f e e i s hereby granted , prov ided t ha t t h i s copy r i g h t no t i c e i s kep t26 // i n t a c t .27 //28 // WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY29 // OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED30 // TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A31 // PARTICULAR PURPOSE, OR NON−INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE32 // FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR33 // DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.34 //35 // THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON−LINE36 // CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL−SAFE37 // PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES , AIRCRAFT38 // NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE39 // SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE40 // SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE41 // PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES" ) . WIDGET WORKSHOP42 // SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR43 // HIGH RISK ACTIVITIES .44 //45 //46 // The r e s t i s :47 //48 // Copyright (C) 1996 by Je f Poskanzer <jef@acme . com>. A l l r i g h t s r e s e rved .

128

49 //50 // Red i s t r i b u t i on and use in source and b inary forms , wi th or wi thout51 // modi f i ca t ion , are permi t t ed prov ided t ha t the f o l l ow i n g cond i t i on s52 // are met :53 // 1 . Red i s t r i b u t i o n s o f source code must r e t a i n the above copy r i g h t54 // not ice , t h i s l i s t o f c ond i t i on s and the f o l l ow i n g d i s c l a imer .55 // 2 . Red i s t r i b u t i o n s in b inary form must reproduce the above copy r i g h t56 // not ice , t h i s l i s t o f c ond i t i on s and the f o l l ow i n g d i s c l a imer in the57 // documentation and/or o ther ma t e r i a l s prov ided wi th the d i s t r i b u t i o n .58 //59 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ` `AS IS ' ' AND60 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE61 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE62 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE63 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL64 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS65 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)66 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT, STRICT67 // LIABILITY , OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY68 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF69 // SUCH DAMAGE.70 //71 // V i s i t the ACME Labs Java page f o r up−to−date v e r s i on s o f t h i s and o ther72 // f i n e Java u t i l i t i e s : h t t p ://www. acme . com/ java /7374 /// The DES encryp t ion method .75 // <P>76 // This i s s u r p r i s i n g l y f a s t , f o r pure Java . On a SPARC 20 , wrapped77 // in Acme. Crypto . EncryptedOutputStream or Acme. Crypto . EncryptedInputStream ,78 // i t does around 7000 by t e s / second .79 // <P>80 // Most o f t h i s code i s by Dave Zimmerman <dzimm@widget . com>, and i s81 // Copyright ( c ) 1996 Widget Workshop , Inc . See the source f i l e f o r d e t a i l s .82 // <P>83 // <A HREF="/resource s / c l a s s e s /Acme/Crypto/DesCipher . java">Fetch the so f tware .</A><BR>84 // <A HREF="/resource s / c l a s s e s /Acme. ta r .Z">Fetch the en t i r e Acme package .</A>85 // <P>86 // @see Des3Cipher87 // @see EncryptedOutputStream88 // @see EncryptedInputStream8990 public class DesCipher91 {9293 // Constructor , byte−array key .94 public DesCipher ( byte [ ] key )95 {96 setKey ( key ) ;97 }

129

9899 // Key rou t i n e s .100101 private int [ ] encryptKeys = new int [ 3 2 ] ;102 private int [ ] decryptKeys = new int [ 3 2 ] ;103104 /// Set the key .105 public void setKey ( byte [ ] key )106 {107 deskey ( key , true , encryptKeys ) ;108 deskey ( key , false , decryptKeys ) ;109 }110111 // Turn an 8−by t e key in to i n t e r n a l keys .112 private void deskey ( byte [ ] keyBlock , boolean encrypt ing , int [ ] KnL )113 {114 int i , j , l , m, n ;115 int [ ] pc1m = new int [ 5 6 ] ;116 int [ ] pcr = new int [ 5 6 ] ;117 int [ ] kn = new int [ 3 2 ] ;118119 for ( j = 0 ; j < 56 ; ++j )120 {121 l = pc1 [ j ] ;122 m = l & 07 ;123 pc1m [ j ] = ( ( keyBlock [ l >>> 3 ] & byteb i t [m] ) != 0 )? 1 : 0 ;124 }125126 for ( i = 0 ; i < 16 ; ++i )127 {128 i f ( encrypt ing )129 m = i << 1 ;130 else

131 m = (15− i ) << 1 ;132 n = m+1;133 kn [m] = kn [ n ] = 0 ;134 for ( j = 0 ; j < 28 ; ++j )135 {136 l = j+to t r o t [ i ] ;137 i f ( l < 28 )138 pcr [ j ] = pc1m [ l ] ;139 else

140 pcr [ j ] = pc1m [ l −28] ;141 }142 for ( j =28; j < 56 ; ++j )143 {144 l = j+to t r o t [ i ] ;145 i f ( l < 56 )146 pcr [ j ] = pc1m [ l ] ;

130

147 else

148 pcr [ j ] = pc1m [ l −28] ;149 }150 for ( j = 0 ; j < 24 ; ++j )151 {152 i f ( pcr [ pc2 [ j ] ] != 0 )153 kn [m] |= bigbyte [ j ] ;154 i f ( pcr [ pc2 [ j +24] ] != 0 )155 kn [ n ] |= bigbyte [ j ] ;156 }157 }158 cookey ( kn , KnL ) ;159 }160161 private void cookey ( int [ ] raw , int KnL [ ] )162 {163 int raw0 , raw1 ;164 int rawi , KnLi ;165 int i ;166167 for ( i = 0 , rawi = 0 , KnLi = 0 ; i < 16 ; ++i )168 {169 raw0 = raw [ rawi++];170 raw1 = raw [ rawi++];171 KnL[ KnLi ] = ( raw0 & 0x00fc0000 ) << 6 ;172 KnL[ KnLi ] |= ( raw0 & 0x00000fc0 ) << 10 ;173 KnL[ KnLi ] |= ( raw1 & 0x00fc0000 ) >>> 10 ;174 KnL[ KnLi ] |= ( raw1 & 0x00000fc0 ) >>> 6 ;175 ++KnLi ;176 KnL[ KnLi ] = ( raw0 & 0x0003f000 ) << 12 ;177 KnL[ KnLi ] |= ( raw0 & 0x0000003f ) << 16 ;178 KnL[ KnLi ] |= ( raw1 & 0x0003f000 ) >>> 4 ;179 KnL[ KnLi ] |= ( raw1 & 0x0000003f ) ;180 ++KnLi ;181 }182 }183184185 // Block encryp t ion rou t i n e s .186187 private int [ ] tempInts = new int [ 2 ] ;188189 /// Encrypt a b l o c k o f e i g h t b y t e s .190 public void encrypt ( byte [ ] c l earText , int c l ea rO f f , byte [ ] c ipherText , int c iphe rOf f )191 {192 squashBytesToInts ( c learText , c l e a rOf f , tempInts , 0 , 2 ) ;193 des ( tempInts , tempInts , encryptKeys ) ;194 spreadIntsToBytes ( tempInts , 0 , c ipherText , c ipherOf f , 2 ) ;195 }

131

196197 /// Decrypt a b l o c k o f e i g h t b y t e s .198 public void decrypt ( byte [ ] c ipherText , int c ipherOf f , byte [ ] c l earText , int c l e a rO f f )199 {200 squashBytesToInts ( cipherText , c ipherOf f , tempInts , 0 , 2 ) ;201 des ( tempInts , tempInts , decryptKeys ) ;202 spreadIntsToBytes ( tempInts , 0 , c learText , c l e a rOf f , 2 ) ;203 }204205 // The DES func t i on .206 private void des ( int [ ] i n In t s , int [ ] outInts , int [ ] keys )207 {208 int f va l , work , r i ght , l e f t t ;209 int round ;210 int key s i = 0 ;211212 l e f t t = i n I n t s [ 0 ] ;213 r i gh t = i n I n t s [ 1 ] ;214215 work = ( ( l e f t t >>> 4) ^ r i gh t ) & 0 x 0 f 0 f 0 f 0 f ;216 r i gh t ^= work ;217 l e f t t ^= (work << 4 ) ;218219 work = ( ( l e f t t >>> 16) ^ r i gh t ) & 0 x 0 0 0 0 f f f f ;220 r i gh t ^= work ;221 l e f t t ^= (work << 16 ) ;222223 work = ( ( r i gh t >>> 2) ^ l e f t t ) & 0x33333333 ;224 l e f t t ^= work ;225 r i gh t ^= (work << 2 ) ;226227 work = ( ( r i gh t >>> 8) ^ l e f t t ) & 0 x 0 0 f f 0 0 f f ;228 l e f t t ^= work ;229 r i gh t ^= (work << 8 ) ;230 r i gh t = ( r i g h t << 1) | ( ( r i g h t >>> 31) & 1 ) ;231232 work = ( l e f t t ^ r i g h t ) & 0xaaaaaaaa ;233 l e f t t ^= work ;234 r i gh t ^= work ;235 l e f t t = ( l e f t t << 1) | ( ( l e f t t >>> 31) & 1 ) ;236237 for ( round = 0 ; round < 8 ; ++round )238 {239 work = ( r i gh t << 28) | ( r i g h t >>> 4 ) ;240 work ^= keys [ k ey s i ++];241 f v a l = SP7 [ work & 0x0000003f ] ;242 f v a l |= SP5 [ ( work >>> 8) & 0x0000003f ] ;243 f v a l |= SP3 [ ( work >>> 16) & 0x0000003f ] ;244 f v a l |= SP1 [ ( work >>> 24) & 0x0000003f ] ;

132

245 work = r i gh t ^ keys [ k ey s i ++];246 f v a l |= SP8 [ work & 0x0000003f ] ;247 f v a l |= SP6 [ ( work >>> 8) & 0x0000003f ] ;248 f v a l |= SP4 [ ( work >>> 16) & 0x0000003f ] ;249 f v a l |= SP2 [ ( work >>> 24) & 0x0000003f ] ;250 l e f t t ^= f v a l ;251 work = ( l e f t t << 28) | ( l e f t t >>> 4 ) ;252 work ^= keys [ k ey s i ++];253 f v a l = SP7 [ work & 0x0000003f ] ;254 f v a l |= SP5 [ ( work >>> 8) & 0x0000003f ] ;255 f v a l |= SP3 [ ( work >>> 16) & 0x0000003f ] ;256 f v a l |= SP1 [ ( work >>> 24) & 0x0000003f ] ;257 work = l e f t t ^ keys [ k ey s i ++];258 f v a l |= SP8 [ work & 0x0000003f ] ;259 f v a l |= SP6 [ ( work >>> 8) & 0x0000003f ] ;260 f v a l |= SP4 [ ( work >>> 16) & 0x0000003f ] ;261 f v a l |= SP2 [ ( work >>> 24) & 0x0000003f ] ;262 r i gh t ^= f v a l ;263 }264265 r i gh t = ( r i g h t << 31) | ( r i g h t >>> 1 ) ;266 work = ( l e f t t ^ r i g h t ) & 0xaaaaaaaa ;267 l e f t t ^= work ;268 r i gh t ^= work ;269 l e f t t = ( l e f t t << 31) | ( l e f t t >>> 1 ) ;270 work = ( ( l e f t t >>> 8) ^ r i gh t ) & 0 x 0 0 f f 0 0 f f ;271 r i gh t ^= work ;272 l e f t t ^= (work << 8 ) ;273 work = ( ( l e f t t >>> 2) ^ r i gh t ) & 0x33333333 ;274 r i gh t ^= work ;275 l e f t t ^= (work << 2 ) ;276 work = ( ( r i gh t >>> 16) ^ l e f t t ) & 0 x 0 0 0 0 f f f f ;277 l e f t t ^= work ;278 r i gh t ^= (work << 16 ) ;279 work = ( ( r i gh t >>> 4) ^ l e f t t ) & 0 x 0 f 0 f 0 f 0 f ;280 l e f t t ^= work ;281 r i gh t ^= (work << 4 ) ;282 out In t s [ 0 ] = r i gh t ;283 out In t s [ 1 ] = l e f t t ;284 }285286287 // Tables , permutations , S−boxes , e t c .288289 private stat ic byte [ ] by t eb i t = {290 (byte )0 x01 , (byte )0 x02 , (byte )0 x04 , (byte )0 x08 ,291 (byte )0 x10 , (byte )0 x20 , (byte )0 x40 , (byte )0 x80292 } ;293 private stat ic int [ ] b igbyte = {

133

294 0x800000 , 0x400000 , 0x200000 , 0x100000 ,295 0x080000 , 0x040000 , 0x020000 , 0x010000 ,296 0x008000 , 0x004000 , 0x002000 , 0x001000 ,297 0x000800 , 0x000400 , 0x000200 , 0x000100 ,298 0x000080 , 0x000040 , 0x000020 , 0x000010 ,299 0x000008 , 0x000004 , 0x000002 , 0x000001300 } ;301 private stat ic byte [ ] pc1 = {302 (byte )56 , (byte )48 , (byte )40 , (byte )32 , (byte )24 , (byte )16 , (byte ) 8 ,303 (byte ) 0 , (byte )57 , (byte )49 , (byte )41 , (byte )33 , (byte )25 , (byte )17 ,304 (byte ) 9 , (byte ) 1 , (byte )58 , (byte )50 , (byte )42 , (byte )34 , (byte )26 ,305 (byte )18 , (byte )10 , (byte ) 2 , (byte )59 , (byte )51 , (byte )43 , (byte )35 ,306 (byte )62 , (byte )54 , (byte )46 , (byte )38 , (byte )30 , (byte )22 , (byte )14 ,307 (byte ) 6 , (byte )61 , (byte )53 , (byte )45 , (byte )37 , (byte )29 , (byte )21 ,308 (byte )13 , (byte ) 5 , (byte )60 , (byte )52 , (byte )44 , (byte )36 , (byte )28 ,309 (byte )20 , (byte )12 , (byte ) 4 , (byte )27 , (byte )19 , (byte )11 , (byte )3310 } ;311 private stat ic int [ ] t o t r o t = {312 1 , 2 , 4 , 6 , 8 , 10 , 12 , 14 , 15 , 17 , 19 , 21 , 23 , 25 , 27 , 28313 } ;314315 private stat ic byte [ ] pc2 = {316 (byte )13 , (byte )16 , (byte )10 , (byte )23 , (byte ) 0 , (byte ) 4 ,317 (byte ) 2 , (byte )27 , (byte )14 , (byte ) 5 , (byte )20 , (byte ) 9 ,318 (byte )22 , (byte )18 , (byte )11 , (byte )3 , (byte )25 , (byte ) 7 ,319 (byte )15 , (byte ) 6 , (byte )26 , (byte )19 , (byte )12 , (byte ) 1 ,320 (byte )40 , (byte )51 , (byte )30 , (byte )36 , (byte )46 , (byte )54 ,321 (byte )29 , (byte )39 , (byte )50 , (byte )44 , (byte )32 , (byte )47 ,322 (byte )43 , (byte )48 , (byte )38 , (byte )55 , (byte )33 , (byte )52 ,323 (byte )45 , (byte )41 , (byte )49 , (byte )35 , (byte )28 , (byte )31 ,324 } ;325326 private stat ic int [ ] SP1 = {327 0x01010400 , 0x00000000 , 0x00010000 , 0x01010404 ,328 0x01010004 , 0x00010404 , 0x00000004 , 0x00010000 ,329 0x00000400 , 0x01010400 , 0x01010404 , 0x00000400 ,330 0x01000404 , 0x01010004 , 0x01000000 , 0x00000004 ,331 0x00000404 , 0x01000400 , 0x01000400 , 0x00010400 ,332 0x00010400 , 0x01010000 , 0x01010000 , 0x01000404 ,333 0x00010004 , 0x01000004 , 0x01000004 , 0x00010004 ,334 0x00000000 , 0x00000404 , 0x00010404 , 0x01000000 ,335 0x00010000 , 0x01010404 , 0x00000004 , 0x01010000 ,336 0x01010400 , 0x01000000 , 0x01000000 , 0x00000400 ,337 0x01010004 , 0x00010000 , 0x00010400 , 0x01000004 ,338 0x00000400 , 0x00000004 , 0x01000404 , 0x00010404 ,339 0x01010404 , 0x00010004 , 0x01010000 , 0x01000404 ,340 0x01000004 , 0x00000404 , 0x00010404 , 0x01010400 ,341 0x00000404 , 0x01000400 , 0x01000400 , 0x00000000 ,342 0x00010004 , 0x00010400 , 0x00000000 , 0x01010004

134

343 } ;344 private stat ic int [ ] SP2 = {345 0x80108020 , 0x80008000 , 0x00008000 , 0x00108020 ,346 0x00100000 , 0x00000020 , 0x80100020 , 0x80008020 ,347 0x80000020 , 0x80108020 , 0x80108000 , 0x80000000 ,348 0x80008000 , 0x00100000 , 0x00000020 , 0x80100020 ,349 0x00108000 , 0x00100020 , 0x80008020 , 0x00000000 ,350 0x80000000 , 0x00008000 , 0x00108020 , 0x80100000 ,351 0x00100020 , 0x80000020 , 0x00000000 , 0x00108000 ,352 0x00008020 , 0x80108000 , 0x80100000 , 0x00008020 ,353 0x00000000 , 0x00108020 , 0x80100020 , 0x00100000 ,354 0x80008020 , 0x80100000 , 0x80108000 , 0x00008000 ,355 0x80100000 , 0x80008000 , 0x00000020 , 0x80108020 ,356 0x00108020 , 0x00000020 , 0x00008000 , 0x80000000 ,357 0x00008020 , 0x80108000 , 0x00100000 , 0x80000020 ,358 0x00100020 , 0x80008020 , 0x80000020 , 0x00100020 ,359 0x00108000 , 0x00000000 , 0x80008000 , 0x00008020 ,360 0x80000000 , 0x80100020 , 0x80108020 , 0x00108000361 } ;362 private stat ic int [ ] SP3 = {363 0x00000208 , 0x08020200 , 0x00000000 , 0x08020008 ,364 0x08000200 , 0x00000000 , 0x00020208 , 0x08000200 ,365 0x00020008 , 0x08000008 , 0x08000008 , 0x00020000 ,366 0x08020208 , 0x00020008 , 0x08020000 , 0x00000208 ,367 0x08000000 , 0x00000008 , 0x08020200 , 0x00000200 ,368 0x00020200 , 0x08020000 , 0x08020008 , 0x00020208 ,369 0x08000208 , 0x00020200 , 0x00020000 , 0x08000208 ,370 0x00000008 , 0x08020208 , 0x00000200 , 0x08000000 ,371 0x08020200 , 0x08000000 , 0x00020008 , 0x00000208 ,372 0x00020000 , 0x08020200 , 0x08000200 , 0x00000000 ,373 0x00000200 , 0x00020008 , 0x08020208 , 0x08000200 ,374 0x08000008 , 0x00000200 , 0x00000000 , 0x08020008 ,375 0x08000208 , 0x00020000 , 0x08000000 , 0x08020208 ,376 0x00000008 , 0x00020208 , 0x00020200 , 0x08000008 ,377 0x08020000 , 0x08000208 , 0x00000208 , 0x08020000 ,378 0x00020208 , 0x00000008 , 0x08020008 , 0x00020200379 } ;380 private stat ic int [ ] SP4 = {381 0x00802001 , 0x00002081 , 0x00002081 , 0x00000080 ,382 0x00802080 , 0x00800081 , 0x00800001 , 0x00002001 ,383 0x00000000 , 0x00802000 , 0x00802000 , 0x00802081 ,384 0x00000081 , 0x00000000 , 0x00800080 , 0x00800001 ,385 0x00000001 , 0x00002000 , 0x00800000 , 0x00802001 ,386 0x00000080 , 0x00800000 , 0x00002001 , 0x00002080 ,387 0x00800081 , 0x00000001 , 0x00002080 , 0x00800080 ,388 0x00002000 , 0x00802080 , 0x00802081 , 0x00000081 ,389 0x00800080 , 0x00800001 , 0x00802000 , 0x00802081 ,390 0x00000081 , 0x00000000 , 0x00000000 , 0x00802000 ,391 0x00002080 , 0x00800080 , 0x00800081 , 0x00000001 ,

135

392 0x00802001 , 0x00002081 , 0x00002081 , 0x00000080 ,393 0x00802081 , 0x00000081 , 0x00000001 , 0x00002000 ,394 0x00800001 , 0x00002001 , 0x00802080 , 0x00800081 ,395 0x00002001 , 0x00002080 , 0x00800000 , 0x00802001 ,396 0x00000080 , 0x00800000 , 0x00002000 , 0x00802080397 } ;398 private stat ic int [ ] SP5 = {399 0x00000100 , 0x02080100 , 0x02080000 , 0x42000100 ,400 0x00080000 , 0x00000100 , 0x40000000 , 0x02080000 ,401 0x40080100 , 0x00080000 , 0x02000100 , 0x40080100 ,402 0x42000100 , 0x42080000 , 0x00080100 , 0x40000000 ,403 0x02000000 , 0x40080000 , 0x40080000 , 0x00000000 ,404 0x40000100 , 0x42080100 , 0x42080100 , 0x02000100 ,405 0x42080000 , 0x40000100 , 0x00000000 , 0x42000000 ,406 0x02080100 , 0x02000000 , 0x42000000 , 0x00080100 ,407 0x00080000 , 0x42000100 , 0x00000100 , 0x02000000 ,408 0x40000000 , 0x02080000 , 0x42000100 , 0x40080100 ,409 0x02000100 , 0x40000000 , 0x42080000 , 0x02080100 ,410 0x40080100 , 0x00000100 , 0x02000000 , 0x42080000 ,411 0x42080100 , 0x00080100 , 0x42000000 , 0x42080100 ,412 0x02080000 , 0x00000000 , 0x40080000 , 0x42000000 ,413 0x00080100 , 0x02000100 , 0x40000100 , 0x00080000 ,414 0x00000000 , 0x40080000 , 0x02080100 , 0x40000100415 } ;416 private stat ic int [ ] SP6 = {417 0x20000010 , 0x20400000 , 0x00004000 , 0x20404010 ,418 0x20400000 , 0x00000010 , 0x20404010 , 0x00400000 ,419 0x20004000 , 0x00404010 , 0x00400000 , 0x20000010 ,420 0x00400010 , 0x20004000 , 0x20000000 , 0x00004010 ,421 0x00000000 , 0x00400010 , 0x20004010 , 0x00004000 ,422 0x00404000 , 0x20004010 , 0x00000010 , 0x20400010 ,423 0x20400010 , 0x00000000 , 0x00404010 , 0x20404000 ,424 0x00004010 , 0x00404000 , 0x20404000 , 0x20000000 ,425 0x20004000 , 0x00000010 , 0x20400010 , 0x00404000 ,426 0x20404010 , 0x00400000 , 0x00004010 , 0x20000010 ,427 0x00400000 , 0x20004000 , 0x20000000 , 0x00004010 ,428 0x20000010 , 0x20404010 , 0x00404000 , 0x20400000 ,429 0x00404010 , 0x20404000 , 0x00000000 , 0x20400010 ,430 0x00000010 , 0x00004000 , 0x20400000 , 0x00404010 ,431 0x00004000 , 0x00400010 , 0x20004010 , 0x00000000 ,432 0x20404000 , 0x20000000 , 0x00400010 , 0x20004010433 } ;434 private stat ic int [ ] SP7 = {435 0x00200000 , 0x04200002 , 0x04000802 , 0x00000000 ,436 0x00000800 , 0x04000802 , 0x00200802 , 0x04200800 ,437 0x04200802 , 0x00200000 , 0x00000000 , 0x04000002 ,438 0x00000002 , 0x04000000 , 0x04200002 , 0x00000802 ,439 0x04000800 , 0x00200802 , 0x00200002 , 0x04000800 ,440 0x04000002 , 0x04200000 , 0x04200800 , 0x00200002 ,

136

441 0x04200000 , 0x00000800 , 0x00000802 , 0x04200802 ,442 0x00200800 , 0x00000002 , 0x04000000 , 0x00200800 ,443 0x04000000 , 0x00200800 , 0x00200000 , 0x04000802 ,444 0x04000802 , 0x04200002 , 0x04200002 , 0x00000002 ,445 0x00200002 , 0x04000000 , 0x04000800 , 0x00200000 ,446 0x04200800 , 0x00000802 , 0x00200802 , 0x04200800 ,447 0x00000802 , 0x04000002 , 0x04200802 , 0x04200000 ,448 0x00200800 , 0x00000000 , 0x00000002 , 0x04200802 ,449 0x00000000 , 0x00200802 , 0x04200000 , 0x00000800 ,450 0x04000002 , 0x04000800 , 0x00000800 , 0x00200002451 } ;452 private stat ic int [ ] SP8 = {453 0x10001040 , 0x00001000 , 0x00040000 , 0x10041040 ,454 0x10000000 , 0x10001040 , 0x00000040 , 0x10000000 ,455 0x00040040 , 0x10040000 , 0x10041040 , 0x00041000 ,456 0x10041000 , 0x00041040 , 0x00001000 , 0x00000040 ,457 0x10040000 , 0x10000040 , 0x10001000 , 0x00001040 ,458 0x00041000 , 0x00040040 , 0x10040040 , 0x10041000 ,459 0x00001040 , 0x00000000 , 0x00000000 , 0x10040040 ,460 0x10000040 , 0x10001000 , 0x00041040 , 0x00040000 ,461 0x00041040 , 0x00040000 , 0x10041000 , 0x00001000 ,462 0x00000040 , 0x10040040 , 0x00001000 , 0x00041040 ,463 0x10001000 , 0x00000040 , 0x10000040 , 0x10040000 ,464 0x10040040 , 0x10000000 , 0x00040000 , 0x10001040 ,465 0x00000000 , 0x10041040 , 0x00040040 , 0x10000040 ,466 0x10040000 , 0x10001000 , 0x10001040 , 0x00000000 ,467 0x10041040 , 0x00041000 , 0x00041000 , 0x00001040 ,468 0x00001040 , 0x00040040 , 0x10000000 , 0x10041000469 } ;470471 // Routines taken from other par t s o f the Acme u t i l i t i e s .472473 /// Squash by t e s down to i n t s .474 public stat ic void squashBytesToInts ( byte [ ] inBytes , int inOff , int [ ] outInts , int outOff , int intLen )475 {476 for ( int i = 0 ; i < intLen ; ++i )477 out In t s [ outOff + i ] =478 ( ( inBytes [ inOf f + i ∗ 4 ] & 0 x f f ) << 24 ) |479 ( ( inBytes [ inOf f + i ∗ 4 + 1 ] & 0 x f f ) << 16 ) |480 ( ( inBytes [ inOf f + i ∗ 4 + 2 ] & 0 x f f ) << 8 ) |481 ( inBytes [ inOf f + i ∗ 4 + 3 ] & 0 x f f ) ;482 }483484 /// Spread i n t s in t o b y t e s .485 public stat ic void spreadIntsToBytes ( int [ ] i n In t s , int inOff , byte [ ] outBytes , int outOff , int intLen )486 {487 for ( int i = 0 ; i < intLen ; ++i )488 {489 outBytes [ outOff + i ∗ 4 ] = (byte ) ( i n I n t s [ inOf f + i ] >>> 24 ) ;

137

490 outBytes [ outOff + i ∗ 4 + 1 ] = (byte ) ( i n I n t s [ inOf f + i ] >>> 16 ) ;491 outBytes [ outOff + i ∗ 4 + 2 ] = (byte ) ( i n I n t s [ inOf f + i ] >>>

8 ) ;492 outBytes [ outOff + i ∗ 4 + 3 ] = (byte ) i n I n t s [ inOf f + i ] ;493 }494 }495 }

138

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003 Michael Lloyd Lee5 ∗6 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify7 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by8 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or9 ∗ ( a t your opt ion ) any l a t e r ve r s i on .10 ∗11 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,12 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f13 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 ∗ GNU General Pub l i c License f o r more d e t a i l s .15 ∗16 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License17 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware18 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA19 ∗/2021 package tk . wetnet . vnc ;2223 /∗∗ Sent updates from VNC serve r v ia the RFBProto c l a s s .24 ∗ Objec t s which wish to r e c e i v e the updates sen t from the VNC serve r shou ld25 ∗ implement t h i s i n t e r f a c e .26 ∗/2728 public interface DrawToable {29 /∗∗ A reque s t to draw a r e c t an g l e .30 ∗ @param red The about o f red , between 0 and 255 o f the square .31 ∗ @param green The about o f green , between 0 and 255 o f the square .32 ∗ @param b lue The about o f b lue , between 0 and 255 o f the square .33 ∗ @param x The x−o f f s e t from the top−r i g h t hand corner34 ∗ @param y The y−o f f s e t from the top−r i g h t hand corner35 ∗ @param w The width o f r e c t an g l e .36 ∗ @param h The he i g h t o f r e c t an g l e .37 ∗/38 public void draw ( int red , int green , int blue , int x , int y , int w, int h ) ;3940 /∗∗ A reque s t to copy a r e c t an g l e .41 ∗ @param x The s t a r t i n g x−o f f s e t o f the r e c t an g l e to copy .42 ∗ @param y The s t a r t i n g y−o f f s e t o f the r e c t an g l e to copy .43 ∗ @param w The width o f the r e c t an g l e to copy .44 ∗ @param h The he i g h t o f the r e c t an g l e to copy .45 ∗ @param srcx The l o c a t i o n to copy t h i s r e c t an g l e to .46 ∗ @param srcy The l o c a t i o n to copy t h i s r e c t an g l e to .47 ∗/48 public void copyRect ( int x , int y , int w, int h , int srcx , int s r cy ) ;

139

4950 /∗∗ Informs the curren t update has s t a r t e d . ∗/51 public void startUpdate ( ) ;5253 /∗∗ Informs the curren t update has ended . ∗/54 public void endUpdate ( ) ;5556 /∗∗ A reque s t to r ing a b e l l . ∗/57 public void r i n gBe l l ( ) ;5859 /∗∗ The RFBProto i s ready to r e c e i v e r e qu e s t s . ∗/60 public void ready ( ) ;6162 /∗∗ Something has gone wrong .63 ∗ @param The message to d i s p l a y to the user .64 ∗/65 public void e r r o r ( S t r ing e r r o r ) ;6667 /∗∗ The c l i e n t i s a s t a g e c l o s e r to a complete connect ion ∗/68 public void incConnect ionStatus ( ) ;69707172 /∗∗73 ∗ @author G i l b e r t o Torrezan Fi lho74 ∗/75 public void showTasks ( S t r ing [ ] t a sk s ) ;76 public void message ( S t r ing message ) ;77 }

140

1 /∗2 ∗ This f i l e i s par t o f J2ME VNC.3 ∗4 ∗ Copyright ( c ) 2003 Michael Lloyd Lee5 ∗6 ∗ Copyright (C) 1999 AT&T Labora tor i e s Cambridge . A l l Righ ts Reserved .7 ∗8 ∗ J2ME VNC i s f r e e so f tware ; you can r e d i s t r i b u t e i t and/or modify9 ∗ i t under the terms o f the GNU General Pub l i c License as pub l i s h ed by10 ∗ the Free Sof tware Foundation ; e i t h e r ve r s i on 2 o f the License , or11 ∗ ( a t your opt ion ) any l a t e r ve r s i on .12 ∗13 ∗ J2ME VNC i s d i s t r i b u t e d in the hope t ha t i t w i l l be u s e fu l ,14 ∗ but WITHOUT ANY WARRANTY; wi thout even the imp l i ed warranty o f15 ∗ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16 ∗ GNU General Pub l i c License f o r more d e t a i l s .17 ∗18 ∗ You shou ld have r e c e i v ed a copy o f the GNU General Pub l i c License19 ∗ a long wi th J2ME VNC; i f not , wr i t e to the Free Sof tware20 ∗ Foundation , Inc . , 59 Temple Place , Su i t e 330 , Boston , MA 02111−1307

USA21 ∗/2223 package tk . wetnet . vnc ;2425 import java . i o . DataInputStream ;26 import java . i o . IOException ;27 import java . i o . OutputStream ;2829 import tk . wetnet . u t i l . Queue ;3031 /∗∗ A simple API f o r VNC c l i e n t s .32 ∗ To use , c r ea t e a RFBProto ob j e c t , then s t i c k i t in a thread .33 ∗ This may use a mono−threaded implementation , due to problems34 ∗ in Nokia phones .35 ∗ I t a l s o i n c l u d e s many hacks and workarounds f o r none−complement36 ∗ mobi le phones , t h i s has made i t l e s s s u i t a b l e f o r37 ∗ @author Michael Lloyd Lee38 ∗ @version 1 . 0 . 039 ∗ @licence GPL40 ∗/4142 public class RFBProto implements Runnable {4344 /∗∗ Cl ient−Server even t s .45 ∗ In the mono−threaded implementation , i n s t ead o f data be ing sen t s t r a i g h t46 ∗ to the server , each item i s p laced in the event queue , and during the47 ∗ main threads execut ion , i t empt ies the queue , sending the data to the48 ∗ s e r v e r .

141

49 ∗/50 private class Event extends tk . wetnet . u t i l . Queue . QueueEntry {51 /∗∗ The Buf fer ∗/52 private byte [ ] b u f f e r = new byte [ 1 0 ] ;53 /∗∗ The l en g t h o f the data be ing send ∗/54 private int s i z e = 0 ;55 /∗∗ The counter ( curren t item ) ∗/56 private int pc = 0 ;57 }5859 /∗∗ Counts the number o f c l i e n t−s e r v e r communications which shou ld r e s u l t60 ∗ in data re turned from the s e r v e r . This i s then used by the mono−thread61 ∗ implementat ion to determine i f i t shou ld wai t f o r server−c l i e n t62 ∗ communications .63 ∗/64 private int returnDataExpected = 0 ;6566 /∗∗ The c l i e n t−s e r v e r event queue .67 ∗ @see RFBProto . Event68 ∗/69 private Queue eventQueue = null ;7071 /∗∗ The c l i e n t−s e r v e r queue cashe , t h i s i s used to reduce memory72 ∗ a l l o c a t i o n s .73 ∗ @see RFBProto . Event74 ∗ @see RFBProto . eventQueue75 ∗/76 private Queue eventQueueCashe = null ;7778 /∗∗ The se r v e r has sen t the no auth r equ i r ed r ep l y .79 ∗ @value 180 ∗ @category Auth81 ∗/82 private stat ic f ina l int NO_AUTH = 1 ;8384 /∗∗ The se r v e r has sen t the normal auth r equ i r ed r ep l y .85 ∗ @value 286 ∗ @category Auth87 ∗/88 private stat ic f ina l int NORMAL_AUTH = 2 ;8990 /∗∗ Can the desk top be shared ∗/91 private boolean sharedFlag ;9293 /∗∗ The input stream ∗/94 public DataInputStream s in ;95 /∗∗ The output stream ∗/96 public OutputStream sout ;97

142

98 /∗∗ The X ( he i g h t ) o f the screen ∗/99 public int x ;100 /∗∗ The Y ( width ) o f the screen ∗/101 public int y ;102103 /∗∗ The " screen " o b j e c t to send draw r e qu e s t s104 ∗ @see DrawToable105 ∗ @example h t t p :// cvs . s f . net / v iewcvs . py/ j2mevnc/VNC/ src / t k /wetnet106 /j2me/vnc/VNCCanvas . java ? view=markup107 ∗/108 private DrawToable drawOnMe = null ;109110 /∗∗ The desk tops name ∗/111 public St r ing desktopName ;112113 /∗∗ I s the RFBProto cu r r en t l y running ∗/114 public volat i le boolean running = fa l se ;115116 /∗∗ I s Nokia Combatab i t i ty mode (mono−threaded ) enab led ∗/117 private boolean ncm ;118119 /∗∗ The password to send in a normal auth120 ∗ @see NORMAL_AUTH121 ∗ @category Auth122 ∗/123 private byte [ ] key ;124125 /∗∗ Creates a RFB Protoca l o b j e c t .126 ∗ @param s in The input stream to use127 ∗ @param sout the output stream to use128 ∗ @param key The password , i f you are not e xpec t i n g to need a password129 ∗ i t may be nu l l .130 ∗ @param d The o b j e c t i n t e r e s t e d in r e c e i v i n g updates .131 ∗ @param ncm Nokia Compa t i b i l i t y Mode132 ∗/133 public RFBProto ( DataInputStream sin , OutputStream sout ,134 byte [ ] key , DrawToable d , boolean sharedFlag ,135 boolean ncm) {136 //#i f d e f DEBUG137 ////VNC. l o g ( "RFBProto . c r ea t e " ) ;138 //#end i f139 this . s i n = s i n ;140 //#i f d e f DEBUG141 //VNC. l o g ( "RFBProto . c r ea t e s in " ) ;142 //#end i f143 this . sout = sout ;144 //#i f d e f DEBUG145 //VNC. l o g ( "RFBProto . c r ea t e sout " ) ;146 //#end i f

143

147148 this . key = key ;149150 //#i f d e f DEBUG151 //VNC. l o g ( "RFBP. c r ea t e ncm" + ncm ) ;152 //#end i f153154 this . drawOnMe = d ;155 this . sharedFlag = sharedFlag ;156 this . ncm = ncm ;157 eventQueueCashe = new Queue ( ) ;158 i f ( ncm ) {159 //#i f d e f DEBUG160 //VNC. l o g ( " c r ea t i n g event queue" ) ;161 //#end i f162 eventQueue = new Queue ( ) ;163 for ( int i = 0 ; i <5; i++){164 eventQueueCashe . push ( new Event ( ) ) ;165 }166 }167 }168169 /∗∗ F i l l s the array wi th b y t e s from the input stream .170 ∗ @param b The Array to ho ld the input171 ∗ @throws Throwable Any excep t i on s thrown by in . read ()172 ∗ @see java . io . InputStream . read ()173 ∗ @todo Sort out e x c ep t i on s ( on ly throws r e l e v an t ones )174 ∗ @note Ev i l Hack f o r Moto phones175 ∗/176 private void readFul ly ( byte [ ] b ) throws IOException {177 readFul ly ( b , b . l ength ) ;178 }179180 /∗∗ Reads b l number o f b y t e s from the input stream , and puts them i t b181 ∗ @param b The Array to ho ld the input182 ∗ @param b l The number o f b y t e s to read .183 ∗ @throws IOException Any excep t i on s thrown by in . read ()184 ∗ @see java . io . InputStream . read ()185 ∗ @todo Sort out e x c ep t i on s ( on ly throws r e l e v an t ones )186 ∗ @note Ev i l Hack f o r Moto phones187 ∗/188 private void readFul ly ( byte [ ] b , int bl ) throws IOException {189 for ( int i = 0 ; i < bl ; i++ ) {190 b [ i ] = (byte ) s i n . read ( ) ;191 }192 }193194 /∗∗ Send i n i t a l i z a t i o n data to the VNC ser ve r195 ∗ This reads the ve r s i on sen t from the s e r v e r

144

196 ∗ Sends our ve r s i on code .197 ∗ Authen t i ca t e s us ( i f a p p l i c a b l e )198 ∗ reads the p i x e l format ( which i t i gnore s ) , and the s e r v e r name199 ∗ Sends the p i x e l format we can understand back .200 ∗201 ∗ @throws java . lang . IOException Any excep t i on s from in . read/out . wr i t e .202 ∗ @returns t rue i f i t i n i t s OK, f a l s e i f not .203 ∗/204 private boolean i n i t ( ) throws IOException{205 //#i f d e f DEBUG206 //VNC. l o g ( " i n i t " ) ;207 //#end i f208 byte [ ] h i = new byte [ 1 2 ] ;209 for ( int i = 0 ; i <12; i++) {210 h i [ i ] = (byte ) s i n . read ( ) ;211 }212 St r ing hiS = new St r ing ( h i ) ;213 //#i f d e f DEBUG214 //# VNC. l o g ( hiS ) ;215 //#end i f216 i f ( ! ( h i [ 0 ] == 'R ' && hi [ 1 ] == 'F ' && hi [ 2 ] == 'B ' ) ) {217 drawOnMe . e r r o r ( "Not a VNC Server ! " ) ;218 return fa l se ;219 }220 //#i f d e f DEBUG221 //# VNC. l o g ( "Writing Version" ) ;222 //#end i f223224 sout . wr i t e ( 0x52 ) ;225 sout . wr i t e ( 0x46 ) ;226 sout . wr i t e ( 0x42 ) ;227 sout . wr i t e ( 0x20 ) ;228 sout . wr i t e ( 0x30 ) ;229 sout . wr i t e ( 0x30 ) ;230 sout . wr i t e ( 0x33 ) ;231 sout . wr i t e ( 0x2e ) ;232 sout . wr i t e ( 0x30 ) ;233 sout . wr i t e ( 0x30 ) ;234 sout . wr i t e ( 0x33 ) ;235 sout . wr i t e ( 0x0a ) ;236237 //#i f d e f DEBUG238 //# VNC. l o g ( "F lush ing Version" ) ;239 //#end i f240 sout . f l u s h ( ) ;241 //#i f d e f DEBUG242 //# VNC. l o g ( "Waiting f o r AUTH" ) ;243 //#end i f244 int c = readCard32 ( ) ;

145

245 //#i f d e f DEBUG246 //# VNC. l o g ( "AUTH:" + c ) ;247 //#end i f248249 drawOnMe . incConnect ionStatus ( ) ;250251 switch ( c ) {252 case NO_AUTH:253 //#i f d e f DEBUG254 //# VNC. l o g ( "NO_AUTH" ) ;255 //#end i f256 break ;257 case NORMAL_AUTH:258 //#i f d e f DEBUG259 //# VNC. l o g ( "NORMAL_AUTH" ) ;260 //#end i f261 byte [ ] f c = new byte [ 1 6 ] ;262263 readFul ly ( f c ) ;264265 //#i f d e f DEBUG266 //# VNC. l o g ( " des ing " ) ;267 //#end i f268 DesCipher des =269 new DesCipher ( key ) ;270 des . encrypt ( fc , 0 , fc , 0 ) ;271 des . encrypt ( fc , 8 , fc , 8 ) ;272 key = null ;273 des = null ;274 //#i f d e f DEBUG275 //# VNC. l o g ( " de s s ing done" ) ;276 //#end i f277 sout . wr i t e ( f c ) ;278 sout . f l u s h ( ) ;279 int authResult = readCard32 ( ) ;280 //#i f d e f DEBUG281 //# VNC. l o g ( "Password :" + authResu l t ) ;282 //#end i f283 i f ( authResult != 0) {284 drawOnMe . e r r o r ( "Password In c o r r e c t " ) ;285 return fa l se ;286 }287288 break ;289 default :290 byte [ ] reason = new byte [ readCard32 ( ) ] ;291 readFul ly ( reason ) ;292 St r ing s t r i n g = new St r ing ( reason ) ;293 //#i f d e f DEBUG

146

294 //# VNC. l o g ( "Connection Refused\n" + s t r i n g ) ;295 //#end i f296 drawOnMe . e r r o r ( "Connection Refused\n" + s t r i n g ) ;297 return fa l se ;298 }299 drawOnMe . incConnect ionStatus ( ) ;300 // share f l a g301 Event e = a l l o c a t e ( 1 ) ;302 writeCard8 ( e , ( sharedFlag ? 1 : 0 ) ) ;303 f l u s h ( e ) ;304 //#i f d e f DEBUG305 //# VNC. l o g ( "Shared f l a g sen t " ) ;306 //#end i f307308 x = readCard16 ( ) ;309 y = readCard16 ( ) ;310311 /∗ The f o l l ow i n g i s the p i x e l format , which312 ∗ I cou ld not care l e s s about .313 ∗ I w i l l t e l l t he s e r v e r to use my format ∗/314 readCard8 ( ) ; // bpp315 readCard8 ( ) ; // depth316317 readCard8 ( ) ; // b i g endian318 readCard8 ( ) ; // t ru e co l ou r319320 readCard16 ( ) ; // Max − red321 readCard16 ( ) ; // green322 readCard16 ( ) ; // b l ue323 readCard8 ( ) ; // s h i f t − red324 readCard8 ( ) ; // green325 readCard8 ( ) ; // b l ue326327 // Padding328 readCard8 ( ) ; readCard8 ( ) ; readCard8 ( ) ;329 //#i f d e f DEBUG330 //# VNC. l o g ( "Read Colour i n f o " ) ;331 //#end i f332333 byte [ ] name = new byte [ readCard32 ( ) ] ;334 readFul ly (name ) ;335 desktopName = new St r ing (name ) ;336337 //#i f d e f DEBUG338 //# VNC. l o g ( desktopName ) ;339 //#end i f340341 drawOnMe . incConnect ionStatus ( ) ;342

147

343 // see , cou ld not care l e s s ;−)344 setDefaultSupportedPixe lFormat ( ) ;345 drawOnMe . incConnect ionStatus ( ) ;346 setDe fau l tEncod ings ( ) ;347348 //#i f d e f DEBUG349 //# VNC. l o g ( " i n i t−end" ) ;350 //#end i f351352 return true ;353 }354355 /∗∗ The thread running t h i s ∗/356 private Thread me = null ;357358 /∗∗ The run method which i s executed in i t s own thread by the359 ∗ c rea to r .360 ∗ The thread l i f e −c y c l e i s :361 ∗ @stage 0 I n i t i a l i z e the Server ({@see i n i t ( )} )362 ∗ @stage 1 t e l l s the DrawOnMe o b j e c t t h a t we have connected OK, and i t can363 ∗ s t a r t sending c l i e n t−s e r v e r commands364 ∗ @stage 2 I f i t s in the mono−threaded mode , wai t u n t i l we have data to365 ∗ send , then send i t366 ∗ @stage 3 Else Read (& b l o c k ) a server−c l i e n t command , and dea l wi th i t .367 ∗ @stage 4 re turn to s t a g e 2368 ∗ @todo Redo the IOException handing369 ∗/370 public void run ( ) {371 me = Thread . currentThread ( ) ;372 //#i f d e f DEBUG373 //# VNC. l o g ( "run s t a r t e d " ) ;374 //#end i f375 try {376 i f ( ! i n i t ( ) )377 return ;378 } catch ( IOException t ) {379 // t h i s . pwd = nu l l ;380 drawOnMe . e r r o r ( "Problem Connection To VNC Server . \ n"381 + t ) ;382 return ;383 }384 int code = 0 ;385 running = true ;386 drawOnMe . ready ( ) ;387 try {388 while ( running ) {389 i f ( ncm ) {390 while ( running && eventQueue . isEmpty ( )391 && returnDataExpected <= 0 ) {

148

392 Thread . y i e l d ( ) ;393 }394395 // do out going even t s396 while ( ! eventQueue . isEmpty ( ) && running ) {397 Event e = (Event ) eventQueue . pop ( ) ;398399 i f ( e != null ) {400 //#i f d e f DEBUG401 //# VNC. l o g ( " sending event : " + e . s i z e ) ;402 //#end i f403 for ( int i = 0 ; i<e . s i z e ; i++ ) {404 sout . wr i t e ( e . bu f f e r [ i ] ) ;405 }406 // sout . wr i t e ( e . bu f f e r , 0 , e . s i z e −1 ) ;407 sout . f l u s h ( ) ;408 eventQueueCashe . push ( e ) ;409 } else {410 //#i f d e f DEBUG411 //# VNC. l o g ( "EventQueue == " + eventQueue . isEmpty ( ) ) ;412 //#end i f413 }414 }415 }416 //#i f d e f DEBUG417 //# VNC. l o g ( " check incoming even t s " ) ;418 //#end i f419420 // check incoming even t s421 code = readCard8 ( ) ;422 //#i f d e f DEBUG423 //# VNC. l o g ( "CODE:" + code ) ;424 //#end i f425 switch ( code ) {426 case COMMAND_CODE_REPAINT: update ( ) ;427 returnDataExpected−−;428 break ;429 case COMMAND_CODE_BELL: drawOnMe . r i n gBe l l ( ) ; break ;430 case COMMAND_CODE_CUT: serverCutText ( ) ; break ;431432433 //Recebeu as t a s k s434 case COMMAND_CODE_TASKS:435 drawOnMe . showTasks ( se rverRece iveTasks ( ) ) ; break ;436437 //Recebeu o r e su l t a do da execução de uma ta s k438 case COMMAND_CODE_TASK_EXECUTED:439 drawOnMe . message ( rece iveTaskReturn ( ) ) ; break ;440

149

441442 default :443 drawOnMe . e r r o r ( " Server Sent Unknown Command! Command: "444 + code ) ;445 running = fa l se ;446 break ;447 }448 }449 } catch ( IOException t ) {450 drawOnMe . e r r o r ( " r fb . run : t : " + t ) ;451 }452 }453454 /∗∗ Received a r e que s t from the VNC ser ve r to r epa in t455 ∗ {@value 0}456 ∗/457 private stat ic f ina l int COMMAND_CODE_REPAINT = 0 ;458 /∗∗ Received a r e que s t from the VNC ser ve r to r ing the b e l l459 ∗ {@value 2}460 ∗/461 private stat ic f ina l int COMMAND_CODE_BELL = 2 ;462 /∗∗ Received a r e que s t from the VNC ser ve r t ha t the463 ∗ s e r v e r s c l i p b oa rd has changed464 ∗ {@value 3}465 ∗/466 private stat ic f ina l int COMMAND_CODE_CUT = 3 ;467468 private stat ic f ina l int COMMAND_CODE_TASKS = 4 ;469470 private stat ic f ina l int COMMAND_CODE_TASK_EXECUTED = 5 ;471472 /∗ The encodings ∗/473 private stat ic f ina l int RAW_ENCODING = 0 ;474 private stat ic f ina l int COPY_RECT_ENCODING = 1 ;475 private stat ic f ina l int RRE_ENCODING = 2 ;476 private stat ic f ina l int CORRE_ENCODING = 4 ;477 private stat ic f ina l int HEXTILE_ENCODING = 5 ;478479 /∗ The sub encodings f o r h e x i t i l e ∗/480 private stat ic f ina l int RAW_SUB_ENCODING = 1 ;481 private stat ic f ina l int BG_SUB_ENCODING = 2 ;482 private stat ic f ina l int FG_SUB_ENCODING = 4 ;483 private stat ic f ina l int AS_SUB_ENCODING = 8 ;484 private stat ic f ina l int SC_SUB_ENCODING = 16 ;485486487 private void rawEncoding ( int mx, int my, int w, int h )488 throws IOException {489 //#i f d e f DEBUG

150

490 //# VNC. l o g ( "rawEncoding s t a r t " ) ;491 //#end i f492 int p i x e l = 0 ;493 for ( int cy = 0 ; cy < h ; cy++) {494 for ( int cx = 0 ; cx < w; cx++) {495 p i x e l = readCard8 ( ) ;496 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 ,497 ( p i x e l >>3 &7) ∗ 36 ,498 ( p i x e l >>6 &3) ∗ 85 ,499 mx+cx , my + cy , 1 , 1 ) ;500 }501 }502 //#i f d e f DEBUG503 //# VNC. l o g ( "rawEncoding end" ) ;504 //#end i f505 }506507 private void rreEncoding ( int mx, int my, int w, int h )508 throws IOException {509 //#i f d e f DEBUG510 //# VNC. l o g ( " rreEncoding S ta r t " ) ;511 //#end i f512 int noRects = readCard32 ( ) ;513 //#i f d e f DEBUG514 //# VNC. l o g ( "rawEncoding noRects − " + noRects ) ;515 //#end i f516 // Draw background517 int p i x e l = readCard8 ( ) ;518 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,519 ( p i x e l >>6 &3) ∗ 85 , mx, my, w, h ) ;520 int l x ;521 int l y ;522 int lw ;523 int lh ;524 // draw inner−r e c t s525 for ( int r = 0 ; r<noRects ; r++ ) {526 p i x e l = readCard8 ( ) ;527 lx = readCard16 ( ) ;528 ly = readCard16 ( ) ;529 lw = readCard16 ( ) ;530 lh = readCard16 ( ) ;531 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,532 ( p i x e l >>6 &3) ∗ 85 , mx + lx , my + ly ,533 lw , lh ) ;534 }535 //#i f d e f DEBUG536 //# VNC. l o g ( " rreEncoding End" ) ;537 //#end i f538 }

151

539540 private void correEncoding ( int mx, int my, int w, int h )541 throws IOException {542 //#i f d e f DEBUG543 //# VNC. l o g ( " correEncoding S ta r t " ) ;544 //#end i f545 int noRects = readCard32 ( ) ;546547 //#i f d e f DEBUG548 //# VNC. l o g ( " correEncoding noRects − " + noRects ) ;549 //#end i f550551 int p i x e l = readCard8 ( ) ;552 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,553 ( p i x e l >>6 &3) ∗ 85 , mx, my, w, h ) ;554 int l x ;555 int l y ;556 int lw ;557 int lh ;558 for ( int r = 0 ; r<noRects ; r++ ) {559 p i x e l = readCard8 ( ) ;560 lx = readCard8 ( ) ;561 ly = readCard8 ( ) ;562 lw = readCard8 ( ) ;563 lh = readCard8 ( ) ;564 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,565 ( p i x e l >>6 &3) ∗ 85 , mx + lx , my + ly ,566 lw , lh ) ;567 }568 //#i f d e f DEBUG569 //# VNC. l o g ( " correEncoding End" ) ;570 //#end i f571 }572573 private void copyRectEncoding ( int mx, int my, int w, int h )574 throws IOException {575 //#i f d e f DEBUG576 //# VNC. l o g ( "copyRectEncoding S ta r t " ) ;577 //#end i f578 int l x = readCard16 ( ) ;579 int l y = readCard16 ( ) ;580 drawOnMe . copyRect ( my, mx, w, h , lx , l y ) ;581 //#i f d e f DEBUG582 //# VNC. l o g ( "copyRectEncoding End" ) ;583 //#end i f584 }585586 private void hexEncoding ( int mx, int my, int w, int h )587 throws IOException {

152

588 //#i f d e f DEBUG589 //# VNC. l o g ( "hexEncoding S ta r t " ) ;590 //#end i f591592 int rows = w / 16 ;593 int sparew = 16 ;594 i f ( w != ( rows ∗ 16 ) ) {595 rows++;596 sparew = 16 − ( ( rows ∗ 16) − w) ;597 }598 int c o l s = h / 16 ;599 int spareh = 16 ;600 i f ( h != ( c o l s ∗ 16 ) ) {601 c o l s++;602 spareh = 16 − ( ( c o l s ∗ 16) − h ) ;603 }604605 //#i f d e f DEBUG606 //# VNC. l o g ( "hexEncoding w " + w + " h" + h + " rows " + rows + " sparew " + sparew + " co l s " + co l s + " spareh " + spareh ) ;607 //#end i f608609 int l x ;610 int l y ;611 int sub ;612 int bg = 0 ;613 int f g = 0 ;614 for ( int c = 0 ; c<c o l s ; c++ ){615 for ( int r = 0 ; r<rows ; r++ ){616 sub = readCard8 ( ) ;617 lx = ( r==rows−1?sparew :16 ) ;618 ly = ( c==co l s −1?spareh :16 ) ;619620 i f ( ( sub & RAW_SUB_ENCODING ) != 0 ) {621 rawEncoding ( mx + ( r ∗16) , my + ( c ∗16) , lx , l y ) ;622 /∗ f o r ( i n t cy = 0; cy < l y ; cy++) {623 f o r ( i n t cx = 0; cx < l x ; cx++) {624 i n t p i x e l = readCard8 ( ) ;625 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 ,626 ( p i x e l >>3 &7) ∗ 36 ,627 ( p i x e l >>6 &3) ∗ 85 ,628 mx + ( r ∗16) + cx ,629 my + ( c ∗16) + cy ,630 1 , 1 ) ;631 }632 }∗/633 } else {634 i f ( ( sub & BG_SUB_ENCODING ) != 0 ) {635 bg = readCard8 ( ) ;636 }

153

637 i f ( ( sub & FG_SUB_ENCODING ) != 0 ) {638 fg = readCard8 ( ) ;639 }640 drawOnMe . draw ( ( bg >>0 &7) ∗ 36 ,641 ( bg >>3 &7) ∗ 36 ,642 ( bg >>6 &3) ∗ 85 ,643 mx+(r ∗16) , my + ( c ∗16) , lx , l y ) ;644 boolean eachRectColoured = ( ( sub645 & SC_SUB_ENCODING )646 != 0 ) ;647 i f ( ( sub & AS_SUB_ENCODING ) != 0 ) {648 int p i x e l = fg ;649 int noRects = readCard8 ( ) ;650651 int xY;652 int hW;653 int tx ;654 int ty ;655 int tw ;656 int th ;657 for ( int loop = 0 ; loop<noRects ; loop++ ) {658 i f ( eachRectColoured ) p i x e l = readCard8 ( ) ;659 xY = readCard8 ( ) ;660 hW = readCard8 ( ) ;661 tx = xY >> 4 ;662 ty = xY & 0 xf ;663 tw = (hW >> 4) + 1 ;664 th = (hW & 0xf ) + 1 ;665 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 ,666 ( p i x e l >>3 &7) ∗ 36 ,667 ( p i x e l >>6 &3) ∗ 85 ,668 mx + ( r ∗16) + tx ,669 my + ( c ∗16) + ty ,670 tw , th ) ;671 }672 }673 }674 }675 }676 //#i f d e f DEBUG677 //# VNC. l o g ( "hexEncoding End" ) ;678 //#end i f679 }680681 /∗∗ An update r e que s t as been r e c e i v ed .682 ∗ @throws java . land . IOException from InputStream . read683 ∗/684 private void update ( ) throws IOException {685 //#i f d e f DEBUG

154

686 //# VNC. l o g ( "update S t a r t " ) ;687 //#end i f688689 drawOnMe . startUpdate ( ) ;690 readCard8 ( ) ; // padding691 int noOfRects = readCard16 ( ) ;692 //#i f d e f DEBUG693 //# VNC. l o g ( "Update noOfRects − " + noOfRects ) ;694 //#end i f695696 int mx, my, w, h , e ;697 for ( int i = 0 ; i < noOfRects ; i++) {698 // //VNC. l o g ( " r e c t " + i ) ;699 mx = readCard16 ( ) ; // The o f f s e t x700 my = readCard16 ( ) ; // The o f f s e t y701 w = readCard16 ( ) ; // The width o f the update702 h = readCard16 ( ) ; // The he i g h t o f the update703 e = readCard32 ( ) ; // The encoding to use/704705706 switch ( e ) {707 case RAW_ENCODING:708 rawEncoding ( mx, my, w, h ) ;709 break ;710 case RRE_ENCODING:711 rreEncoding ( mx, my, w, h ) ;712 break ;713 case CORRE_ENCODING:714 correEncoding ( mx, my, w, h ) ;715 break ;716 case COPY_RECT_ENCODING:717 copyRectEncoding ( mx, my, w, h ) ;718 break ;719 case HEXTILE_ENCODING:720 hexEncoding ( mx, my, w, h ) ;721 break ;722 default :723 drawOnMe . e r r o r ( " Server Sent Unknown Encoding ! Update : "724 + e ) ;725 running = fa l se ;726 break ;727 }728 }729 drawOnMe . endUpdate ( ) ;730 //#i f d e f DEBUG731 //# VNC. l o g ( "update End" ) ;732 //#end i f733 }734

155

735 /∗∗ Ei ther g e t s an Event from the event cashe , or c r ea t e s a new one736 ∗ @see eventQueueCashe737 ∗ @param s i z e The s i z e o f the event738 ∗ @returns a new Event .739 ∗ @throws I l l e ga lArgumentExcep t ion i f s i z e g r ea t e r than ten .740 ∗/741 private Event a l l o c a t e ( int s i z e ) {742 ////# VNC. l o g ( " a l l o c a t e " ) ;743 i f ( s i z e > 10 ) {744 throw new I l l ega lArgumentExcept ion ( " a l l o c a t e " ) ;745 }746 Event e = (Event ) eventQueueCashe . pop ( ) ;747 i f ( e == null ) {748 e = new Event ( ) ;749 }750 e . s i z e = s i z e ;751 e . pc = 0 ;752 ////VNC. l o g ( " a l l o c a t e d " + e . s i z e ) ;753 return e ;754 }755756 /∗∗ Move the mouse757 ∗ @param x The X l o c a t i o n to move the mouse too758 ∗ @param y the Y l o c a t i o n to move the mouse too759 ∗ @param but The bu t tons s t a t u s .760 ∗/761 public void mouse ( int x , int y , int but )762 throws IOException{763 Event e = a l l o c a t e ( 6 ) ;764 writeCard8 ( e , 5 ) ;765 writeCard8 ( e , but ) ;766 writeCard16 ( e , x ) ;767 writeCard16 ( e , y ) ;768 f l u s h ( e ) ;769 }770771 /∗∗ The VNC Server has a new c l i p b oa rd772 ∗ @todo Unnull i t .773 ∗/774 private void serverCutText ( )775 throws IOException {776 //#i f d e f DEBUG777 //# VNC. l o g ( " serverCutText S t a r t " ) ;778 //#end i f779 readCard8 ( ) ; readCard8 ( ) ; readCard8 ( ) ; // Padding780781 for ( int i = readCard32 ( ) ; i >0; i−−) {782 readCard8 ( ) ;783 }

156

784 //#i f d e f DEBUG785 //# VNC. l o g ( " serverCutText End" ) ;786 //#end i f787 }788789 /∗∗790 ∗ @author G i l b e r t o Torrezan Fi lho791 ∗/792 private St r ing [ ] s e rverRece iveTasks ( ) throws IOException{793 System . out . p r i n t l n ( "Recebendo ta sk s . . . " ) ;794 int noOfTasks = readCard16 ( ) ; // l e o número de t a s k s cadas t radas795 System . out . p r i n t l n ( "No . de ta sk s : "+noOfTasks ) ;796797 St r ing [ ] t a sk s = new St r ing [ noOfTasks ] ;798799 for ( int i =0; i< noOfTasks ; i++){800 //cada ta s k deverá po s su i r uma S t r ing que a descreva801 int noOfChars = readCard16 ( ) ; // l e o número de l e t r a s da S t r ing802803 S t r i ngBu f f e r bu f f = new St r i ngBu f f e r ( ) ;804 for ( int j = 0 ; j< noOfChars ; j++){805 bu f f . append ( ( char ) readCard16 ( ) ) ; //monta a S t r ing de cada ta s k806 }807 ta sk s [ i ] = bu f f . t oS t r i ng ( ) ;808 System . out . p r i n t l n ( "Tarefa "+i+" : "+tasks [ i ] ) ;809 }810811 return ta sk s ;812 }813814 /∗∗815 ∗ @author G i l b e r t o Torrezan Fi lho816 ∗/817 public void requestTasks ( ) throws IOException{818 Event e = a l l o c a t e ( 1 ) ;819 writeCard8 ( e , 129 ) ; //129 , cód igo da t a r e f a820 f l u s h ( e ) ;821 }822823 /∗∗824 ∗ @author G i l b e r t o Torrezan Fi lho825 ∗/826 public void executeTask ( int id ) throws IOException{827 Event e = a l l o c a t e ( 3 ) ;828 writeCard8 ( e , 130 ) ; //130 , cód igo da t a r e f a829 writeCard16 ( e , id ) ;830 f l u s h ( e ) ;831 }832

157

833 /∗∗834 ∗ @author G i l b e r t o Torrezan Fi lho835 ∗/836 public St r ing rece iveTaskReturn ( ) throws IOException{837 System . out . p r i n t l n ( "Recebendo re to rno de task . . . " ) ;838 readCard8 ( ) ; // l e o t i p o da ta s k executada839 int noOfChars = readCard16 ( ) ; // l e o número de l e t r a s da S t r ing de re torno840841 S t r i ngBu f f e r bu f f = new St r i ngBu f f e r ( ) ;842 for ( int i = 0 ; i< noOfChars ; i++){843 bu f f . append ( ( char ) readCard16 ( ) ) ; //monta a S t r ing844 }845 St r ing s = bu f f . t oS t r i ng ( ) ;846847 System . out . p r i n t l n ( s ) ;848849 return s ;850 }851852 /∗∗ Send a s t r i n g to the VNC serve r .853 ∗ @param va lue The s t r i n g to send .854 ∗/855 public void s endStr ing ( S t r ing value )856 throws IOException {857 byte [ ] s t r = value . getBytes ( ) ;858 for ( int i = 0 ; i<s t r . l ength ; i++){859 key ( ( int ) s t r [ i ] , true ) ;860 key ( ( int ) s t r [ i ] , fa l se ) ;861 }862 }863864 /∗∗ Sends a s i n g l e key event to the s e r v e r865 ∗ @param keyCode The key866 ∗ @param down I f the key has gone down ( t rue ) or up ( f a l s e )867 ∗/868 public void key ( int keyCode , boolean down )869 throws IOException {870 Event e = a l l o c a t e ( 8 ) ;871 writeCard8 ( e , 4 ) ; // Message Type872 writeCard8 ( e , (down?1 : 0 ) ) ;873 writeCard16 ( e , 0 ) ; // Padding874 writeCard32 ( e , keyCode ) ;875 f l u s h ( e ) ;876 }877878 /∗∗ Request t ha t the VNC serv e r sends you an update o f the screen .879 ∗ @param x The x o f f s e t .880 ∗ @param y The y o f f s e t .881 ∗ @param w The width o f the r e c t an g l e .

158

882 ∗ @param h The he i g h t o f the r e c t an g l e .883 ∗ @param incrementa l Should the s e r v e r assume the c l i e n t knows what i s884 ∗ cu r r en t l y on the screen885 ∗/886 public void requestUpdate ( int x , int y , int w, int h ,887 boolean inc rementa l ) throws IOException{888 ////VNC. l o g ( " reques tUpdate " ) ;889 Event e = a l l o c a t e ( 10 ) ;890 writeCard8 ( e , 3 ) ;891 writeCard8 ( e , ( incrementa l ? 1 : 0 ) ) ;892 writeCard16 ( e , x ) ;893 writeCard16 ( e , y ) ;894 writeCard16 ( e , w ) ;895 writeCard16 ( e , h ) ;896 f l u s h ( e ) ;897 returnDataExpected++;898 ////VNC. l o g ( " requestUpdated " ) ;899 }900901 /∗∗ Se t s the d e f a u l t supported p i x e l format902 ∗ This implementat ion only suppor t s on p i x e l format903 ∗ t h i s i s i t .904 ∗ @todo depreca ted and suppor t o ther p i x e l formats905 ∗/906 private void setDefaultSupportedPixe lFormat ( )907 throws IOException{908 ////VNC. l o g ( " se tDe fau l tSuppor tedPixe lFormat " ) ;909 Event e = a l l o c a t e ( 8 ) ;910 writeCard8 ( e , 0 ) ; // msg type911 writeCard8 ( e , 0 ) ; // padding912 writeCard8 ( e , 0 ) ; // padding913 writeCard8 ( e , 0 ) ; // padding914 writeCard8 ( e , 8 ) ;915 writeCard8 ( e , 8 ) ;916 writeCard8 ( e , 0 ) ;917 writeCard8 ( e , 1 ) ;918 f l u s h ( e ) ;919 e = a l l o c a t e ( 9 ) ;920 writeCard16 ( e , 7 ) ;921 writeCard16 ( e , 7 ) ;922 writeCard16 ( e , 3 ) ;923 writeCard8 ( e , 0 ) ;924 writeCard8 ( e , 3 ) ;925 writeCard8 ( e , 6 ) ;926 f l u s h ( e ) ;927 e = a l l o c a t e ( 3 ) ;928 writeCard8 ( e , 0 ) ;929 writeCard8 ( e , 0 ) ;930 writeCard8 ( e , 0 ) ;

159

931 f l u s h ( e ) ;932 }933934935 /∗∗936 ∗ Se t s the d e f a u l t encodings , i t does not by d e f a u l t use937 ∗ copy rec t , as I don ' t t r u s t my implementat ion .938 ∗ @todo Deprecated , and a l l ow the c r ea to r to choose what i s and i s not939 ∗ suppor ted .940 ∗/941 private void se tDe fau l tEncod ings ( ) throws IOException{942 ////VNC. l o g ( " se tDe fau l tEncod ings " ) ;943 Event e = a l l o c a t e ( 8 ) ;944 writeCard8 ( e , 2 ) ; // Msg type945 writeCard8 ( e , 0 ) ; // padding946 writeCard16 ( e , 3 ) ; // number o f encodings947 writeCard32 ( e , HEXTILE_ENCODING ) ;948 f l u s h ( e ) ;949950 e = a l l o c a t e ( 8 ) ;951 writeCard32 ( e , CORRE_ENCODING ) ;952 writeCard32 ( e , RRE_ENCODING ) ;953 f l u s h ( e ) ;954 /∗ removed , to save sending data over955 e = a l l o c a t e ( 4 ) ;956 writeCard32 ( e , RAW_ENCODING ) ;957 f l u s h ( e ) ; ∗/958 }959960 /∗∗ Writes a 32 b i t card as de f ined by the RFB Protoca l to the b u f f e r961 ∗ ready to be f l u s h e d ∗/962 private void writeCard32 ( Event e , int v ) {963 e . bu f f e r [ e . pc++ ] = (byte ) ( ( v & 0 xf f000000 ) >>> 24 ) ;964 e . bu f f e r [ e . pc++ ] = (byte ) ( ( v & 0 x00 f f0000 ) >>> 16 ) ;965 e . bu f f e r [ e . pc++ ] = (byte ) ( ( v & 0 x0000 f f00 ) >>> 8 ) ;966 e . bu f f e r [ e . pc++ ] = (byte ) ( v & 0 x000000 f f ) ;967 }968969 /∗∗ Writes a 16 b i t card as de f ined by the RFB Protoca l to the b u f f e r970 ∗ ready to be f l u s h e d ∗/971 private void writeCard16 ( Event e , int v ) {972 e . bu f f e r [ e . pc++ ] = (byte ) ( ( v & 0 x0000 f f00 ) >>> 8 ) ;973 e . bu f f e r [ e . pc++ ] = (byte ) ( v & 0 x000000 f f ) ;974 }975976 /∗∗ Writes a 8 b i t card as de f ined by the RFB Protoca l to the b u f f e r977 ∗ ready to be f l u s h e d ∗/978 private void writeCard8 ( Event e , int v ) {979 e . bu f f e r [ e . pc++ ] = (byte ) ( v & 0 x f f ) ;

160

980 }981982 /∗∗ Flushes the b u f f e r to the VNC Server ∗/983 private void f l u s h ( Event e ) throws IOException {984 i f ( Thread . currentThread ( ) == me | | ! ncm ) {985 //VNC. l o g ( " f lushedCT" ) ;986 for ( int i = 0 ; i<e . s i z e ; i++ ) {987 sout . wr i t e ( e . bu f f e r [ i ] ) ;988 }989 // sout . wr i t e ( e . bu f f e r , 0 , e . s i z e −1 ) ;990 sout . f l u s h ( ) ;991 eventQueueCashe . push ( e ) ;992 } else {993 //VNC. l o g ( " f l u s h e d " + e . s i z e + " " + eventQueue . s i z e ( ) ) ;994 eventQueue . push ( e ) ;995 }996 }997998 /∗∗ Reads a 8 b i t card as de f ined by the RFB Protoca l ∗/999 private int readCard8 ( ) throws IOException{1000 return ( (byte ) s i n . read ( ) & 0 x f f ) ;1001 }10021003 /∗∗ Reads a 16 b i t card as de f ined by the RFB Protoca l ∗/1004 private int readCard16 ( ) throws IOException{1005 return ( ( (byte ) s i n . read ( ) << 8 ) & 0 x f f 0 0 )1006 | ( (byte ) s i n . read ( ) & 0 x00 f f ) ;1007 }10081009 /∗∗ Reads a 32 b i t card as de f ined by the RFB Protoca l ∗/1010 private int readCard32 ( ) throws IOException {10111012 return ( ( (byte ) s i n . read ( ) << 24 ) & 0 xf f000000 )1013 | ( ( (byte ) s i n . read ( ) << 16 ) & 0 x00 f f0000 )1014 | ( ( (byte ) s i n . read ( ) << 8 ) & 0 x0000 f f00 )1015 | ( (byte ) s i n . read ( ) & 0 x000000 f f ) ;1016 }10171018 }101910201021 // LocalWords : RFBProto eventQueue

161

C.2 Código Fonte do Servidor Bridge

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . vnc ;56 import java . i o . IOException ;7 import java . i o . InputStream ;8 import java . i o . OutputStream ;9 import java . net . ServerSocket ;10 import java . net . Socket ;11 import java . u t i l . Co l l e c t i on ;1213 import u f s c . t c c . s e r v e r . c o n t r o l l e r . TaskExecuter ;14 import u f s c . t c c . s e r v e r . c o n t r o l l e r . TaskValuesContro l l e r ;15 import u f s c . t c c . s e r v e r . c o n t r o l l e r . WaitContro l l e r ;16 import u f s c . t c c . s e r v e r . model .CommandTask ;17 import u f s c . t c c . s e r v e r . model . Connect ionPropert i e s ;18 import u f s c . t c c . s e r v e r . model . ScheduledTask ;19 import u f s c . t c c . s e r v e r . model . Task ;20 import u f s c . t c c . s e r v e r . p e r s i s t e n c e . H ibernateUt i l ;2122 /∗∗23 ∗ @author G i l b e r t o Torrezan Fi lho24 ∗/25 public class BridgeServer {26 private ServerSocket c l i en tToServe rSocke t ;27 private Socket c l i entToServerConnect ion ;28 private Socket serverToCl ientConnect ion ;2930 /∗ The encodings ∗/31 private stat ic f ina l int RAW_ENCODING = 0 ;32 private stat ic f ina l int COPY_RECT_ENCODING = 1 ;33 private stat ic f ina l int RRE_ENCODING = 2 ;34 private stat ic f ina l int CORRE_ENCODING = 4 ;35 private stat ic f ina l int HEXTILE_ENCODING = 5 ;3637 /∗ The sub encodings f o r h e x i t i l e ∗/38 private stat ic f ina l int RAW_SUB_ENCODING = 1 ;39 private stat ic f ina l int BG_SUB_ENCODING = 2 ;40 private stat ic f ina l int FG_SUB_ENCODING = 4 ;41 private stat ic f ina l int AS_SUB_ENCODING = 8 ;42 private stat ic f ina l int SC_SUB_ENCODING = 16 ;434445 private ByteArrayStorage s to rage = new ByteArrayStorage ( ) ;4647 private Cl i en tSc r e enCont r o l l e r drawOnMe = new Cl i en tSc r e enCont r o l l e r ( ) ;

162

4849 private stat ic BridgeServer i n s t anc e ;5051 private BridgeServer ( ){}5253 public void s t a r t ( ){54 new Thread ( ){55 public void run ( ){56 try {57 c l i en tToServe rSocke t =58 new ServerSocket ( In t eg e r . pa r s e In t ( Connect ionPropert i e s . g e t In s tance ( ) . getProperty (59 Connect ionPropert i e s .BRIDGE_PORT) ) ) ;60 serverToCl ientConnect ion =61 new Socket ( Connect ionPropert i e s . g e t In s tance ( ) . getProperty (62 Connect ionPropert i e s .VNC_SERVER_IP) , In t eg e r . pa r s e In t (63 Connect ionPropert i e s . g e t In s tance ( ) . getProperty (64 Connect ionPropert i e s .VNC_SERVER_PORT) ) ) ;65 } catch ( Exception e ) {66 e . pr intStackTrace ( ) ;67 }68 executeCl i entToServer ( ) ;69 }70 } . s t a r t ( ) ;71 }7273 private void executeCl i entToServer ( ){74 InputStream in ;75 OutputStream out ;76 byte [ ] array ;77 int read ;7879 try {80 c l i entToServerConnect ion = c l i en tToServe rSocke t . accept ( ) ;81 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( " C l i en t e VNC conectado : "+c l i entToServerConnect ion . get InetAddress ( ) ) ;82 System . out . p r i n t l n ( "Conectou ! ! ! " ) ;83 new Thread ( ){84 public void run ( ){85 executeServerToCl i ent ( ) ;86 try{87 Br idgeServer . this . c l o s e ( ) ;88 }89 f ina l ly {90 Br idgeServer . this . s t a r t ( ) ;91 }92 }93 } . s t a r t ( ) ;94 new Thread ( ){95 public void run ( ){96 while ( true ){

163

97 processAnswer ( ) ;98 }99 }100 } . s t a r t ( ) ;101 } catch ( IOException e1 ) {102 i f ( ! e1 . getMessage ( ) . equa l s IgnoreCase ( " socke t c l o s ed " ) ){103 e1 . pr intStackTrace ( ) ;104 }105 }106 // wh i l e ( ! serverToCl ientConnect ion . i sC lo s ed ( ) && ! c l i entToServerConnect ion . i sC lo s ed ( ) ){107 try {108 in = serverToCl ientConnect ion . getInputStream ( ) ;109 out = c l i entToServerConnect ion . getOutputStream ( ) ;110111 array = new byte [ 4 0 9 6 ] ;112113 System . out . p r i n t l n ( "Recebendo r e spo s t a s . . . " ) ;114 read = 0 ;115 while ( ( read = in . read ( array ) ) > 0){116 out . wr i t e ( array , 0 , read ) ;117 out . f l u s h ( ) ;118 s to rage . wr i t e ( array , 0 , read ) ;119 System . out . p r i n t l n ( "Resposta enviada ! ! ! " ) ;120 }121122 }123 catch ( Exception e ){124 i f ( e . getMessage ( ) != null && ! e . getMessage ( ) . equa l s IgnoreCase ( " socket i s c l o s ed " ) ){125 e . pr intStackTrace ( ) ;126 }127 return ;128 }129 //}130 }131132 private void executeServerToCl i ent ( ){133 InputStream in ;134 OutputStream out ;135 byte [ ] array ;136 int read ;137 // wh i l e ( ! serverToCl ientConnect ion . i sC lo s ed ( ) && ! c l i entToServerConnect ion . i sC lo s ed ( ) ){138 try {139 in = c l i entToServerConnect ion . getInputStream ( ) ;140 out = serverToCl ientConnect ion . getOutputStream ( ) ;141142 array = new byte [ 4 0 9 6 ] ;143 System . out . p r i n t l n ( "Recebendo comandos . . . " ) ;144 int i dS ta t e = 0 ;145 byte lastRead = 0 ;

164

146147 while ( ( read = in . read ( array ) ) > 0){148 i f ( i dS ta t e > 0 ){149 i f ( read == 2){150 idS ta t e = 0 ;151 int id = ( ( array [ 0 ] << 8 ) & 0 x f f 0 0 ) | ( array [ 1 ] & 0 x00 f f ) ;152 executeTask ( id ) ;153 System . out . p r i n t l n ( "Recebeu id da task . . . " ) ;154 System . out . p r i n t l n ( " Id : "+id ) ;155 }156 else i f ( read == 1){157 i f ( i dS ta t e == 1){158 lastRead = array [ 0 ] ;159 idS ta t e++;160 }161 else {162 idS ta t e = 0 ;163 int id = ( ( lastRead << 8 ) & 0 x f f 0 0 ) | ( array [ 0 ] & 0 x00 f f ) ;164 executeTask ( id ) ;165 System . out . p r i n t l n ( "Recebeu id da task . . . " ) ;166 System . out . p r i n t l n ( " Id : "+id ) ;167 }168 }169 }170 else i f ( read == 1 && ( array [ 0 ] & 0 x f f ) == 129){ //comando para capturar t a s k s171 System . out . p r i n t l n ( "Recebeu comando para capturar ta sk s . . . " ) ;172 writeTasks ( ) ;173 }174 else i f ( read == 1 && ( array [ 0 ] & 0 x f f ) == 130){ // ta s k s e l e c i onada175 System . out . p r i n t l n ( "Recebeu comando para executar task . . . " ) ;176 idS ta t e = 1 ;177 }178 else i f ( read == 3 && ( array [ 0 ] & 0 x f f ) == 130){179 System . out . p r i n t l n ( "Recebeu comando para executar task . . . " ) ;180 int id = ( ( array [ 1 ] << 8 ) & 0 x f f 0 0 ) | ( array [ 2 ] & 0 x00 f f ) ;181 System . out . p r i n t l n ( "Recebeu id da task . . . " ) ;182 System . out . p r i n t l n ( " Id : "+id ) ;183 executeTask ( id ) ;184 idS ta t e = 0 ;185 }186 else {187 out . wr i t e ( array , 0 , read ) ;188 out . f l u s h ( ) ;189 System . out . p r i n t l n ( "Comando enviado ! ! ! " ) ;190 }191 }192 }193 catch ( Exception e ){194 i f ( ! e . getMessage ( ) . equa l s IgnoreCase ( " socke t i s c l o s ed " ) ){

165

195 e . pr intStackTrace ( ) ;196 }197 return ;198 }199 //}200 }201202 public void c l o s e ( ) {203 try {204 c l i entToServerConnect ion . c l o s e ( ) ;205 } catch ( Exception e ) {}206207 try {208 serverToCl ientConnect ion . c l o s e ( ) ;209 } catch ( Exception e ) {}210211 try {212 c l i en tToServe rSocke t . c l o s e ( ) ;213 } catch ( Exception e ) {}214 }215216 public stat ic BridgeServer ge t In s tance ( ){217 i f ( i n s t anc e == null ){218 in s t anc e = new BridgeServer ( ) ;219 }220 return i n s t ance ;221 }222223 private void processAnswer ( ){224 i f ( ( readCard8 ( ) == 0)){ // r ep in t a r ! ! !225 drawOnMe . startUpdate ( ) ;226 readCard8 ( ) ; // padding227 int noOfRects = readCard16 ( ) ;228229 int mx, my, w, h , e ;230 for ( int i = 0 ; i < noOfRects ; i++) {231 mx = readCard16 ( ) ; // The o f f s e t x232 my = readCard16 ( ) ; // The o f f s e t y233 w = readCard16 ( ) ; // The width o f the update234 h = readCard16 ( ) ; // The he i g h t o f the update235 e = readCard32 ( ) ; // The encoding to use/236237238 switch ( e ) {239 case RAW_ENCODING:240 rawEncoding (mx, my, w, h ) ;241 break ;242 case RRE_ENCODING:243 rreEncoding (mx, my, w, h ) ;

166

244 break ;245 case CORRE_ENCODING:246 correEncoding (mx, my, w, h ) ;247 break ;248 case COPY_RECT_ENCODING:249 copyRectEncoding (mx, my, w, h ) ;250 break ;251 case HEXTILE_ENCODING:252 hexEncoding (mx, my, w, h ) ;253 break ;254 default :255 break ;256 }257 }258 drawOnMe . endUpdate ( ) ;259 }260 else {261 s to rage . r e s e t ( ) ;262 }263 }264265 private void rawEncoding ( int mx, int my, int w, int h ) {266267 int p i x e l = 0 ;268 for ( int cy = 0 ; cy < h ; cy++) {269 for ( int cx = 0 ; cx < w; cx++) {270 p i x e l = readCard8 ( ) ;271 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 ,272 ( p i x e l >>3 &7) ∗ 36 ,273 ( p i x e l >>6 &3) ∗ 85 ,274 mx+cx , my + cy , 1 , 1 ) ;275 }276 }277 }278279 private void rreEncoding ( int mx, int my, int w, int h ){280 int noRects = readCard32 ( ) ;281282 int p i x e l = readCard8 ( ) ;283 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,284 ( p i x e l >>6 &3) ∗ 85 , mx, my, w, h ) ;285 int l x ;286 int l y ;287 int lw ;288 int lh ;289 for ( int r = 0 ; r<noRects ; r++ ) {290 p i x e l = readCard8 ( ) ;291 lx = readCard16 ( ) ;292 ly = readCard16 ( ) ;

167

293 lw = readCard16 ( ) ;294 lh = readCard16 ( ) ;295 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,296 ( p i x e l >>6 &3) ∗ 85 , mx + lx , my + ly ,297 lw , lh ) ;298 }299 }300301 private void correEncoding ( int mx, int my, int w, int h ){302 int noRects = readCard32 ( ) ;303304305 int p i x e l = readCard8 ( ) ;306 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,307 ( p i x e l >>6 &3) ∗ 85 , mx, my, w, h ) ;308 int l x ;309 int l y ;310 int lw ;311 int lh ;312 for ( int r = 0 ; r<noRects ; r++ ) {313 p i x e l = readCard8 ( ) ;314 lx = readCard8 ( ) ;315 ly = readCard8 ( ) ;316 lw = readCard8 ( ) ;317 lh = readCard8 ( ) ;318 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 , ( p i x e l >>3 &7) ∗ 36 ,319 ( p i x e l >>6 &3) ∗ 85 , mx + lx , my + ly ,320 lw , lh ) ;321 }322 }323324 private void copyRectEncoding ( int mx, int my, int w, int h ){325 int l x = readCard16 ( ) ;326 int l y = readCard16 ( ) ;327 drawOnMe . copyRect ( my, mx, w, h , lx , l y ) ;328 }329330 private void hexEncoding ( int mx, int my, int w, int h ){331332 int rows = w / 16 ;333 int sparew = 16 ;334 i f ( w != ( rows ∗ 16 ) ) {335 rows++;336 sparew = 16 − ( ( rows ∗ 16) − w) ;337 }338 int c o l s = h / 16 ;339 int spareh = 16 ;340 i f ( h != ( c o l s ∗ 16 ) ) {341 c o l s++;

168

342 spareh = 16 − ( ( c o l s ∗ 16) − h ) ;343 }344 int l x ;345 int l y ;346 int sub ;347 int bg = 0 ;348 int f g = 0 ;349 for ( int c = 0 ; c<c o l s ; c++ ){350 for ( int r = 0 ; r<rows ; r++ ){351 sub = readCard8 ( ) ;352 lx = ( r==rows−1?sparew :16 ) ;353 ly = ( c==co l s −1?spareh :16 ) ;354355 i f ( ( sub & RAW_SUB_ENCODING ) != 0 ) {356 rawEncoding (mx + ( r ∗16) , my + ( c ∗16) , lx , l y ) ;357 } else {358 i f ( ( sub & BG_SUB_ENCODING ) != 0 ) {359 bg = readCard8 ( ) ;360 }361 i f ( ( sub & FG_SUB_ENCODING ) != 0 ) {362 fg = readCard8 ( ) ;363 }364 drawOnMe . draw ( ( bg >>0 &7) ∗ 36 ,365 ( bg >>3 &7) ∗ 36 ,366 ( bg >>6 &3) ∗ 85 ,367 mx+(r ∗16) , my + ( c ∗16) , lx , l y ) ;368 boolean eachRectColoured = ( ( sub369 & SC_SUB_ENCODING )370 != 0 ) ;371 i f ( ( sub & AS_SUB_ENCODING ) != 0 ) {372 int p i x e l = fg ;373 int noRects = readCard8 ( ) ;374375 int xY;376 int hW;377 int tx ;378 int ty ;379 int tw ;380 int th ;381 for ( int loop = 0 ; loop<noRects ; loop++ ) {382 i f ( eachRectColoured ) p i x e l = readCard8 ( ) ;383 xY = readCard8 ( ) ;384 hW = readCard8 ( ) ;385 tx = xY >> 4 ;386 ty = xY & 0 xf ;387 tw = (hW >> 4) + 1 ;388 th = (hW & 0xf ) + 1 ;389 drawOnMe . draw ( ( p i x e l >>0 &7) ∗ 36 ,390 ( p i x e l >>3 &7) ∗ 36 ,

169

391 ( p i x e l >>6 &3) ∗ 85 ,392 mx + ( r ∗16) + tx ,393 my + ( c ∗16) + ty ,394 tw , th ) ;395 }396 }397 }398 }399 }400 }401402 private void writeTasks ( ) throws IOException{403 Co l l e c t i on<Task> tasks = HibernateUt i l . getTaskDAO ( ) . getTasks ( ) ;404 i f ( ta sk s . s i z e ( ) > 0){405 St r ing [ ] s s = new St r ing [ ta sk s . s i z e ( ) ] ;406 int i = 0 ;407 for (Task t : t a sk s ){408 s s [ i++] = t . get Id ()+"− "+t . getName()+" ( "+t . g e tDe s c r i p t i on ()+" ) " ;409 }410 OutputStream out = c l i entToServerConnect ion . getOutputStream ( ) ;411 byte [ ] b = writeCard8 ( 4 ) ;412 out . wr i t e (b ) ;413 out . f l u s h ( ) ;414 b = writeCard16 ( s s . l ength ) ;415 out . wr i t e (b ) ;416 out . f l u s h ( ) ;417 for ( S t r ing s : s s ){418 b = writeCard16 ( s . l ength ( ) ) ;419 out . wr i t e (b ) ;420 out . f l u s h ( ) ;421 char [ ] c s = s . toCharArray ( ) ;422 for ( i = 0 ; i< cs . l ength ; i++){423 b = writeCard16 ( cs [ i ] ) ;424 out . wr i t e (b ) ;425 out . f l u s h ( ) ;426 }427 }428 }429 }430431 private void executeTask ( int id ) throws IOException{432 Co l l e c t i on<Task> tasks = HibernateUt i l . getTaskDAO ( ) . getTasks ( ) ;433 i f ( ta sk s . s i z e ( ) > 0){434 Task task = null ;435 for (Task t : t a sk s ){ // procura pe l a t a s k cujo id s e j a o s e l e c i onado436 i f ( t . ge t Id ( ) == id ){437 task = t ;438 break ;439 }

170

440 }441 i f ( task == null ){442 return ;443 }444 OutputStream out = c l i entToServerConnect ion . getOutputStream ( ) ;445 St r ing r e t S t r i n g ;446 byte [ ] b = writeCard8 ( 5 ) ; // n o t i f i c a o c l i e n t de que a ta s k e s t á pra i r447 out . wr i t e (b ) ;448 out . f l u s h ( ) ;449 i f ( task instanceof CommandTask){450 b = writeCard8 ( 0 ) ; // código de command ta s k451 out . wr i t e (b ) ;452 out . f l u s h ( ) ;453 CommandTask t = (CommandTask) task ;454 r e t S t r i n g = TaskExecuter . g e t In s tance ( ) . execute ( t ) ; // executa a task , e pega o re torno455456 }457 else {458 writeCard8 ( 1 ) ; // código de schedu l ed t a s k459 out . wr i t e (b ) ;460 out . f l u s h ( ) ;461 ScheduledTask t = ( ScheduledTask ) task ;462 r e t S t r i n g = TaskValuesContro l l e r . ge tCa lcu latedValues ( t ) ; // c a l c u l a as e s t a t í s t i c a s da ta s k463 }464465 b = writeCard16 ( r e t S t r i n g . l ength ( ) ) ; // esc reve o tamanho da s t r i n g466 out . wr i t e (b ) ;467 out . f l u s h ( ) ;468 char [ ] c = r e t S t r i n g . toCharArray ( ) ;469 for ( int i = 0 ; i< c . l ength ; i++){ // esc reve a s t r i n g de re torno470 b = writeCard16 ( c [ i ] ) ;471 out . wr i t e (b ) ;472 out . f l u s h ( ) ;473 }474 }475 }476477 private int readCard8 ( ){478 return ( s t o rage . readNext ( ) & 0 x f f ) ;479 }480481 private int readCard16 ( ) {482 return ( ( s t o rage . readNext ( ) << 8 ) & 0 x f f 0 0 )483 | ( s t o rage . readNext ( ) & 0 x00 f f ) ;484 }485486 private int readCard32 ( ) {487 return ( ( s t o rage . readNext ( ) << 24 ) & 0 xf f000000 )488 | ( ( s t o rage . readNext ( ) << 16 ) & 0 x00 f f0000 )

171

489 | ( ( s t o rage . readNext ( ) << 8 ) & 0 x0000 f f00 )490 | ( s t o rage . readNext ( ) & 0 x000000 f f ) ;491 }492493 @SuppressWarnings ( "unused" )494 private byte [ ] writeCard32 ( int v ) {495 byte [ ] b u f f e r = new byte [ 4 ] ;496 bu f f e r [ 0 ] = (byte ) ( ( v & 0 xf f000000 ) >>> 24 ) ;497 bu f f e r [ 1 ] = (byte ) ( ( v & 0 x00 f f0000 ) >>> 16 ) ;498 bu f f e r [ 2 ] = (byte ) ( ( v & 0 x0000 f f00 ) >>> 8 ) ;499 bu f f e r [ 3 ] = (byte ) ( v & 0 x000000 f f ) ;500 return bu f f e r ;501 }502503 private byte [ ] writeCard16 ( int v ) {504 byte [ ] b u f f e r = new byte [ 2 ] ;505 bu f f e r [ 0 ] = (byte ) ( ( v & 0 x0000 f f00 ) >>> 8 ) ;506 bu f f e r [ 1 ] = (byte ) ( v & 0 x000000 f f ) ;507 return bu f f e r ;508 }509510 private byte [ ] writeCard8 ( int v ) {511 byte [ ] b u f f e r = new byte [ 1 ] ;512 bu f f e r [ 0 ] = (byte ) ( v & 0 x f f ) ;513 return bu f f e r ;514 }515516 }

172

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i ;56 import java . awt . BorderLayout ;7 import java . awt . Dimension ;8 import java . awt . Frame ;9 import java . awt . event . ActionEvent ;10 import java . awt . event . Act i onL i s t ene r ;1112 import javax . swing . Box ;13 import javax . swing . BoxLayout ;14 import javax . swing . JButton ;15 import javax . swing . JDialog ;16 import javax . swing . JLabel ;17 import javax . swing . JPanel ;18 import javax . swing . JSpinner ;19 import javax . swing . JTextFie ld ;20 import javax . swing . SpinnerNumberModel ;2122 import u f s c . t c c . s e r v e r . c o n t r o l l e r . vnc . Br idgeServer ;23 import u f s c . t c c . s e r v e r . model . Connect ionPropert i e s ;2425 /∗∗26 ∗ @author G i l b e r t o Torrezan Fi lho27 ∗/28 public class BridgeServerDia log extends JDialog {2930 private JPanel31 panel = new JPanel ( ) ,32 down = new JPanel ( ) ;3334 private JLabel35 ipLabe l = new JLabel ( "IP : " ) ,36 portLabe l = new JLabel ( "Porta : " ) ,37 br idgePortLabe l = new JLabel ( "Porta Local : " ) ;3839 private JTextFie ld40 ip = new JTextFie ld ( ) ;4142 private JSpinner43 br idgePort = new JSpinner (new SpinnerNumberModel (5900 ,0 , 65535 ,1 ) ) ,44 port = new JSpinner (new SpinnerNumberModel ( 5900 , 0 , 65535 , 1 ) ) ;4546 private JButton47 ok = new JButton ( "Ok" ) ,48 cance l = new JButton ( "Cancelar " ) ;49

173

50 public BridgeServerDia log (Frame owner ){51 super ( owner , "Conf iguração do s e r v i d o r VNC" , true ) ;52 se tDe fau l tC lo seOperat ion ( JDialog .DISPOSE_ON_CLOSE) ;53 pack ( ) ;54 s e t S i z e ( 300 , 200 ) ;55 se tLocat ionRe lat iveTo ( null ) ;56 s e tRe s i z ab l e ( fa l se ) ;5758 this . getContentPane ( ) . setLayout (new BorderLayout ( ) ) ;59 this . getContentPane ( ) . add ( panel , BorderLayout .CENTER) ;60 this . getContentPane ( ) . add (down , BorderLayout .SOUTH) ;6162 down . add ( ok ) ;63 down . add ( cance l ) ;6465 JPanel [ ] ps = new JPanel [ 3 ] ;6667 panel . setLayout (new BoxLayout ( panel , BoxLayout .Y_AXIS) ) ;6869 for ( int i = 0 ; i< ps . l ength ; i++){70 ps [ i ] = new JPanel ( ) ;71 ps [ i ] . setLayout (new BoxLayout ( ps [ i ] , BoxLayout .X_AXIS) ) ;72 ps [ i ] . add (Box . c r e a t eHo r i z on ta l S t ru t ( 1 5 ) ) ;73 panel . add ( ps [ i ] ) ;74 }7576 ps [ 0 ] . add ( ipLabe l ) ;77 ps [ 0 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;78 ps [ 0 ] . add ( ip ) ;79 ps [ 0 ] . add (Box . c r e a t eHo r i z on ta l S t ru t ( 1 5 ) ) ;8081 ps [ 1 ] . add ( portLabe l ) ;82 ps [ 1 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;83 ps [ 1 ] . add ( port ) ;84 ps [ 1 ] . add (Box . c r e a t eHo r i z on ta l S t ru t ( 1 5 ) ) ;8586 ps [ 2 ] . add ( br idgePortLabe l ) ;87 ps [ 2 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;88 ps [ 2 ] . add ( br idgePort ) ;89 ps [ 2 ] . add (Box . c r e a t eHo r i z on ta l S t ru t ( 1 5 ) ) ;9091 Dimension d = new Dimension ( 120 , 2 2 ) ;92 ok . s e tP r e f e r r e dS i z e (d ) ;93 cance l . s e tP r e f e r r e dS i z e (d ) ;9495 d = new Dimension ( 150 , 2 2 ) ;96 ipLabe l . s e tP r e f e r r e dS i z e (d ) ;97 portLabe l . s e tP r e f e r r e dS i z e (d ) ;98 br idgePortLabe l . s e tP r e f e r r e dS i z e (d ) ;

174

99100 d = new Dimension ( 120 , 2 2 ) ;101 ip . s e tP r e f e r r e dS i z e (d ) ;102 port . s e tP r e f e r r e dS i z e (d ) ;103 br idgePort . s e tP r e f e r r e dS i z e (d ) ;104105 ip . setMaximumSize (d ) ;106 port . setMaximumSize (d ) ;107 br idgePort . setMaximumSize (d ) ;108109 cance l . addAct ionListener (new Act ionL i s t ene r ( ){110 public void act ionPerformed ( ActionEvent e ) {111 s e tV i s i b l e ( fa l se ) ;112 d i spo s e ( ) ;113 }114 } ) ;115 ok . addAct ionListener (new Act ionL i s t ene r ( ){116 public void act ionPerformed ( ActionEvent e ) {117 try {118 Connect ionPropert i e s props = Connect ionPropert i e s . g e t In s tance ( ) ;119 props . put ( Connect ionPropert i e s .VNC_SERVER_IP, ip . getText ( ) ) ;120 props . put ( Connect ionPropert i e s .VNC_SERVER_PORT, port . getValue ( ) . t oS t r i ng ( ) ) ;121 props . put ( Connect ionPropert i e s .BRIDGE_PORT, br idgePort . getValue ( ) . t oS t r i ng ( ) ) ;122 props . save ( ) ;123 Br idgeServer . g e t In s tance ( ) . c l o s e ( ) ;124 Br idgeServer . g e t In s tance ( ) . s t a r t ( ) ;125 }126 catch ( Exception e1 ) {127 e1 . pr intStackTrace ( ) ;128 }129 f ina l ly {130 s e tV i s i b l e ( fa l se ) ;131 d i spo s e ( ) ;132 }133 }134 } ) ;135 }136137 @Override138 public void s e tV i s i b l e (boolean b) {139 i f (b){140 try {141 Connect ionPropert i e s props = Connect ionPropert i e s . g e t In s tance ( ) ;142 props . load ( ) ;143 ip . setText ( props . getProperty ( Connect ionPropert i e s .VNC_SERVER_IP) ) ;144 port . setValue ( In t eg e r . pa r s e In t ( props . getProperty ( Connect ionPropert i e s .VNC_SERVER_PORT) ) ) ;145 br idgePort . setValue ( In t eg e r . pa r s e In t ( props . getProperty ( Connect ionPropert i e s .BRIDGE_PORT) ) ) ;146 }147 catch ( Exception e ){

175

148 e . pr intStackTrace ( ) ;149 }150 }151 super . s e tV i s i b l e (b ) ;152 }153154155 }

176

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . vnc ;56 import java . u t i l . ArrayList ;7 import java . u t i l . L i s t ;89 /∗∗10 ∗ @author G i l b e r t o Torrezan Fi lho11 ∗/12 public class ByteArrayStorage {13 private List<Byte> l i s t = new ArrayList<Byte >() ;1415 public synchronized void wr i t e (byte [ ] array , int index , int l ength ){16 byte [ ] des t = new byte [ l ength ] ;17 System . arraycopy ( array , index , dest , 0 , l ength ) ;18 for ( int i = 0 ; i< dest . l ength ; i++){19 l i s t . add ( dest [ i ] ) ;20 }21 n o t i f yA l l ( ) ;22 }2324 public synchronized byte readNext ( ){25 while ( l i s t . isEmpty ( ) ) {26 try {27 wait ( ) ;28 }29 catch ( Inter ruptedExcept ion e ) {30 e . pr intStackTrace ( ) ;31 }32 }33 byte b = l i s t . remove ( 0 ) ;34 return b ;35 }3637 public synchronized void r e s e t ( ){38 l i s t . c l e a r ( ) ;39 }40 }

177

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r ;56 import java . awt . Color ;7 import java . awt . GradientPaint ;8 import java . t ex t . DateFormat ;9 import java . t ex t . SimpleDateFormat ;10 import java . u t i l . Date ;11 import java . u t i l . L i s t ;1213 import org . j f r e e . chart . ChartFactory ;14 import org . j f r e e . chart . JFreeChart ;15 import org . j f r e e . chart . p l o t . CategoryPlot ;16 import org . j f r e e . chart . p l o t . P lo tOr i enta t i on ;17 import org . j f r e e . data . category . DefaultCategoryDataset ;18 import org . j f r e e . data . g ene ra l . De fau l tPieDataset ;1920 import u f s c . t c c . s e r v e r . model . TaskValue ;2122 /∗∗23 ∗ @author G i l b e r t o Torrezan Fi lho24 ∗/25 public class ChartContro l l e r {26 public stat ic f ina l int

27 TYPE_LINE = 0 ,28 TYPE_BARS = 1 ,29 TYPE_PIE = 2 ;3031 public stat ic JFreeChart createChart ( Li s t<TaskValue> values , int type ){32 switch ( type ){33 case TYPE_LINE:34 return createLineChart ( va lue s ) ;35 case TYPE_BARS:36 return createBarChart ( va lue s ) ;37 case TYPE_PIE:38 return createPieChart ( va lue s ) ;39 }40 return null ;41 }4243 public stat ic JFreeChart createLineChart ( Li s t<TaskValue> va lue s ){44 DateFormat format = SimpleDateFormat . getDateTimeInstance ( ) ;45 DefaultCategoryDataset data = new DefaultCategoryDataset ( ) ;4647 for ( TaskValue t : va lue s ){48 St r ing parse = format . format (new Date ( t . getDateTime ( ) ) ) ;49 data . addValue ( t . getValue ( ) , "" , parse ) ;

178

50 }5152 JFreeChart chart = ChartFactory . c reateLineChart ( va lue s . get ( 0 ) . getTask ( ) . getName ( ) ,53 "Horár ios " , "Valores " , data , P lo tOr i enta t i on .VERTICAL, false , true , true ) ;5455 chart . setBackgroundPaint ( Color .WHITE) ;56 ( ( CategoryPlot ) ( chart . ge tP lo t ( ) ) ) . getRenderer ( ) . s e t S e r i e sPa i n t (0 ,new GradientPaint (0 ,600 ,new Color ( 0 , 255 , 0 ) , 0 , 0 ,new Color ( 1 8 0 , 0 , 0 ) ) ) ;5758 return chart ;59 }6061 public stat ic JFreeChart createBarChart ( Li s t<TaskValue> va lues ){62 DateFormat format = SimpleDateFormat . getDateTimeInstance ( ) ;63 DefaultCategoryDataset data = new DefaultCategoryDataset ( ) ;6465 for ( TaskValue t : va lue s ){66 St r ing parse = format . format (new Date ( t . getDateTime ( ) ) ) ;67 data . addValue ( t . getValue ( ) , "" , parse ) ;68 }69 JFreeChart chart = ChartFactory . createBarChart3D ( va lue s . get ( 0 ) . getTask ( ) . getName ( ) ,70 "Horár ios " , "Valores " , data , P lo tOr i enta t i on .HORIZONTAL, false , true , true ) ;71 chart . setBackgroundPaint ( Color .WHITE) ;72 ( ( CategoryPlot ) ( chart . ge tP lo t ( ) ) ) . getRenderer ( ) . s e t S e r i e sPa i n t (0 ,new GradientPaint (0 , 0 ,new Color (0 , 255 , 0 ) , 800 , 0 ,new Color ( 1 8 0 , 0 , 0 ) ) ) ;7374 return chart ;75 }7677 public stat ic JFreeChart createPieChart ( Li s t<TaskValue> va lue s ){78 DateFormat format = SimpleDateFormat . getDateTimeInstance ( ) ;79 Defau l tPieDataset data = new Defau l tPieDataset ( ) ;8081 for ( TaskValue t : va lue s ){82 St r ing parse = format . format (new Date ( t . getDateTime ( ) ) ) ;83 data . setValue ( parse , t . getValue ( ) ) ;84 }8586 JFreeChart chart = ChartFactory . c reatePieChart ( va lue s . get ( 0 ) . getTask ( ) . getName ( ) ,87 data , false , true , true ) ;88 chart . setBackgroundPaint ( Color .WHITE) ;8990 return chart ;9192 }93 }

179

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . vnc ;56 import java . awt . Color ;7 import java . awt . Graphics2D ;8 import java . awt . image . BufferedImage ;9 import java . i o . F i l e ;10 import java . i o . IOException ;1112 import javax . imageio . ImageIO ;1314 import tk . wetnet . vnc . DrawToable ;1516 /∗∗17 ∗ @author G i l b e r t o Torrezan Fi lho18 ∗/19 public class Cl i en tSc r e enCont r o l l e r implements DrawToable{20 private BufferedImage bu f f ;21 private Graphics2D g2d ;22 private F i l e f i l e ;23 private int screen , ix , i y ;2425 public Cl i en tSc r e enCont r o l l e r ( ){26 f i l e = new F i l e ( " l a s t S c r e en . png" ) ;27 try {28 f i l e . createNewFi le ( ) ;29 }30 catch ( IOException e ) {31 e . pr intStackTrace ( ) ;32 }33 }3435 public void copyRect ( int x , int y , int w, int h , int srcx , int s r cy ) {3637 }3839 public void draw ( int red , int green , int blue , int x , int y , int w, int h) {40 g2d . s e tCo lo r (new Color ( red , green , b lue ) ) ;41 i f ( i x < 0){42 ix = x ;43 iy = y ;44 }45 g2d . f i l l R e c t (x−ix , y−iy , w, h ) ;46 }4748 public void endUpdate ( ) {49 System . out . p r i n t l n(++screen+" − Escrevendo arquivo . . . " ) ;

180

50 try {51 ImageIO . wr i t e ( buf f , "PNG" , f i l e ) ;52 }53 catch ( IOException e ) {54 e . pr intStackTrace ( ) ;55 }56 }5758 public void e r r o r ( S t r ing e r r o r ) {5960 }6162 public void incConnect ionStatus ( ) {6364 }6566 public void ready ( ) {6768 }6970 public void r i n gBe l l ( ) {7172 }7374 public void startUpdate ( ) {75 bu f f = new BufferedImage (350 ,400 , BufferedImage .TYPE_INT_RGB) ;76 g2d = bu f f . c r eateGraph ic s ( ) ;77 ix = −1;78 }79 }

181

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r ;56 import u f s c . t c c . s e r v e r . c o n t r o l l e r . vnc . Br idgeServer ;7 import u f s c . t c c . s e r v e r . p e r s i s t e n c e . H ibernateUt i l ;89 /∗∗10 ∗ @author G i l b e r t o Torrezan Fi lho11 ∗/12 public class Ex i tCont ro l l e r {13 private Ex i tCont ro l l e r ( ) { } ;1415 public stat ic void e x i t ( int code ){16 try {17 Br idgeServer . g e t In s tance ( ) . c l o s e ( ) ;18 HibernateUt i l . c l o s e ( ) ;19 }20 catch ( Exception e ){21 e . pr intStackTrace ( ) ;22 }23 f ina l ly {24 System . e x i t ( code ) ;25 }26 }27 }

182

1 package u f s c . t c c . s e r v e r . gu i . tablemodel ;23 import java . u t i l . Co l l e c t i on ;4 import java . u t i l . Comparator ;5 import java . u t i l . L i s t ;6 import java . u t i l . Vector ;78 import javax . swing . t ab l e . AbstractTableModel ;910 public abstract class GenericTableModel<E> extends AbstractTableModel {11 public stat ic f ina l boolean TOP_DOWN = true , BOTTOM_UP = fa l se ;1213 protected int NUM_COLUMNS = 0 ;14 protected int START_NUM_ROWS = 0 ;15 protected int nextEmptyRow = 0 ;16 protected int numRows = 0 ;1718 protected St r ing [ ] columnNames ;1920 protected boolean i n se r t i onType ;2122 protected int l im i t ;2324 protected List<E> data = new Vector<E>() ;2526 public GenericTableModel ( int numStartRows , int l im i t , boolean insert ionType , S t r ing . . . columnNames ){27 this . columnNames = columnNames ;28 NUM_COLUMNS = columnNames . l ength ;29 START_NUM_ROWS = numStartRows ;30 numRows = numStartRows ;31 nextEmptyRow = numRows + 1 ;32 this . l im i t = l im i t ;33 this . i n se r t i onType = inse r t ionType ;34 } ;3536 public GenericTableModel ( Co l l e c t i on<E> col , int l im i t , boolean insert ionType , S t r ing . . . columnNames ){37 this ( c o l . s i z e ( ) , l im i t , insert ionType , columnNames ) ;38 data . addAll ( c o l ) ;39 } ;4041 public GenericTableModel ( int l im i t , boolean insert ionType , S t r ing . . . columnNames ){42 this (0 , l im i t , insert ionType , columnNames ) ;43 } ;4445 public GenericTableModel ( Co l l e c t i on<E> col , S t r ing . . . columnNames ){46 this ( co l , I n t e g e r .MAX_VALUE, TOP_DOWN, columnNames ) ;47 } ;4849 public GenericTableModel ( S t r ing . . . columnNames ){

183

50 this (0 , I n t eg e r .MAX_VALUE, TOP_DOWN, columnNames ) ;51 } ;5253 public St r ing getColumnName( int column ) {54 return columnNames [ column ] ;55 }5657 public int getColumnCount ( ) {58 return NUM_COLUMNS;59 }6061 public int getRowCount ( ) {62 i f (numRows < START_NUM_ROWS) {63 return START_NUM_ROWS;64 }6566 return numRows ;67 }6869 public E [ ] getDataAsArray (E [ ] e ){70 return data . toArray ( e ) ;71 }7273 public List<E> getData ( ){74 return data ;75 }7677 public abstract Object getValueAt ( int row , int column ) ;7879 public E getItemAt ( int row ){80 return data . get ( row ) ;81 }8283 public void updateData (E [ ] item ){84 i f ( item != null && item . l ength > 0 && item . l ength <= l im i t ){85 data . c l e a r ( ) ;86 for (E i : item ){87 data . add ( i ) ;88 }89 numRows = data . s i z e ( ) ;90 nextEmptyRow = numRows + 1 ;91 f i r eTab leRowsInse r ted (0 ,numRows ) ;92 fireTableDataChanged ( ) ;93 }94 else {95 c l e a r ( ) ;96 }97 }98

184

99 public void updateData ( Co l l e c t i on<E> items ){100 c l e a r ( ) ;101 i f ( i tems != null && items . s i z e ( ) > 0 && items . s i z e ( ) <= l im i t ){102 data . addAll ( i tems ) ;103 numRows = data . s i z e ( ) ;104 nextEmptyRow = numRows + 1 ;105 f i r eTab leRowsInse r ted (0 ,numRows ) ;106 fireTableDataChanged ( ) ;107 }108 }109110 public boolean r ep l a c e (E item , Comparator<E> comparator ){111 for ( int i = 0 ; i< data . s i z e ( ) ; i++){112 E elem = data . get ( i ) ;113 i f ( comparator . compare ( elem , item ) == 0){114 data . remove ( i ) ;115 data . add ( i , item ) ;116 fireTableRowsUpdated ( i , i ) ;117 return true ;118 }119 }120 return fa l se ;121 }122123 public void update (E item ){124 for ( int i = 0 ; i< data . s i z e ( ) ; i++){125 E elem = data . get ( i ) ;126 i f ( elem . equa l s ( item )){127 fireTableRowsUpdated ( i , i ) ;128 break ;129 }130 }131 }132133 public void addItem (E item ){134 i f ( item != null ){135 i f ( ! data . conta in s ( item )){136 boolean outOfLimit = ( data . s i z e ( ) > l im i t ) ;137 i f ( outOfLimit ){138 data . remove ( data . s i z e ()−1) ;139 }140 i f ( in se r t i onType ){141 data . add ( item ) ;142 }143 else {144 data . add (0 , item ) ;145 }146 i f ( ! outOfLimit ){147 numRows++;

185

148 nextEmptyRow = numRows + 1 ;149 f i r eTab leRowsInse r ted (numRows , numRows ) ;150 }151 fireTableDataChanged ( ) ;152 /∗ f o r ( i n t i = 0 ; i< data . l e n g t h ; i++){153 numRows++;154 nextEmptyRow++;155 f i r eTab l eRowsInser t ed ( i , i ) ;156 }∗/157 }158 }159 }160161 public void removeItem (E item ){162 i f ( item != null ){163 i f ( data . remove ( item )){164 numRows−−;165 nextEmptyRow = numRows + 1 ;166 f i reTableRowsDeleted (numRows+1,numRows+1);167 fireTableDataChanged ( ) ;168 }169 }170 }171172 public E removeItem ( int row ){173 E r e s u l t = data . remove ( row ) ;174 i f ( r e s u l t != null ){175 numRows−−;176 nextEmptyRow = numRows + 1 ;177 f i reTableRowsDeleted ( row , row ) ;178 fireTableDataChanged ( ) ;179 }180 return r e s u l t ;181 }182183 public int getDataSize ( ){184 return data . s i z e ( ) ;185 }186187 public void c l e a r ( ){188 data . c l e a r ( ) ;189 int oldNumRows = numRows ;190 numRows = 0 ;191 nextEmptyRow = 0 ;192 f i reTableRowsDeleted (0 , oldNumRows ) ;193 fireTableDataChanged ( ) ;194 }195196 public Class<?> getColumnClass ( int c ) {

186

197 return St r ing . class ;198 }199200 public boolean i s I n s e r t i onType ( ) {201 return i n se r t i onType ;202 }203204 public void s e t In s e r t i onType (boolean i n se r t i onType ) {205 this . i n se r t i onType = inse r t ionType ;206 }207208 public int getLimit ( ) {209 return l im i t ;210 }211212 public void s e tL imi t ( int l im i t ) {213 this . l im i t = l im i t ;214 }215216 public St r ing [ ] getColumnNames ( ) {217 return columnNames ;218 }219 }

187

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . u t i l ;56 import java . i o . BufferedInputStream ;7 import java . i o . IOException ;8 import java . i o . InputStream ;910 /∗∗11 ∗ @author g i l b e r t o12 ∗13 ∗/14 public class InputStreamHandler extends Thread {15 private InputStream stream = null ;1617 public InputStreamHandler ( InputStream stream ) {18 super ( "Process Input Stream Handler " ) ;19 setDaemon ( true ) ;20 this . stream = new BufferedInputStream ( stream ) ;21 }2223 /∗∗ Override t h i s method to do something meaningfu l wi th the output . ∗/24 public void handleBytes (byte [ ] buf , int count ) { }2526 // WARNING: c l o s i n g a proces s output stream premature ly may r e s u l t in27 // the Process o b j e c t never d e t e c t i n g i t s t erminat ion !28 private void c l o s e ( ) {29 try { stream . c l o s e ( ) ; }30 catch ( IOException i o ) {31 //Log . debug ( io ) ;32 }33 }3435 public void run ( ) {36 int BUFSIZE = 256 ;37 byte [ ] buf = new byte [BUFSIZE ] ;38 //Log . debug (" Stream reader s t a r t e d " ) ;39 while ( true ) {40 try {41 //Log . debug ("Reading from stream ") ;42 int count = stream . read ( buf , 0 , buf . l ength ) ;43 i f ( count == −1) {44 //Log . debug (" end o f stream ") ;45 break ;46 }47 else i f ( count == 0) {48 //Log . debug ("No input , s l e e p i n g " ) ;49 try { s l e e p ( 1 0 0 ) ; }

188

50 catch ( Inter ruptedExcept ion e ) {51 //Log . debug ( e ) ;52 }53 }54 else i f ( count > 0) {55 //Log . debug ("Got " + count + " by t e s " ) ;56 handleBytes ( buf , count ) ;57 }58 }59 catch ( IOException i o ) {60 // we ' l l g e t t h i s when the stream c l o s e s61 //Log . debug ( io ) ;62 break ;63 }64 }65 c l o s e ( ) ;66 //Log . debug (" stream hand ler t e rmina t ing " ) ;67 }68 }

189

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . u t i l ;56 /∗∗7 ∗ @author g i l b e r t o8 ∗9 ∗/1011 import java . i o . IOException ;12 import java . i o . UnsupportedEncodingException ;13 import java . net . URLEncoder ;14 import java . n io . cha r s e t . Charset ;15 import java . u t i l . ArrayList ;16 import java . u t i l . Arrays ;1718 /∗∗ Mail and browser launcher which augments <code>Runtime . exec ()</code>19 ∗ f unc t i on s . Provides f o r b u i l t−in emai l and web browser suppor t .20 ∗/21 public class Launcher {2223 // TODO: prov ide an array o f known mai l to : hand l e r s24 // f o r now we assume the browsers w i l l make an attempt to handle mai l to :25 private stat ic f ina l St r ing [ ] HTTP = {26 " ga leon " , " konqueror " , " opera " ,27 " f i r e f o x " , "moz i l l a " , " netscape " , "mosaic " ,28 } ;2930 /∗∗ Perform t r i c k e r y to ge t the r i g h t con ten t s in t o the emai l hand ler from31 a mai l to : l i n e .32 ∗ @throws UnsupportedEncodingException33 ∗/34 private stat ic St r ing encodeForMail ( S t r ing base ) throws UnsupportedEncodingException {35 S t r i ngBu f f e r buf = new St r i ngBu f f e r ( base ) ;36 // Avoid URLEncoder . encode f o r spaces ; i t r e p l a c e s them with p l u s37 // s igns , which remain p l u s e s when decoded .38 St r ing SPACE = "−−SPACE−−" ;39 for ( int idx = buf . t oS t r i ng ( ) . indexOf ( " " ) ;40 idx != −1; idx = buf . t oS t r i ng ( ) . indexOf ( " " ) ) {41 buf . r ep l a c e ( idx , idx+1, SPACE) ;42 }43 buf = new St r i ngBu f f e r (URLEncoder . encode ( buf . t oS t r i ng ( ) , Charset . de fau l tChar s e t ( ) . name ( ) ) ) ;44 for ( int idx = buf . t oS t r i ng ( ) . indexOf (SPACE) ;45 idx != −1; idx = buf . t oS t r i ng ( ) . indexOf (SPACE) ) {46 i f ( Platform . isOSX ( ) ) {47 // The "open" command parses spaces48 buf . r ep l a c e ( idx , idx + SPACE. l ength ( ) , "%20" ) ;49 }

190

50 else {51 buf . r ep l a c e ( idx , idx + SPACE. l ength ( ) , " " ) ;52 }53 }54 return buf . t oS t r i ng ( ) ;55 }5657 /∗∗ Format a message to the g iven user wi th the g iven s u b j e c t and message58 body . ∗/59 public stat ic void mail ( S t r ing user , S t r ing subject , S t r ing body )60 throws IOException {61 mail ( user , sub jec t , body , null ) ;62 }63 /∗∗ Format a message to the g iven user wi th the g iven s u b j e c t and message64 body , i n c l u d i n g a CC l i s t . ∗/65 public stat ic void mail ( S t r ing user , S t r ing subject , S t r ing body ,66 St r ing cc ) throws IOException {67 mail ( user , sub jec t , body , cc , null ) ;68 }69 /∗∗ Format a message to the g iven user wi th the g iven s u b j e c t and message70 body , i n c l u d i n g CC and BCC l i s t s . ∗/71 public stat ic void mail ( S t r ing user , S t r ing subject , S t r ing body ,72 St r ing cc , S t r ing bcc ) throws IOException {73 S t r i ngBu f f e r mai l to = new St r i ngBu f f e r ( "mai l to : " + user + "?" ) ;74 i f ( cc != null )75 mai l to . append ( "CC=" + cc + "&" ) ;76 i f ( bcc != null )77 mai l to . append ( "BCC=" + bcc + "&" ) ;7879 mai l to . append ( " Subject=" + encodeForMail ( sub j e c t )80 + "&" + "Body=" + encodeForMail ( body ) + "" ) ;81 open ( mai l to . t oS t r i ng ( ) ) ;82 }8384 /∗∗ Open the g iven t a r g e t URL in the p la t form ' s browser . ∗/85 public stat ic void open ( St r ing t a r g e t ) throws IOException {86 open (null , t a r g e t ) ;87 }8889 /∗∗ Use the g iven command/program to open the g iven t a r g e t . ∗/90 public stat ic void open ( St r ing command , S t r ing t a r g e t ) throws IOException {91 boolean tryBrowsers = fa l se ;92 ArrayList<Str ing> args = new ArrayList<Str ing >() ;93 i f (command != null ) {94 args . add (command ) ;95 }96 else {97 i f ( Platform . isOSX ( ) ) {98 args . add ( "open" ) ;

191

99 }100 else i f ( Platform . isWindows ( ) ) {101 // Probab ly won ' t work r i g h t on win9x102 args . add ( Platform . isWindows9X ( )103 ? "command . com" : "cmd . exe " ) ;104 args . add ( "/c" ) ;105 args . add ( " s t a r t " ) ;106 args . add ( "\" T i t l e \"" ) ;107 // Always quote the argument , j u s t in case108 // See MS docs f o r cmd . exe ; &, | , and () must be escaped wi th109 // ^ or double−quoted . semicolon and comma are command110 // argument separa tors , and probab l y r e qu i r e quo t ing as w e l l .111 ta r g e t = "\"" + ta rg e t + "\"" ;112 }113 else {114 args . add ( " p l a c eho ld e r " ) ;115 tryBrowsers = true ;116 }117 }118 args . add ( t a r g e t ) ;119120 St r ing [ ] cmd = args . toArray (new St r ing [ args . s i z e ( ) ] ) ;121 i f ( ! tryBrowsers ) {122 ProcessOutputHandler . exec (cmd ) ;123 }124 else {125 // TODO: choose the appropr ia t e a p p l i c a t i o n based on the t a r g e t126 // URL format , i n s t ead o f r e l y i n g on browsers to do i t .127 for ( int i =0; i < HTTP. l ength ; i++) {128 try {129 cmd [ 0 ] = HTTP[ i ] ;130 ProcessOutputHandler . exec (cmd ) ;131 return ;132 }133 catch ( IOException e ) {134 // not found , t r y another one135 }136 }137 throw new IOException ( "No ta r g e t handler found ( t r i e d "138 + Arrays . a sL i s t (HTTP) + " ) " ) ;139 }140 }141 }

192

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . main ;56 import java . u t i l . Co l l e c t i on ;78 import javax . swing . UIManager ;910 import u f s c . t c c . s e r v e r . c o n t r o l l e r . QuartzScheduler ;11 import u f s c . t c c . s e r v e r . c o n t r o l l e r . WaitContro l l e r ;12 import u f s c . t c c . s e r v e r . c o n t r o l l e r . vnc . Br idgeServer ;13 import u f s c . t c c . s e r v e r . gu i . MainFrame ;14 import u f s c . t c c . s e r v e r . model . Connect ionPropert i e s ;15 import u f s c . t c c . s e r v e r . model . Task ;16 import u f s c . t c c . s e r v e r . p e r s i s t e n c e . H ibernateUt i l ;1718 import com . b i r o s o f t . l i q u i d . LiquidLookAndFeel ;1920 /∗∗21 ∗ @author G i l b e r t o Torrezan Fi lho22 ∗/23 public class Main {2425 public stat ic void main ( St r ing [ ] a rgs ) {26 try{27 UIManager . setLookAndFeel ( "com . b i r o s o f t . l i q u i d . LiquidLookAndFeel " ) ;28 LiquidLookAndFeel . s e tL iqu idDeco ra t i on s ( true , " panther " ) ;29 }30 catch ( Exception e ){31 e . pr intStackTrace ( ) ;32 }33 f ina l MainFrame frame = MainFrame . ge t In s tance ( ) ;34 WaitContro l l e r . g e t In s tance ( ) . addWaitListener ( frame ) ;35 frame . s e tV i s i b l e ( true ) ;36 new Thread ( ){37 public void run ( ){38 try{39 Connect ionPropert i e s . g e t In s tance ( ) . load ( ) ;40 Co l l e c t i on<Task> tasks = HibernateUt i l . getTaskDAO ( ) . getTasks ( ) ;41 frame . getTaskPanel ( ) . setTasks ( ta sk s ) ;42 QuartzScheduler . schecu leTasks ( ta sk s ) ;43 }44 catch ( Exception e ){45 e . pr intStackTrace ( ) ;46 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Erro ao ac e s s a r t a r e f a s cadast radas . " ) ;47 return ;48 }49 Br idgeServer . g e t In s tance ( ) . s t a r t ( ) ;

193

50 }51 } . s t a r t ( ) ;52 /∗53 // Hibe rna t eUt i l . getTaskDAO ( ) . getTasks ( ) ;54 // Ex i tCon t r o l l e r . e x i t ( 0 ) ;55 l ong t o t a l = SystemInfoFactory . ge tSys temInfo ( ) . getSystemTotalMemory ( ) ;56 l ong used = SystemInfoFactory . ge tSys temInfo ( ) . getUsedMemoryByProcesses ( ) ;57 System . out . p r i n t l n ("Memória : "+ t o t a l ) ;58 i n t p id = SystemInfoFactory . ge tSys temInfo ( ) . getPID (" javaw " ) ;59 System . out . p r i n t l n ("PID : "+pid ) ;60 System . out . p r i n t l n ("Memory Use do PID : "+SystemInfoFactory . ge tSys temInfo ( ) . getUsedVirtualMemory ( pid ) ) ;61 System . out . p r i n t l n (" System f r e e memory : "+( t o t a l − used ) ) ;62 ∗/63 }64 }

194

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i ;56 import java . awt . BorderLayout ;7 import java . awt . event .WindowAdapter ;8 import java . awt . event .WindowEvent ;910 import javax . swing . JFrame ;1112 import u f s c . t c c . s e r v e r . c o n t r o l l e r . Ex i tCont ro l l e r ;13 import u f s c . t c c . s e r v e r . c o n t r o l l e r . TaskExecuter ;14 import u f s c . t c c . s e r v e r . c o n t r o l l e r . l i s t e n e r . WaitListener ;15 import u f s c . t c c . s e r v e r . main . Vers ion ;1617 /∗∗18 ∗ @author G i l b e r t o Torrezan Fi lho19 ∗/20 public class MainFrame extends JFrame implements WaitListener {21 private stat ic MainFrame in s tanc e ;2223 private TaskPanel24 ta sk s = new TaskPanel ( ) ;2526 private WaitPanel27 wait = new WaitPanel ( ) ;2829 private MainFrame ( ){30 super ( Vers ion . getProductName ( ) ) ;31 se tDe fau l tC lo seOperat ion (JFrame .DO_NOTHING_ON_CLOSE) ;32 pack ( ) ;33 s e t S i z e (1024 , 600 ) ;34 se tLocat ionRe lat iveTo ( null ) ;3536 this . getContentPane ( ) . setLayout (new BorderLayout ( ) ) ;37 this . getContentPane ( ) . add ( tasks , BorderLayout .CENTER) ;38 this . getContentPane ( ) . add ( wait , BorderLayout .SOUTH) ;3940 TaskExecuter . g e t In s tance ( ) . addTaskListener ( ta sk s ) ;4142 this . addWindowListener (new WindowAdapter ( ){43 @Override44 public void windowClosing (WindowEvent e ) {45 Ex i tCont ro l l e r . e x i t ( 0 ) ;46 }47 } ) ;48 }49

195

50 public TaskPanel getTaskPanel ( ){51 return ta sk s ;52 }5354 public stat ic MainFrame ge t In s tance ( ){55 i f ( i n s t anc e == null ){56 in s t anc e = new MainFrame ( ) ;57 }58 return i n s t ance ;59 }606162 public void setWait ing ( S t r ing message ) {63 wait . setText ( message ) ;64 }65 }

196

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . u t i l ;56 import java . u t i l . S t r ingToken ize r ;78 /∗∗9 ∗ @author g i l b e r t o10 ∗11 ∗/12 public class Platform {1314 public stat ic f ina l int JAVA_1_0 = 0x1000 ;15 public stat ic f ina l int JAVA_1_1 = 0x1100 ;16 public stat ic f ina l int JAVA_1_2 = 0x1200 ;17 public stat ic f ina l int JAVA_1_3 = 0x1300 ;18 public stat ic f ina l int JAVA_1_4 = 0x1400 ;19 public stat ic f ina l int JAVA_1_5 = 0x1500 ;20 public stat ic f ina l int JAVA_1_6 = 0x1600 ;2122 public stat ic f ina l St r ing OS_NAME;23 public stat ic f ina l St r ing JAVA_VERSION_STRING;24 public stat ic f ina l int JAVA_VERSION;2526 stat ic {27 OS_NAME = System . getProperty ( " os . name" ) ;28 JAVA_VERSION_STRING = System . getProperty ( " java . v e r s i on " ) ;29 JAVA_VERSION = parse (JAVA_VERSION_STRING) ;30 }3132 private stat ic boolean isWindows = OS_NAME. startsWith ( "Windows" ) ;33 private stat ic boolean isWindows9X = isWindows34 && (OS_NAME. indexOf ( "95" ) != −135 | | OS_NAME. indexOf ( "98" ) != −136 | | OS_NAME. indexOf ( "ME" ) != −1);37 private stat ic boolean isWindowsXP = isWindows && OS_NAME. indexOf ( "XP" ) != −1;38 private stat ic boolean isMac = System . getProperty ( "mrj . v e r s i on " ) != null ;39 private stat ic boolean isOSX = isMac && OS_NAME. indexOf ( "OS X" ) != −1;40 private stat ic boolean isSunOS = (OS_NAME. startsWith ( "SunOS" )41 | | OS_NAME. startsWith ( " S o l a r i s " ) ) ;42 private stat ic boolean isHPUX = OS_NAME. equa l s ( "HP−UX" ) ;43 private stat ic boolean i sL inux = OS_NAME. equa l s ( "Linux" ) ;4445 /∗∗ No i n s t a n t i a t i o n s . ∗/46 private Platform ( ) {47 }4849 private stat ic St r ing s t r i p ( S t r ing number ) {

197

50 while ( number . s tartsWith ( "0" ) && number . l ength ( ) > 1)51 number = number . sub s t r i ng ( 1 ) ;52 return number ;53 }5455 stat ic int parse ( S t r ing vs ) {56 int ve r s i on = 0 ;57 try {58 Str ingToken i ze r s t = new Str ingToken ize r ( vs , " ._" ) ;59 ve r s i on = In t eg e r . pa r s e In t ( s t r i p ( s t . nextToken ( ) ) ) ∗ 0x1000 ;60 ve r s i on += Int eg e r . pa r s e In t ( s t r i p ( s t . nextToken ( ) ) ) ∗ 0x100 ;61 ve r s i on += Int eg e r . pa r s e In t ( s t r i p ( s t . nextToken ( ) ) ) ∗ 0x10 ;62 ve r s i on += Int eg e r . pa r s e In t ( s t r i p ( s t . nextToken ( ) ) ) ;63 }64 catch (NumberFormatException nfe ) {65 }66 catch ( java . u t i l . NoSuchElementException nse ) {67 }68 return ve r s i on ;69 }7071 // FIXME t h i s i sn ' t e n t i r e l y correc t , maybe shou ld l ook f o r a mot i f c l a s s72 // in s t ead .73 public stat ic boolean isX11 ( ) { return ! isOSX && ! isWindows ; }74 public stat ic boolean isWindows ( ) { return isWindows ; }75 public stat ic boolean isWindows9X ( ) { return isWindows9X ; }76 public stat ic boolean isWindowsXP ( ) { return isWindowsXP ; }77 public stat ic boolean i sMacintosh ( ) { return isMac ; }78 public stat ic boolean isOSX ( ) { return isOSX ; }79 public stat ic boolean i s S o l a r i s ( ) { return isSunOS ; }80 public stat ic boolean isHPUX() { return isHPUX ; }81 public stat ic boolean i sL inux ( ) { return i sL inux ; }82 /∗ pu b l i c s t a t i c vo id main( S t r ing [ ] args ) {83 System . out . p r i n t l n (" Java ve r s i on i s " + JAVA_VERSION_STRING) ;84 System . out . p r i n t l n (" Version number i s " + In t e g e r . toHexStr ing (JAVA_VERSION) ) ;85 System . out . p r i n t l n (" os . name=" + OS_NAME) ;86 }∗/87 }

198

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . u t i l ;56 import java . i o . F i l e ;7 import java . i o . IOException ;8 import java . u t i l . Arrays ;910 /∗∗11 ∗ @author g i l b e r t o12 ∗13 ∗/14 public class ProcessOutputHandler {1516 public stat ic class ProcessAbnormalExitException extends IOException {17 private int code ;18 private ProcessAbnormalExitException ( St r ing msg , int code ) {19 super (msg ) ;20 this . code = code ;21 }22 public int getExitValue ( ) { return code ; }23 }2425 private InputStreamHandler s t d e r r ;26 private InputStreamHandler stdout ;27 private St r i ngBu f f e r e r r = new St r i ngBu f f e r ( ) ;2829 public ProcessOutputHandler ( ) { }3031 public ProcessOutputHandler ( Process p) {32 s e tProc e s s (p ) ;33 }3435 public St r ing getError ( ) {36 return e r r . t oS t r i ng ( ) ;37 }3839 public synchronized void s e tProc e s s ( Process p) {40 stdout = new InputStreamHandler (p . getInputStream ( ) ) {41 public void handleBytes (byte [ ] buf , int count ) {42 handleOutput ( buf , count ) ;43 }44 } ;45 stdout . s t a r t ( ) ;46 s t d e r r = new InputStreamHandler (p . getErrorStream ( ) ) {47 public void handleBytes (byte [ ] buf , int count ) {48 e r r . append (new St r ing ( buf , 0 , count ) ) ;49 handleError ( buf , count ) ;

199

50 }51 } ;52 s t d e r r . s t a r t ( ) ;53 }5455 /∗∗ Override t h i s method to handle s t dou t output . The d e f a u l t56 implementat ion does noth ing . ∗/57 protected void handleOutput (byte [ ] buf , int count ) { }5859 /∗∗ Override t h i s method to handle s t d e r r output . The d e f a u l t60 implementat ion does noth ing . ∗/61 protected void handleError (byte [ ] buf , int count ) { }6263 public synchronized void waitFor ( ) throws Inte r ruptedExcept ion {64 i f ( s t d e r r != null )65 s t d e r r . j o i n ( ) ;66 i f ( stdout != null )67 stdout . j o i n ( ) ;68 }6970 /∗∗ Returns the output o f the g iven command as a S t r ing . ∗/71 public stat ic St r ing exec ( S t r ing [ ] command)72 throws IOException {73 return exec (command , null ) ;74 }7576 /∗∗ Returns the output o f the g iven command as a S t r ing . ∗/77 public stat ic St r ing exec ( S t r ing [ ] command , S t r ing [ ] environment )78 throws IOException {79 return exec (command , environment , null ) ;80 }8182 /∗∗ Returns the output o f the g iven command as a S t r ing . ∗/83 public stat ic St r ing exec ( S t r ing [ ] command , S t r ing [ ] environment , F i l e d i r )84 throws IOException {85 f ina l St r i ngBu f f e r output = new St r i ngBu f f e r ( ) ;86 //Log . debug ("Running " + Arrays . a sL i s t (command ) ) ;87 Process p = Runtime . getRuntime ( ) . exec (command , environment , d i r ) ;88 ProcessOutputHandler handler = new ProcessOutputHandler (p) {89 public void handleOutput (byte [ ] buf , int count ) {90 output . append (new St r ing ( buf , 0 , count ) ) ;91 }92 } ;93 try { p . waitFor ( ) ; } catch ( Inter ruptedExcept ion e ) {94 //Log . debug ( e ) ;95 }96 try { handler . waitFor ( ) ; } catch ( Inter ruptedExcept ion e ) { }97 int code = p . ex i tVa lue ( ) ;98 i f ( code != 0) {

200

99 St r ing msg = "Process " + Arrays . a sL i s t (command)100 + " ex i t ed with " + code ;101 St r ing e r r = handler . ge tError ( ) ;102 i f ( ! "" . equa l s ( e r r ) )103 msg += " :\ n" + e r r ;104 //Log . debug (msg ) ;105 throw new ProcessAbnormalExitException (msg , code ) ;106 }107 //Log . debug (" output=" + output . t oS t r i n g ( ) ) ;108 return output . t oS t r i ng ( ) ;109 }110 }

201

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r ;56 import java . u t i l . Co l l e c t i on ;78 import org . quartz . CronTrigger ;9 import org . quartz . JobDeta i l ;10 import org . quartz . Scheduler ;11 import org . quartz . impl . StdSchedulerFactory ;1213 import u f s c . t c c . s e r v e r . model . ScheduledTask ;14 import u f s c . t c c . s e r v e r . model . Task ;1516 /∗∗17 ∗ @author G i l b e r t o Torrezan Fi lho18 ∗/19 public class QuartzScheduler {2021 private QuartzScheduler ( ){}2223 public stat ic void schecu leTasks ( Co l l e c t i on<Task> tasks ){24 i f ( ta sk s != null ){25 try {26 Scheduler sched = StdSchedulerFactory . ge tDe fau l tSchedu l e r ( ) ;27 for (Task t : t a sk s ){28 i f ( t instanceof ScheduledTask ){29 ScheduledTask s = ( ScheduledTask ) t ;3031 JobDeta i l j obDe ta i l = new JobDeta i l ( s . ge t Id ()+" − "+s . getName ( ) ,32 Scheduler .DEFAULT_GROUP,33 TaskExecuter . class ) ;34 j obDeta i l . getJobDataMap ( ) . put ( " task " , s ) ;3536 CronTrigger cron = new CronTrigger ( s . ge t Id ()+" − "+s . getName()+" t r i g g e r " , Scheduler .DEFAULT_GROUP, s . getSchedu leExpres s ion ( ) ) ;37 sched . unscheduleJob ( s . ge t Id ()+" − "+s . getName()+" t r i g g e r " , Scheduler .DEFAULT_GROUP) ;38 sched . scheduleJob ( jobDeta i l , cron ) ;39 }40 }41 sched . s t a r t ( ) ;42 sched . resumeAll ( ) ;43 } catch ( Exception e ) {44 e . pr intStackTrace ( ) ;45 }46 }47 }4849 public stat ic void scheculeTask (Task task ){

202

50 i f ( task instanceof ScheduledTask ){51 try{52 Scheduler sched = StdSchedulerFactory . ge tDe fau l tSchedu l e r ( ) ;53 ScheduledTask s = ( ScheduledTask ) task ;5455 JobDeta i l j obDe ta i l = new JobDeta i l ( s . ge t Id ()+" − "+s . getName ( ) ,56 Scheduler .DEFAULT_GROUP,57 TaskExecuter . class ) ;58 j obDe ta i l . getJobDataMap ( ) . put ( " task " , s ) ;5960 CronTrigger cron = new CronTrigger ( s . ge t Id ()+" − "+s . getName()+" t r i g g e r " , Scheduler .DEFAULT_GROUP, s . getSchedu leExpres s ion ( ) ) ;61 sched . unscheduleJob ( s . ge t Id ()+" − "+s . getName()+" t r i g g e r " , Scheduler .DEFAULT_GROUP) ;62 sched . scheduleJob ( jobDeta i l , cron ) ;63 sched . s t a r t ( ) ;64 sched . resumeAll ( ) ;65 }66 catch ( Exception e ){67 e . pr intStackTrace ( ) ;68 }69 }70 }7172 public stat ic void unscheculeTask (Task task ){73 i f ( task instanceof ScheduledTask ){74 try{75 Scheduler sched = StdSchedulerFactory . ge tDe fau l tSchedu l e r ( ) ;76 ScheduledTask s = ( ScheduledTask ) task ;77 sched . unscheduleJob ( s . ge t Id ()+" − "+s . getName()+" t r i g g e r " , Scheduler .DEFAULT_GROUP) ;78 }79 catch ( Exception e ){80 e . pr intStackTrace ( ) ;81 }82 }83 }84 }

203

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . i n f o ;56 /∗∗7 ∗ @author G i l b e r t o Torrezan Fi lho8 ∗/9 public interface SystemInfo {10 public long getUsedMemoryByProcesses ( ) ;11 public long getSystemTotalMemory ( ) ;1213 public long getUsedMemory ( int pid ) ;14 public long getUsedVirtualMemory ( int pid ) ;1516 public long getFreeDiskSpace ( ) ;17 public long getTotalDiskSpace ( ) ;1819 public long getUsedDiskSpace ( S t r ing path ) ;2021 public int getCPUUse ( ) ;22 public int getCPUUse ( int pid ) ;2324 public int getPID ( St r ing processName ) ;25 public St r ing [ ] g e tProce s s e s ( ) ;26 public St r ing [ ] ge tProce s se sTree ( ) ;27 }

204

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . i n f o ;56 /∗∗7 ∗ @author G i l b e r t o Torrezan Fi lho8 ∗/9 public class SystemInfoFactory {10 private stat ic SystemInfo s y s I n f o ;1112 private SystemInfoFactory ( ) { } ;1314 public stat ic SystemInfo getSystemInfo ( ){15 i f ( s y s I n f o == null ){16 sy s I n f o = new SystemInfoImp ( ) ;17 }18 return s y s I n f o ;19 }20 }

205

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . i n f o ;56 import java . i o . BufferedInputStream ;7 import java . i o . F i l e ;8 import java . i o . InputStream ;9 import java . u t i l . ArrayList ;10 import java . u t i l . L i s t ;11 import java . u t i l . S t r ingToken ize r ;1213 import com . j c o n f i g . DiskVolume ;14 import com . j c o n f i g . F i l eReg i s t r y ;15 import com . j c o n f i g . JUt i l s ;1617 /∗∗18 ∗ @author G i l b e r t o Torrezan Fi lho19 ∗/20 public class SystemInfoImp implements SystemInfo {2122 protected stat ic f ina l St r ing path = new F i l e ( " ext " ) . getAbsolutePath ( ) ;2324 protected DiskVolume cur rent ;2526 protected SystemInfoImp (){2728 }2930 public long getUsedMemoryByProcesses ( ) {31 try {32 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\ p s l i s t . exe \" −m" ) ;33 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;3435 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;36 for ( ; ; ) {37 int c = stdoutStream . read ( ) ;38 i f ( c == −1) break ;39 bu f f e r . append ( ( char ) c ) ;40 }41 St r ing out = bu f f e r . t oS t r i ng ( ) ;42 stdoutStream . c l o s e ( ) ;4344 out = out . sub s t r i ng ( out . indexOf ( "Name" ) ) ;4546 Str ingToken i ze r toker = new Str ingToken ize r ( out , "\n" ) ;47 toker . nextToken ( ) ;48 long count = 0 ;49

206

50 while ( toker . hasMoreTokens ( ) ) {51 St r ing s = toker . nextToken ( ) ;52 Str ingToken ize r toker2 = new Str ingToken ize r ( s , " " ) ;53 toker2 . nextToken ( ) ;54 toker2 . nextToken ( ) ;55 toker2 . nextToken ( ) ;56 St r ing s2 = toker2 . nextToken ( ) ;57 count += Long . parseLong ( s2 ) ;58 }5960 return count ;61 } catch ( Exception e ) {62 e . pr intStackTrace ( ) ;63 }64 return −1;65 }6667 public long getSystemTotalMemory ( ) {68 try {69 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\memory . exe \"" ) ;70 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;7172 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;73 for ( ; ; ) {74 int c = stdoutStream . read ( ) ;75 i f ( c == −1) break ;76 bu f f e r . append ( ( char ) c ) ;77 }78 St r ing out = bu f f e r . t oS t r i ng ( ) ;7980 stdoutStream . c l o s e ( ) ;8182 out = out . r ep l a c e ( " Phys i ca l memory i s " , "" ) ;83 out = out . sub s t r i ng (0 , out . indexOf ( " " ) ) ;8485 return Long . parseLong ( out )/1024 ;8687 } catch ( Exception e ) {88 e . pr intStackTrace ( ) ;89 }9091 return −1;92 }9394 public long getUsedMemory ( int pid ) {95 try {96 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\ p s l i s t . exe \" "+pid+" −m" ) ;97 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;98

207

99 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;100 for ( ; ; ) {101 int c = stdoutStream . read ( ) ;102 i f ( c == −1) break ;103 bu f f e r . append ( ( char ) c ) ;104 }105 St r ing out = bu f f e r . t oS t r i ng ( ) ;106 stdoutStream . c l o s e ( ) ;107108 out = out . sub s t r i ng ( out . indexOf ( "Name" ) ) ;109110 Str ingToken i ze r toker = new Str ingToken ize r ( out , "\n" ) ;111 toker . nextToken ( ) ;112113 while ( toker . hasMoreTokens ( ) ) {114 St r ing s = toker . nextToken ( ) ;115 Str ingToken ize r toker2 = new Str ingToken ize r ( s , " " ) ;116 toker2 . nextToken ( ) ;117 toker2 . nextToken ( ) ;118 toker2 . nextToken ( ) ;119 St r ing s2 = toker2 . nextToken ( ) ;120 return Long . parseLong ( s2 ) ;121 }122123 return −1;124 } catch ( Exception e ) {125 e . pr intStackTrace ( ) ;126 }127 return −1;128 }129130 public long getUsedVirtualMemory ( int pid ) {131 try {132 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\ p s l i s t . exe \" "+pid+" −m" ) ;133 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;134135 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;136 for ( ; ; ) {137 int c = stdoutStream . read ( ) ;138 i f ( c == −1) break ;139 bu f f e r . append ( ( char ) c ) ;140 }141 St r ing out = bu f f e r . t oS t r i ng ( ) ;142 stdoutStream . c l o s e ( ) ;143144 out = out . sub s t r i ng ( out . indexOf ( "Name" ) ) ;145146 Str ingToken i ze r toker = new Str ingToken ize r ( out , "\n" ) ;147 toker . nextToken ( ) ;

208

148149 while ( toker . hasMoreTokens ( ) ) {150 St r ing s = toker . nextToken ( ) ;151 Str ingToken ize r toker2 = new Str ingToken ize r ( s , " " ) ;152 toker2 . nextToken ( ) ;153 toker2 . nextToken ( ) ;154 toker2 . nextToken ( ) ;155 toker2 . nextToken ( ) ;156 St r ing s2 = toker2 . nextToken ( ) ;157 return Long . parseLong ( s2 ) ;158 }159160 return −1;161 } catch ( Exception e ) {162 e . pr intStackTrace ( ) ;163 }164 return −1;165 }166167 public long getFreeDiskSpace ( ) {168 i n i t ( ) ;169 return cur rent . getFreeSpace ( ) ;170 }171172 public long getTotalDiskSpace ( ) {173 i n i t ( ) ;174 return cur rent . getMaxCapacity ( ) ;175 }176177 public long getUsedDiskSpace ( S t r ing path ) {178 i n i t ( ) ;179 return cur rent . getMaxCapacity ( ) − cur rent . getFreeSpace ( ) ;180 }181182 protected boolean i n i t ( ) {183 i f ( ! F i l eReg i s t r y . i s I n i t e d ( ) ) {184 try {185 F i l e curDir = new F i l e ( " . " ) ;186187 St r ing s t r = curDir . getAbsolutePath ( ) . s ub s t r i ng ( 0 , 3 ) ;188189 F i l eReg i s t r y . i n i t i a l i z e ( curDir , JUt i l s . a s c i iTo In t ( "Br idgeServer " ) ) ;190191 DiskVolume [ ] ds = F i l eReg i s t r y . getVolumes ( ) ;192 for ( int i = 0 ; i< ds . l ength ; i++){193 i f ( ds [ i ] . g e tP r e f i x ( ) . equa l s IgnoreCase ( s t r ) ){194 cur rent = ds [ i ] ;195 break ;196 }

209

197 }198 }199 catch ( Exception e ) {200 e . pr intStackTrace ( ) ;201 return fa l se ;202 }203 }204 return true ;205 }206207 public int getCPUUse ( ) {208 int pid = getPID ( " I d l e " ) ;209 int use = getCPUUse ( pid ) ;210 return 100 − use ;211 }212213 public int getCPUUse ( int pid ) {214 try {215 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\ p s l i s t . exe \" "+pid+" −s 2" ) ;216 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;217218 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;219 for ( ; ; ) {220 int c = stdoutStream . read ( ) ;221 i f ( c == −1) break ;222 bu f f e r . append ( ( char ) c ) ;223 }224 St r ing out = bu f f e r . t oS t r i ng ( ) ;225 stdoutStream . c l o s e ( ) ;226227 //System . out . p r i n t l n ( out ) ;228229 out = out . sub s t r i ng ( out . indexOf ( "Name" ) ) ;230231 Str ingToken i ze r toker = new Str ingToken ize r ( out , "\n" ) ;232 toker . nextToken ( ) ;233 toker . nextToken ( ) ;234 toker . nextToken ( ) ;235 toker . nextToken ( ) ;236 toker . nextToken ( ) ;237 while ( toker . hasMoreTokens ( ) ) {238 St r ing s = toker . nextToken ( ) ;239 Str ingToken ize r toker2 = new Str ingToken ize r ( s , " " ) ;240 toker2 . nextToken ( ) ;241 toker2 . nextToken ( ) ;242 St r ing s2 = toker2 . nextToken ( ) ;243 return I n t eg e r . pa r s e In t ( s2 ) ;244 }245

210

246 return −1;247 } catch ( Exception e ) {248 e . pr intStackTrace ( ) ;249 }250 return −1;251 }252253 public int getPID ( St r ing processName ) {254 try {255 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\ p s l i s t . exe \" "+processName ) ;256 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;257258 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;259 for ( ; ; ) {260 int c = stdoutStream . read ( ) ;261 i f ( c == −1) break ;262 bu f f e r . append ( ( char ) c ) ;263 }264 St r ing out = bu f f e r . t oS t r i ng ( ) ;265266 stdoutStream . c l o s e ( ) ;267268 out = out . sub s t r i ng ( out . indexOf ( "Name" ) ) ;269270 Str ingToken i ze r toker = new Str ingToken ize r ( out , "\n" ) ;271 toker . nextToken ( ) ;272 while ( toker . hasMoreTokens ( ) ) {273 St r ing s = toker . nextToken ( ) ;274 Str ingToken ize r toker2 = new Str ingToken ize r ( s , " " ) ;275 toker2 . nextToken ( ) ;276 St r ing s2 = toker2 . nextToken ( ) ;277 return I n t eg e r . pa r s e In t ( s2 ) ;278 }279280 return −1;281 } catch ( Exception e ) {282 e . pr intStackTrace ( ) ;283 }284 return −1;285 }286287 public St r ing [ ] g e tProce s s e s ( ) {288 try {289 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\ p s l i s t . exe \"" ) ;290 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;291292 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;293 for ( ; ; ) {294 int c = stdoutStream . read ( ) ;

211

295 i f ( c == −1) break ;296 bu f f e r . append ( ( char ) c ) ;297 }298 St r ing out = bu f f e r . t oS t r i ng ( ) ;299300 stdoutStream . c l o s e ( ) ;301302 out = out . sub s t r i ng ( out . indexOf ( "Name" ) ) ;303 List<Str ing> l i s t = new ArrayList<Str ing >() ;304305 Str ingToken i ze r toker = new Str ingToken ize r ( out , "\n" ) ;306 toker . nextToken ( ) ;307 while ( toker . hasMoreTokens ( ) ) {308 St r ing s = toker . nextToken ( ) ;309 Str ingToken ize r toker2 = new Str ingToken ize r ( s , " " ) ;310 St r ing s2 = toker2 . nextToken ( ) ;311 l i s t . add ( s2 ) ;312 }313314 return l i s t . toArray (new St r ing [ 0 ] ) ;315 } catch ( Exception e ) {316 e . pr intStackTrace ( ) ;317 }318 return null ;319 }320321 public St r ing [ ] ge tProce s se sTree ( ) {322 try {323 Process p = Runtime . getRuntime ( ) . exec ( "\""+path+"\\ p s l i s t . exe \" −t " ) ;324 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;325326 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;327 for ( ; ; ) {328 int c = stdoutStream . read ( ) ;329 i f ( c == −1) break ;330 bu f f e r . append ( ( char ) c ) ;331 }332 St r ing out = bu f f e r . t oS t r i ng ( ) ;333334 stdoutStream . c l o s e ( ) ;335336 out = out . sub s t r i ng ( out . indexOf ( "Name" ) ) ;337 List<Str ing> l i s t = new ArrayList<Str ing >() ;338339 Str ingToken i ze r toker = new Str ingToken ize r ( out , "\n" ) ;340 toker . nextToken ( ) ;341 while ( toker . hasMoreTokens ( ) ) {342 St r ing s = toker . nextToken ( ) ;343 Str ingToken ize r toker2 = new Str ingToken ize r ( s , " " ) ;

212

344 St r ing s2 = toker2 . nextToken ( ) ;345 char [ ] chars = s . toCharArray ( ) ;346 for ( int i = 0 ; i< chars . l ength ; i++){347 i f ( chars [ i ] == ' ' ){348 s2 = ' '+s2 ;349 }350 else {351 break ;352 }353 }354 l i s t . add ( s2 ) ;355 }356 return l i s t . toArray (new St r ing [ 0 ] ) ;357358 } catch ( Exception e ) {359 e . pr intStackTrace ( ) ;360 }361 return null ;362 }363 }

213

1 /∗2 ∗ Created on 08/12/20043 ∗4 ∗ TODO To change the temp la te f o r t h i s generated f i l e go to5 ∗ Window − Pre ferences − Java − Code S t y l e − Code Templates6 ∗/7 package u f s c . t c c . s e r v e r . gu i . tablemodel ;89 import java . awt . Color ;10 import java . awt . Component ;11 import java . awt . Graphics ;12 import java . awt . event . MouseAdapter ;13 import java . awt . event . MouseEvent ;14 import java . awt . event . MouseListener ;15 import java . u t i l . ArrayList ;16 import java . u t i l . Arrays ;17 import java . u t i l . Comparator ;18 import java . u t i l . HashMap ;19 import java . u t i l . I t e r a t o r ;20 import java . u t i l . L i s t ;21 import java . u t i l .Map;2223 import javax . swing . Icon ;24 import javax . swing . JLabel ;25 import javax . swing . JTable ;26 import javax . swing . event . TableModelEvent ;27 import javax . swing . event . TableModelListener ;28 import javax . swing . t ab l e . AbstractTableModel ;29 import javax . swing . t ab l e . JTableHeader ;30 import javax . swing . t ab l e . TableCel lRenderer ;31 import javax . swing . t ab l e . TableColumnModel ;32 import javax . swing . t ab l e . TableModel ;3334 /∗∗35 ∗ @author g i l b e r t o36 ∗37 ∗ TODO To change the temp la te f o r t h i s generated type comment go to38 ∗ Window − Pre ferences − Java − Code S t y l e − Code Templates39 ∗/40 public class TableSorter extends AbstractTableModel {41 protected TableModel tableModel ;4243 public stat ic f ina l int DESCENDING = −1;44 public stat ic f ina l int NOT_SORTED = 0 ;45 public stat ic f ina l int ASCENDING = 1 ;4647 private stat ic Di r e c t i v e EMPTY_DIRECTIVE = new Di r e c t i v e (−1 , NOT_SORTED) ;4849 public stat ic f ina l Comparator COMPARABLE_COMAPRATOR = new Comparator ( ) {

214

50 @SuppressWarnings ( "unchecked" )51 public int compare ( Object o1 , Object o2 ) {52 return ( ( Comparable ) o1 ) . compareTo ( o2 ) ;53 }54 } ;55 public stat ic f ina l Comparator LEXICAL_COMPARATOR = new Comparator ( ) {56 public int compare ( Object o1 , Object o2 ) {57 return o1 . t oS t r i ng ( ) . compareTo ( o2 . t oS t r i ng ( ) ) ;58 }59 } ;6061 private Row [ ] viewToModel ;62 private int [ ] modelToView ;6364 private JTableHeader tableHeader ;65 private MouseListener mouseListener ;66 private TableModelListener tab l eMode lL i s t ener ;67 private Map columnComparators = new HashMap ( ) ;68 private L i s t sort ingColumns = new ArrayList ( ) ;6970 public TableSorter ( ) {71 this . mouseListener = new MouseHandler ( ) ;72 this . t ab l eMode lL i s t ener = new TableModelHandler ( ) ;73 }7475 public TableSorter ( TableModel tableModel ) {76 this ( ) ;77 setTableModel ( tableModel ) ;78 }7980 public TableSorter ( TableModel tableModel , JTableHeader tableHeader ) {81 this ( ) ;82 setTableHeader ( tableHeader ) ;83 setTableModel ( tableModel ) ;84 }8586 private void c l e a r S o r t i n gS t a t e ( ) {87 viewToModel = null ;88 modelToView = null ;89 }9091 public TableModel getTableModel ( ) {92 return tableModel ;93 }9495 public void setTableModel ( TableModel tableModel ) {96 i f ( this . tableModel != null ) {97 this . tableModel . removeTableModelListener ( tab l eMode lL i s t ener ) ;98 }

215

99100 this . tableModel = tableModel ;101 i f ( this . tableModel != null ) {102 this . tableModel . addTableModelListener ( tab l eMode lL i s t ener ) ;103 }104105 c l e a r S o r t i n gS t a t e ( ) ;106 f i reTableStructureChanged ( ) ;107 }108109 public JTableHeader getTableHeader ( ) {110 return tableHeader ;111 }112113 public void setTableHeader ( JTableHeader tableHeader ) {114 i f ( this . tableHeader != null ) {115 this . tableHeader . removeMouseListener ( mouseListener ) ;116 TableCel lRenderer de fau l tRenderer = this . tableHeader . getDefau l tRenderer ( ) ;117 i f ( de fau l tRenderer instanceof SortableHeaderRenderer ) {118 this . tableHeader . s e tDe fau l tRenderer ( ( ( SortableHeaderRenderer ) de fau l tRendere r ) . t ab l eCe l lRendere r ) ;119 }120 }121 this . tableHeader = tableHeader ;122 i f ( this . tableHeader != null ) {123 this . tableHeader . addMouseListener ( mouseListener ) ;124 this . tableHeader . s e tDe fau l tRenderer (125 new SortableHeaderRenderer ( this . tableHeader . getDefau l tRenderer ( ) ) ) ;126 }127 }128129 public boolean i s S o r t i n g ( ) {130 return sort ingColumns . s i z e ( ) != 0 ;131 }132133 private Di r e c t i v e g e tD i r e c t i v e ( int column ) {134 for ( int i = 0 ; i < sort ingColumns . s i z e ( ) ; i++) {135 D i r e c t i v e d i r e c t i v e = ( D i r e c t i v e ) sort ingColumns . get ( i ) ;136 i f ( d i r e c t i v e . column == column ) {137 return d i r e c t i v e ;138 }139 }140 return EMPTY_DIRECTIVE;141 }142143 public int ge tSo r t i ngS ta tu s ( int column ) {144 return g e tD i r e c t i v e ( column ) . d i r e c t i o n ;145 }146147 private void sort ingStatusChanged ( ) {

216

148 c l e a r S o r t i n gS t a t e ( ) ;149 fireTableDataChanged ( ) ;150 i f ( tableHeader != null ) {151 tableHeader . r epa in t ( ) ;152 }153 }154155 @SuppressWarnings ( "unchecked" )156 public void s e tSo r t i n gS t a tu s ( int column , int s t a tu s ) {157 D i r e c t i v e d i r e c t i v e = ge tD i r e c t i v e ( column ) ;158 i f ( d i r e c t i v e != EMPTY_DIRECTIVE) {159 sortingColumns . remove ( d i r e c t i v e ) ;160 }161 i f ( s t a tu s != NOT_SORTED) {162 sortingColumns . add (new Di r e c t i v e ( column , s t a tu s ) ) ;163 }164 sort ingStatusChanged ( ) ;165 }166167 protected Icon getHeaderRendererIcon ( int column , int s i z e ) {168 D i r e c t i v e d i r e c t i v e = ge tD i r e c t i v e ( column ) ;169 i f ( d i r e c t i v e == EMPTY_DIRECTIVE) {170 return null ;171 }172 return new Arrow( d i r e c t i v e . d i r e c t i o n == DESCENDING, s i z e , sort ingColumns . indexOf ( d i r e c t i v e ) ) ;173 }174175 private void canc e l So r t i ng ( ) {176 sort ingColumns . c l e a r ( ) ;177 sort ingStatusChanged ( ) ;178 }179180 @SuppressWarnings ( "unchecked" )181 public void setColumnComparator ( Class type , Comparator comparator ) {182 i f ( comparator == null ) {183 columnComparators . remove ( type ) ;184 } else {185 columnComparators . put ( type , comparator ) ;186 }187 }188189 protected Comparator getComparator ( int column ) {190 Class columnType = tableModel . getColumnClass ( column ) ;191 Comparator comparator = (Comparator ) columnComparators . get ( columnType ) ;192 i f ( comparator != null ) {193 return comparator ;194 }195 i f ( Comparable . class . i sAss ignableFrom ( columnType ) ) {196 return COMPARABLE_COMAPRATOR;

217

197 }198 return LEXICAL_COMPARATOR;199 }200201 private Row [ ] getViewToModel ( ) {202 i f ( viewToModel == null ) {203 int tableModelRowCount = tableModel . getRowCount ( ) ;204 viewToModel = new Row[ tableModelRowCount ] ;205 for ( int row = 0 ; row < tableModelRowCount ; row++) {206 viewToModel [ row ] = new Row( row ) ;207 }208209 i f ( i s S o r t i n g ( ) ) {210 Arrays . s o r t ( viewToModel ) ;211 }212 }213 return viewToModel ;214 }215216 public int modelIndex ( int viewIndex ) {217 return getViewToModel ( ) [ viewIndex ] . modelIndex ;218 }219220 private int [ ] getModelToView ( ) {221 i f (modelToView == null ) {222 int n = getViewToModel ( ) . l ength ;223 modelToView = new int [ n ] ;224 for ( int i = 0 ; i < n ; i++) {225 modelToView [ modelIndex ( i ) ] = i ;226 }227 }228 return modelToView ;229 }230231 // TableModel i n t e r f a c e methods232233 public int getRowCount ( ) {234 return ( tableModel == null ) ? 0 : tableModel . getRowCount ( ) ;235 }236237 public int getColumnCount ( ) {238 return ( tableModel == null ) ? 0 : tableModel . getColumnCount ( ) ;239 }240241 public St r ing getColumnName( int column ) {242 return tableModel . getColumnName( column ) ;243 }244245 public Class<?> getColumnClass ( int column ) {

218

246 return tableModel . getColumnClass ( column ) ;247 }248249 public boolean i sC e l l Ed i t a b l e ( int row , int column ) {250 return tableModel . i sC e l l Ed i t a b l e ( modelIndex ( row ) , column ) ;251 }252253 public Object getValueAt ( int row , int column ) {254 return tableModel . getValueAt (modelIndex ( row ) , column ) ;255 }256257 public void setValueAt ( Object aValue , int row , int column ) {258 tableModel . setValueAt ( aValue , modelIndex ( row ) , column ) ;259 }260261 // Helper c l a s s e s262263 private class Row implements Comparable {264 private int modelIndex ;265266 public Row( int index ) {267 this . modelIndex = index ;268 }269270 @SuppressWarnings ( "unchecked" )271 public int compareTo ( Object o ) {272 int row1 = modelIndex ;273 int row2 = ( (Row) o ) . modelIndex ;274275 for ( I t e r a t o r i t = sortingColumns . i t e r a t o r ( ) ; i t . hasNext ( ) ; ) {276 D i r e c t i v e d i r e c t i v e = ( D i r e c t i v e ) i t . next ( ) ;277 int column = d i r e c t i v e . column ;278 Object o1 = tableModel . getValueAt ( row1 , column ) ;279 Object o2 = tableModel . getValueAt ( row2 , column ) ;280281 int comparison = 0 ;282 // Define n u l l l e s s than every th ing , excep t n u l l .283 i f ( o1 == null && o2 == null ) {284 comparison = 0 ;285 } else i f ( o1 == null ) {286 comparison = −1;287 } else i f ( o2 == null ) {288 comparison = 1 ;289 } else {290 comparison = getComparator ( column ) . compare ( o1 , o2 ) ;291 }292 i f ( comparison != 0) {293 return d i r e c t i v e . d i r e c t i o n == DESCENDING ? −comparison : comparison ;294 }

219

295 }296 return 0 ;297 }298 }299300 private class TableModelHandler implements TableModelListener {301 public void tableChanged ( TableModelEvent e ) {302 // I f we ' re not s o r t i n g by anything , j u s t pass the event a long .303 i f ( ! i s S o r t i n g ( ) ) {304 c l e a r S o r t i n gS t a t e ( ) ;305 f ireTableChanged ( e ) ;306 return ;307 }308309 // I f the t a b l e s t r u c t u r e has changed , cance l the s o r t i n g ; the310 // s o r t i n g columns may have been e i t h e r moved or d e l e t e d from311 // the model .312 i f ( e . getFirstRow ( ) == TableModelEvent .HEADER_ROW) {313 canc e l So r t i ng ( ) ;314 f ireTableChanged ( e ) ;315 return ;316 }317318 // We can map a c e l l event through to the view wi thout widening319 // when the f o l l ow i n g cond i t i on s app ly :320 //321 // a ) a l l the changes are on one row ( e . getFirstRow () == e . getLastRow ( ) ) and ,322 // b ) a l l the changes are in one column ( column != TableModelEvent .ALL_COLUMNS) and ,323 // c ) we are not s o r t i n g on t ha t column ( g e t So r t i n gS t a t u s ( column ) == NOT_SORTED) and ,324 // d ) a r e v e r s e lookup w i l l not t r i g g e r a s o r t (modelToView != nu l l )325 //326 // Note : INSERT and DELETE even t s f a i l t h i s t e s t as they have column == ALL_COLUMNS.327 //328 // The l a s t check , f o r (modelToView != nu l l ) i s to see i f modelToView329 // i s a l r eady a l l o c a t e d . I f we don ' t do t h i s check ; s o r t i n g can become330 // a performance b o t t l e n e c k f o r a p p l i c a t i o n s where c e l l s331 // change r a p i d l y in d i f f e r e n t par t s o f the t a b l e . I f c e l l s332 // change a l t e r n a t e l y in the s o r t i n g column and then ou t s i d e o f333 // i t t h i s c l a s s can end up re−s o r t i n g on a l t e r n a t e c e l l updates −334 // which can be a performance problem fo r l a r g e t a b l e s . The l a s t335 // c l au s e avo ids t h i s problem .336 int column = e . getColumn ( ) ;337 i f ( e . getFirstRow ( ) == e . getLastRow ( )338 && column != TableModelEvent .ALL_COLUMNS339 && getSo r t i ngS ta tu s ( column ) == NOT_SORTED340 && modelToView != null ) {341 int viewIndex = getModelToView ( ) [ e . getFirstRow ( ) ] ;342 f ireTableChanged (new TableModelEvent ( TableSorter . this ,343 viewIndex , viewIndex ,

220

344 column , e . getType ( ) ) ) ;345 return ;346 }347348 // Something has happened to the data t ha t may have i n v a l i d a t e d the row order .349 c l e a r S o r t i n gS t a t e ( ) ;350 fireTableDataChanged ( ) ;351 return ;352 }353 }354355 private class MouseHandler extends MouseAdapter {356 public void mouseClicked (MouseEvent e ) {357 JTableHeader h = ( JTableHeader ) e . getSource ( ) ;358 TableColumnModel columnModel = h . getColumnModel ( ) ;359 int viewColumn = columnModel . getColumnIndexAtX ( e . getX ( ) ) ;360 int column = columnModel . getColumn ( viewColumn ) . getModelIndex ( ) ;361 i f ( column != −1) {362 int s t a tu s = ge tSo r t i ngS ta tu s ( column ) ;363 i f ( ! e . isControlDown ( ) ) {364 canc e l So r t i ng ( ) ;365 }366 // Cycle the s o r t i n g s t a t e s through {NOT_SORTED, ASCENDING, DESCENDING} or367 // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether s h i f t i s pres sed .368 s t a tu s = s ta tu s + ( e . isShi ftDown ( ) ? −1 : 1 ) ;369 s t a tu s = ( s t a tu s + 4) % 3 − 1 ; // s i gned mod , r e tu rn ing {−1, 0 , 1}370 s e tSo r t i ngS ta tu s ( column , s t a tu s ) ;371 }372 }373 }374375 private stat ic class Arrow implements Icon {376 private boolean descending ;377 private int s i z e ;378 private int p r i o r i t y ;379380 public Arrow(boolean descending , int s i z e , int p r i o r i t y ) {381 this . descending = descending ;382 this . s i z e = s i z e ;383 this . p r i o r i t y = p r i o r i t y ;384 }385386 public void pa int I con (Component c , Graphics g , int x , int y ) {387 Color c o l o r = c == null ? Color .GRAY : c . getBackground ( ) ;388 // In a compound sor t , make each su c c e s i v e t r i a n g l e 20%389 // sma l l e r than the prev ious one .390 int dx = ( int ) ( s i z e /2∗Math . pow ( 0 . 8 , p r i o r i t y ) ) ;391 int dy = descending ? dx : −dx ;392 // Align icon ( rough ly ) wi th f on t b a s e l i n e .

221

393 y = y + 5∗ s i z e /6 + ( descending ? −dy : 0 ) ;394 int s h i f t = descending ? 1 : −1;395 g . t r a n s l a t e (x , y ) ;396397 // Right d iagona l .398 g . s e tCo lo r ( c o l o r . darker ( ) ) ;399 g . drawLine (dx / 2 , dy , 0 , 0 ) ;400 g . drawLine (dx / 2 , dy + sh i f t , 0 , s h i f t ) ;401402 // Le f t d iagona l .403 g . s e tCo lo r ( c o l o r . b r i gh t e r ( ) ) ;404 g . drawLine (dx / 2 , dy , dx , 0 ) ;405 g . drawLine (dx / 2 , dy + sh i f t , dx , s h i f t ) ;406407 // Hor i zon ta l l i n e .408 i f ( descending ) {409 g . s e tCo lo r ( c o l o r . darker ( ) . darker ( ) ) ;410 } else {411 g . s e tCo lo r ( c o l o r . b r i gh t e r ( ) . b r i gh t e r ( ) ) ;412 }413 g . drawLine (dx , 0 , 0 , 0 ) ;414415 g . s e tCo lo r ( c o l o r ) ;416 g . t r a n s l a t e (−x , −y ) ;417 }418419 public int getIconWidth ( ) {420 return s i z e ;421 }422423 public int get IconHeight ( ) {424 return s i z e ;425 }426 }427428 private class SortableHeaderRenderer implements TableCel lRenderer {429 private TableCel lRenderer tab l eCe l lRendere r ;430431 public SortableHeaderRenderer ( TableCel lRenderer tab l eCe l lRendere r ) {432 this . t ab l eCe l lRendere r = tab l eCe l lRendere r ;433 }434435 public Component getTableCellRendererComponent ( JTable tab le ,436 Object value ,437 boolean i s S e l e c t e d ,438 boolean hasFocus ,439 int row ,440 int column ) {441 Component c = tab l eCe l lRendere r . getTableCellRendererComponent ( tab le ,

222

442 value , i s S e l e c t e d , hasFocus , row , column ) ;443 i f ( c instanceof JLabel ) {444 JLabel l = ( JLabel ) c ;445 l . s e tHor i zon ta lTex tPos i t i on ( JLabel .LEFT) ;446 int modelColumn = tab l e . convertColumnIndexToModel ( column ) ;447 l . s e t I c on ( getHeaderRendererIcon (modelColumn , l . getFont ( ) . g e tS i z e ( ) ) ) ;448 }449 return c ;450 }451 }452453 private stat ic class Di r e c t i v e {454 private int column ;455 private int d i r e c t i o n ;456457 public Di r e c t i v e ( int column , int d i r e c t i o n ) {458 this . column = column ;459 this . d i r e c t i o n = d i r e c t i o n ;460 }461 }462 }

223

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i ;56 import java . awt . BorderLayout ;7 import java . awt . Dimension ;8 import java . awt . Frame ;9 import java . awt . event . ActionEvent ;10 import java . awt . event . Act i onL i s t ene r ;1112 import javax . swing . JButton ;13 import javax . swing . JDialog ;14 import javax . swing . JOptionPane ;15 import javax . swing . JPanel ;1617 import u f s c . t c c . s e r v e r . c o n t r o l l e r . QuartzScheduler ;18 import u f s c . t c c . s e r v e r . model . Task ;19 import u f s c . t c c . s e r v e r . model . except ion . Inva l idTaskFie ldsExcept ion ;20 import u f s c . t c c . s e r v e r . p e r s i s t e n c e . H ibernateUt i l ;2122 /∗∗23 ∗ @author G i l b e r t o Torrezan Fi lho24 ∗/25 public class TaskDialog extends JDialog {2627 private f ina l boolean editMode ;2829 private TaskEditPanel30 panel = new TaskEditPanel ( ) ;3132 private JPanel33 down = new JPanel ( ) ;3435 private JButton36 ok = new JButton ( "Ok" ) ,37 cance l = new JButton ( "Cancelar " ) ;3839 public TaskDialog (Frame owner , f ina l boolean editMode ){40 super ( owner , editMode ? "Edição de Tarefa " : "Adição de Tarefa " , true ) ;41 se tDe fau l tC lo seOperat ion ( JDialog .DISPOSE_ON_CLOSE) ;42 pack ( ) ;43 s e t S i z e ( 500 , 550 ) ;44 se tLocat ionRe lat iveTo ( null ) ;45 s e tRe s i z ab l e ( fa l se ) ;4647 this . editMode = editMode ;4849 this . getContentPane ( ) . setLayout (new BorderLayout ( ) ) ;

224

50 this . getContentPane ( ) . add ( panel , BorderLayout .CENTER) ;51 this . getContentPane ( ) . add (down , BorderLayout .SOUTH) ;5253 down . add ( ok ) ;54 down . add ( cance l ) ;5556 Dimension d = new Dimension ( 120 , 2 2 ) ;57 ok . s e tP r e f e r r e dS i z e (d ) ;58 cance l . s e tP r e f e r r e dS i z e (d ) ;5960 ok . addAct ionListener (new Act ionL i s t ene r ( ){61 public void act ionPerformed ( ActionEvent e ) {62 try {63 Task task = panel . getTask ( ) ;64 i f ( editMode ){65 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;66 MainFrame . ge t In s tance ( ) . getTaskPanel ( ) . updateTask ( task ) ;67 }68 else {69 HibernateUt i l . getTaskDAO ( ) . in se r tTask ( task ) ;70 MainFrame . ge t In s tance ( ) . getTaskPanel ( ) . addTask ( task ) ;71 }72 QuartzScheduler . scheculeTask ( task ) ;73 s e tV i s i b l e ( fa l se ) ;74 d i spo s e ( ) ;75 }76 catch ( Inva l idTaskFie ldsExcept ion e1 ) {77 JOptionPane opt = new JOptionPane ( e1 . getMessage ( ) , JOptionPane .WARNING_MESSAGE,78 JOptionPane .OK_OPTION, null ,new St r ing [ ] { "Ok" } ) ;79 opt . c r ea t eD ia l og ( TaskDialog . this , "Atenção" ) . s e tV i s i b l e ( true ) ;80 }81 }82 } ) ;8384 cance l . addAct ionLis tener (new Act ionL i s t ene r ( ){85 public void act ionPerformed ( ActionEvent e ) {86 s e tV i s i b l e ( fa l se ) ;87 d i spo s e ( ) ;88 }89 } ) ;90 }9192 public void setTask (Task task ){93 panel . setTask ( task ) ;94 }9596 public boolean isEditMode ( ) {97 return editMode ;98 }

225

99 }

226

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i ;56 import java . awt . Dimension ;7 import java . awt . GridBagLayout ;8 import java . awt . GridLayout ;9 import java . awt . event . ActionEvent ;10 import java . awt . event . Act i onL i s t ene r ;11 import java . i o . IOException ;12 import java . t ex t . ParseException ;1314 import javax . swing . BorderFactory ;15 import javax . swing . ButtonGroup ;16 import javax . swing . JButton ;17 import javax . swing . JComboBox ;18 import javax . swing . JPanel ;19 import javax . swing . JRadioButton ;20 import javax . swing . JTextFie ld ;21 import javax . swing . event . ChangeEvent ;22 import javax . swing . event . ChangeListener ;2324 import org . quartz . CronTrigger ;25 import org . quartz . Scheduler ;2627 import u f s c . t c c . s e r v e r . c o n t r o l l e r . i n f o . SystemInfoFactory ;28 import u f s c . t c c . s e r v e r . c o n t r o l l e r . u t i l . Launcher ;29 import u f s c . t c c . s e r v e r . model .CommandTask ;30 import u f s c . t c c . s e r v e r . model . ScheduledTask ;31 import u f s c . t c c . s e r v e r . model . Task ;32 import u f s c . t c c . s e r v e r . model . except ion . Inva l idTaskFie ldsExcept ion ;3334 /∗∗35 ∗ @author G i l b e r t o Torrezan Fi lho36 ∗/37 public class TaskEditPanel extends JPanel {3839 private JPanel40 pane1 = new JPanel ( ) ,41 pane2 = new JPanel ( ) ,42 pane3 = new JPanel ( ) ,43 pane4 = new JPanel ( ) ,44 pane5 = new JPanel ( ) ,45 pane6 = new JPanel ( ) ,46 pane7 = new JPanel ( ) ,47 pane8 = new JPanel ( ) ;4849 private JRadioButton

227

50 rad io1 = new JRadioButton ( "Execução de l i nha de comando" , true ) ,51 rad io2 = new JRadioButton ( "Tarefa agendada ( c o l e t a de dados ) " ) ,5253 rad io11 = new JRadioButton ( "Não aguardar pe lo output " , true ) ,54 rad io12 = new JRadioButton ( "Aguardar output da execução " ) ;5556 private JComboBox57 combo1 = new JComboBox(new St r ing [ ] {58 "Aval iação do uso de CPU por todos os p ro c e s s o s " ,59 "Aval iação do uso de CPU por um proce s so e s p e c í f i c o " ,60 "Aval iação do espaço em d i s co " ,61 "Aval iação da memória l i v r e " ,62 "Aval iação do uso de memória por todos os p ro c e s s o s " ,63 "Aval iação do uso de memória por um proce s so e s p e c í f i c o " ,64 "Aval iação do uso de memória v i r t u a l por um proce s so e s p e c í f i c o "65 }) ,66 combo2 = new JComboBox( SystemInfoFactory . getSystemInfo ( ) . g e tProc e s s e s ( ) ) ;6768 private JTextFie ld69 f i e l d 1 = new JTextFie ld ( ) ,70 f i e l d 2 = new JTextFie ld ( ) ,71 f i e l d 3 = new JTextFie ld ( ) ,72 f i e l d 4 = new JTextFie ld ( ) ;7374 private JButton75 i n f o = new JButton ( "?" ) ;7677 private Task task ;7879 public TaskEditPanel ( ){80 ButtonGroup g1 = new ButtonGroup ( ) ;81 g1 . add ( rad io1 ) ;82 g1 . add ( rad io2 ) ;8384 ButtonGroup g2 = new ButtonGroup ( ) ;85 g2 . add ( rad io11 ) ;86 g2 . add ( rad io12 ) ;8788 this . setLayout (new GridLayout ( 0 , 1 ) ) ;89 this . add ( pane1 ) ;90 this . add ( pane2 ) ;91 this . add ( pane3 ) ;9293 combo2 . s e tEd i t ab l e ( true ) ;9495 pane1 . setLayout (new GridBagLayout ( ) ) ;96 pane1 . add ( f i e l d 1 ) ;9798 pane2 . setLayout (new GridBagLayout ( ) ) ;

228

99 pane2 . add ( f i e l d 2 ) ;100101 pane3 . setLayout (new GridLayout ( 0 , 1 ) ) ;102 pane3 . add ( rad io1 ) ;103 pane3 . add ( rad io2 ) ;104105 pane4 . setLayout (new GridBagLayout ( ) ) ;106 pane4 . add ( f i e l d 3 ) ;107108 pane5 . setLayout (new GridLayout ( 0 , 1 ) ) ;109 pane5 . add ( rad io11 ) ;110 pane5 . add ( rad io12 ) ;111112 pane6 . setLayout (new GridBagLayout ( ) ) ;113 pane6 . add ( combo1 ) ;114115 pane7 . setLayout (new GridBagLayout ( ) ) ;116 pane7 . add ( combo2 ) ;117118 pane8 . setLayout (new GridBagLayout ( ) ) ;119 pane8 . add ( f i e l d 4 ) ;120 pane8 . add ( i n f o ) ;121122 pane1 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Nome da Tarefa " ) ) ;123 pane2 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Descr i ção da Tarefa " ) ) ;124 pane3 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Tipo da Tarefa " ) ) ;125 pane4 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Comando a s e r executado " ) ) ;126 pane5 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Resultado da execução da t a r e f a " ) ) ;127 pane6 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Dados a serem co l e t ado s " ) ) ;128 pane7 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Nome do proce s so a s e r ava l i ado " ) ) ;129 pane8 . setBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Freqüência de execução " ) ) ;130131 Dimension d = new Dimension ( 350 , 2 3 ) ;132 f i e l d 1 . s e tP r e f e r r e dS i z e (d ) ;133 f i e l d 2 . s e tP r e f e r r e dS i z e (d ) ;134 f i e l d 3 . s e tP r e f e r r e dS i z e (d ) ;135136 f i e l d 1 . setMinimumSize (d ) ;137 f i e l d 2 . setMinimumSize (d ) ;138 f i e l d 3 . setMinimumSize (d ) ;139140 d = new Dimension ( 305 , 2 3 ) ;141 f i e l d 4 . s e tP r e f e r r e dS i z e (d ) ;142 f i e l d 4 . setMinimumSize (d ) ;143144 d = new Dimension ( 4 5 , 2 0 ) ;145 i n f o . s e tP r e f e r r e dS i z e (d ) ;146147 d = new Dimension ( 350 , 2 2 ) ;

229

148 combo2 . s e tP r e f e r r e dS i z e (d ) ;149150 reva l idateType ( ) ;151152 ChangeListener c l = new ChangeListener ( ){153 public void stateChanged (ChangeEvent e ) {154 reva l idateType ( ) ;155 }156 } ;157 rad io1 . addChangeListener ( c l ) ;158159 combo1 . addAct ionLis tener (new Act ionL i s t ene r ( ){160 public void act ionPerformed ( ActionEvent e ) {161 reva l idateType ( ) ;162 }163 } ) ;164165 i n f o . addAct ionListener (new Act ionL i s t ene r ( ){166 public void act ionPerformed ( ActionEvent e ) {167 try {168 Launcher . open ( "http ://www. opensymphony . com/quartz /wik idocs /CronTriggers%20Tutor i a l . html" ) ;169 }170 catch ( IOException e1 ) {171 e1 . pr intStackTrace ( ) ;172 }173 }174 } ) ;175 }176177 private void reva l idateType ( ){178 i f ( rad io1 . i s S e l e c t e d ( ) ) {179 remove ( pane6 ) ;180 remove ( pane7 ) ;181 remove ( pane8 ) ;182 add ( pane4 ) ;183 add ( pane5 ) ;184 }185 else {186 remove ( pane4 ) ;187 remove ( pane5 ) ;188 add ( pane6 ) ;189 int i = combo1 . ge tSe l e c t ed Index ( ) ;190 i f ( i == 1 | | i == 5 | | i == 6){191 add ( pane7 ) ;192 }193 else {194 remove ( pane7 ) ;195 }196 add ( pane8 ) ;

230

197 }198 r e v a l i d a t e ( ) ;199 r epa in t ( ) ;200 }201202 public Task getTask ( ) throws Inva l idTaskFie ldsExcept ion {203 v e r i f y F i e l d s ( ) ;204205 Task task = this . task ;206 i f ( task == null ){207 i f ( rad io1 . i s S e l e c t e d ( ) ) {208 task = new CommandTask ( ) ;209 }210 else {211 task = new ScheduledTask ( ) ;212 }213 }214 task . setName ( f i e l d 1 . getText ( ) ) ;215 task . s e tDe s c r i p t i on ( f i e l d 2 . getText ( ) ) ;216 i f ( task instanceof CommandTask){217 CommandTask c = (CommandTask) task ;218 c . setCommand( f i e l d 3 . getText ( ) ) ;219 c . setWaitForReturn ( rad io12 . i s S e l e c t e d ( ) ) ;220 }221 else {222 ScheduledTask s = ( ScheduledTask ) task ;223 setType ( s ) ;224 s . s e tSchedu l eExpre s s i on ( f i e l d 4 . getText ( ) ) ;225 s . removeAllTaskValues ( ) ;226 }227 return task ;228 }229230 public void setTask (Task task ) {231 this . task = task ;232 i f ( task != null ){233 f i e l d 1 . setText ( task . getName ( ) ) ;234 f i e l d 2 . setText ( task . g e tDe s c r i p t i on ( ) ) ;235 i f ( task instanceof CommandTask){236 rad io1 . s e t S e l e c t e d ( true ) ;237 rad io2 . setEnabled ( fa l se ) ;238 CommandTask c = (CommandTask) task ;239 f i e l d 3 . setText ( c . getCommand ( ) ) ;240 i f ( c . isWaitForReturn ( ) ) {241 rad io12 . s e t S e l e c t e d ( true ) ;242 }243 else {244 rad io11 . s e t S e l e c t e d ( true ) ;245 }

231

246 }247 else {248 rad io2 . s e t S e l e c t e d ( true ) ;249 rad io1 . setEnabled ( fa l se ) ;250 ScheduledTask s = ( ScheduledTask ) task ;251 int index = getType ( s ) ;252 combo1 . s e tS e l e c t ed Index ( index ) ;253 i f ( index == 1 | | index == 5){254 combo2 . s e tSe l e c t ed I t em ( s . getArgumentsAsArray ( ) [ 0 ] ) ;255 }256 else i f ( index == 6){257 combo2 . s e tSe l e c t ed I t em ( s . getArgumentsAsArray ( ) [ 1 ] ) ;258 }259 f i e l d 4 . setText ( s . getSchedu leExpres s ion ( ) ) ;260 }261 }262 else {263 rad io1 . setEnabled ( true ) ;264 rad io1 . setEnabled ( true ) ;265 }266 reva l idateType ( ) ;267 }268269 private void v e r i f y F i e l d s ( ) throws Inva l idTaskFie ldsExcept ion {270 i f ( f i e l d 1 . getText ( ) . tr im ( ) . l ength ( ) <= 0){271 throw new Inva l idTaskFie ldsExcept ion ( "O campo nome da t a r e f a não pode e s t a r vaz io . \ n" +272 "Por favor d i g i t e o nome da t a r e f a antes de conf i rmar . " ) ;273 }274 i f ( f i e l d 2 . getText ( ) . tr im ( ) . l ength ( ) <= 0){275 throw new Inva l idTaskFie ldsExcept ion ( "O campo de s c r i ç ã o da t a r e f a não pode e s t a r vaz io . \ n" +276 "Por favor d i g i t e a d e s c r i ç ã o da t a r e f a antes de conf i rmar . " ) ;277 }278 i f ( rad io1 . i s S e l e c t e d ( ) && f i e l d 3 . getText ( ) . tr im ( ) . l ength ( ) <= 0){279 throw new Inva l idTaskFie ldsExcept ion ( "O campo comando a s e r executado não pode e s t a r vaz io . \ n" +280 "Por favor d i g i t e o comando antes de conf i rmar . " ) ;281 }282 i f ( rad io2 . i s S e l e c t e d ( ) ) {283 i f ( f i e l d 4 . getText ( ) . tr im ( ) . l ength ( ) <= 0){284 throw new Inva l idTaskFie ldsExcept ion ( "O campo f r eqüênc i a da t a r e f a não pode e s t a r vaz io . \ n" +285 "Por favor d i g i t e a f r eqüênc i a da t a r e f a antes de conf i rmar . " ) ;286 }287 try {288 new CronTrigger ( "0" , Scheduler .DEFAULT_GROUP, f i e l d 4 . getText ( ) ) ;289 } catch ( ParseException e ) {290 throw new Inva l idTaskFie ldsExcept ion ( "O campo f r eqüênc i a da não pos su i uma expres são vá l i da . \ n" +291 "Por favor d i g i t e uma f r eqüênc i a vá l i da . " ) ;292 }293 int i = combo1 . ge tSe l e c t ed Index ( ) ;294 i f ( ( i == 1 | | i == 5 | | i == 6) && combo2 . ge tSe l e c t ed I t em ( ) . t oS t r i ng ( ) . tr im ( ) . l ength ( ) <= 0){

232

295 throw new Inva l idTaskFie ldsExcept ion ( "O campo proce s so a s e r ana l i s ado não pode e s t a r vaz io . \ n" +296 "Por favor d i g i t e o proce s so antes de conf i rmar . " ) ;297 }298 }299 }300301 private void setType ( ScheduledTask t ){302 switch ( combo1 . ge tSe l e c t ed Index ( ) ) {303 case 0 :304 t . setType ( ScheduledTask .TYPE_CPU_USE) ;305 t . setArguments ( null ) ;306 break ;307 case 1 :308 t . setType ( ScheduledTask .TYPE_CPU_USE) ;309 t . setArguments ( combo2 . ge tSe l e c t ed I t em ( ) . t oS t r i ng ( ) ) ;310 break ;311 case 2 :312 t . setType ( ScheduledTask .TYPE_HD_SPACE) ;313 t . setArguments ( null ) ;314 break ;315 case 3 :316 t . setType ( ScheduledTask .TYPE_MEMORY) ;317 t . setArguments ( null ) ;318 break ;319 case 4 :320 t . setType ( ScheduledTask .TYPE_MEMORY) ;321 t . setArguments ( "−used" ) ;322 break ;323 case 5 :324 t . setType ( ScheduledTask .TYPE_MEMORY) ;325 t . setArguments ( combo2 . ge tSe l e c t ed I t em ( ) . t oS t r i ng ( ) ) ;326 break ;327 case 6 :328 t . setType ( ScheduledTask .TYPE_MEMORY) ;329 t . setArguments ( "−v i r t u a l "+combo2 . ge tSe l e c t ed I t em ( ) . t oS t r i ng ( ) ) ;330 break ;331 }332 }333334 private int getType ( ScheduledTask t ){335 St r ing [ ] arguments = t . getArgumentsAsArray ( ) ;336 switch ( t . getType ( ) ) {337 case ScheduledTask .TYPE_CPU_USE:338 i f ( arguments == null ){339 return 0 ;340 }341 return 1 ;342 case ScheduledTask .TYPE_HD_SPACE:343 return 2 ;

233

344 case ScheduledTask .TYPE_MEMORY:345 i f ( arguments == null ){346 return 3 ;347 }348 i f ( arguments . l ength == 1){349 i f ( arguments [ 0 ] . equa l s IgnoreCase ( "−used" ) ){350 return 4 ;351 }352 return 5 ;353 }354 i f ( arguments . l ength == 2 && arguments [ 0 ] . equa l s IgnoreCase ( "−v i r t u a l " ) ){355 return 6 ;356 }357 }358 return 0 ;359 }360 }

234

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r ;56 import java . i o . BufferedInputStream ;7 import java . i o . InputStream ;8 import java . u t i l . L i s t ;9 import java . u t i l . Vector ;1011 import org . quartz . Job ;12 import org . quartz . JobDataMap ;13 import org . quartz . JobExecutionContext ;14 import org . quartz . JobExecutionException ;1516 import u f s c . t c c . s e r v e r . c o n t r o l l e r . i n f o . SystemInfo ;17 import u f s c . t c c . s e r v e r . c o n t r o l l e r . i n f o . SystemInfoFactory ;18 import u f s c . t c c . s e r v e r . c o n t r o l l e r . l i s t e n e r . TaskListener ;19 import u f s c . t c c . s e r v e r . model .CommandTask ;20 import u f s c . t c c . s e r v e r . model . ScheduledTask ;21 import u f s c . t c c . s e r v e r . model . Task ;22 import u f s c . t c c . s e r v e r . model . TaskValue ;23 import u f s c . t c c . s e r v e r . p e r s i s t e n c e . H ibernateUt i l ;2425 /∗∗26 ∗ @author G i l b e r t o Torrezan Fi lho27 ∗/28 public class TaskExecuter implements Job{2930 private stat ic List<TaskListener> l i s t e n e r s = new Vector<TaskListener >() ;3132 private stat ic TaskExecuter i n s t anc e ;3334 public TaskExecuter ( ){35 in s t anc e = this ;36 }3738 public St r ing execute (Task task ){39 i f ( task instanceof CommandTask){40 return this . execute ( (CommandTask) task ) ;41 }42 else i f ( task instanceof ScheduledTask ){43 return this . execute ( ( ScheduledTask ) task ) ;44 }45 return null ;46 }4748 public St r ing execute (CommandTask task ){49 try {

235

50 Process p = Runtime . getRuntime ( ) . exec ( task . getCommand ( ) ) ;51 i f ( task . isWaitForReturn ( ) ) {52 InputStream stdoutStream = new BufferedInputStream (p . getInputStream ( ) ) ;5354 S t r i ngBu f f e r bu f f e r= new St r i ngBu f f e r ( ) ;55 for ( ; ; ) {56 int c = stdoutStream . read ( ) ;57 i f ( c == −1) break ;58 bu f f e r . append ( ( char ) c ) ;59 }60 St r ing out = bu f f e r . t oS t r i ng ( ) ;61 stdoutStream . c l o s e ( ) ;6263 return out ;64 }65 St r ing r e s u l t = "Comando "+task . ge t Id ()+" − "+task . getName()+" executado com suce s so . " ;66 f i reTaskExecuted ( task , r e s u l t ) ;67 return r e s u l t ;68 }69 catch ( Exception e ){70 e . pr intStackTrace ( ) ;71 return "Erro ao executar o comando "+task . ge t Id ()+" − "+task . getName()+" : \ n"+e . getMessage ( ) ;72 }73 }7475 public St r ing execute ( ScheduledTask task ){76 St r ing r e s u l t ;77 SystemInfo i n f o = SystemInfoFactory . getSystemInfo ( ) ;78 St r ing [ ] a rgs = task . getArgumentsAsArray ( ) ;7980 switch ( task . getType ( ) ) {81 case ScheduledTask .TYPE_MEMORY:82 i f ( args == null ){83 long t o t a l = i n f o . getSystemTotalMemory ( ) ;84 long used = in f o . getUsedMemoryByProcesses ( ) ;85 task . setTimesExecuted ( task . getTimesExecuted ()+1) ;86 TaskValue value = new TaskValue ( task . ge t Id ()+" . "+task . getTimesExecuted ( ) ) ;87 value . setTask ( task ) ;88 value . setDateTime ( System . cur rentT imeMi l l i s ( ) ) ;89 value . setValue ( to ta l−used ) ;90 task . addTaskValue ( va lue ) ;91 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;92 r e s u l t = "Tarefa "+task . ge t Id ()+" − "+task . getName()+" executada com suce s so . " ;93 f i reTaskExecuted ( task , r e s u l t ) ;94 }95 else i f ( args . l ength == 1){96 i f ( args [ 0 ] . equa l s IgnoreCase ( "−used" ) ){97 long used = in f o . getUsedMemoryByProcesses ( ) ;98 task . setTimesExecuted ( task . getTimesExecuted ()+1) ;

236

99 TaskValue value = new TaskValue ( task . ge t Id ()+" . "+task . getTimesExecuted ( ) ) ;100 value . setTask ( task ) ;101 value . setDateTime ( System . cur r entT imeMi l l i s ( ) ) ;102 value . setValue ( used ) ;103 task . addTaskValue ( va lue ) ;104 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;105 r e s u l t = "Tarefa "+task . ge t Id ()+" − "+task . getName()+" executada com suce s so . " ;106 f i reTaskExecuted ( task , r e s u l t ) ;107 }108 else {109 int pid = i n f o . getPID ( args [ 0 ] ) ;110 long used = in f o . getUsedMemory ( pid ) ;111 task . setTimesExecuted ( task . getTimesExecuted ()+1) ;112 TaskValue value = new TaskValue ( task . ge t Id ()+" . "+task . getTimesExecuted ( ) ) ;113 value . setTask ( task ) ;114 value . setDateTime ( System . cur r entT imeMi l l i s ( ) ) ;115 value . setValue ( used ) ;116 task . addTaskValue ( va lue ) ;117 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;118 r e s u l t = "Tarefa "+task . ge t Id ()+" − "+task . getName()+" executada com suce s so . " ;119 f i reTaskExecuted ( task , r e s u l t ) ;120 }121 }122 else i f ( args . l ength == 2 && args [ 0 ] . equa l s IgnoreCase ( "−v i r t u a l " ) ){123 int pid = i n f o . getPID ( args [ 0 ] ) ;124 long used = in f o . getUsedVirtualMemory ( pid ) ;125 task . setTimesExecuted ( task . getTimesExecuted ()+1) ;126 TaskValue value = new TaskValue ( task . ge t Id ()+" . "+task . getTimesExecuted ( ) ) ;127 value . setTask ( task ) ;128 value . setDateTime ( System . cur rentT imeMi l l i s ( ) ) ;129 value . setValue ( used ) ;130 task . addTaskValue ( va lue ) ;131 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;132 r e s u l t = "Tarefa "+task . ge t Id ()+" − "+task . getName()+" executada com suce s so . " ;133 f i reTaskExecuted ( task , r e s u l t ) ;134 }135 else {136 r e s u l t = "Tipo desconhec ido de t a r e f a ( "+task . ge t Id ()+" − "+task . getName()+" ) . " ;137 }138 break ;139140 case ScheduledTask .TYPE_HD_SPACE:141 //TODO142 long f r eeDi skSpace = i n f o . getFreeDiskSpace ( ) ;143144 task . setTimesExecuted ( task . getTimesExecuted ( )+1) ;145 TaskValue tValue = new TaskValue ( task . ge t Id ()+" . "+task . getTimesExecuted ( ) ) ;146147 tValue . setTask ( task ) ;

237

148 tValue . setDateTime ( System . cur rentT imeMi l l i s ( ) ) ;149 tValue . setValue ( f r eeDi skSpace ) ;150 task . addTaskValue ( tValue ) ;151 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;152 r e s u l t = "Tarefa "+task . ge t Id ()+" − "+task . getName()+" executada com suce s so . " ;153 f i reTaskExecuted ( task , r e s u l t ) ;154155 // r e s u l t = "Tipo de t a r e f a ("+ ta s k . g e t I d ()+" − "+ta sk . getName()+") ainda não implementada . " ;156 // System . out . p r i n t l n ("Espaco Tota l = "+in f o . ge tTota lDiskSpace ( ) ) ;157 // System . out . p r i n t l n ("Espaco Livre = "+in f o . getFreeDiskSpace ( ) ) ;158 // System . out . p r i n t l n ("Espaco Usado = "+in f o . getUsedDiskSpace ( " " ) ) ;159 break ;160161 case ScheduledTask .TYPE_CPU_USE:162 i f ( args == null ){163 long used = in f o . getCPUUse ( ) ;164 task . setTimesExecuted ( task . getTimesExecuted ()+1) ;165 TaskValue value = new TaskValue ( task . ge t Id ()+" . "+task . getTimesExecuted ( ) ) ;166 value . setTask ( task ) ;167 value . setDateTime ( System . cur rentT imeMi l l i s ( ) ) ;168 value . setValue ( used ) ;169 task . addTaskValue ( va lue ) ;170 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;171 r e s u l t = "Tarefa "+task . ge t Id ()+" − "+task . getName()+" executada com suce s so . " ;172 f i reTaskExecuted ( task , r e s u l t ) ;173 }174 else i f ( args . l ength == 1){175 int pid = i n f o . getPID ( args [ 0 ] ) ;176 long used = in f o . getCPUUse ( pid ) ;177 task . setTimesExecuted ( task . getTimesExecuted ()+1) ;178 TaskValue value = new TaskValue ( task . ge t Id ()+" . "+task . getTimesExecuted ( ) ) ;179 value . setTask ( task ) ;180 value . setDateTime ( System . cur rentT imeMi l l i s ( ) ) ;181 value . setValue ( used ) ;182 task . addTaskValue ( va lue ) ;183 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;184 r e s u l t = "Tarefa "+task . ge t Id ()+" − "+task . getName()+" executada com suce s so . " ;185 f i reTaskExecuted ( task , r e s u l t ) ;186 }187 else {188 r e s u l t = "Tipo desconhec ido de t a r e f a ( "+task . ge t Id ()+" − "+task . getName()+" ) . " ;189 }190 break ;191 default :192 r e s u l t = "Tipo desconhec ido de t a r e f a ( "+task . ge t Id ()+" − "+task . getName()+" ) . " ;193 break ;194 }195 return r e s u l t ;196 }

238

197198 public stat ic TaskExecuter ge t In s tance ( ){199 i f ( i n s t anc e == null ){200 in s t anc e = new TaskExecuter ( ) ;201 }202 return i n s t ance ;203 }204205 public boolean addTaskListener ( TaskListener l i s t e n e r ){206 return l i s t e n e r s . add ( l i s t e n e r ) ;207 }208209 public boolean removeTaskListener ( TaskListener l i s t e n e r ){210 return l i s t e n e r s . remove ( l i s t e n e r ) ;211 }212213 public List<TaskListener> getTaskL i s t ene r s ( ){214 return l i s t e n e r s ;215 }216217 public void f i reTaskExecuted (Task task , S t r ing r e s u l t ){218 for ( TaskListener l : l i s t e n e r s ){219 l . taskExecuted ( task , r e s u l t ) ;220 }221 }222223 public void execute ( JobExecutionContext context ) throws JobExecutionException {224 JobDataMap dataMap = context . ge tJobDeta i l ( ) . getJobDataMap ( ) ;225 Task task = (Task )dataMap . get ( " task " ) ;226 ge t In s tance ( ) . execute ( task ) ;227 }228 }

239

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . l i s t e n e r ;56 import u f s c . t c c . s e r v e r . model . Task ;78 /∗∗9 ∗ @author G i l b e r t o Torrezan Fi lho10 ∗/11 public interface TaskListener {12 public void taskExecuted (Task task , S t r ing r e s u l t ) ;13 }

240

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i ;56 import java . awt . BorderLayout ;7 import java . awt . Dimension ;8 import java . awt . Frame ;9 import java . awt . GridLayout ;10 import java . awt . event . ActionEvent ;11 import java . awt . event . Act i onL i s t ene r ;12 import java . awt . event . MouseAdapter ;13 import java . awt . event . MouseEvent ;14 import java . u t i l . Co l l e c t i on ;1516 import javax . swing . BorderFactory ;17 import javax . swing . Box ;18 import javax . swing . BoxLayout ;19 import javax . swing . JButton ;20 import javax . swing . JPanel ;21 import javax . swing . JScro l lPane ;22 import javax . swing . JSeparator ;23 import javax . swing . JTable ;24 import javax . swing . L i s tSe l e c t i onMode l ;25 import javax . swing . Sw i n gU t i l i t i e s ;26 import javax . swing . event . L i s tS e l e c t i onEven t ;27 import javax . swing . event . L i s t S e l e c t i o nL i s t e n e r ;28 import javax . swing . t ab l e . TableColumnModel ;2930 import u f s c . t c c . s e r v e r . c o n t r o l l e r . Ex i tCont ro l l e r ;31 import u f s c . t c c . s e r v e r . c o n t r o l l e r . QuartzScheduler ;32 import u f s c . t c c . s e r v e r . c o n t r o l l e r . TaskExecuter ;33 import u f s c . t c c . s e r v e r . c o n t r o l l e r . WaitContro l l e r ;34 import u f s c . t c c . s e r v e r . c o n t r o l l e r . l i s t e n e r . TaskListener ;35 import u f s c . t c c . s e r v e r . gu i . tablemodel . TableSorter ;36 import u f s c . t c c . s e r v e r . gu i . tablemodel . TaskTableModel ;37 import u f s c . t c c . s e r v e r . model . ScheduledTask ;38 import u f s c . t c c . s e r v e r . model . Task ;39 import u f s c . t c c . s e r v e r . p e r s i s t e n c e . H ibernateUt i l ;4041 /∗∗42 ∗ @author G i l b e r t o Torrezan Fi lho43 ∗/44 public class TaskPanel extends JPanel implements TaskListener {4546 private JPanel47 l e f t = new JPanel ( ) ,48 cente r = new JPanel ( ) ;49

241

50 private TaskTableModel51 model = new TaskTableModel ( ) ;5253 private TableSorter54 s o r t e r = new TableSorter (model ) ;5556 private JTable57 tab l e = new JTable ( s o r t e r ) ;5859 private JScro l lPane60 s c r o l l = new JScro l lPane ( t ab l e ) ;6162 private JButton63 add = new JButton ( "Adic ionar Tarefa . . . " ) ,64 update = new JButton ( "Al t e ra r Tarefa . . . " ) ,65 remove = new JButton ( "Remover Tarefa " ) ,66 execute = new JButton ( "Executar Tarefa " ) ,67 va lue s = new JButton ( "Valores Medidos . . . " ) ,68 vnc = new JButton ( " Serv idor VNC. . . " ) ,69 c r e d i t s = new JButton ( "Créd i tos " ) ,70 e x i t = new JButton ( " Sa i r " ) ;7172 private TaskValueDialog tvd ;7374 public TaskPanel ( ){75 this . setLayout (new BorderLayout ( ) ) ;76 this . add ( center , BorderLayout .CENTER) ;77 this . add ( l e f t , BorderLayout .WEST) ;7879 cente r . setLayout (new GridLayout ( 1 , 1 , 0 , 0 ) ) ;80 cente r . add ( s c r o l l ) ;8182 l e f t . setLayout (new BoxLayout ( l e f t , BoxLayout .Y_AXIS) ) ;8384 s o r t e r . setTableHeader ( t ab l e . getTableHeader ( ) ) ;8586 JPanel [ ] pane l s = new JPanel [ 8 ] ;87 for ( int i = 0 ; i< pane l s . l ength ; i++){88 pane l s [ i ] = new JPanel ( ) ;89 pane l s [ i ] . setLayout (new BoxLayout ( pane l s [ i ] , BoxLayout .X_AXIS) ) ;90 pane l s [ i ] . add (Box . c r ea t eHor i zonta lG lue ( ) ) ;91 }9293 pane l s [ 0 ] . add ( add ) ;94 pane l s [ 0 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;9596 pane l s [ 1 ] . add ( update ) ;97 pane l s [ 1 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;98

242

99 pane l s [ 2 ] . add ( remove ) ;100 pane l s [ 2 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;101102 pane l s [ 3 ] . add ( execute ) ;103 pane l s [ 3 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;104105 pane l s [ 4 ] . add ( va lue s ) ;106 pane l s [ 4 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;107108 pane l s [ 5 ] . add ( vnc ) ;109 pane l s [ 5 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;110111 pane l s [ 6 ] . add ( c r e d i t s ) ;112 pane l s [ 6 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;113114 pane l s [ 7 ] . add ( e x i t ) ;115 pane l s [ 7 ] . add (Box . c r ea teHor i zonta lG lue ( ) ) ;116117 int s = 25 ;118119 l e f t . add (Box . c r e a t eVe r t i c a l S t r u t ( 5 0 ) ) ;120 l e f t . add ( pane l s [ 0 ] ) ;121 l e f t . add (Box . c r e a t eVe r t i c a l S t r u t ( s ) ) ;122 l e f t . add ( pane l s [ 1 ] ) ;123 l e f t . add (Box . c r e a t eVe r t i c a l S t r u t ( s ) ) ;124 l e f t . add ( pane l s [ 2 ] ) ;125 l e f t . add (Box . c r e a t eVe r t i c a l S t r u t ( s ) ) ;126 l e f t . add ( pane l s [ 3 ] ) ;127 l e f t . add (Box . c r e a t eVe r t i c a l S t r u t ( s ) ) ;128 l e f t . add ( pane l s [ 4 ] ) ;129 l e f t . add (Box . c r e a t eVe r t i c a lG lue ( ) ) ;130 l e f t . add (new JSeparator ( ) ) ;131 l e f t . add ( pane l s [ 5 ] ) ;132 l e f t . add (Box . c r e a t eVe r t i c a l S t r u t ( s ) ) ;133 l e f t . add ( pane l s [ 6 ] ) ;134 l e f t . add (Box . c r e a t eVe r t i c a l S t r u t ( s ) ) ;135 l e f t . add ( pane l s [ 7 ] ) ;136 l e f t . add (Box . c r e a t eVe r t i c a lG lue ( ) ) ;137138 s c r o l l . se tBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Tare fas cadast radas " ) ) ;139140 Dimension d = new Dimension ( 160 , 2 4 ) ;141 add . s e tP r e f e r r e dS i z e (d ) ;142 update . s e tP r e f e r r e dS i z e (d ) ;143 remove . s e tP r e f e r r e dS i z e (d ) ;144 execute . s e tP r e f e r r e dS i z e (d ) ;145 va lue s . s e tP r e f e r r e dS i z e (d ) ;146 vnc . s e tP r e f e r r e dS i z e (d ) ;147 c r e d i t s . s e tP r e f e r r e dS i z e (d ) ;

243

148 e x i t . s e tP r e f e r r e dS i z e (d ) ;149150 l e f t . s e tP r e f e r r e dS i z e (new Dimension ( 200 , 5 00 ) ) ;151 l e f t . setMinimumSize (new Dimension ( 2 0 0 , 0 ) ) ;152153 tab l e . ge tSe l ec t i onMode l ( ) . se tSe lect ionMode ( L i s tSe l e c t i onMode l .SINGLE_SELECTION) ;154155 TableColumnModel tcm = tab l e . getColumnModel ( ) ;156 tcm . getColumn ( 0 ) . setPre ferredWidth ( 5 0 ) ;157 tcm . getColumn ( 1 ) . setPre ferredWidth ( 1 7 5 ) ;158 tcm . getColumn ( 2 ) . setPre ferredWidth ( 1 7 5 ) ;159 tcm . getColumn ( 3 ) . setPre ferredWidth ( 2 0 0 ) ;160 tcm . getColumn ( 4 ) . setPre ferredWidth ( 7 5 ) ;161 tcm . getColumn ( 5 ) . setPre ferredWidth ( 1 7 5 ) ;162163 va lue s . setEnabled ( fa l se ) ;164165 tab l e . ge tSe l ec t i onMode l ( ) . a ddL i s t S e l e c t i o nL i s t e n e r (new L i s t S e l e c t i o nL i s t e n e r ( ){166 public void valueChanged ( L i s tS e l e c t i onEven t e ) {167 int row = tab l e . getSelectedRow ( ) ;168 i f ( row >= 0){169 Task t = (Task ) s o r t e r . getValueAt ( row ,−1) ;170 i f ( t != null && t instanceof ScheduledTask ){171 va lue s . setEnabled ( true ) ;172 }173 else {174 va lues . setEnabled ( fa l se ) ;175 }176 }177 else {178 va lue s . setEnabled ( fa l se ) ;179 }180 }181 } ) ;182183 tab l e . addMouseListener (new MouseAdapter ( ){184 @Override185 public void mouseClicked (MouseEvent e ) {186 i f ( e . getCl ickCount ( ) >= 2){187 int row = tab l e . getSelectedRow ( ) ;188 i f ( row >= 0){189 Task t = (Task ) s o r t e r . getValueAt ( row ,−1) ;190 i f ( t != null ){191 TaskDialog td = new TaskDialog ( ( Frame) getTopLevelAncestor ( ) , true ) ;192 td . setTask ( t ) ;193 td . s e tV i s i b l e ( true ) ;194 }195 }196 }

244

197 else i f ( Sw i n gU t i l i t i e s . isRightMouseButton ( e ) ){198 int row = tab l e . getSelectedRow ( ) ;199 i f ( row >= 0){200 Task t = (Task ) s o r t e r . getValueAt ( row ,−1) ;201 i f ( t != null && t instanceof ScheduledTask ){202 i f ( tvd == null )203 tvd = new TaskValueDialog ( ( Frame) getTopLevelAncestor ( ) ) ;204 tvd . setTask ( ( ScheduledTask ) t ) ;205 tvd . s e tV i s i b l e ( true ) ;206 }207 }208 }209 }210 } ) ;211212 add . addAct ionListener (new Act ionL i s t ene r ( ){213 public void act ionPerformed ( ActionEvent e ) {214 TaskDialog td = new TaskDialog ( ( Frame) getTopLevelAncestor ( ) , fa l se ) ;215 td . s e tV i s i b l e ( true ) ;216 }217 } ) ;218219 update . addAct ionListener (new Act ionL i s t ene r ( ){220 public void act ionPerformed ( ActionEvent e ) {221 int row = tab l e . getSelectedRow ( ) ;222 i f ( row >= 0){223 Task t = (Task ) s o r t e r . getValueAt ( row ,−1) ;224 i f ( t != null ){225 TaskDialog td = new TaskDialog ( ( Frame) getTopLevelAncestor ( ) , true ) ;226 td . setTask ( t ) ;227 td . s e tV i s i b l e ( true ) ;228 }229 }230 }231 } ) ;232233 remove . addAct ionLis tener (new Act ionL i s t ene r ( ){234 public void act ionPerformed ( ActionEvent e ) {235 int row = tab l e . getSelectedRow ( ) ;236 i f ( row >= 0){237 Task t = (Task ) s o r t e r . getValueAt ( row ,−1) ;238 i f ( t != null ){239 HibernateUt i l . getTaskDAO ( ) . removeTask ( t ) ;240 QuartzScheduler . unscheculeTask ( t ) ;241 model . removeItem ( t ) ;242 }243 }244 }245 } ) ;

245

246247 execute . addAct ionListener (new Act ionL i s t ene r ( ){248 public void act ionPerformed ( ActionEvent e ) {249 int row = tab l e . getSelectedRow ( ) ;250 i f ( row >= 0){251 Task t = (Task ) s o r t e r . getValueAt ( row ,−1) ;252 i f ( t != null ){253 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Executando t a r e f a . . . " ) ;254 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng (255 TaskExecuter . g e t In s tance ( ) . execute ( t ) ) ;256 }257 }258 }259 } ) ;260261 va lue s . addAct ionListener (new Act ionL i s t ene r ( ){262 public void act ionPerformed ( ActionEvent e ) {263 int row = tab l e . getSelectedRow ( ) ;264 i f ( row >= 0){265 Task t = (Task ) s o r t e r . getValueAt ( row ,−1) ;266 i f ( t != null && t instanceof ScheduledTask ){267 i f ( tvd == null )268 tvd = new TaskValueDialog ( ( Frame) getTopLevelAncestor ( ) ) ;269 tvd . setTask ( ( ScheduledTask ) t ) ;270 tvd . s e tV i s i b l e ( true ) ;271 }272 }273 }274 } ) ;275276 vnc . addAct ionListener (new Act ionL i s t ene r ( ){277 public void act ionPerformed ( ActionEvent e ) {278 new BridgeServerDia log ( ( Frame) getTopLevelAncestor ( ) ) . s e tV i s i b l e ( true ) ;279 }280 } ) ;281282 e x i t . addAct ionListener (new Act ionL i s t ene r ( ){283 public void act ionPerformed ( ActionEvent e ) {284 Ex i tCont ro l l e r . e x i t ( 0 ) ;285 }286 } ) ;287288 }289290 public void setTasks ( Co l l e c t i on<Task> tasks ){291 model . updateData ( ta sk s ) ;292 }293294 public void addTask (Task task ){

246

295 model . addItem ( task ) ;296 }297298 public void removeTask (Task task ){299 model . removeItem ( task ) ;300 }301302 public void updateTasks ( ){303 model . f ireTableDataChanged ( ) ;304 }305306 public void updateTask (Task task ){307 model . update ( task ) ;308 }309310 public void taskExecuted (Task task , S t r ing r e s u l t ) {311 model . update ( task ) ;312 i f ( tvd != null && tvd . getTask ( ) != null && tvd . getTask ( ) . equa l s ( task ) ){313 tvd . setTask ( ( ScheduledTask ) task ) ;314 }315 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( r e s u l t ) ;316 }317 }

247

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i . tablemodel ;56 import u f s c . t c c . s e r v e r . model .CommandTask ;7 import u f s c . t c c . s e r v e r . model . ScheduledTask ;8 import u f s c . t c c . s e r v e r . model . Task ;910 /∗∗11 ∗ @author G i l b e r t o Torrezan Fi lho12 ∗/13 public class TaskTableModel extends GenericTableModel<Task> {1415 public TaskTableModel ( ){16 super ( " Id" , "Nome" , "Descr i ção " , "Tipo" , "Vezes Executada" , "Atr ibutos " ) ;17 }1819 @Override20 public Object getValueAt ( int row , int column ) {21 Task t = data . get ( row ) ;22 switch ( column ){23 case −1: return t ;24 case 0 : return ""+t . get Id ( ) ;25 case 1 : return t . getName ( ) ;26 case 2 : return t . g e tDe s c r i p t i on ( ) ;27 case 3 : return getTaskType ( t ) ;28 case 4 : return ""+t . getTimesExecuted ( ) ;29 case 5 : return ge tAt t r i bu t e s ( t ) ;30 }31 return null ;32 }3334 private St r ing getTaskType (Task t ){35 i f ( t instanceof CommandTask){36 CommandTask c = (CommandTask) t ;37 i f ( c . isWaitForReturn ( ) ) {38 return "Comando − gera output" ;39 }40 return "Comando − não gera output " ;41 }42 else i f ( t instanceof ScheduledTask ){43 ScheduledTask s = ( ScheduledTask ) t ;44 St r ing [ ] a rgs = s . getArgumentsAsArray ( ) ;45 switch ( s . getType ( ) ) {46 case ScheduledTask .TYPE_CPU_USE:47 i f ( args == null ){48 return "Aval iação do uso de CPU por todos os p ro c e s s o s " ;49 }

248

50 else i f ( args . l ength == 1){51 return "Aval iação do uso de CPU pe lo proce s so \""+args [0 ]+ "\"" ;52 }53 break ;54 case ScheduledTask .TYPE_HD_SPACE:55 return "Aval iação do espaço em d i s co " ;56 case ScheduledTask .TYPE_MEMORY:57 i f ( args == null ){58 return "Aval iação da memória l i v r e " ;59 }60 else i f ( args . l ength == 1){61 i f ( args [ 0 ] . equa l s IgnoreCase ( "−used" ) ){62 return "Aval iação do uso de memória por todos os p ro c e s s o s " ;63 }64 else {65 return "Aval iação do uso de memória pe lo proce s so \""+args [0 ]+ "\"" ;66 }67 }68 else i f ( args . l ength == 2 && args [ 0 ] . equa l s IgnoreCase ( "−v i r t u a l " ) ){69 return "Aval iação do uso de memória v i r t u a l pe lo proce s so \""+args [1 ]+ "\"" ;70 }71 break ;72 }73 }74 return "Tipo indeterminado " ;75 }7677 private St r ing ge tAt t r i bu t e s (Task t ){78 i f ( t instanceof CommandTask){79 CommandTask c = (CommandTask) t ;80 return c . getCommand ( ) ;81 }82 else i f ( t instanceof ScheduledTask ){83 ScheduledTask s = ( ScheduledTask ) t ;84 return s . ge tSchedu leExpres s ion ( ) ;85 }86 return "" ;87 }8889 }

249

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i ;56 import java . awt . BorderLayout ;7 import java . awt . Dimension ;8 import java . awt . Frame ;9 import java . awt . GridLayout ;10 import java . awt . event . ActionEvent ;11 import java . awt . event . Act i onL i s t ene r ;12 import java . awt . event .WindowAdapter ;13 import java . awt . event .WindowEvent ;14 import java . u t i l . ArrayList ;15 import java . u t i l . L i s t ;1617 import javax . swing . BorderFactory ;18 import javax . swing . JButton ;19 import javax . swing . JDialog ;20 import javax . swing . JOptionPane ;21 import javax . swing . JPanel ;22 import javax . swing . JScro l lPane ;23 import javax . swing . JTable ;24 import javax . swing . t ab l e . TableColumnModel ;2526 import org . j f r e e . chart . ChartFrame ;27 import org . j f r e e . chart . JFreeChart ;2829 import u f s c . t c c . s e r v e r . c o n t r o l l e r . ChartContro l l e r ;30 import u f s c . t c c . s e r v e r . gu i . tablemodel . TableSorter ;31 import u f s c . t c c . s e r v e r . gu i . tablemodel . TaskValueTableModel ;32 import u f s c . t c c . s e r v e r . model . ScheduledTask ;33 import u f s c . t c c . s e r v e r . model . TaskValue ;34 import u f s c . t c c . s e r v e r . p e r s i s t e n c e . H ibernateUt i l ;3536 /∗∗37 ∗ @author G i l b e r t o Torrezan Fi lho38 ∗/39 public class TaskValueDialog extends JDialog {4041 private JPanel42 down = new JPanel ( ) ,43 cente r = new JPanel ( ) ;4445 private TaskValueTableModel46 model = new TaskValueTableModel ( ) ;4748 private TableSorter49 s o r t e r = new TableSorter (model ) ;

250

5051 private JTable52 tab l e = new JTable ( s o r t e r ) ;5354 private JScro l lPane55 s c r o l l = new JScro l lPane ( t ab l e ) ;5657 private JButton58 char t s = new JButton ( "Grá f i co s . . . " ) ,59 remove = new JButton ( "Remover" ) ,60 c l o s e = new JButton ( "Fechar" ) ;6162 private ScheduledTask task ;6364 public TaskValueDialog (Frame owner ){65 super ( owner , "Valores Medidos" , true ) ;66 se tDe fau l tC lo seOperat ion ( JDialog .DISPOSE_ON_CLOSE) ;67 pack ( ) ;68 s e t S i z e ( 400 , 580 ) ;69 se tLocat ionRe lat iveTo ( null ) ;7071 this . getContentPane ( ) . setLayout (new BorderLayout ( ) ) ;72 this . getContentPane ( ) . add ( center , BorderLayout .CENTER) ;73 this . getContentPane ( ) . add (down , BorderLayout .SOUTH) ;7475 down . add ( char t s ) ;76 down . add ( remove ) ;77 down . add ( c l o s e ) ;7879 cente r . setLayout (new GridLayout ( 1 , 1 , 0 , 0 ) ) ;80 cente r . add ( s c r o l l ) ;8182 s o r t e r . setTableHeader ( t ab l e . getTableHeader ( ) ) ;83 s c r o l l . se tBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Valores da Tarefa " ) ) ;8485 TableColumnModel tcm = tab l e . getColumnModel ( ) ;86 tcm . getColumn ( 0 ) . setPre ferredWidth ( 5 0 ) ;87 tcm . getColumn ( 1 ) . setPre ferredWidth ( 1 7 5 ) ;88 tcm . getColumn ( 2 ) . setPre ferredWidth ( 2 2 5 ) ;8990 Dimension d = new Dimension ( 120 , 2 4 ) ;91 char t s . s e tP r e f e r r e dS i z e (d ) ;92 remove . s e tP r e f e r r e dS i z e (d ) ;93 c l o s e . s e tP r e f e r r e dS i z e (d ) ;9495 this . addWindowListener (new WindowAdapter ( ){96 @Override97 public void windowClosing (WindowEvent e ) {98 task = null ;

251

99 model . c l e a r ( ) ;100 }101 } ) ;102103 char t s . addAct ionListener (new Act ionL i s t ene r ( ){104 public void act ionPerformed ( ActionEvent e ) {105 int [ ] rows = tab l e . getSelectedRows ( ) ;106 List<TaskValue> l i s t ;107 i f ( rows == null | | rows . l ength <= 1){108 l i s t = model . getData ( ) ;109 }110 else {111 l i s t = new ArrayList<TaskValue >() ;112 for ( int i = 0 ; i< rows . l ength ; i++){113 l i s t . add ( ( TaskValue ) s o r t e r . getValueAt ( rows [ i ] , −1) ) ;114 }115 }116 i f ( l i s t . s i z e ( ) > 1){117 St r ing [ ] opts = new St r ing [ ] { "Linha" , "Barra" , "Pizza " , "Cancelar " } ;118 JOptionPane opt = new JOptionPane ( "Que forma de g r á f i c o de s e j a c r i a r para e s s e s v a l o r e s ? . " , JOptionPane .QUESTION_MESSAGE,119 JOptionPane .OK_OPTION, null , opts ) ;120 opt . c r ea t eD ia l og ( TaskValueDialog . this , "Grá f i co " ) . s e tV i s i b l e ( true ) ;121 Object obj = opt . getValue ( ) ;122 i f ( obj != null && ! obj . equa l s ( opts [ 3 ] ) ) {123 int type ;124 i f ( obj . equa l s ( opts [ 0 ] ) ) {125 type = ChartContro l l e r .TYPE_LINE;126 }127 else i f ( obj . equa l s ( opts [ 1 ] ) ) {128 type = ChartContro l l e r .TYPE_BARS;129 }130 else {131 type = ChartContro l l e r .TYPE_PIE;132 }133 JFreeChart chart = ChartContro l l e r . c reateChart ( l i s t , type ) ;134 ChartFrame frame = new ChartFrame ( "Grá f i co " , chart ) ;135 frame . s e t S i z e (new Dimension ( 960 , 6 40 ) ) ;136 frame . se tLocat ionRe lat iveTo ( null ) ;137 s e tV i s i b l e ( fa l se ) ;138 d i spo s e ( ) ;139 frame . s e tV i s i b l e ( true ) ;140 }141 }142 }143 } ) ;144145 remove . addAct ionLis tener (new Act ionL i s t ene r ( ){146 public void act ionPerformed ( ActionEvent e ) {147 int [ ] rows = tab l e . getSelectedRows ( ) ;

252

148 i f ( rows != null && rows . l ength > 0){149 TaskValue [ ] tvs = new TaskValue [ rows . l ength ] ;150 for ( int i = 0 ; i< rows . l ength ; i++){151 tvs [ i ] = ( TaskValue ) s o r t e r . getValueAt ( rows [ i ] , −1) ;152 task . removeTaskValue ( tvs [ i ] ) ;153 }154 HibernateUt i l . getTaskDAO ( ) . removeTaskValues ( tvs ) ;155 HibernateUt i l . getTaskDAO ( ) . updateTask ( task ) ;156 MainFrame . ge t In s tance ( ) . getTaskPanel ( ) . updateTask ( task ) ;157 setTask ( task ) ;158 }159 }160 } ) ;161162 c l o s e . addAct ionListener (new Act ionL i s t ene r ( ){163 public void act ionPerformed ( ActionEvent e ) {164 s e tV i s i b l e ( fa l se ) ;165 d i spo s e ( ) ;166 task = null ;167 model . c l e a r ( ) ;168 }169 } ) ;170 }171172 public synchronized ScheduledTask getTask ( ) {173 return task ;174 }175176 public synchronized void setTask ( ScheduledTask task ){177 this . task = task ;178 model . updateData ( task . getTaskValues ( ) ) ;179 s c r o l l . s e tBorder ( BorderFactory . c r ea t eT i t l edBorde r ( "Valores da Tarefa "+task . ge t Id ()+" − "+task . getName ( ) ) ) ;180 }181 }

253

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r ;56 import java . t ex t . DateFormat ;7 import java . t ex t . NumberFormat ;8 import java . u t i l . Date ;9 import java . u t i l . L i s t ;1011 import u f s c . t c c . s e r v e r . model . ScheduledTask ;12 import u f s c . t c c . s e r v e r . model . TaskValue ;1314 /∗∗15 ∗ @author G i l b e r t o Torrezan Fi lho16 ∗/17 public class TaskValuesContro l l e r {18 private TaskValuesContro l l e r ( ){}1920 public stat ic St r ing getCa lcu latedValues ( ScheduledTask task ){21 List<TaskValue> l i s t = task . getTaskValues ( ) ;22 i f ( l i s t . isEmpty ( ) ) {23 return "Não há va l o r e s medidos para a t a r e f a "+task . getName()+" ( "+task . g e tDe s c r i p t i on ()+" ) . " ;24 }25 else {26 TaskValue min = l i s t . get ( 0 ) ;27 TaskValue max = l i s t . get ( 0 ) ;28 TaskValue l a s t = l i s t . s i z e ( ) > 1 ? l i s t . get ( l i s t . s i z e ()−1) : l i s t . get ( 0 ) ;29 double avg = 0 ;30 for ( TaskValue v : l i s t ){31 i f ( v . getValue ( ) < min . getValue ( ) ) {32 min = v ;33 }34 i f ( v . getValue ( ) > max . getValue ( ) ) {35 max = v ;36 }37 avg += v . getValue ( ) ;38 }39 avg /= l i s t . s i z e ( ) ;40 S t r i ngBu f f e r bu f f = new St r i ngBu f f e r ( ) ;41 bu f f . append ( " E s t a t í s t i c a s da t a r e f a "+task . getName()+" ( "+task . g e tDe s c r i p t i on ()+" ) : \ n" ) ;42 bu f f . append ( "\nÚltima medição : \ n" ) ;43 bu f f . append (DateFormat . getDateTimeInstance ( ) . format (new Date ( l a s t . getDateTime ()))+"\n" +44 "Valor : "+NumberFormat . g e t In s tance ( ) . format ( l a s t . getValue ( ) ) ) ;45 bu f f . append ( "\n\nValor mínimo : \ n" ) ;46 bu f f . append (DateFormat . getDateTimeInstance ( ) . format (new Date (min . getDateTime ()))+"\n" +47 "Valor : "+NumberFormat . g e t In s tance ( ) . format (min . getValue ( ) ) ) ;48 bu f f . append ( "\n\nValor máximo : \ n" ) ;49 bu f f . append (DateFormat . getDateTimeInstance ( ) . format (new Date (max . getDateTime ()))+"\n" +

254

50 "Valor : "+NumberFormat . g e t In s tance ( ) . format (max . getValue ( ) ) ) ;51 bu f f . append ( "\n\nMédia : " ) ;52 bu f f . append (NumberFormat . g e t In s tance ( ) . format ( avg ) ) ;53 bu f f . append ( "\nNúmero de medições : " ) ;54 bu f f . append ( l i s t . s i z e ( ) ) ;55 return bu f f . t oS t r i ng ( ) ;56 }57 }58 }

255

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i . tablemodel ;56 import java . t ex t . DateFormat ;7 import java . u t i l . Date ;89 import u f s c . t c c . s e r v e r . model . TaskValue ;1011 /∗∗12 ∗ @author G i l b e r t o Torrezan Fi lho13 ∗/14 public class TaskValueTableModel extends GenericTableModel<TaskValue>{1516 public TaskValueTableModel ( ){17 super ( "No" , "Data" , "Valor " ) ;18 }1920 @Override21 public Object getValueAt ( int row , int column ) {22 TaskValue tv = data . get ( row ) ;23 switch ( column ){24 case −1: return tv ;25 case 0 : return tv . ge t Id ( ) . sub s t r i ng ( tv . ge t Id ( ) . indexOf ( ' . ' )+1) ;26 case 1 : return DateFormat . getDateTimeInstance ( ) . format (new Date ( tv . getDateTime ( ) ) ) ;27 case 2 : return ""+( int ) tv . getValue ( ) ;28 }29 return null ;30 }3132 }

256

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . main ;56 /∗∗7 ∗ @author G i l b e r t o Torrezan Fi lho8 ∗/9 public class Vers ion {10 private Vers ion (){}1112 public stat ic St r ing getProductName ( ){13 return "Gerenciador de Tare fas v ia VNC" ;14 }15 public stat ic St r ing getLastCompilat ionDate ( ){16 return "06/11/2006" ;17 }18 public stat ic St r ing getVers ion ( ){19 return " 1 .0 " ;20 }21 }

257

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r ;56 import java . u t i l . L i s t ;7 import java . u t i l . Vector ;89 import u f s c . t c c . s e r v e r . c o n t r o l l e r . l i s t e n e r . WaitListener ;1011 /∗∗12 ∗ @author G i l b e r t o Torrezan Fi lho13 ∗/14 public class WaitContro l l e r {1516 private stat ic WaitContro l l e r i n s t anc e ;17 private List<WaitListener> l i s t e n e r s ;1819 private WaitContro l l e r ( ){20 l i s t e n e r s = new Vector<WaitListener >() ;21 }2223 public boolean addWaitListener ( WaitListener l i s t e n e r ){24 return l i s t e n e r s . add ( l i s t e n e r ) ;25 }2627 public boolean removeWaitListener ( WaitListener l i s t e n e r ){28 return l i s t e n e r s . remove ( l i s t e n e r ) ;29 }3031 public WaitListener [ ] ge tWai tL i s t ener s ( ){32 return l i s t e n e r s . toArray (new WaitListener [ 0 ] ) ;33 }3435 public void f i r eS e tWa i t i ng ( f ina l St r ing message ){36 new Thread ( ){37 public void run ( ){38 for ( WaitListener w : l i s t e n e r s ){39 w. setWait ing ( message ) ;40 }41 }42 } . s t a r t ( ) ;43 }4445 public stat ic WaitContro l l e r g e t In s tance ( ){46 i f ( i n s t anc e == null ){47 in s t anc e = new WaitContro l l e r ( ) ;48 }49 return i n s t ance ;

258

50 }51 }

259

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . c o n t r o l l e r . l i s t e n e r ;56 /∗∗7 ∗ @author G i l b e r t o Torrezan Fi lho8 ∗/9 public interface WaitListener {10 public void setWait ing ( S t r ing message ) ;11 }

260

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . gu i ;56 import java . awt . Dimension ;78 import javax . swing . Box ;9 import javax . swing . BoxLayout ;10 import javax . swing . JLabel ;11 import javax . swing . JPanel ;1213 /∗∗14 ∗ @author G i l b e r t o Torrezan Fi lho15 ∗/16 public class WaitPanel extends JPanel {17 private JLabel18 label = new JLabel ( ) ;1920 public WaitPanel ( ){21 this . setLayout (new BoxLayout ( this , BoxLayout .X_AXIS) ) ;22 this . add (Box . c r e a t eHo r i z on ta l S t ru t ( 1 5 ) ) ;23 this . add ( label ) ;24 this . add (Box . c r ea teHor i zonta lG lue ( ) ) ;25 this . add (Box . createRig idArea (new Dimension ( 1 , 2 1 ) ) ) ;26 }2728 public void setText ( S t r ing text ){29 label . setText ( t ex t ) ;30 }3132 public St r ing getText ( ){33 return label . getText ( ) ;34 }35 }

261

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . model ;56 import javax . p e r s i s t e n c e . Entity ;789 /∗∗10 ∗ @author G i l b e r t o Torrezan Fi lho11 ∗/12 @Entity13 public class CommandTask extends Task{1415 private St r ing command ;16 private boolean waitForReturn ;1718 public CommandTask(){}1920 public CommandTask( St r ing command , boolean waitForReturn ){21 this . command = command ;22 this . waitForReturn = waitForReturn ;23 }2425 public St r ing getCommand ( ) {26 return command ;27 }2829 public void setCommand( St r ing command) {30 this . command = command ;31 }3233 public boolean isWaitForReturn ( ) {34 return waitForReturn ;35 }3637 public void setWaitForReturn (boolean waitForReturn ) {38 this . waitForReturn = waitForReturn ;39 }40 }

262

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . model ;56 import java . i o . F i l e ;7 import java . i o . Fi le InputStream ;8 import java . i o . FileOutputStream ;9 import java . i o . IOException ;10 import java . u t i l . P rope r t i e s ;1112 /∗∗13 ∗ @author G i l b e r t o Torrezan Fi lho14 ∗/15 public class Connect ionPropert i e s extends Prope r t i e s {16 public stat ic f ina l St r ing17 VNC_SERVER_IP = "VNC_SERVER_IP" ,18 BRIDGE_PORT = "BRIDGE_PORT" ,19 VNC_SERVER_PORT = "VNC_SERVER_PORT" ;2021 private f ina l St r ing f i l e = " connect ion . p r op e r t i e s " ;2223 private stat ic Connect ionPropert i e s i n s t ance ;2425 public void save ( ) throws IOException{26 F i l e f = new F i l e ( f i l e ) ;27 f . createNewFi le ( ) ;28 FileOutputStream f o s = new FileOutputStream ( f ) ;29 this . s t o r e ( fos , "Connection Prope r t i e s " ) ;30 f o s . f l u s h ( ) ;31 f o s . c l o s e ( ) ;32 }3334 public void load ( ) throws IOException{35 F i l e f = new F i l e ( f i l e ) ;36 i f ( f . e x i s t s ( ) ) {37 Fi le InputStream f i s = new Fi leInputStream ( f ) ;38 this . load ( f i s ) ;39 f i s . c l o s e ( ) ;40 }41 else {42 this . put (VNC_SERVER_IP, " 1 2 7 . 0 . 0 . 1 " ) ;43 this . put (VNC_SERVER_PORT, "5900" ) ;44 this . put (BRIDGE_PORT, "8081" ) ;45 }46 }4748 public stat ic Connect ionPropert i e s g e t In s tance ( ){49 i f ( i n s t anc e == null ){

263

50 in s t anc e = new Connect ionPropert i e s ( ) ;51 }52 return i n s t ance ;53 }54 }

264

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . model ;56 import java . u t i l . ArrayList ;7 import java . u t i l . L i s t ;8 import java . u t i l . S t r ingToken ize r ;9 import java . u t i l . Vector ;1011 import javax . p e r s i s t e n c e . CascadeType ;12 import javax . p e r s i s t e n c e . Entity ;13 import javax . p e r s i s t e n c e . FetchType ;14 import javax . p e r s i s t e n c e .OneToMany ;15 import javax . p e r s i s t e n c e . OrderBy ;161718 /∗∗19 ∗ @author G i l b e r t o Torrezan Fi lho20 ∗/21 @Entity22 public class ScheduledTask extends Task{2324 public stat ic f ina l int

25 TYPE_MEMORY = 0 ,26 TYPE_CPU_USE = 1 ,27 TYPE_HD_SPACE = 2 ;2829 private int type ;30 private St r ing schedu leExpres s i on ;31 private St r ing arguments ;3233 @OneToMany(mappedBy=" task " , cascade=CascadeType .ALL, f e t ch = FetchType .EAGER)34 @OrderBy( "dateTime" )35 private List<TaskValue> taskValues ;3637 public ScheduledTask ( ){38 this . taskValues = new Vector<TaskValue >() ;39 }4041 public ScheduledTask ( int type , S t r ing . . . a rgs ){42 this ( ) ;43 this . type = type ;44 i f ( args != null ){45 arguments = "" ;46 for ( S t r ing arg : args ){47 arguments += arg+" " ;48 }49 }

265

50 }5152 public St r ing getSchedu leExpres s ion ( ) {53 return s chedu leExpres s i on ;54 }5556 public void s e tSchedu l eExpre s s i on ( S t r ing schedu leExpres s i on ) {57 this . s chedu leExpres s ion = schedu leExpres s i on ;58 }5960 public int getType ( ) {61 return type ;62 }6364 public void setType ( int type ) {65 this . type = type ;66 }6768 public St r ing getArguments ( ) {69 return arguments ;70 }7172 public void setArguments ( S t r ing arguments ) {73 this . arguments = arguments ;74 }7576 public St r ing [ ] getArgumentsAsArray ( ){77 i f ( arguments == null ){78 return null ;79 }80 Str ingToken ize r toker = new Str ingToken ize r ( arguments , " " ) ;81 Lis t<Str ing> l i s t = new ArrayList<Str ing >() ;82 while ( toker . hasMoreTokens ( ) ) {83 l i s t . add ( toker . nextToken ( ) ) ;84 }85 return l i s t . toArray (new St r ing [ 0 ] ) ;86 }8788 public boolean addTaskValue ( TaskValue value ){89 return taskValues . add ( value ) ;90 }9192 public boolean removeTaskValue ( TaskValue value ){93 return taskValues . remove ( value ) ;94 }9596 public List<TaskValue> getTaskValues ( ){97 return taskValues ;98 }

266

99100 public void setTaskValues ( Li s t<TaskValue> taskValues ) {101 this . taskValues = taskValues ;102 }103104 public void removeAllTaskValues ( ){105 taskValues . c l e a r ( ) ;106 }107 }

267

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . model ;56 import java . i o . S e r i a l i z a b l e ;78 import javax . p e r s i s t e n c e . Entity ;9 import javax . p e r s i s t e n c e . GeneratedValue ;10 import javax . p e r s i s t e n c e . Id ;11 import javax . p e r s i s t e n c e . I nhe r i t anc e ;12 import javax . p e r s i s t e n c e . Inher i tanceType ;13 import javax . p e r s i s t e n c e . NamedQueries ;14 import javax . p e r s i s t e n c e . NamedQuery ;1516 /∗∗17 ∗ @author G i l b e r t o Torrezan Fi lho18 ∗/19 @Entity20 @Inher i tance ( s t r a t e gy = Inher i tanceType .JOINED)21 @NamedQueries ({22 @NamedQuery(name=" task . g e tA l l " , query="from Task" ) ,23 })2425 public abstract class Task implements S e r i a l i z a b l e {2627 @Id @GeneratedValue28 private int id ;29 private int t imesExecuted ;30 private St r ing name ;31 private St r ing d e s c r i p t i o n ;3233 public St r ing ge tDe s c r i p t i on ( ) {34 return d e s c r i p t i o n ;35 }36 public void s e tDe s c r i p t i on ( S t r ing d e s c r i p t i o n ) {37 this . d e s c r i p t i o n = de s c r i p t i o n ;38 }39 public int get Id ( ) {40 return id ;41 }42 public void s e t I d ( int id ) {43 this . id = id ;44 }45 public St r ing getName ( ) {46 return name ;47 }48 public void setName ( St r ing name) {49 this . name = name ;

268

50 }51 public int getTimesExecuted ( ) {52 return t imesExecuted ;53 }54 public void setTimesExecuted ( int t imesExecuted ) {55 this . t imesExecuted = timesExecuted ;56 }57 }

269

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . model ;56 import java . i o . S e r i a l i z a b l e ;78 import javax . p e r s i s t e n c e . Entity ;9 import javax . p e r s i s t e n c e . Id ;10 import javax . p e r s i s t e n c e .ManyToOne ;1112 /∗∗13 ∗ @author G i l b e r t o Torrezan Fi lho14 ∗/15 @Entity16 public class TaskValue implements S e r i a l i z a b l e , Comparable{17 @Id18 private St r ing id ;1920 @ManyToOne21 private Task task ;22 private double value ;23 private long dateTime ;2425 public TaskValue ( ){26 }2728 public TaskValue ( S t r ing id ){29 this . id = id ;30 }3132 public St r ing get Id ( ) {33 return id ;34 }35 public void s e t I d ( S t r ing id ) {36 this . id = id ;37 }38 public long getDateTime ( ) {39 return dateTime ;40 }41 public void setDateTime ( long dateTime ) {42 this . dateTime = dateTime ;43 }44 public double getValue ( ) {45 return value ;46 }47 public void setValue (double value ) {48 this . va lue = value ;49 }

270

50 public Task getTask ( ) {51 return task ;52 }53 public void setTask (Task task ) {54 this . task = task ;55 }56 public int compareTo ( Object o ) {57 i f ( o == this ){58 return 0 ;59 }60 i f ( o instanceof TaskValue ){61 TaskValue tv = (TaskValue ) o ;62 i f ( this . dateTime < tv . getDateTime ( ) ) {63 return −1;64 }65 else i f ( this . dateTime > tv . getDateTime ( ) ) {66 return 1 ;67 }68 return 0 ;69 }70 return −1;71 }72 }

271

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . model . except ion ;56 /∗∗7 ∗ @author G i l b e r t o Torrezan Fi lho8 ∗/9 public class Inva l idTaskFie ldsExcept ion extends Exception {1011 public Inva l idTaskFie ldsExcept ion ( St r ing message ){12 super ( message ) ;13 }14 }

272

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . p e r s i s t e n c e ;56 import java . u t i l . ArrayList ;7 import java . u t i l . Co l l e c t i on ;8 import java . u t i l . Co l l e c t i o n s ;9 import java . u t i l . L i s t ;1011 import javax . p e r s i s t e n c e . EntityManager ;12 import javax . p e r s i s t e n c e . Ent i tyTransact ion ;13 import javax . p e r s i s t e n c e . Query ;1415 import u f s c . t c c . s e r v e r . c o n t r o l l e r . WaitContro l l e r ;16 import u f s c . t c c . s e r v e r . model . Task ;17 import u f s c . t c c . s e r v e r . model . TaskValue ;1819 /∗∗20 ∗ @author G i l b e r t o Torrezan Fi lho21 ∗/22 public class TaskDAOImp implements TaskDAO {2324 public void i n s e r tTask (Task task ) {25 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( " In s e r i ndo t a r e f a . . . " ) ;26 EntityManager em = HibernateUt i l . getEntityManager ( ) ;27 Ent i tyTransact ion tx = null ;28 try {29 tx = em. getTransact ion ( ) ;30 tx . begin ( ) ;31 em. p e r s i s t ( task ) ;32 tx . commit ( ) ;33 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Tarefa i n s e r i d a . " ) ;34 }35 catch ( RuntimeException e ) {36 i f ( tx != null && tx . i sAc t i v e ( ) ) tx . r o l l b a ck ( ) ;37 e . pr intStackTrace ( ) ;38 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Erro ao i n s e r i r t a r e f a . " ) ;39 throw e ;40 }41 f ina l ly {42 em. c l o s e ( ) ;43 }44 }4546 public void removeTask (Task task ) {47 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Removendo t a r e f a . . . " ) ;48 EntityManager em = HibernateUt i l . getEntityManager ( ) ;49 Ent i tyTransact ion tx = null ;

273

50 try {51 tx = em. getTransact ion ( ) ;52 tx . begin ( ) ;53 em. remove ( task ) ;54 tx . commit ( ) ;55 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Tarefa removida . " ) ;56 }57 catch ( RuntimeException e ) {58 i f ( tx != null && tx . i sAc t i v e ( ) ) tx . r o l l b a ck ( ) ;59 e . pr intStackTrace ( ) ;60 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Erro ao remover t a r e f a . " ) ;61 throw e ;62 }63 f ina l ly {64 em. c l o s e ( ) ;65 }66 }6768 public void removeTaskValues ( TaskValue [ ] tvs ) {69 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Removendo va l o r e s . . . " ) ;70 EntityManager em = HibernateUt i l . getEntityManager ( ) ;71 Ent i tyTransact ion tx = null ;72 try {73 tx = em. getTransact ion ( ) ;74 tx . begin ( ) ;75 for ( TaskValue tv : tvs ){76 em. remove ( tv ) ;77 }78 tx . commit ( ) ;79 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Valores removidos . " ) ;80 }81 catch ( RuntimeException e ) {82 i f ( tx != null && tx . i sAc t i v e ( ) ) tx . r o l l b a ck ( ) ;83 e . pr intStackTrace ( ) ;84 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Erro ao remover va l o r e s . " ) ;85 throw e ;86 }87 f ina l ly {88 em. c l o s e ( ) ;89 }90 }9192 @SuppressWarnings ( "unchecked" )93 public Co l l e c t i on<Task> getTasks ( ) {94 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Consultando t a r e f a s cadast radas . . . " ) ;95 EntityManager manager = HibernateUt i l . getEntityManager ( ) ;96 Query q = manager . createNamedQuery ( " task . g e tA l l " ) ;97 L i s t r e s u l t s = q . g e tRe su l tL i s t ( ) ;98 Lis t<Task> r e t L i s t = new ArrayList<Task >() ;

274

99 Co l l e c t i o n s . addAll ( r e tL i s t , ( Task [ ] ) r e s u l t s . toArray (new Task [ 0 ] ) ) ;100 manager . c l o s e ( ) ;101 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Tare fas consu l tadas . " ) ;102 return r e t L i s t ;103 }104105 public void updateTask (Task task ) {106 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Atual izando t a r e f a . . . " ) ;107 EntityManager em = HibernateUt i l . getEntityManager ( ) ;108 Ent i tyTransact ion tx = null ;109 try {110 tx = em. getTransact ion ( ) ;111 tx . begin ( ) ;112 em. merge ( task ) ;113 tx . commit ( ) ;114 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Tarefa a tua l i z ada . " ) ;115 }116 catch ( RuntimeException e ) {117 i f ( tx != null && tx . i sAc t i v e ( ) ) tx . r o l l b a ck ( ) ;118 e . pr intStackTrace ( ) ;119 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Erro ao a t u a l i z a r t a r e f a . " ) ;120 throw e ;121122 }123 f ina l ly {124 em. c l o s e ( ) ;125 }126 }127 }

275

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . p e r s i s t e n c e ;56 import java . s q l . DriverManager ;78 import javax . p e r s i s t e n c e . EntityManager ;9 import javax . p e r s i s t e n c e . EntityManagerFactory ;10 import javax . p e r s i s t e n c e . Pe r s i s t en c e ;1112 import u f s c . t c c . s e r v e r . c o n t r o l l e r . Ex i tCont ro l l e r ;13 import u f s c . t c c . s e r v e r . c o n t r o l l e r . WaitContro l l e r ;1415 /∗∗16 ∗ @author G i l b e r t o Torrezan Fi lho17 ∗/18 public class HibernateUt i l {19 private stat ic f ina l EntityManagerFactory emf ;20 private stat ic f ina l TaskDAO tdao ;2122 private HibernateUt i l ( ){}2324 stat ic {25 try{26 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( "Carregando p e r s i s t ê n c i a . . . " ) ;27 Class . forName ( " org . hsqldb . jdbcDr iver " ) ;28 DriverManager . getConnect ion ( " jdbc : hsqldb : f i l e : t c c " , " sa " , "" ) ;29 }30 catch ( Exception e ){31 Ex i tCont ro l l e r . e x i t (−1);32 }33 try {34 emf = Pe r s i s t en c e . createEntityManagerFactory ( "manager" ) ;35 tdao = new TaskDAOImp ( ) ;36 WaitContro l l e r . g e t In s tance ( ) . f i r eSe tWa i t i ng ( " P e r s i s t ê n c i a i n i c i a l i a z a d a . " ) ;37 } catch ( Throwable ex ) {38 throw new Exc ep t i o n I n I n i t i a l i z e rE r r o r ( ex ) ;39 }40 }4142 public stat ic EntityManager getEntityManager ( ){43 return emf . createEntityManager ( ) ;44 }4546 public stat ic void c l o s e ( ){47 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Fechando conexões . . . " ) ;48 emf . c l o s e ( ) ;49 WaitContro l l e r . g e t In s tance ( ) . f i r eS e tWa i t i ng ( "Conexões fechadas . " ) ;

276

50 }5152 public stat ic TaskDAO getTaskDAO(){53 return tdao ;54 }55 }

277

1 /∗∗2 ∗3 ∗/4 package u f s c . t c c . s e r v e r . p e r s i s t e n c e ;56 import java . u t i l . Co l l e c t i on ;78 import u f s c . t c c . s e r v e r . model . Task ;9 import u f s c . t c c . s e r v e r . model . TaskValue ;1011 /∗∗12 ∗ @author G i l b e r t o Torrezan Fi lho13 ∗/14 public interface TaskDAO {15 public void i n s e r tTask (Task task ) ;16 public void removeTask (Task task ) ;17 public void updateTask (Task task ) ;18 public Co l l e c t i on<Task> getTasks ( ) ;19 public void removeTaskValues ( TaskValue [ ] tvs ) ;20 }

278

Apêndice D

Artigo

Um Sistema de Gerência de Estações Remotas Utilizando RFBSobre VNC

Anderson Bu�on Berto, Gilberto Torrezan FilhoDepartamento de Informática e Estatística (INE)

Centro Tecnológico (CTC)Universidade Federal de Santa Catarina (UFSC)

Florianópolis - Santa Catarina - Brasil{abu�on, hidra}@inf.ufsc.br

Orientador: Prof. Dr. Leandro J. KomosinskiDepartamento de Informática e Estatística (INE)

Centro Tecnológico (CTC)Universidade Federal de Santa Catarina (UFSC)

Florianópolis - Santa Catarina - Brasil

26 de Fevereiro de 2007

279

D.1 Resumo

Esse trabalho se destina à cons-trução de um software de gerencia-mento remoto de estações de trabalhovia dispositivos móveis. Os requisitosnão funcionais de�nidos são: usabili-dade, con�abilidade e desempenho.

Foi realizada a análise de proje-tos correlatos, os mesmos foram ana-lisados segundo o código, navegabi-lidade, portabilidade e desempenho.Fizemos um servidor bridge para acomunicação entre o cliente e o ser-vidor VNC. Nesse servidor bridge foifeita a construção da persistência dastarefas e a execução das mesmas, po-dendo mostrar o uso da CPU, espaçoem disco, memória livre, entre outros.Foi implementada uma �casca� no cli-ente (wrapper) com a função de rece-ber as tarefas do servidor, as infor-mações pertinentes a cada tarefa e oenvio de comandos para que as tare-fas possam ser executadas através dodispositivo móvel.

Com o servidor e o cliente �naliza-dos, podemos testar o projeto e con-�rmar que é possível que se faça umgerenciamento remoto de estações detrabalho sem que se exija muito pro-cessamento do dispositivo cliente.

Palavras-chave: Telefone Celu-lar, VNC, RFB, Computação Re-mota, Ferramentas de Gerência.

D.2 Introdução

Com a crescente velocidade comque a informação é gerada e trans-mitida, fazem-se necessárias cada vezmais tecnologias para expandir e agi-lizar os processos de gerência, manu-tenção e assistência de produtos e ser-viços através dos diversos meios. Nãose pode mais perder tempo entre aocorrência de um problema e a to-mada de decisão que inicie o processode solução do mesmo.

O que as tecnologias de informa-ção mais prezam é o fator agilidade.As tecnologias móveis ou sem �o sãoum exemplo: ter um dispositivo re-ceptor de informação disponível emqualquer lugar independente de fontede alimentação ou ponto de comu-nicação. Porém, tanta mobilidade epraticidade têm um custo. Um dis-positivo móvel isolado possui capaci-dade de armazenamento e processa-mento muito inferiores aos dispositi-vos ditos �xos. Isso limita o alcanceda tecnologia móvel de certa maneira,mas instiga a procura de soluções viá-veis para o uso adequado de suas fun-cionalidades.

Esse trabalho se insere no seguintecontexto: promover a delegação detarefas de um dispositivo móvel paraum computador �xo, via internet. Oprincípio de delegação de funções deum dispositivo para outro não é no-vidade, já que há muito que a inter-net é uma realidade. O que é rela-tivamente novo é a possibilidade decomunicação e delegação de tarefasentre dispositivos de diferentes "na-turezas", como é o caso de um apa-relho celular e um computador pes-

280

soal. Um famoso método de acessoentre dois computadores pessoais évia VNC (Virtual Network Compu-ting), que é um programa que permiteacessar as funções de um computadorremotamente como se não o fosse re-moto.

D.2.1 Objetivo Geral

Originalmente se propôs estendere aprimorar o trabalho JNC Mobile -Sistema de Acesso Remoto para Dis-positivos Móveis [3], desenvolvido porAndrei Luciano Krause e Rafael Au-gusto da Silva, implementando requi-sitos descritos como trabalhos futurospelos autores, além de outros novosrequisitos.

Porém, com a análise feita no tra-balho JNC Mobile, descobriu-se vá-rios problemas que estavam além daimplementação de novos requisitos.Dados esses problemas, decidiu-se en-tão que seria melhor estender um pro-jeto open-source correlato ao JNCMobile, onde esses problemas não setornassem uma barreira ao desenvol-vimento. O projeto adotado comobase foi o J2ME VNC [9]. Por-tanto, o objetivo passou a ser a im-plementação dos requisitos apontadoscomo trabalhos futuros no projetoJNC Mobile, além de outros requi-sitos descritos a seguir, tendo comobase de desenvolvimento o projetoJ2ME VNC.

D.2.2 Objetivos Especí�-

cos

• Estudo do protocolo RFB (Re-mote Framebu�er) para a utili-zação no sistema VNC;

• Implementação de um servidorbridge que recebe e gerencia asnovas requisições feitas pelo cli-ente;

• Cadastro de Tarefas (desligar,reiniciar, ativar desfragmenta-dor de disco, rotinas de traba-lho, rodar antivírus, entre ou-tras) no servidor bridge, alémda correspondente interface nocliente;

• Implementação da função dezoom panorâmico.

D.3 VNC e RFB

D.3.1 VNC

VNC (Virtual Network Compu-ting) [1] é um projeto desenvolvidopela ORL (Olivetti Research Labo-ratory), e comprado em 1999 pelaAT&T. É um sistema criado parapossibilitar o acesso a computadoresremotos. Com o VNC o usuário podeacessar todas as funcionalidades docomputador (controlar o mouse, o te-clado, executar programas, etc) como

281

se estivesse na frente do mesmo, in-dependendo do sistema operacional.

D.3.2 RFB

O RFB (Remote FrameBu�er) [2]é um protocolo construído para oacesso remoto em interfaces grá�cas.Aplicável a todos os sistemas de jane-las (X11, Windows e Macintosh).

O protocolo funciona no modelocliente-servidor. O computador re-moto, computador o qual possui o sis-tema operacional e as aplicações quepoderão ser usadas, é chamado de ser-vidor RFB. O cliente RFB é o compu-tador (ou qualquer outro dispositivoque possa fazer esse tipo de conexão,no caso desse trabalho, é utilizado umdispositivo móvel).

O RFB foi desenvolvido para serleve e com sua implementação o maissimples possível, de tal maneira quese exija quase nada do dispositivo cli-ente. Assim vários dispositivos po-dem ser usados, inclusive os apare-lhos celulares que possuem uma ca-pacidade muito menor de processa-mento.

D.4 Trabalhos Corre-

latos Analisados

Para o desenvolvimento desse tra-balho foram analisados alguns pro-jetos correlatos segundo os seguintescritérios:

1. Código: Análise da estruturado código fonte do projeto (sedisponível). Levando em contaa legibilidade, os comentários ea documentação.

2. Navegabilidade: Análise da in-terface grá�ca do programa cli-ente.

3. Portabilidade: Segundo essecritério é analisada a gama dedispositivos que podem execu-tar o projeto, além da gama deservidores VNC aos quais elespodem se conectar.

4. Desempenho: Analisado o trá-fego de dados e o processamentono servidor devido ao uso doprojeto.

Dentre os projetos analisados ti-vemos: VNC2Go [6], PocketVNC [7],.NET VNC Viewer [8], J2ME VNC[9], JNC Mobile [3], VNC Viewer [10]e Imhotek VNC [11].

D.4.1 Comparação entre

os projetos

Na comparação feita entre osprojetos correlatos decidiu-se adotarcomo projeto base para esse trabalhoo J2ME VNC devido as seguintes ca-racterísticas:

Código

O código do J2ME VNC é aberto(licença GPL[4]) e de fácil acesso

282

via um repositório público de versões(CVS[5]). Além disso, a estruturaçãodo código é agradável, bem comen-tado e inteligível. Essa característicafoi a determinante para o descarte de-�nitivo do JNC Mobile como projetobase para este trabalho.

Navegabilidade

A navegabilidade do J2ME VNC émuito boa, possuindo várias funçõesde navegação direta e vários menuscom funções de ajuda.

Portabilidade

O J2ME VNC se sobressai, por funci-onar com uma vasta gama de servido-res VNC e em vários aparelhos celu-lares, inclusive nos complicados apa-relhos da Nokia, e por ser feito 100%em Java (J2ME) [17].

Desempenho

O desempenho do projeto J2MEVNC é satisfatório, tanto em nível detráfego de rede quanto em nível deprocessamento no cliente e no servi-dor.

D.5 Projeto e Desen-

volvimento

D.5.1 Projeto

Um sistema de acesso remotobaseia-se em dois programas distin-tos: o programa cliente (visualiza-dor), e o programa servidor (máquinaacessada).

O cliente é responsável por pedirinformações ou solicitar serviços aoservidor através do envio de coman-dos. O servidor, por sua vez, esperaser noti�cado pelo cliente para enviarinformações (esse modo de operaçãodo servidor é conhecido como modopassivo).

Portanto, para desenvolver umsistema VNC completo, é necessáriodesenvolver um programa cliente eum programa servidor, �gura D.5.1.Dado que o programa servidor é ba-sicamente o mesmo, independente deplataforma e que há vários servidoresgratuitos e de fácil acesso na inter-net, esse projeto será focado na cons-trução de um wrapper de um clienteVNC móvel.

D.5.2 Desenvolvimento

O desenvolvimento da soluçãoproposta se divide em duas áreas, quesão: Servidor Bridge e o Wrapper docliente.

Servidor Bridge

O servidor Bridge é ao mesmo tempocliente e servidor. Ele é o servidor noqual o cliente do sistema (o celular) seconecta via RFB, e o cliente do ser-vidor VNC nativo do sistema. É neleque o protocolo RFB será expandido.

283

Figura D.1: Estrutura do projeto.

Dentro do servidor Bridge, há umanova divisão no problema. Um pro-blema é a adição de novas codi�ca-ções ao protocolo RFB, permitindo aconexão do cliente. Outro problema éo modelo de dados, algoritmos e per-sistência das entidades relacionadasàs funções desejadas, como por exem-plo, as entidades relacionadas ao ca-dastro de tarefas pré-de�nidas no ser-vidor para acesso futuro via cliente.

• Entidades: Temos a classe Taské a super classe de todas as tare-fas a serem cadastradas no ser-

vidor. Dela derivam duas clas-ses: CommandTask e Schedu-ledTask, �gura D.2.

A CommandTask representauma tarefa que deve ser exe-cutada como uma linha de co-mando. A execução de co-mando pode retornar um va-lor útil ao usuário, como o es-paço livre no HD, ou simples-mente executar uma ação de-sejada, como matar um pro-cesso ou resetar a máquina. Poresse motivo, essa classe possui oatributo waitForReturn, que in-dica se o servidor deve esperarpor um valor de retorno ou não.

A ScheduledTask representauma tarefa que é periodica-mente executada, armazenandovalores obtidos para futura con-sulta, possivelmente gerandográ�cos. Os tipos predetermi-nados de tarefas agendadas são:Avaliação do uso de CPU, Ava-liação do espaço em disco, Ava-liação da memória livre, Avalia-ção do uso de memória.

• Execução: O �uxo de cada ta-refa é totalmente dependente dotipo dessa tarefa.

As CommandTasks são execu-tadas, e dependendo do valor doatributo waitForReturn, a apli-cação espera ou não um valorde retorno, para posteriormenteretornar esse valor ao cliente. Ainterpretação dos dados retor-nados cabe ao usuário.

284

Já as ScheduledTasks são exe-cutadas periodicamente, se-gundo a expressão Quartz [13]associada. Cada execução re-sulta em um valor numérico,que por sua vez é associado aum Task- Value, que por suavez é persistido no banco.

• Extensão do Protocolo RFB: Éa adição de novas codi�caçõespara a execução de novas tare-fas. Para que o servidor bridgeexerça a verdadeira função deponte, ele deve permitir que to-das as funções normais de umservidor VNC sejam executa-das, tratando somente as tagsespeciais (novas tags). Ou seja,o servidor bridge deve analisartudo o que chega do cliente, e seo que chegar não correspondera uma tag nova, deve repassartodo o comando para o servidorVNC.

Então, para que o servidorbridge exerça essa função, eledeve compreender o protocoloRFB, e as extensões de�nidas.

Para estender o protocolo bastautilizar uma tag não reservada,e dar um signi�cado lógico paraela, tanto no servidor quantono cliente, assim os estadosno cliente e servidor �cam deacordo com as �guras D.3 eD.4. Sendo assim, é necessárioanalisar quais as novas funçõesque se deseja agregar ao proto-colo, para então escolher as no-

vas tags.

Novas Funções:

1. Pedido da lista de tarefascadastradas no bridge: có-digo 129;

2. Execução de uma deter-minada tarefa cadastrada:código 130;

3. Informa no dispositivo cli-ente que a lista de tarefasfoi recebida: código 4;

4. Informa no dispositivo cli-ente que o resultado daexecução de uma tarefa foirecebida: código 5;

Figura D.2: Entidades.

285

Figura D.3: Extensão do RFB no cli-ente.

Wrapper do Cliente

Wrapper do cliente é uma �casca� im-plementada no cliente J2ME VNCque estará rodando no aparelho ce-lular. Ele contém as funcionalidadesdo cliente J2ME VNC e mais a exten-são do protocolo RFB para que possase comunicar com o servidor Bridge,e assim usufruir das funções que omesmo oferece.

O cliente J2ME VNC possui vá-rias funcionalidades para comandar ocomputador via celular, entre elas po-demos citar: Ctrl Alt Del, ApertarEnter, Repintar, Chamar o mouse,Entrar com texto, entre outras. Aessas funcionalidades foi adicionadaa opção Tarefas, que é a comunica-ção do cliente VNC com o servidor

Figura D.4: Extensão do RFB no ser-vidor RFB.

Bridge, para que o mesmo execute ouenvie ao cliente as informações das ta-refas previamente cadastradas no ser-vidor.

Assim que a opção Tarefas é aces-sada no menu é enviado ao servidoruma requisição para que o mesmomande as tarefas existentes. Assimque é escolhida qual tarefa se desejaobter as informações o servidor enviaas informações da mesma.

Extensão do Protocolo no Cliente:Para que as novas funcionalidades im-plementadas no servidor Bridge se-jam entendidas pelo cliente, este tam-bém deve extender o protocolo RFBe assim ter suporte as novas tags exis-tentes. As funções e os códigos são osmesmos feitos no servidor Bridge.

286

D.6 Discussão dos Re-

sultados

A análise foi feita seguindo os se-guintes critérios:

1. Tempo.

2. Número de pacotes enviados erecebidos no servidor.

3. Pico de processamento no ser-vidor.

Em cada um dos itens acima fo-ram analisados os seguintes critérios:inicio de conexão, movimento simplespela tela do cliente, abertura de umarquivo com extensão txt e a ação deabrir o menu iniciar. No item, Pico deprocessamento do servidor, foi anali-sada também a porcentagem do pro-cessamento enquanto o cliente estavaocioso.

Todos os projetos foram testa-dos em um computador Pentium 42.4GHz com 768 megabytes de me-mória RAM e placa de vídeo GForceFX5200 de 128 megabytes usandoo sistema operacional Windows XPSP2 R©. Os dispositivos cliente e ser-vidor rodaram localmente.

• Tempo (segundos):

1. Iniciar Conexão: O crité-rio Iniciar Conexão refere-se ao tempo de inicio daconexão do cliente com oservidor VNC. Na análisefeita a média de tempo de

conexão foi de 12,2 segun-dos. O projeto .NET Vi-ewer foi o mais lento, issopode ter ocorrido devidoao fato do emulador desseprojeto ser bastante lento.

2. Movimento Pela Tela: Aquifoi analisado um sim-ples movimento pela tela.Nesse quesito o .NET Vi-ewer foi o mais rápido. OJ2ME VNC teve um bomdesempenho, isso acontecepor que em um movimentode tela o que é enviado ésomente o �pedaço� da telarequisitado e não a tela in-teira.

3. Abrir Menu Iniciar: o cri-tério abrir menu iniciar éavaliado desde o clique domouse para abrir o menuaté o menu aparecer com-pletamente na tela do cli-ente. Os resultados forammuito parecidos entre osprojetos.

• Número de Pacotes enviados erecebidos: Para cada um dositens já citados, analisou-se onúmero de pacotes enviados erecebidos. Como o cliente e oservidor estavam rodando local-mente esse número foi na mai-oria das vezes abaixo do espe-rado. Exceto o projeto .NETViewer.

A análise dos pacotes enviados erecebidos deste projeto não foi

287

feita localmente e sim remota-mente, por isso os valores en-contrados para ele são �mais re-ais�.

• Pico do processamento do ser-vidor: Foi feita a análise domáximo que chegou o proces-samento no servidor para cadacritério e colocado mais o itemcliente ocioso.

1. Iniciar Conexão: Comoera de se esperar no inicioda conexão entre o clientee o servidor todos os pro-jetos chegaram aos seus100% de processamento.Já que o cliente e o ser-vidor trocavam dados parafazer o handshake inicial.

2. Movimento Pela Tela: Namovimentação pela telatrês projetos chegaram acerca de 80% de proces-samento, o VNC2Go, oJ2ME VNC e o nosso tra-balho.

3. Abrir Arquivo (txt): Paraabrir um arquivo de texto,mesmo que seja pouco pro-cessamento, foi-se exigidoum pouco mais do servi-dor, para fazer essa ta-refa simples alguns proje-tos chegaram a 100%.

4. Abrir Menu Iniciar: Assimcomo o item abrir arquivo,abrir menu iniciar teve nasua maioria um processa-mento chegando a 100%.

Os únicos trabalhos quenão chegaram ao máximode processamento foram oJ2ME VNC e o nosso tra-balho.

5. Cliente Ocioso: Com o cli-ente ocioso pode-se per-ceber que o projeto JNCMobile possui algum pro-blema, a�nal, quando ocliente não exigia nenhumprocessamento o servidor�cou em seus 100% cons-tantemente.

D.7 Conclusão

Como esse trabalho foi feito utili-zando o cliente J2ME pode-se perce-ber na discussão dos resultados, queos valores medidos dos dois trabalhossão muito parecidos. A maior dife-rença entre os dois projetos foi naquestão de envio e recebimento depacotes, isso se deve ao fato que oprojeto J2ME VNC foi testado local-mente e esse testado remotamente.Isso mostra a grande vantagem doJ2ME em relação aos outros proje-tos, já que ele faz as mesmas funçõesem menor tempo e com menor uso doprocessador no servidor.

No desenvolvimento tivemos al-guns problemas:

• Na adição de novas codi�caçõesao protocolo RFB foi encon-trada uma pequena di�culdade.

288

Quais tags poderiam ser usa-das para as novas codi�cações?Como a especi�cação do proto-colo não esclarece quais as tagsque são usadas pelo mesmo, asolução foi escolher uma tagqualquer e testar todas as fun-cionalidades para saber se essatag escolhida já era usada poroutra função.

• Após o wrapper do clienteterminado e funcionando noemulador, foi hora de testar-mos num aparelho celular real.Como o cliente é feito em Java,e Java tem como característicaser portável, era de se espe-rar que o cliente funcionasse naprimeira tentativa, porém noJ2ME a portabilidade de Javanão funciona muito bem, e oprojeto não rodou de primeirano aparelho celular. Após mo-di�cações para que o projetofuncionasse num celular Nokiaespecí�co (aparelho usado paratestes), o projeto funcionou cor-retamente nesse telefone, paraque o projeto funcione deve serfeitas modi�cações de acordocom o aparelho.

Ao �nal, concluímos que é possí-vel e fácil adicionar novas codi�caçõesao protocolo RFB para que o mesmopossa �entender� a uma variada gamade funções. E com a criação de umservidor que faça o processamento lo-cal é possível adicionar muitas funci-onalidades em um dispositivo móvel

que não tenha poder para processartal, tarefas que exijam muito proces-samento, por exemplo. E com issocriar funções inovadoras.

D.8 Trabalhos Futu-

ros

• Envio ao aparelho celular dosgrá�cos que resultam da execu-ção das tarefas no servidor:

• Implementação de um sistemade monitoramento via web, uti-lizando a mesma tecnologiaadotada no sistema VNC:

• Implementação de um conjuntomais complexo e útil de tarefas:

289

Referências Bibliográ�cas

[1] Real VNC,http://www.realvnc.com/, Aces-sado em: Julho, 2006.

[2] Remote Framebu�er,http://realvnc.com/docs/rfbproto.pdf,Acessado em: Julho, 2006.

[3] JNC Mobile,http://projetos.inf.ufsc.br/arquivos_projetos/projeto_79/Re-lat%F3rio_Final_TCC.pdf,Acessado em: Novembro, 2005.

[4] General Public License,http://www.gnu.org/licenses/gpl.html,Acessado em: Julho, 2006.

[5] Concurrent Version System,http://focalinux.cipsga.org.br/guia/avancado/ch-s-cvs.htm, Acessado em: Julho,2006.

[6] VNC2Go,http://www.freeutils.net/vnc2go/index.jsp,Acessado em: Julho, 2006.

[7] PocketVNC,http://www.pocketvnc.com/pocketVNC.aspx,Acessado em: Julho, 2006.

[8] .NET VNC Viewer,http://dotnetvnc.sourceforge.net/,Acessado em: Julho, 2006.

[9] J2ME VNC,http://j2mevnc.sourceforge.net/,Acessado em: Julho, 2006.

[10] VNC Viewer,http://www.p800.info/app.php?app_id=13,Acessado em: Julho, 2006.

[11] Imhotek VNC,http://www.imhotek.com/html/vnc.html,Acessado em: Julho, 2006.

[12] Tecnologia de mapeamentoautomático entre modelos re-lacional e orientado a objetos,http://www.hibernate.org/, Aces-sado em: Julho, 2006.

[13] Agendador avançado de tarefas,http://www.opensymphony.com/quartz/,Acessado em: Julho, 2006.

[14] Biblioteca avançadapara desenho de grá�cos,http://www.jfree.org/jfreechart/,Acessado em: Julho, 2006.

[15] IDE Eclipse,http://www.eclipse.org/, Aces-sado em: Outubro, 2006.

[16] Antenna,http://antenna.sourceforge.net/,Acessado em: Outubro, 2006.

290

[17] J2ME,http://java.sun.com/javame/index.jsp,Acessado em: Outubro, 2006.

[18] JCon�g,http://tolstoy.com/samizdat/jcon�g.html,Acessado em: Novembro, 2006.

291