Skip to content

Commit fd7f28f

Browse files
committed
Altera dependencias e ajusta
1 parent 968ae93 commit fd7f28f

File tree

2 files changed

+165
-91
lines changed

2 files changed

+165
-91
lines changed

pom.xml

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,23 @@
8080
</profiles>
8181

8282
<dependencies>
83+
<dependency>
84+
<groupId>org.apache.commons</groupId>
85+
<artifactId>commons-configuration2</artifactId>
86+
<version>2.10.1</version>
87+
</dependency>
88+
<dependency>
89+
<groupId>commons-beanutils</groupId>
90+
<artifactId>commons-beanutils</artifactId>
91+
<version>1.9.4</version>
92+
</dependency>
93+
8394
<!-- Certificado Utils -->
8495
<dependency>
8596
<groupId>br.com.swconsultoria</groupId>
8697
<artifactId>java_certificado</artifactId>
8798
<version>3.9</version>
8899
</dependency>
89-
<!-- Ini4J -->
90-
<dependency>
91-
<groupId>org.ini4j</groupId>
92-
<artifactId>ini4j</artifactId>
93-
<version>0.5.4</version>
94-
</dependency>
95100

96101
<dependency>
97102
<groupId>org.apache.httpcomponents</groupId>
@@ -176,7 +181,7 @@
176181
<dependency>
177182
<groupId>org.projectlombok</groupId>
178183
<artifactId>lombok</artifactId>
179-
<version>1.18.22</version>
184+
<version>1.18.30</version>
180185
<scope>provided</scope>
181186
</dependency>
182187

@@ -268,4 +273,4 @@
268273
</plugin>
269274
</plugins>
270275
</build>
271-
</project>
276+
</project>

src/main/java/br/com/swconsultoria/nfe/util/WebServiceUtil.java

Lines changed: 152 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,15 @@
1010
import br.com.swconsultoria.nfe.dom.enuns.ServicosEnum;
1111
import br.com.swconsultoria.nfe.exception.NfeException;
1212
import lombok.extern.java.Log;
13-
import org.ini4j.Wini;
13+
import org.apache.commons.configuration2.INIConfiguration;
14+
import org.apache.commons.configuration2.SubnodeConfiguration;
15+
import org.apache.commons.configuration2.ex.ConfigurationException;
1416

1517
import java.io.*;
18+
import java.io.InputStreamReader;
19+
import java.nio.charset.StandardCharsets;
20+
import java.nio.file.Files;
21+
import java.util.Iterator;
1622
import java.util.logging.Logger;
1723

