org.unlaxer.jaddress.parser.processor.PrefectureToTownNameTokenizer Maven / Gradle / Ivy
package org.unlaxer.jaddress.parser.processor;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.unlaxer.jaddress.entity.standard.定義済みRange階層要素;
import org.unlaxer.jaddress.entity.standard.階層要素;
import org.unlaxer.jaddress.entity.zip.ZipBasedAddress;
import org.unlaxer.jaddress.parser.AddressContext;
import org.unlaxer.jaddress.parser.AddressElement;
import org.unlaxer.jaddress.parser.AddressElementFactory;
import org.unlaxer.jaddress.parser.AddressProcessor;
import org.unlaxer.jaddress.parser.IntermediateResult;
import org.unlaxer.jaddress.parser.ParsingState;
import org.unlaxer.jaddress.parser.ParsingTarget;
import org.unlaxer.jaddress.parser.ResolverResultKind;
import org.unlaxer.jaddress.parser.ResolverResultKindOfMatchKind;
import org.unlaxer.jaddress.parser.SeparatorKind;
import org.unlaxer.jaddress.parser.StringAndCharacterKinds;
import org.unlaxer.jaddress.parser.StringIndex;
import org.unlaxer.jaddress.parser.TargetStateAndElement;
import org.unlaxer.util.collection.TreeNode;
import org.unlaxer.util.function.Unchecked;
public class PrefectureToTownNameTokenizer implements AddressProcessor {
@Override
public ParsingState targetState() {
return ParsingState.都道府県から町名までを分割する;
}
@Override
public TargetStateAndElement process(ParsingTarget parsingTarget) {
AddressContext addressContext = parsingTarget.addressContext();
IntermediateResult intermediateResult = parsingTarget.intermediateResult();
TreeNode targetNode = targetNode(parsingTarget);
StringAndCharacterKinds address = addressContext.addressString();
List> allResults = new ArrayList<>();
for (ZipBasedAddress zipBasedAddress : intermediateResult.zipBasedAddressesFromZip()) {
StringIndex currentIndex = new StringIndex(0);
List results = new ArrayList<>();
// 1:都道府県 その他
currentIndex = search(parsingTarget , addressContext, targetNode, address,
currentIndex,zipBasedAddress.kenName() ,results , 階層要素.都道府県)
.map(SearchResult::next)
.orElse(currentIndex);
// 2 市, 東京23区, 政令指定市, 群
currentIndex = search(parsingTarget , addressContext, targetNode, address,
currentIndex, zipBasedAddress.cityName() ,results , 階層要素.市)
.map(SearchResult::next)
.orElse(currentIndex);
// 3:区,町村
currentIndex = search(parsingTarget , addressContext, targetNode, address,
currentIndex, zipBasedAddress.townName() , results , 階層要素.町村)
.map(SearchResult::next)
.orElse(currentIndex);
// 4:町または大字 ?
// FIXME!!
// currentIndex = search(parsingTarget , addressContext, targetNode, address,
// currentIndex, zipBasedAddress.kyotoStreet() , results , 階層要素.町または大字)
// .map(SearchResult::next)
// .orElse(currentIndex);
boolean allMatch = results.stream()
.allMatch(SearchResult::isValid);
if(allMatch && results.size() ==4) {
return process(addressContext , targetNode , results);
}else {
allResults.add(results);
}
}
List results = select(allResults);
return process(addressContext , targetNode , results);
}
private List select(List> allResults) {
allResults.sort(
(list1,list2)->
level(list2) - level(list1)
);
List list = allResults.get(0);
return list;
}
public int level(List results) {
return results.isEmpty() ?
0 :
results.get(results.size()-1).next.value;
}
private TargetStateAndElement process(
AddressContext addressContext,
TreeNode targetNode, List results) {
if(results.isEmpty()) {
return new TargetStateAndElement(ParsingState.町名分割エラー , 定義済みRange階層要素.全体);
}
SearchResult lastSearchResult = results.get(results.size()-1);
if(lastSearchResult._階層要素.level <= 階層要素.区.level) {
return new TargetStateAndElement(ParsingState.町名分割エラー , 定義済みRange階層要素.全体);
}
results.stream()
.forEach(SearchResult::run);
StringIndex next = lastSearchResult.next();
StringAndCharacterKinds substring =
addressContext.addressString().substring(next, SeparatorKind.domainSpecificSeparator, SeparatorKind.terminator);
addressContext.addChild(
targetNode,
AddressElementFactory.of(substring, 定義済みRange階層要素.町名より後 ,
SeparatorKind.domainSpecificSeparator , SeparatorKind.domainSpecificSeparator
)
);
return new TargetStateAndElement(ParsingState.町名から丁目の階層種類をDBを用いて求める , 定義済みRange階層要素.町名より後);
}
private Optional search(
ParsingTarget parsingTarget,
AddressContext addressContext,
TreeNode targetNode,
StringAndCharacterKinds address,
StringIndex currentIndex,
String nameOfPart,
List results,
階層要素 _階層要素) {
Optional search =
search(addressContext, targetNode, address, currentIndex, nameOfPart, _階層要素);
search.ifPresent(result->{
results.add(result);
ResolverResultKind resolverResultKind = null;
switch (_階層要素) {
case 都道府県:
resolverResultKind = ResolverResultKindOfMatchKind.郵便番号辞書match都道府県;
break;
case 市:
resolverResultKind = ResolverResultKindOfMatchKind.郵便番号辞書match市;
break;
case 町村:
resolverResultKind = ResolverResultKindOfMatchKind.郵便番号辞書match町村;
break;
case 町または大字:
resolverResultKind = ResolverResultKindOfMatchKind.郵便番号辞書match町または大字;
break;
default:
throw new IllegalArgumentException();
}
parsingTarget.addResolverResult(resolverResultKind);
});
return search;
}
private Optional search(
AddressContext addressContext,
TreeNode targetNode,
StringAndCharacterKinds address,
StringIndex currentIndex,
String nameOfPart,
階層要素 _階層要素) {
if (false == isEmpty(nameOfPart)) {
StringIndex indexOf = address.indexOf(nameOfPart, currentIndex);
if(indexOf.isValid()) {
return Optional.of(
new SearchResult(_階層要素 , indexOf, indexOf.plus(nameOfPart.length()),
()->{
addressContext.addChild(
targetNode,
AddressElementFactory.of(nameOfPart, _階層要素 ,
SeparatorKind.domainSpecificSeparator , SeparatorKind.domainSpecificSeparator
)
);
}
)
);
}else {
Optional.of(
new SearchResult(_階層要素 , StringIndex.invalid(), currentIndex,()->{})
);
}
}
return Optional.empty();
}
static class SearchResult implements Runnable{
public final 階層要素 _階層要素;
public final StringIndex indexOf;
public final StringIndex next;
public final Runnable runnable;
public SearchResult(階層要素 _階層要素 , StringIndex indexOf, StringIndex next , Runnable runnable) {
super();
this._階層要素 = _階層要素;
this.next = next;
this.indexOf = indexOf;
this.runnable = runnable;
}
public boolean isValid() {
return indexOf.isValid();
}
public StringIndex next() {
return next;
}
@Override
public void run() {
Unchecked.run(()->runnable.run());
}
}
static boolean isEmpty(String word) {
return word == null || word.equalsIgnoreCase("NULL") || word.isEmpty();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy