Skip to content

Commit 7e13d1a

Browse files
Melhorias WebService Util
1 parent cc00882 commit 7e13d1a

File tree

3 files changed

+201
-83
lines changed

3 files changed

+201
-83
lines changed
Lines changed: 71 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
/**
2-
*
3-
*/
41
package br.com.swconsultoria.nfe.util;
52

63
import br.com.swconsultoria.nfe.dom.ConfiguracoesNfe;
@@ -12,24 +9,20 @@
129
import lombok.extern.java.Log;
1310

1411
import java.io.*;
15-
import java.io.InputStreamReader;
1612
import java.nio.charset.StandardCharsets;
17-
import java.util.logging.Logger;
18-
import java.util.Map;
1913
import java.util.HashMap;
14+
import java.util.Map;
2015
import java.util.regex.Matcher;
2116
import java.util.regex.Pattern;
2217

23-
2418
/**
2519
* @author Samuel Oliveira
26-
*
20+
* <p>
2721
* Classe responsávelem montar as URL's de consulta de serviços do SEFAZ.
2822
*/
2923
@Log
3024
public class WebServiceUtil {
3125

32-
private final static Logger logger = Logger.getLogger(WebServiceUtil.class.getName());
3326
private static final Pattern sectionPattern = Pattern.compile("^\\[(.+)\\]$");
3427

3528
/**
@@ -40,13 +33,13 @@ public class WebServiceUtil {
4033
*
4134
* @param sectionMap O Mapa ({@code Map<String, String>}) contendo os pares de chave-valor da seção específica.
4235
* Pode ser nulo ou vazio.
43-
* @param targetKey A chave alvo (geralmente esperada em lowercase, vinda de {@code ServicosEnum}, ou "Usar" em PascalCase)
44-
* a ser buscada dentro da seção.
45-
* @param logger O logger para registrar informações de depuração (ex: qual chave está sendo comparada).
36+
* @param targetKey A chave alvo (geralmente esperada em lowercase, vinda de {@code ServicosEnum}, ou "Usar" em PascalCase)
37+
* a ser buscada dentro da seção.
38+
* @param log O log para registrar informações de depuração (ex: qual chave está sendo comparada).
4639
* @return O valor da propriedade como String, se uma correspondência case-insensitive for encontrada;
47-
* {@code null} caso contrário, ou se {@code sectionMap} for nulo/vazio, ou se {@code targetKey} for nula.
40+
* {@code null} caso contrário, ou se {@code sectionMap} for nulo/vazio, ou se {@code targetKey} for nula.
4841
*/
49-
private static String getIniValueIgnoreCase(Map<String, String> sectionMap, String targetKey, Logger logger) {
42+
private static String getIniValueIgnoreCase(Map<String, String> sectionMap, String targetKey) {
5043
if (sectionMap == null || sectionMap.isEmpty() || targetKey == null) {
5144
return null;
5245
}
@@ -70,9 +63,9 @@ private static String getIniValueIgnoreCase(Map<String, String> sectionMap, Stri
7063
*
7164
* @param inputStream O {@link InputStream} do arquivo INI a ser analisado. O stream é fechado ao final do parsing.
7265
* @return Um {@code Map<String, Map<String, String>>} representando os dados do INI.
73-
* A chave do mapa externo é o nome da seção. O valor é outro mapa contendo
74-
* os pares de chave-valor daquela seção.
75-
* @throws IOException Se ocorrer um erro de I/O durante a leitura do stream.
66+
* A chave do mapa externo é o nome da seção. O valor é outro mapa contendo
67+
* os pares de chave-valor daquela seção.
68+
* @throws IOException Se ocorrer um erro de I/O durante a leitura do stream.
7669
* @throws NfeException Se forem encontradas linhas malformadas que não se encaixam no padrão esperado
7770
* de seção ou chave-valor (ex: nome de seção vazio em {@code []}, ou uma chave-valor fora de uma seção).
7871
*/
@@ -87,60 +80,42 @@ private static Map<String, Map<String, String>> parseIniFile(InputStream inputSt
8780
line = line.trim();
8881

8982
if (line.isEmpty() || line.startsWith(";") || line.startsWith("#")) {
90-
continue; // Skip empty lines and comments
83+
continue;
9184
}
9285

9386
Matcher sectionMatcher = sectionPattern.matcher(line);
9487
if (sectionMatcher.matches()) {
95-
// If currentSectionMap is not null and not empty, it means a previous section was being processed.
96-
// It's already in iniData, as we put it there when its name was found.
9788
currentSectionName = sectionMatcher.group(1).trim();
9889
if (currentSectionName.isEmpty()) {
9990
throw new NfeException("Nome da seção inválido (vazio) no arquivo INI.");
10091
}
101-
// Ensure new section map is created, even if previous one with same name existed (though INI typically doesn't repeat sections)
10292
currentSectionMap = new HashMap<>();
10393
iniData.put(currentSectionName, currentSectionMap);
10494
} else {
10595
if (currentSectionName == null) {
106-
// Property outside of any section - not expected for WebServicesNfe.ini
107-
// For now, we can log and ignore, or throw an exception.
108-
// Based on prompt, let's be strict for this specific INI structure.
10996
throw new NfeException("Propriedade encontrada fora de uma seção: " + line);
11097
}
11198

112-
int separatorPos = -1;
113-
int equalsPos = line.indexOf('=');
114-
// According to INI standards, some parsers also accept ':' but '=' is more common.
115-
// The original ini4j might have handled both. For this custom parser, let's stick to '=' for simplicity
116-
// unless ':' is confirmed to be used in WebServicesNfe.ini for key-value.
117-
// A quick check of WebServicesNfe.ini shows only '='.
118-
separatorPos = equalsPos;
99+
int separatorPos;
100+
separatorPos = line.indexOf('=');
119101

120102
if (separatorPos != -1) {
121103
String key = line.substring(0, separatorPos).trim();
122104
String value = line.substring(separatorPos + 1).trim();
123-
if (!key.isEmpty() && currentSectionMap != null) {
105+
if (!key.isEmpty()) {
124106
currentSectionMap.put(key, value);
125-
} else if (key.isEmpty()){
126-
logger.warning("Linha malformada (chave vazia): " + line);
127107
} else {
128-
// currentSectionMap should not be null here if currentSectionName is set.
129-
// This case implies currentSectionName was set, but currentSectionMap wasn't put in iniData or was null.
130-
// This should ideally not happen if logic is correct.
131-
logger.warning("Tentativa de adicionar propriedade a uma seção nula: " + line);
108+
log.warning("Linha malformada (chave vazia): " + line);
132109
}
133110
} else {
134-
// Line is not a comment, not a section, and not a valid key-value pair.
135-
logger.warning("Linha malformada ignorada: " + line);
111+
log.warning("Linha malformada ignorada: " + line);
136112
}
137113
}
138114
}
139115
}
140116
return iniData;
141117
}
142118

143-
144119
/**
145120
* Retorna a URL para consulta de operações do SEFAZ.<br>
146121
*
@@ -151,15 +126,13 @@ private static Map<String, Map<String, String>> parseIniFile(InputStream inputSt
151126
* e retorna essa URL.
152127
* </p>
153128
*
154-
* @param config interface que contêm os dados necessários para a comunicação.
129+
* @param config interface que contêm os dados necessários para a comunicação.
155130
* @param tipoDocumento {@link DocumentoEnum#NFE} ou {@link DocumentoEnum#NFCE}.
156-
* @param tipoServico é a operação que se deseja fazer.<br>
157-
* Ex.: para consultas status deserviço no ambiente de produção
158-
* use ServicosEnum.NfeStatusServico_4.00
159-
*
131+
* @param tipoServico é a operação que se deseja fazer.<br>
132+
* Ex.: para consultas status deserviço no ambiente de produção
133+
* use ServicosEnum.NfeStatusServico_4.00
160134
* @return url String que representa a URL do serviço.
161135
* @throws NfeException
162-
*
163136
* @see ConfiguracoesNfe
164137
*/
165138
public static String getUrl(ConfiguracoesNfe config, DocumentoEnum tipoDocumento, ServicosEnum tipoServico) throws NfeException {
@@ -172,7 +145,7 @@ public static String getUrl(ConfiguracoesNfe config, DocumentoEnum tipoDocumento
172145
throw new FileNotFoundException("Arquivo WebService " + config.getArquivoWebService() + " não encontrado");
173146
}
174147
is = new FileInputStream(arquivo);
175-
logger.info("[ARQUIVO INI CUSTOMIZADO]: " + config.getArquivoWebService());
148+
log.info("[ARQUIVO INI CUSTOMIZADO]: " + config.getArquivoWebService());
176149
} else {
177150
is = WebServiceUtil.class.getResourceAsStream("/WebServicesNfe.ini");
178151
if (is == null) {
@@ -187,70 +160,85 @@ public static String getUrl(ConfiguracoesNfe config, DocumentoEnum tipoDocumento
187160
try {
188161
is.close();
189162
} catch (IOException e) {
190-
logger.fine("Erro ao fechar InputStream: " + e.getMessage());
163+
log.fine("Erro ao fechar InputStream: " + e.getMessage());
191164
}
192165
}
193166
}
194167

195168
String initialSecaoKey = tipoDocumento.getTipo() + "_" + config.getEstado() + "_"
196-
+ (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
169+
+ (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
197170

198171
String lookupSectionKey = initialSecaoKey;
199172
Map<String, String> initialSectionMap = iniData.get(initialSecaoKey);
200-
// Pass the static logger from the class to the helper method
201-
String usarValue = getIniValueIgnoreCase(initialSectionMap, "Usar", logger);
173+
// Pass the static log from the class to the helper method
174+
String usarValue = getIniValueIgnoreCase(initialSectionMap, "Usar");
202175

203-
String finalUrl = null;
176+
String finalUrl;
204177

205-
if (tipoServico.equals(ServicosEnum.CONSULTA_CADASTRO) && (
206-
config.getEstado().equals(EstadosEnum.PA) ||
207-
config.getEstado().equals(EstadosEnum.AM) ||
208-
config.getEstado().equals(EstadosEnum.AL) ||
209-
config.getEstado().equals(EstadosEnum.AP) ||
210-
config.getEstado().equals(EstadosEnum.DF) ||
211-
config.getEstado().equals(EstadosEnum.PI) ||
212-
config.getEstado().equals(EstadosEnum.RJ) ||
213-
config.getEstado().equals(EstadosEnum.RO) ||
214-
config.getEstado().equals(EstadosEnum.SE) ||
215-
config.getEstado().equals(EstadosEnum.TO))) {
178+
if (verificaEstadosConsultaCadastro(config, tipoServico)) {
216179
throw new NfeException("Estado não possui Consulta Cadastro.");
217-
} else if (tipoServico.equals(ServicosEnum.DISTRIBUICAO_DFE) ||
218-
tipoServico.equals(ServicosEnum.MANIFESTACAO) ||
219-
tipoServico.equals(ServicosEnum.EPEC)) {
180+
} else if (verificaServicosAmbienteNacional(tipoServico)) {
220181
lookupSectionKey = config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "NFe_AN_H" : "NFe_AN_P";
221182
Map<String, String> nationalSectionMap = iniData.get(lookupSectionKey);
222-
finalUrl = getIniValueIgnoreCase(nationalSectionMap, tipoServico.getServico(), logger);
223-
} else if (!tipoServico.equals(ServicosEnum.URL_CONSULTANFCE) &&
224-
!tipoServico.equals(ServicosEnum.URL_QRCODE) &&
225-
config.isContigenciaSVC() && tipoDocumento.equals(DocumentoEnum.NFE)) {
226-
if (config.getEstado().equals(EstadosEnum.GO) || config.getEstado().equals(EstadosEnum.AM) ||
227-
config.getEstado().equals(EstadosEnum.BA) || config.getEstado().equals(EstadosEnum.CE) ||
228-
config.getEstado().equals(EstadosEnum.MA) || config.getEstado().equals(EstadosEnum.MS) ||
229-
config.getEstado().equals(EstadosEnum.MT) || config.getEstado().equals(EstadosEnum.PA) ||
230-
config.getEstado().equals(EstadosEnum.PE) || config.getEstado().equals(EstadosEnum.PI) ||
231-
config.getEstado().equals(EstadosEnum.PR)) {
183+
finalUrl = getIniValueIgnoreCase(nationalSectionMap, tipoServico.getServico());
184+
} else if (verificaSeContingenciaSvcNfe(config, tipoDocumento, tipoServico)) {
185+
if (verificaEstadosComServidorProprio(config)) {
232186
lookupSectionKey = tipoDocumento.getTipo() + "_SVRS_" + (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
233187
} else {
234188
lookupSectionKey = tipoDocumento.getTipo() + "_SVC-AN_" + (config.getAmbiente().equals(AmbienteEnum.HOMOLOGACAO) ? "H" : "P");
235189
}
236190
Map<String, String> svcSectionMap = iniData.get(lookupSectionKey);
237-
finalUrl = getIniValueIgnoreCase(svcSectionMap, tipoServico.getServico(), logger);
191+
finalUrl = getIniValueIgnoreCase(svcSectionMap, tipoServico.getServico());
238192
} else if (ObjetoUtil.verifica(usarValue).isPresent() &&
239-
!tipoServico.equals(ServicosEnum.URL_CONSULTANFCE) &&
240-
!tipoServico.equals(ServicosEnum.URL_QRCODE)) {
193+
!tipoServico.equals(ServicosEnum.URL_CONSULTANFCE) &&
194+
!tipoServico.equals(ServicosEnum.URL_QRCODE)) {
241195
lookupSectionKey = usarValue;
242196
Map<String, String> usarRedirectedSectionMap = iniData.get(lookupSectionKey);
243-
finalUrl = getIniValueIgnoreCase(usarRedirectedSectionMap, tipoServico.getServico(), logger);
197+
finalUrl = getIniValueIgnoreCase(usarRedirectedSectionMap, tipoServico.getServico());
244198
} else {
245199
Map<String, String> currentSectionMap = iniData.get(lookupSectionKey);
246-
finalUrl = getIniValueIgnoreCase(currentSectionMap, tipoServico.getServico(), logger);
200+
finalUrl = getIniValueIgnoreCase(currentSectionMap, tipoServico.getServico());
247201
}
248202

249203
final String finalLookupSectionKeyForLambda = lookupSectionKey;
250204
ObjetoUtil.verifica(finalUrl).orElseThrow(() -> new NfeException(
251205
"WebService de " + tipoServico + " não encontrado para " + config.getEstado().getNome() + " na seção " + finalLookupSectionKeyForLambda));
252206

253-
logger.info("[URL]: " + tipoServico + ": " + finalUrl);
207+
log.info("[URL]: " + tipoServico + ": " + finalUrl);
254208
return finalUrl;
255209
}
210+
211+
private static boolean verificaSeContingenciaSvcNfe(ConfiguracoesNfe config, DocumentoEnum tipoDocumento, ServicosEnum tipoServico) {
212+
return !tipoServico.equals(ServicosEnum.URL_CONSULTANFCE) &&
213+
!tipoServico.equals(ServicosEnum.URL_QRCODE) &&
214+
config.isContigenciaSVC() && tipoDocumento.equals(DocumentoEnum.NFE);
215+
}
216+
217+
private static boolean verificaEstadosComServidorProprio(ConfiguracoesNfe config) {
218+
return config.getEstado().equals(EstadosEnum.GO) || config.getEstado().equals(EstadosEnum.AM) ||
219+
config.getEstado().equals(EstadosEnum.BA) || config.getEstado().equals(EstadosEnum.CE) ||
220+
config.getEstado().equals(EstadosEnum.MA) || config.getEstado().equals(EstadosEnum.MS) ||
221+
config.getEstado().equals(EstadosEnum.MT) || config.getEstado().equals(EstadosEnum.PA) ||
222+
config.getEstado().equals(EstadosEnum.PE) || config.getEstado().equals(EstadosEnum.PI) ||
223+
config.getEstado().equals(EstadosEnum.PR);
224+
}
225+
226+
private static boolean verificaServicosAmbienteNacional(ServicosEnum tipoServico) {
227+
return tipoServico.equals(ServicosEnum.DISTRIBUICAO_DFE) ||
228+
tipoServico.equals(ServicosEnum.MANIFESTACAO) ||
229+
tipoServico.equals(ServicosEnum.EPEC);
230+
}
231+
232+
private static boolean verificaEstadosConsultaCadastro(ConfiguracoesNfe config, ServicosEnum tipoServico) {
233+
return tipoServico.equals(ServicosEnum.CONSULTA_CADASTRO) && (
234+
config.getEstado().equals(EstadosEnum.PA) ||
235+
config.getEstado().equals(EstadosEnum.AL) ||
236+
config.getEstado().equals(EstadosEnum.AP) ||
237+
config.getEstado().equals(EstadosEnum.DF) ||
238+
config.getEstado().equals(EstadosEnum.PI) ||
239+
config.getEstado().equals(EstadosEnum.RJ) ||
240+
config.getEstado().equals(EstadosEnum.RO) ||
241+
config.getEstado().equals(EstadosEnum.SE) ||
242+
config.getEstado().equals(EstadosEnum.TO));
243+
}
256244
}

src/main/resources/WebServicesNfe.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,7 @@ NfeAutorizacao_4.00=https://nfce.sefazrs.rs.gov.br/ws/NfeAutorizacao/NFeAutoriza
648648
RecepcaoEvento_4.00=https://nfce.sefazrs.rs.gov.br/ws/recepcaoevento/recepcaoevento4.asmx
649649
NfeConsultaProtocolo_4.00=https://nfce.sefazrs.rs.gov.br/ws/NfeConsulta/NfeConsulta4.asmx
650650
NfeInutilizacao_4.00=https://nfce.sefazrs.rs.gov.br/ws/nfeinutilizacao/nfeinutilizacao4.asmx
651+
NFeRetAutorizacao_4.00=https://nfce.sefazrs.rs.gov.br/ws/NfeRetAutorizacao/NFeRetAutorizacao4.asmx
651652
URL-QRCode=https://www.sefaz.rs.gov.br/NFCE/NFCE-COM.aspx
652653
URL-ConsultaNFCe=www.sefaz.rs.gov.br/nfce/consulta
653654

0 commit comments

Comments
 (0)