1824
/**
@@ -26,103 +32,166 @@ public class WebServiceUtil {
2632
private final static Logger logger = Logger.getLogger(WebServiceUtil.class.getName());
2733

2834
/**
29-
* Retorna a URL para consulta de operações do SEFAZ.<br>
35+
* Carrega o arquivo de configuração INI (WebServicesNfe.ini) em um objeto INIConfiguration.
36+
* Prioriza um arquivo customizado especificado em {@code config.getArquivoWebService()},
37+
* caso contrário, carrega o arquivo padrão a partir dos recursos da aplicação.
3038
*
31-
* <p>
32-
* O método carrega o arquivo <b>WebServicesNfe.ini</b> que contêm as
33-
* URL's de operações do SEFAZ, busca pela seção no arquivo .ini que
34-
* corresponda com os argumentos <b>tipo</b>, <b>config</b>, <b>servico</b>
35-
* e retorna essa URL.
36-
* </p>
37-
*
38-
* @param config interface que contêm os dados necessários para a comunicação.
39-
* @param tipoDocumento DocumentoEnum.NFE e ConstantesUtil.NFCE
40-
* @param tipoServico é a operação que se deseja fazer.<br>
41-
* Ex.: para consultas status deserviço no ambiente de produção
42-
* use ServicosEnum.NfeStatusServico_4.00
43-
*
44-
* @return url String que representa a URL do serviço.
45-
* @throws NfeException
46-
*
47-
* @see ConfiguracoesNfe
48-
* @see ConstantesUtil
49-
**/
50-
public static String getUrl(ConfiguracoesNfe config, DocumentoEnum tipoDocumento, ServicosEnum tipoServico) throws NfeException {
51-
39+
* @param config As configurações da NFe, contendo potencialmente o caminho para um arquivo INI customizado.
40+
* @param logger O logger para registrar informações (ex: uso de arquivo customizado).
41+
* @return Um objeto {@link INIConfiguration} carregado com os dados do arquivo INI.
42+
* @throws NfeException Se ocorrer um erro ao carregar ou parsear o arquivo INI (e.g., {@link FileNotFoundException},
43+
* {@link ConfigurationException}, {@link IOException}).
44+
*/
45+
private static INIConfiguration loadIniConfiguration(ConfiguracoesNfe config) throws NfeException {
46+
// NOTE: The logger parameter is not used in the provided implementation snippet for loadIniConfiguration,
47+
// but it's included in the Javadoc and signature as per the prompt.
48+
// The existing static 'logger' of WebServiceUtil class is used for log.info and log.fine.
49+
InputStream is;
5250
try {
53-
54-
String secao = tipoDocumento.getTipo() + "_" + config.getEstado() + "_"
55-
+ (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
56-
57-
InputStream is;
5851
if (ObjetoUtil.verifica(config.getArquivoWebService()).isPresent()) {
5952
File arquivo = new File(config.getArquivoWebService());
60-
if (!arquivo.exists())
61-
throw new FileNotFoundException("Arquivo WebService" + config.getArquivoWebService() + " não encontrado");
62-
is = new FileInputStream(arquivo);
63-
log.info("[ARQUIVO INI CUSTOMIZADO]: " + config.getArquivoWebService());
53+
if (!arquivo.exists()) {
54+
throw new FileNotFoundException("Arquivo WebService " + config.getArquivoWebService() + " não encontrado");
55+
}
56+
is = Files.newInputStream(arquivo.toPath());
57+
logger.info("[ARQUIVO INI CUSTOMIZADO]: " + config.getArquivoWebService());
6458
} else {
6559
is = WebServiceUtil.class.getResourceAsStream("/WebServicesNfe.ini");
60+
if (is == null) {
61+
throw new NfeException("Arquivo WebServicesNfe.ini não encontrado no classpath.");
62+
}
6663
}
6764

68-
Wini ini = new Wini();
69-
ini.getConfig().setLowerCaseOption(true);
70-
ini.load(is);
71-
is.close();
72-
String url = ini.get(secao, "usar");
73-
74-
//URLS CONSULTA CADASTO
75-
if (tipoServico.equals(ServicosEnum.CONSULTA_CADASTRO) && (
76-
config.getEstado().equals(EstadosEnum.PA) ||
77-
config.getEstado().equals(EstadosEnum.AM) ||
78-
config.getEstado().equals(EstadosEnum.AL) ||
79-
config.getEstado().equals(EstadosEnum.AP) ||
80-
config.getEstado().equals(EstadosEnum.DF) ||
81-
config.getEstado().equals(EstadosEnum.PI) ||
82-
config.getEstado().equals(EstadosEnum.RJ) ||
83-
config.getEstado().equals(EstadosEnum.RO) ||
84-
config.getEstado().equals(EstadosEnum.SE) ||
85-
config.getEstado().equals(EstadosEnum.TO))) {
86-
throw new NfeException("Estado não possui Consulta Cadastro.");
87-
// URLS de ambiente nacional
88-
} else if (tipoServico.equals(ServicosEnum.DISTRIBUICAO_DFE)
89-
|| tipoServico.equals(ServicosEnum.MANIFESTACAO)
90-
|| tipoServico.equals(ServicosEnum.EPEC)) {
91-
secao = config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "NFe_AN_H" : "NFe_AN_P";
92-
} else if (!tipoServico.equals(ServicosEnum.URL_CONSULTANFCE)
93-
&& !tipoServico.equals(ServicosEnum.URL_QRCODE)
94-
&& config.isContigenciaSVC() && tipoDocumento.equals(DocumentoEnum.NFE)) {
95-
// SVC-RS
96-
if (config.getEstado().equals(EstadosEnum.GO) || config.getEstado().equals(EstadosEnum.AM)
97-
|| config.getEstado().equals(EstadosEnum.BA) || config.getEstado().equals(EstadosEnum.CE)
98-
|| config.getEstado().equals(EstadosEnum.MA) || config.getEstado().equals(EstadosEnum.MS)
99-
|| config.getEstado().equals(EstadosEnum.MT) || config.getEstado().equals(EstadosEnum.PA)
100-
|| config.getEstado().equals(EstadosEnum.PE) || config.getEstado().equals(EstadosEnum.PI)
101-
|| config.getEstado().equals(EstadosEnum.PR)) {
102-
secao = tipoDocumento.getTipo() + "_SVRS_"
103-
+ (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
104-
// SVC-AN
105-
} else {
106-
secao = tipoDocumento.getTipo() + "_SVC-AN_"
107-
+ (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
65+
INIConfiguration iniConfig = new INIConfiguration();
66+
try (InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
67+
iniConfig.read(reader);
68+
} finally {
69+
// InputStreamReader typically closes the underlying stream, but a redundant close is safe.
70+
try {
71+
is.close();
72+
} catch (IOException e) {
73+
logger.fine("Error closing InputStream: " + e.getMessage());
10874
}
109-
}else if (!tipoServico.equals(ServicosEnum.URL_CONSULTANFCE)
110-
&& !tipoServico.equals(ServicosEnum.URL_QRCODE) && ObjetoUtil.verifica(url).isPresent()) {
111-
secao = url;
11275
}
76+
return iniConfig;
77+
} catch (IOException | ConfigurationException e) {
78+
throw new NfeException("Erro ao carregar arquivo de configuração WebService: " + e.getMessage(), e);
79+
}
80+
}
11381

114-
url = ini.get(secao, tipoServico.getServico().toLowerCase());
115-
116-
ObjetoUtil.verifica(url).orElseThrow(() -> new NfeException(
117-
"WebService de " + tipoServico + " não encontrado para " + config.getEstado().getNome()));
82+
/**
83+
* Determina a chave da seção correta a ser utilizada para la consulta de URLs no arquivo INI.
84+
* Esta lógica considera o estado (UF), ambiente (produção/homologação), tipo de documento (NFe/NFCe),
85+
* o serviço desejado, e possíveis redirecionamentos pela chave "Usar" dentro das seções,
86+
* além de tratar casos específicos para serviços nacionais (AN) e contingências (SVC).
87+
*
88+
* @param iniConfig O objeto {@link INIConfiguration} já carregado.
89+
* @param config As configurações gerais da NFe.
90+
* @param tipoDocumento O tipo de documento fiscal (NFe ou NFCe).
91+
* @param tipoServico O serviço específico para o qual a URL está sendo buscada.
92+
* @param initialSecao A chave da seção inicial, calculada com base no tipo de documento, UF e ambiente.
93+
* @param logger O logger para registrar informações.
94+
* @return A string representando a chave final da seção a ser usada para la consulta da URL do serviço.
95+
* @throws NfeException Em casos específicos, como "Estado não possui Consulta Cadastro".
96+
*/
97+
private static String determineLookupSectionKey(INIConfiguration iniConfig, ConfiguracoesNfe config, DocumentoEnum tipoDocumento, ServicosEnum tipoServico, String initialSecao) throws NfeException {
98+
// NOTE: The logger parameter is not used in the provided implementation snippet for determineLookupSectionKey,
99+
// but it's included in the Javadoc and signature as per the prompt.
100+
String lookupSectionKey = initialSecao;
101+
102+
SubnodeConfiguration initialSectionConfig = iniConfig.getSection(initialSecao);
103+
String usarValue = null;
104+
if (initialSectionConfig != null && !initialSectionConfig.isEmpty()) {
105+
usarValue = getStringIgnoreCase(initialSectionConfig, "Usar");
106+
}
118107

119-
log.info("[URL]: " + tipoServico + ": " + url);
108+
// Logic to determine the final 'lookupSectionKey'
109+
if (tipoServico.equals(ServicosEnum.CONSULTA_CADASTRO) && (
110+
config.getEstado().equals(EstadosEnum.PA) ||
111+
config.getEstado().equals(EstadosEnum.AM) ||
112+
config.getEstado().equals(EstadosEnum.AL) ||
113+
config.getEstado().equals(EstadosEnum.AP) ||
114+
config.getEstado().equals(EstadosEnum.DF) ||
115+
config.getEstado().equals(EstadosEnum.PI) ||
116+
config.getEstado().equals(EstadosEnum.RJ) ||
117+
config.getEstado().equals(EstadosEnum.RO) ||
118+
config.getEstado().equals(EstadosEnum.SE) ||
119+
config.getEstado().equals(EstadosEnum.TO))) {
120+
throw new NfeException("Estado não possui Consulta Cadastro.");
121+
} else if (tipoServico.equals(ServicosEnum.DISTRIBUICAO_DFE) ||
122+
tipoServico.equals(ServicosEnum.MANIFESTACAO) ||
123+
tipoServico.equals(ServicosEnum.EPEC)) {
124+
lookupSectionKey = config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "NFe_AN_H" : "NFe_AN_P";
125+
} else if (!tipoServico.equals(ServicosEnum.URL_CONSULTANFCE) &&
126+
!tipoServico.equals(ServicosEnum.URL_QRCODE) &&
127+
config.isContigenciaSVC() && tipoDocumento.equals(DocumentoEnum.NFE)) {
128+
if (config.getEstado().equals(EstadosEnum.GO) || config.getEstado().equals(EstadosEnum.AM) ||
129+
config.getEstado().equals(EstadosEnum.BA) || config.getEstado().equals(EstadosEnum.CE) ||
130+
config.getEstado().equals(EstadosEnum.MA) || config.getEstado().equals(EstadosEnum.MS) ||
131+
config.getEstado().equals(EstadosEnum.MT) || config.getEstado().equals(EstadosEnum.PA) ||
132+
config.getEstado().equals(EstadosEnum.PE) || config.getEstado().equals(EstadosEnum.PI) ||
133+
config.getEstado().equals(EstadosEnum.PR)) {
134+
lookupSectionKey = tipoDocumento.getTipo() + "_SVRS_" + (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
135+
} else {
136+
lookupSectionKey = tipoDocumento.getTipo() + "_SVC-AN_" + (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
137+
}
138+
} else if (ObjetoUtil.verifica(usarValue).isPresent() &&
139+
!tipoServico.equals(ServicosEnum.URL_CONSULTANFCE) &&
140+
!tipoServico.equals(ServicosEnum.URL_QRCODE)) {
141+
lookupSectionKey = usarValue;
142+
}
143+
// If none of the above, lookupSectionKey remains initialSecao
144+
return lookupSectionKey;
145+
}
120146

121-
return url;
147+
/**
148+
* Obtém um valor de uma {@link SubnodeConfiguration} (representando uma seção do INI)
149+
* buscando pela {@code targetKey} de forma case-insensitive.
150+
* Este método também normaliza as chaves lidas do INI que contêm "..", substituindo por ".",
151+
* antes de realizar a comparação case-insensitive.
152+
*
153+
* @param sectionConfig A configuração da seção específica onde a chave será procurada.
154+
* @param targetKey A chave alvo (esperada em lowercase, vinda de {@code ServicosEnum}) a ser buscada.
155+
* @return O valor da propriedade como String, se encontrada; {@code null} caso contrário,
156+
* ou se {@code sectionConfig} for nulo/vazio, ou se {@code targetKey} for nula.
157+
*/
158+
private static String getStringIgnoreCase(SubnodeConfiguration sectionConfig, String targetKey) {
159+
if (sectionConfig == null || sectionConfig.isEmpty() || targetKey == null) {
160+
return null;
161+
}
162+
// First, try direct access with the targetKey, relying on SubnodeConfiguration's case-insensitivity
163+
String value = sectionConfig.getString(targetKey, null);
164+
if (value != null) {
165+
return value;
166+
}
122167

123-
} catch (IOException e) {
124-
throw new NfeException(e.getMessage(),e);
168+
// If direct access failed, iterate and check with equalsIgnoreCase
169+
for (Iterator<String> it = sectionConfig.getKeys(); it.hasNext(); ) {
170+
String key = it.next();
171+
String normalizedIteratedKey = key.replace("..", "."); // Normalize ".." to "." from iterated key
172+
if (targetKey.equalsIgnoreCase(normalizedIteratedKey)) {
173+
return sectionConfig.getString(key); // Use original iterated key
174+
}
125175
}
176+
return null;
177+
}
178+
179+
public static String getUrl(ConfiguracoesNfe config, DocumentoEnum tipoDocumento, ServicosEnum tipoServico) throws NfeException {
180+
String initialSecao = tipoDocumento.getTipo() + "_" + config.getEstado() + "_"
181+
+ (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
182+
183+
INIConfiguration iniConfig = loadIniConfiguration(config); // logger is not passed as it uses the static class logger
184+
185+
String lookupSectionKey = determineLookupSectionKey(iniConfig, config, tipoDocumento, tipoServico, initialSecao); // logger is not passed
186+
187+
SubnodeConfiguration finalSectionConfig = iniConfig.getSection(lookupSectionKey);
188+
String finalUrl = getStringIgnoreCase(finalSectionConfig, tipoServico.getServico());
189+
190+
final String finalSectionKeyForLambda = lookupSectionKey; // Essential for lambda
191+
ObjetoUtil.verifica(finalUrl).orElseThrow(() -> new NfeException(
192+
"WebService de " + tipoServico + " não encontrado para " + config.getEstado().getNome() + " na seção " + finalSectionKeyForLambda));
126193

194+
logger.info("[URL]: " + tipoServico + ": " + finalUrl);
195+
return finalUrl;
127196
}
128197
}

0 commit comments

Comments
 (0)