This commit is contained in:
parent
89fe02d557
commit
86b832d03c
6 changed files with 243 additions and 26 deletions
|
|
@ -1,5 +1,8 @@
|
|||
package ru.spcex.clearing.account.config.validation;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import ru.clearing.classes.statics.data.account.Account;
|
||||
|
|
@ -13,10 +16,9 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewReq
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonIdRequest;
|
||||
import ru.spcex.clearing.validation.common.rules.DictionaryPresentRule;
|
||||
import ru.spcex.clearing.validation.common.rules.FieldNotBlankRequiredRule;
|
||||
import ru.spcex.clearing.validation.common.rules.FieldRequiredRule;
|
||||
import ru.spcex.clearing.validation.common.rules.IdPresentRule;
|
||||
import ru.spcex.clearing.validation.common.rules.specific.FieldRequiredSpecificRule;
|
||||
import ru.spcex.clearing.validation.common.rules.ValidateSymbolsRule;
|
||||
import ru.spcex.clearing.validation.common.rules.specific.IdPresentSpecificRule;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
import ru.spcex.platform.enumeration.AccountStatus;
|
||||
|
|
@ -27,11 +29,6 @@ import ru.spcex.platform.utils.enumeration.EnumMessage;
|
|||
import ru.spcex.platform.utils.validation.IValidator;
|
||||
import ru.spcex.platform.utils.validation.ValidatorImpl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Configuration
|
||||
public class BankAccountValidationConfig {
|
||||
|
||||
|
|
@ -48,6 +45,7 @@ public class BankAccountValidationConfig {
|
|||
addImdg.accept(IMDGDistributedNames.Map_Company);
|
||||
addImdg.accept(IMDGDistributedNames.Map_ServiceStatusDictionary);
|
||||
addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary);
|
||||
addImdg.accept(IMDGDistributedNames.Map_ValidationSymbols);
|
||||
return new ValidatorImpl<>(context,
|
||||
IdPresentRule.instance("companyId",
|
||||
BankAccountNewRequest::getCompanyId,
|
||||
|
|
@ -63,9 +61,6 @@ public class BankAccountValidationConfig {
|
|||
CurrencyCodeDictionary.class,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.DictionaryNotFound),
|
||||
FieldRequiredRule.instance("bankIdentificationCode",
|
||||
BankAccountNewRequest::getBankIdentificationCode,
|
||||
AccountError.RequiredFieldEmpty),
|
||||
FieldRequiredRule.instance("bankName",
|
||||
BankAccountNewRequest::getBankName,
|
||||
AccountError.RequiredFieldEmpty),
|
||||
|
|
@ -75,8 +70,41 @@ public class BankAccountValidationConfig {
|
|||
ServiceStatusDictionary.class,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.DictionaryNotFound,
|
||||
false)
|
||||
);
|
||||
false),
|
||||
ValidateSymbolsRule.required("bankIdentificationCode",
|
||||
BankAccountNewRequest::getBankIdentificationCode,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.required("bankName",
|
||||
BankAccountNewRequest::getBankName,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("correspondentAccount",
|
||||
BankAccountNewRequest::getCorrespondentAccount,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("correspondentAccountName",
|
||||
BankAccountNewRequest::getCorrespondentAccountName,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("destination",
|
||||
BankAccountNewRequest::getDestination,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.required("account",
|
||||
BankAccountNewRequest::getAccount,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("taxpayerIdentificationNumber",
|
||||
BankAccountNewRequest::getTaxpayerIdentificationNumber,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("taxRegistrationReasonCode",
|
||||
BankAccountNewRequest::getTaxRegistrationReasonCode,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("swiftCode",
|
||||
BankAccountNewRequest::getSwiftCode,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("intermediarySwiftCode",
|
||||
BankAccountNewRequest::getIntermediarySwiftCode,
|
||||
AccountError.BadSymbol)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -92,6 +120,7 @@ public class BankAccountValidationConfig {
|
|||
addImdg.accept(IMDGDistributedNames.Map_CurrencyCodeDictionary);
|
||||
addImdg.accept(IMDGDistributedNames.Map_BankAccount);
|
||||
addImdg.accept(IMDGDistributedNames.Map_Company);
|
||||
addImdg.accept(IMDGDistributedNames.Map_ValidationSymbols);
|
||||
return new ValidatorImpl<>(context,
|
||||
IdPresentRule.instance("id",
|
||||
BankAccountUpdateRequest::getId,
|
||||
|
|
@ -115,7 +144,37 @@ public class BankAccountValidationConfig {
|
|||
CurrencyCodeDictionary.class,
|
||||
AccountError.RequiredFieldEmpty,
|
||||
AccountError.DictionaryNotFound,
|
||||
false)
|
||||
false),
|
||||
ValidateSymbolsRule.notRequired("bankIdentificationCode",
|
||||
BankAccountUpdateRequest::getBankIdentificationCode,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("bankName",
|
||||
BankAccountUpdateRequest::getBankName,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("correspondentAccount",
|
||||
BankAccountUpdateRequest::getCorrespondentAccount,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("correspondentAccountName",
|
||||
BankAccountUpdateRequest::getCorrespondentAccountName,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("destination",
|
||||
BankAccountUpdateRequest::getDestination,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("account",
|
||||
BankAccountUpdateRequest::getAccount,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("taxpayerIdentificationNumber",
|
||||
BankAccountUpdateRequest::getTaxpayerIdentificationNumber,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("taxRegistrationReasonCode",
|
||||
BankAccountUpdateRequest::getTaxRegistrationReasonCode,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("swiftCode",
|
||||
BankAccountUpdateRequest::getSwiftCode,
|
||||
AccountError.BadSymbol),
|
||||
ValidateSymbolsRule.notRequired("intermediarySwiftCode",
|
||||
BankAccountUpdateRequest::getIntermediarySwiftCode,
|
||||
AccountError.BadSymbol)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,14 @@ import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
|
|||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.CompanySymbols;
|
||||
import ru.clearing.classes.statics.data.misc.Currency;
|
||||
import ru.clearing.classes.statics.data.misc.ValidationSymbols;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistry;
|
||||
import ru.clearing.classes.statics.data.registry.TradingClearingRegistryList;
|
||||
import ru.clearing.platform.dictionary.*;
|
||||
import ru.clearing.platform.dictionary.AccountTypeDictionary;
|
||||
import ru.clearing.platform.dictionary.ClearingAccountTypeDictionary;
|
||||
import ru.clearing.platform.dictionary.CurrencyCodeDictionary;
|
||||
import ru.clearing.platform.dictionary.ServiceStatusDictionary;
|
||||
import ru.clearing.platform.dictionary.TradingClearingRegistryTypeDictionary;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.clearing.validation.common.ValidationHelper;
|
||||
import ru.spcex.platform.classes.base.SpcexObjectBase;
|
||||
|
|
@ -52,6 +57,7 @@ public class ValidationConfig {
|
|||
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistryList, TradingClearingRegistryList.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_Currency, Currency.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_TradingClearingRegistryTypeDictionary, TradingClearingRegistryTypeDictionary.class);
|
||||
addImdg.accept(IMDGDistributedNames.Map_ValidationSymbols, ValidationSymbols.class);
|
||||
|
||||
//for ClientCodeValidationConfig
|
||||
addImdg.accept(IMDGDistributedNames.Map_ClientCode, ClientCode.class);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public enum AccountError implements IErrorEnumId {
|
|||
ACCOUNT_NOT_FOUND_GTW(5029L),
|
||||
COMPANY_NOT_FOUND_GTW(5030L),
|
||||
CurrencyForTradingClearingRegistryListAlreadyUsed(5031L),
|
||||
BadSymbol(5032L),
|
||||
TradingClearingRegistryNotFound(3022L),
|
||||
CurrencyNotFound(1016L),
|
||||
;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
package ru.spcex.clearing.account.service;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.apache.kafka.clients.consumer.MockConsumer;
|
||||
import org.apache.kafka.clients.producer.Producer;
|
||||
import org.apache.kafka.clients.producer.ProducerRecord;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
|
@ -15,6 +20,7 @@ import ru.clearing.classes.statics.data.account.BankAccount;
|
|||
import ru.clearing.classes.statics.data.company.ClearingMemberCategory;
|
||||
import ru.clearing.classes.statics.data.company.Company;
|
||||
import ru.clearing.classes.statics.data.company.relation.Relation;
|
||||
import ru.clearing.classes.statics.data.misc.ValidationSymbols;
|
||||
import ru.clearing.platform.dictionary.CurrencyCodeDictionary;
|
||||
import ru.spcex.clearing.account.config.BeanConfiguration;
|
||||
import ru.spcex.clearing.account.config.validation.AccountValidationConfig;
|
||||
|
|
@ -29,27 +35,25 @@ import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountNewReq
|
|||
import ru.spcex.clearing.platform.messaging.domain.cud.account.BankAccountUpdateRequest;
|
||||
import ru.spcex.clearing.platform.messaging.domain.cud.common.CommonDeleteRequest;
|
||||
import ru.spcex.clearing.platform.messaging.service.RequestInfoUpdate;
|
||||
import static ru.spcex.clearing.platform.messaging.service.Status.Error;
|
||||
import ru.spcex.clearing.test.MatcherFactory.Matcher;
|
||||
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import ru.spcex.clearing.test.TestObjectCreator;
|
||||
import static ru.spcex.clearing.test.TestUtils.*;
|
||||
import ru.spcex.clearing.test.config.ImdgTestConfig;
|
||||
import ru.spcex.clearing.test.config.KafkaTestConfig;
|
||||
import ru.spcex.platform.enumeration.*;
|
||||
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
|
||||
import ru.spcex.platform.enumeration.AccountType;
|
||||
import ru.spcex.platform.enumeration.Allowed;
|
||||
import ru.spcex.platform.enumeration.ClearingCategory;
|
||||
import ru.spcex.platform.enumeration.Service;
|
||||
import ru.spcex.platform.enumeration.Status;
|
||||
import ru.spcex.platform.enumeration.WorkflowStatus;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.api.ImdgProvider;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IMessageResolver;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.timeout;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static ru.spcex.clearing.platform.messaging.service.Status.Error;
|
||||
import static ru.spcex.clearing.test.MatcherFactory.usingIgnoringFieldsComparator;
|
||||
import static ru.spcex.clearing.test.TestUtils.*;
|
||||
import static ru.spcex.clearing.test.config.KafkaTestConfig.getCaptor;
|
||||
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration(classes = {
|
||||
AccountHelper.class,
|
||||
|
|
@ -89,6 +93,7 @@ public class BankAccountServiceTest {
|
|||
private Imdg<CurrencyCodeDictionary> currencyCodeDictionaryImdg;
|
||||
private Imdg<ClearingMemberCategory> clearingMemberCategoryImdg;
|
||||
private Imdg<Relation> relationImdg;
|
||||
private Imdg<ValidationSymbols> validationSymbolsImdg;
|
||||
|
||||
@Autowired
|
||||
private IMessageResolver messageResolver;
|
||||
|
|
@ -119,10 +124,26 @@ public class BankAccountServiceTest {
|
|||
relationImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_Relation, Relation.class
|
||||
);
|
||||
validationSymbolsImdg = hazelcastServiceTest.getImdg(
|
||||
IMDGDistributedNames.Map_ValidationSymbols, ValidationSymbols.class
|
||||
);
|
||||
CurrencyCodeDictionary currencyCodeDictionary = new CurrencyCodeDictionary();
|
||||
currencyCodeDictionary.setCode("RUB");
|
||||
currencyCodeDictionary.setName("RUB");
|
||||
currencyCodeDictionaryImdg.insert(currencyCodeDictionary);
|
||||
ValidationSymbols validationSymbols = new ValidationSymbols();
|
||||
validationSymbols.setId(1L);
|
||||
validationSymbols.setSymbols("а-яА-ЯёЁ");
|
||||
validationSymbolsImdg.insert(validationSymbols);
|
||||
validationSymbols.setId(2L);
|
||||
validationSymbols.setSymbols("a-zA-Z");
|
||||
validationSymbolsImdg.insert(validationSymbols);
|
||||
validationSymbols.setId(3L);
|
||||
validationSymbols.setSymbols("0-9");
|
||||
validationSymbolsImdg.insert(validationSymbols);
|
||||
validationSymbols.setId(4L);
|
||||
validationSymbols.setSymbols("-_., ;\"%");
|
||||
validationSymbolsImdg.insert(validationSymbols);
|
||||
|
||||
new TestObjectCreator(hazelcastServiceTest).createUserAdmin(1000L);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -450,6 +450,7 @@
|
|||
<errorCode id="5029" code="ACNT" name="Счет %s не найден в клиринговой системе."/>
|
||||
<errorCode id="5030" code="ACNT" name="Компания %s не найдена в клиринговой системе."/>
|
||||
<errorCode id="5031" code="ACNT" name="Для данной валюты в ТКР уже задан счет."/>
|
||||
<errorCode id="5032" code="ACNT" name="В поле %s недопустимый символ %s."/>
|
||||
<!-- error code for balance-service -->
|
||||
<errorCode id="5200" code="BLNC" name="Общая ошибка модуля balance-service."/>
|
||||
<errorCode id="5210" code="BLNC" name="Клиринговая сессия неактивна."/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
package ru.spcex.clearing.validation.common.rules;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import ru.clearing.classes.statics.data.misc.ValidationSymbols;
|
||||
import ru.spcex.clearing.imdg.IMDGDistributedNames;
|
||||
import ru.spcex.platform.imdg.api.Imdg;
|
||||
import ru.spcex.platform.imdg.validation.ImdgValidationContext;
|
||||
import ru.spcex.platform.utils.enumeration.EnumMessage;
|
||||
import ru.spcex.platform.utils.enumeration.IErrorEnumId;
|
||||
import ru.spcex.platform.utils.validation.IValidationRule;
|
||||
|
||||
/**
|
||||
* Проверка полей на символы из validation_symbols.
|
||||
* Требует наличия в контексте мапы IMDGDistributedNames.Map_ValidationSymbols.
|
||||
*
|
||||
* @param <R> - Класс проверяемого объекта
|
||||
*/
|
||||
public final class ValidateSymbolsRule<R> implements IValidationRule<ImdgValidationContext<R>> {
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
private final Pattern rangePattern = Pattern.compile("([\\p{L}0-9]-[\\p{L}0-9]|.)");
|
||||
|
||||
private final static ThreadLocal<Set<Character>> allowedSymbols = new ThreadLocal<>();
|
||||
private final static ThreadLocal<Integer> allowedSymbolsHash = new ThreadLocal<>();
|
||||
|
||||
private final String fieldName;
|
||||
private final Function<R, String> getter;
|
||||
private final IErrorEnumId errorEmptyRequiredValue;
|
||||
private final IErrorEnumId errorBadSymbol;
|
||||
private final boolean required;
|
||||
|
||||
public ValidateSymbolsRule(
|
||||
String fieldName,
|
||||
Function<R, String> getter,
|
||||
IErrorEnumId errorEmptyRequiredValue,
|
||||
IErrorEnumId errorBadSymbol,
|
||||
boolean required
|
||||
) {
|
||||
this.fieldName = fieldName;
|
||||
this.getter = getter;
|
||||
this.errorEmptyRequiredValue = errorEmptyRequiredValue;
|
||||
this.errorBadSymbol = errorBadSymbol;
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
public static <R> ValidateSymbolsRule<R> notRequired(String fieldName,
|
||||
Function<R, String> getter,
|
||||
IErrorEnumId errorBadSymbol) {
|
||||
return new ValidateSymbolsRule<>(fieldName, getter, null, errorBadSymbol, false);
|
||||
}
|
||||
|
||||
public static <R> ValidateSymbolsRule<R> required(String fieldName,
|
||||
Function<R, String> getter,
|
||||
IErrorEnumId errorEmptyRequiredValue,
|
||||
IErrorEnumId errorBadSymbol) {
|
||||
return new ValidateSymbolsRule<>(fieldName, getter, errorEmptyRequiredValue, errorBadSymbol, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<EnumMessage> validate(ImdgValidationContext<R> context) {
|
||||
String value = getter.apply(context.getValidatedObject());
|
||||
if (StringUtils.isBlank(value)) {
|
||||
if (!required) return Optional.empty();
|
||||
else return Optional.of(new EnumMessage(errorEmptyRequiredValue, fieldName));
|
||||
}
|
||||
|
||||
checkAndSetAllowed(context);
|
||||
Set<Character> allowed = allowedSymbols.get();
|
||||
if (allowed.isEmpty()) {
|
||||
log.warn("Can't validate field {}: empty validation_symbols, skipped", fieldName);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Set<String> invalidSymbols = new HashSet<>();
|
||||
for (int charIdx = 0; charIdx < value.length(); charIdx++) {
|
||||
char character = value.charAt(charIdx);
|
||||
if (!allowed.contains(character)) invalidSymbols.add(String.valueOf(character));
|
||||
}
|
||||
|
||||
if (invalidSymbols.isEmpty()) return Optional.empty();
|
||||
|
||||
return Optional.of(new EnumMessage(errorBadSymbol, fieldName, String.join(", ", invalidSymbols)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет изменения в validation_symbols. Если изменения есть, создает новую коллекцию разрешенных символов
|
||||
*/
|
||||
private void checkAndSetAllowed(ImdgValidationContext<R> context) {
|
||||
Imdg<ValidationSymbols> validationSymbolsImdg = context.obtainMap(
|
||||
IMDGDistributedNames.Map_ValidationSymbols, ValidationSymbols.class
|
||||
);
|
||||
Collection<ValidationSymbols> validationSymbols = validationSymbolsImdg.getAllValues();
|
||||
String forHash = validationSymbols.stream().map(ValidationSymbols::getSymbols).collect(Collectors.joining());
|
||||
Integer hash = forHash.hashCode();
|
||||
if (!Objects.equals(allowedSymbolsHash.get(), hash)) {
|
||||
Matcher matcher = rangePattern.matcher(forHash);
|
||||
Set<Character> currAllowedSymbols = new HashSet<>();
|
||||
while (matcher.find()) {
|
||||
String part = matcher.group();
|
||||
if (part.length() == 3 && part.charAt(1) == '-') {
|
||||
char start = part.charAt(0);
|
||||
char end = part.charAt(2);
|
||||
if (start > end) {
|
||||
log.warn("Invalid character range: {}, skipped", part);
|
||||
continue;
|
||||
}
|
||||
for (char c = start; c <= end; c++) {
|
||||
currAllowedSymbols.add(c);
|
||||
}
|
||||
} else {
|
||||
currAllowedSymbols.add(part.charAt(0));
|
||||
}
|
||||
}
|
||||
allowedSymbols.set(currAllowedSymbols);
|
||||
allowedSymbolsHash.set(hash);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue