OPENBUS-3113 Informações do usuário armazenadas:

- Foi necessário criar customização de tamanho máximo para JComboBox
- Retirado o título de 'Configurações' do login
- Uma classe reutilizável foi criada apenas para preferences
- Retirado todas as referências a propriedades na tela de login
parent a6ee566d
......@@ -43,8 +43,9 @@
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
......
package tecgraf.openbus.admin;
import com.google.common.collect.ArrayListMultimap;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Object;
import org.omg.PortableServer.POA;
......@@ -23,6 +23,8 @@ import java.util.Properties;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
import static org.junit.jupiter.api.Assertions.*;
public class BusAdminTest {
private static final int MAX_OFFERS_TO_REGISTER = 5;
......@@ -33,7 +35,7 @@ public class BusAdminTest {
private static byte[] password;
private static String domain;
@BeforeClass
@BeforeAll
public static void oneTimeSetUp() throws Exception {
Properties properties = Utils.readPropertyFile("/test.properties");
host = properties.getProperty("openbus.host.name");
......@@ -76,11 +78,11 @@ public class BusAdminTest {
try {
expected.add(localOffer.remoteOffer());
} catch (Exception e) {
Assert.fail(e.getMessage());
fail(e.getMessage());
}
});
// fim da barreira de sincronizao
Assert.assertEquals(MAX_OFFERS_TO_REGISTER, expected.size());
assertEquals(MAX_OFFERS_TO_REGISTER, expected.size());
// tarefa sncrona porque usa as interfaces de administrao diretamente
List<ServiceOfferDesc> allOffers = admin.getOffers();
......@@ -92,8 +94,8 @@ public class BusAdminTest {
}
return false;
});
Assert.assertEquals(0, expected.size());
Assert.assertTrue(conn.logout());
assertEquals(0, expected.size());
assertTrue(conn.logout());
orb.shutdown(true);
orb.destroy();
}
......
......@@ -114,5 +114,20 @@
<artifactId>japura-gui</artifactId>
<version>7.5.2</version>
</dependency>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<type>bom</type>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.3.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package busexplorer.desktop.dialog;
import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class JComboBoxKeyAdapterMaxLength extends KeyAdapter {
private int maxLength;
private JComboBox jComboBox;
public JComboBoxKeyAdapterMaxLength(JComboBox jComboBox, int maxLength) {
this.jComboBox = jComboBox;
this.maxLength = maxLength;
jComboBox.getEditor().getEditorComponent().addKeyListener(this);
}
@Override
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (jComboBox.getEditor().getItem().toString().length() < maxLength) {
if (!(c == '.' || c == ':' || Character.isAlphabetic(c) || Character.isDigit(c)
|| (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE))) {
jComboBox.getToolkit().beep();
e.consume();
}
} else {
e.consume();
}
}
}
package busexplorer.utils;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
/**
* Propriedades de configurao do BusExplorer.
*
* As propriedades de configurao, por padro, so obtidas do arquivo
* "busexplorer.conf" presente no prprio diretrio de execuo. O usurio pode
* especificar um arquivo em particular atravs da propriedade "configPath".
*
* @author Tecgraf
*/
public class ConfigurationProperties extends Properties {
/**
* Construtor.
*/
public ConfigurationProperties() {
try {
String configPath = System.getProperty("configPath") != null ?
System.getProperty("configPath") : "busexplorer.conf";
FileInputStream configStream = new FileInputStream(configPath);
load(configStream);
}
catch (FileNotFoundException e) {
System.err.println(Language.get(this.getClass(),
"warning.configFileNotFound"));
}
catch (IOException e) {
System.err.println(Language.get(this.getClass(),
"warning.configFileLoadFailure"));
}
}
}
package busexplorer.utils.preferences;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.prefs.Preferences;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Preferências de configuração da aplicação.
*
* As preferências do usuário serão armazenadas de acordo com sua própria
* necessidade. Atentar que as exclusões de entrada são de total
* responsabilidade da interface que utiliza essa classe, que serve como
* centralizadoras das preferências.
*
* Todas as preferências devem ser armazenadas na forma de String, e qualquer
* tipagem deverá ser resolvida externamente. É interessante que cada aplicação
* guarde as strings de preferences em uma classe ou interface separada.
*
* Para o método {@link #write(String, String, Collection)} não é necessário
* qualquer preocupação com os valores sendo escritos, pois, internamente, um
* scape já é adicionado para que os valores sejam corretamente separados
* na forma de lista.
*
* @author Tecgraf
*/
public class ApplicationPreferences {
public static final String EMPTY = null;
public static final String SCAPE_CHAR = "\\\\";
public static final String SEP = ",";
private Preferences preferences;
public ApplicationPreferences(String appname) {
preferences = Preferences.userRoot().node(appname);
}
/**
* Escreve um valor no item indicado.
* @param preferences instância de preferences
* @param name nome da propriedade a ser escrita
* @param value valor da propriedade a ser escrita
*/
private void write(Preferences preferences, String name, String value) {
preferences.put(name, value);
}
/**
* Escreve um valor na raiz da aplicação.
* @param name nome da propriedade a ser escrita
* @param value valor da propriedade a ser escrita
*/
public void write(String name, String value) {
write(preferences, name, value);
}
/**
* Escreve um valor no path indicado, na raiz da aplicação.
* @param name nome da propriedade a ser escrita
* @param value valor da propriedade a ser escrita
*/
public void write(String path, String name, String value) {
write(preferences.node(path), name, value);
}
/**
* Lê um valor do item indicado.
* @param preferences instância de preferences
* @param name nome da propriedade a ser lida
* @return valor encontrado nas preferências
*/
private String read(Preferences preferences, String name) {
return preferences.get(name, EMPTY);
}
/**
* Lê um valor da raiz da aplicação.
* @param name nome da propriedade a ser lida
* @return valor encontrado nas preferências
*/
public String read(String name) {
return read(preferences, name);
}
/**
* Lê um valor do path indicado.
* @param name nome da propriedade a ser lida
* @return valor encontrado nas preferências
*/
public String read(String path, String name) {
return read(preferences.node(path), name);
}
/**
* Adiciona um valor de scape para o item informado.
* @param item valor sem scape
* @return valor com scape
*/
private String scape(String item) {
return item.replace(SEP, SCAPE_CHAR + SEP);
}
/**
* Retira valor de scape para o item informado.
* @param item valor com scape
* @return valor sem scape
*/
private String unscape(String item) {
return item.replace(SCAPE_CHAR + SEP, SEP);
}
/**
* Escreve uma coleção de valores no item indicado.
* @param preferences instância de preferences
* @param name nome da propriedade a ser escrita
* @param value coleção a ser escrita
*/
private void write(Preferences preferences, String name, Collection<String> value) {
String storeValue = value.stream().map(i -> scape(i)).collect(Collectors.joining(SEP));
preferences.put(name, storeValue);
}
/**
* Escreve uma coleção de valores na raiz da aplicação.
* Antente-se que a ordem não importa para o objetivo de armazenamento de
* preferências, a escrita será feita com qualquer tipo de coleção e a leitura
* {@link #readCollection(String)} será realizada ser qualquer compromisso de
* ordenação.
* É importante atentar para que o separador {@link #SEP} não seja utilizado
* como um valor escrito. Caso isso aconteça, os valores retornados serão diretamente
* afetados, corrompendo o valor esperado. Exemplo: caso seja informada a tupla
* ("nome", "valor1|valor2|val|or3"), 4 (quatro) valores serão retornados pelo
* método {@link #readCollection(String)}: ["valor1", "valor2", "val", "or3"].
*
* @param name nome da propriedade a ser escrita
* @param value coleção a ser escrita
*/
public void write(String name, Collection<String> value) {
write(preferences, name, value);
}
/**
* Escreve uma coleção de valores no path indicado.
* Antente-se que a ordem não importa para o objetivo de armazenamento de
* preferências, a escrita será feita com qualquer tipo de coleção e a leitura
* {@link #readCollection(String)} será realizada ser qualquer compromisso de
* ordenação.
* É importante atentar para que o separador {@link #SEP} não seja utilizado
* como um valor escrito. Caso isso aconteça, os valores retornados serão diretamente
* afetados, corrompendo o valor esperado. Exemplo: caso seja informada a tupla
* ("nome", "valor1|valor2|val|or3"), 4 (quatro) valores serão retornados pelo
* método {@link #readCollection(String)}: ["valor1", "valor2", "val", "or3"].
*
* @param path caminho no qual o par nome/valor será adicionado
* @param name nome da propriedade a ser escrita
* @param value coleção a ser escrita
*/
public void write(String path, String name, Collection<String> value) {
write(preferences.node(path), name, value);
}
/**
* Adiciona um item a uma lista.
*
* @param name nome a ser adicionado
* @param value valor a ser adicionado
* @param addIfExists caso o parâmetro name seja encontrado, adiciona valor mesmo que já exista caso verdadeiro
*/
public void addToCollection(String name, String value, boolean addIfExists) {
Collection<String> items = readCollection(name);
boolean exists = items.stream().filter(it -> it.equals(value)).findFirst().isPresent();
if (!exists || (exists && addIfExists)) {
items.add(value);
write(name, items);
}
}
/**
* Adiciona um item a uma lista.
*
* @param path caminho no qual o par nome/valor será adicionado
* @param name nome a ser adicionado
* @param value valor a ser adicionado
* @param addIfExists caso o parâmetro name seja encontrado, adiciona valor mesmo que já exista caso verdadeiro
*/
public void addToCollection(String path, String name, String value, boolean addIfExists) {
Collection<String> items = readCollection(path, name);
boolean exists = items.stream().filter(it -> it.equals(value)).findFirst().isPresent();
if (!exists || (exists && addIfExists)) {
items.add(value);
write(path, name, items);
}
}
/**
* Lê uma coleção de valores do item indicado.
* Há restrições para a utilização de valores na escrita que afetam diretamente
* os valores retornados. Verifique como a leitura é afetada em {@link #write(String, Collection)}.
*
* Não há compromisso com o valor retornado, apesar de uma lista estar sendo retornada
* como implementação atualmente.
*
* @see #write(String, Collection)
* @param preferences
* @param name
* @return
*/
private Collection<String> readCollection(Preferences preferences, String name) {
String storedValue = preferences.get(name, EMPTY);
String[] items = storedValue == null ? new String[]{} : storedValue.split("(?<!" + SCAPE_CHAR + ")" + SEP);
return Stream.of(items)
.map(item -> unscape(item))
.collect(Collectors.toList());
}
/**
* Lê uma coleção de valores da raiz da aplicação.
* Há restrições para a utilização de valores na escrita que afetam diretamente
* os valores retornados. Verifique como a leitura é afetada em {@link #write(String, Collection)}.
*
* Não há compromisso com o valor retornado, apesar de uma lista estar sendo retornada
* como implementação atualmente.
*
* @see #write(String, Collection)
* @param name
* @return
*/
public Collection<String> readCollection(String name) {
return readCollection(preferences, name);
}
/**
* Lê uma coleção de valores do path indicado.
* Há restrições para a utilização de valores na escrita que afetam diretamente
* os valores retornados. Verifique como a leitura é afetada em {@link #write(String, Collection)}.
*
* Não há compromisso com o valor retornado, apesar de uma lista estar sendo retornada
* como implementação atualmente.
*
* @see #write(String, Collection)
* @param path
* @param name
* @return
*/
public Collection<String> readCollection(String path, String name) {
return readCollection(preferences.node(path), name);
}
}
package busexplorer.utils.preferences;
public class BusExplorerPrefs {
private static ApplicationPreferences preferences;
public static ApplicationPreferences instance() {
if (preferences == null) {
preferences = new ApplicationPreferences(PrefName.APPLICATION_NAME);
}
return preferences;
}
}
package busexplorer.utils.preferences;
public interface PrefName {
String APPLICATION_NAME = "busexplorer";
String LAST_USER = "lastuser";
String ADDRESSES = "addresses";
String DOMAINS = "domains";
}
......@@ -154,6 +154,7 @@ CertificateRefreshAction.waiting.title Recarregar certificados
CertificateTableProvider.entity Entidade
ConfigurationProperties.warning.configFileLoadFailure AVISO: No foi possvel carregar o arquivo de configuraes.
ConfigurationProperties.warning.configFileWriteFailure AVISO: No foi possvel escrever no arquivo de configuraes (o Arquivo destino um diretrio? H permisso para escrita?).
ConfigurationProperties.warning.configFileNotFound AVISO: O arquivo de configuraes no foi encontrado.
ExceptionDialog.contactError Clique no boto Detalhar para ver mais informaes.
......@@ -234,7 +235,6 @@ LoginDialog.bug.error Houve erro no servidor. Procure o administrador do sistema
LoginDialog.bus.label Barramento
LoginDialog.bus.other Outro...
LoginDialog.ca.invalid.error Erro na interface com o Sistema de Controle de Acesso. Procure o administrador do sistema.
LoginDialog.config.label Configuraes de acesso ao barramento
LoginDialog.confirm.button Conectar
LoginDialog.confirm.button.mnemonic C
LoginDialog.confirm.help Realiza o login no barramento usando os dados informados
......
package busexplorer.utils.preferences;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.util.*;
import static org.junit.jupiter.api.Assertions.*;
public class ApplicationPreferencesTest {
static final String APPNAME = "appname";
static ApplicationPreferences preferences;
@BeforeAll
public static void before() {
preferences = new ApplicationPreferences(APPNAME);
}
@Test
public void testWriteReadRoot() {
preferences.write("nome1", "valor1");
preferences.write("nome2", "valor2");
preferences.write("nome3", "valor3");
assertEquals("valor1", preferences.read("nome1"));
assertEquals("valor2", preferences.read("nome2"));
assertEquals("valor3", preferences.read("nome3"));
}
@Test
public void testWriteReadPath1() {
String path1 = "item1";
preferences.write(path1, "nome1", "item1_valor1");
preferences.write(path1, "nome2", "item1_valor2");
preferences.write(path1, "nome3", "item1_valor3");
assertEquals("item1_valor1", preferences.read(path1, "nome1"));
assertEquals("item1_valor2", preferences.read(path1, "nome2"));
assertEquals("item1_valor3", preferences.read(path1, "nome3"));
}
@Test
public void testWriteReadPath2() {
String path1 = "item1/child1";
preferences.write(path1, "nome1", "item1_child1_valor1");
preferences.write(path1, "nome2", "item1_child1_valor2");
preferences.write(path1, "nome3", "item1_child1_valor3");
assertEquals("item1_child1_valor1", preferences.read(path1, "nome1"));
assertEquals("item1_child1_valor2", preferences.read(path1, "nome2"));
assertEquals("item1_child1_valor3", preferences.read(path1, "nome3"));
}
@Test
public void testWriteReadCollection() {
String[] diseases = { "Abdominal Aortic Aneurysm", "Acanthamoeba Infection", "ACE (Adverse Childhood Experiences)",
"Acinetobacter Infection", "Acquired Immunodeficiency Syndrome (AIDS)",
"Adenovirus Infection", "Adenovirus Vaccination" };
String prefName = "diseases";
preferences.write(prefName, Arrays.asList(diseases));
// Verifica apenas se o item de doenas consta no que foi armazenado
for (String item: diseases) {
assertTrue(preferences.readCollection(prefName).stream().filter(it -> it.equals(item)).findFirst().isPresent(), "Item falho: '" + item + "'");
}
}
@Test
public void testCommaWriteReadCollection() {
String[] diseases = { "Abdominal, Aortic Aneurysm", "Acantha,moeba Infection", "ACE (Adverse, Childhood Experiences)",
"Acinetobacter Inf,ection", "Acquired Immunodeficiency Syndrom,e (AIDS)",
"Adenovirus Infec,tion", "Adenovirus Vac,cination" };
String prefName = "diseases";
preferences.write(prefName, Arrays.asList(diseases));
for (String item: diseases) {
assertTrue(preferences.readCollection(prefName).stream().filter(it -> it.equals(item)).findFirst().isPresent(), "Item falho: '" + item + "'");
}
}
@Test
public void addCollectionCheckNonEmptyFirsItem() {
assertEquals(0, preferences.readCollection("rxy").size());
preferences.addToCollection("rxy", "primeiro-item", false);
assertEquals(1, preferences.readCollection("rxy").size());
}
@Test
public void addCollectionWithoutPath() {
String etmologia = "etmologia";
String[] items = { "abajour", "aafro", "aucar", "aude", "alcachofra", "alcalide", "alcatia", "lcool" };
for (String item: items) {
preferences.addToCollection(etmologia, item, false);
}
for (String item: items) {
assertTrue(preferences.readCollection(etmologia).stream().filter(it -> it.equals(item)).findFirst().isPresent(), "Item falho: '" + item + "'");
}
}
@Test
public void addCollectionWithPath() {
String tribos = "tribos";
String[] acre = { "Amawka", "Arara", "Deni", "Nawa" };
String[] amapa = { "Karipuna", "Palikur", "Wayampi" };
String[] amazonas = { "Kambeba", "Jarawara", "Korubo", "Wanana" };
String[] para = { "Anamb", "Jaruna", "Kayap", "Munduruku" };
String[] rondonia = { "Arara", "Aru", "Nambikwara", "Tupari" };
String[] roraima = { "Macuxi", "Yanomami", "Waiwai", "Ingaric" };
String[] tocantins = { "Apinaye", "Guarani", "Karaja", "Kraho", "Xerente" };
Map<String, String[]> map = new HashMap<>();
map.put("acre", acre);
map.put("amapa", amapa);
map.put("amazonas", amazonas);
map.put("para", para);
map.put("rondonia", rondonia);
map.put("roraima", roraima);
map.put("tocantins", tocantins);
for (String path: map.keySet()) {
for (String item: map.get(path)) {
preferences.addToCollection(path, tribos, item, false);
}
for (String item: map.get(path)) {
assertTrue(preferences.readCollection(path, tribos).stream().filter(it -> it.equals(item)).findFirst().isPresent(), "Item falho: '" + path + "/" + item + "'");
}
}
}
@Test
public void readCollectionEmptyNullValue() {
assertFalse(preferences.readCollection("xxxx") == null);
}
}
package busexplorer.utils.preferences;
import busexplorer.utils.BusAddress;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
public class OpenBusPreferencesTest {
static final String APPNAME = "appname";
static ApplicationPreferences preferences;
@BeforeAll
public static void before() {
preferences = BusExplorerPrefs.instance();
}
@Test
public void busAdressWriteTest() {
BusAddress bus = BusAddress.toAddress("", "127.0.0.1:2089");
System.out.println(bus.toString());
}
}
......@@ -15,7 +15,7 @@
<javautils.version>4.0.0</javautils.version>
<javautils.gui.version>5.0.1</javautils.gui.version>
<jacorb.version>3.8</jacorb.version>
<junit.version>4.6</junit.version>
<junit.version>5.3.1</junit.version>
<miglayout.version>4.2</miglayout.version>
<openbus-sdk.version>2.1.1.2-SNAPSHOT</openbus-sdk.version>
<governance.version>1.0.1-SNAPSHOT</governance.version>
......@@ -140,10 +140,13 @@
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>${junit.version}</version>
<type>bom</type>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment