All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.unlaxer.jaddress.parser.processor.BlockHierarchyResolver Maven / Gradle / Ivy

The newest version!
package org.unlaxer.jaddress.parser.processor;

import java.util.Optional;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.unlaxer.jaddress.entity.standard.郵便番号;
import org.unlaxer.jaddress.entity.standard.階層要素;
import org.unlaxer.jaddress.parser.AddressContext;
import org.unlaxer.jaddress.parser.AddressElement;
import org.unlaxer.jaddress.parser.AddressProcessor;
import org.unlaxer.jaddress.parser.CharacterKind;
import org.unlaxer.jaddress.parser.CharacterKinds;
import org.unlaxer.jaddress.parser.DataAccessContext;
import org.unlaxer.jaddress.parser.IntermediateResult;
import org.unlaxer.jaddress.parser.ParsingState;
import org.unlaxer.jaddress.parser.ParsingTarget;
import org.unlaxer.jaddress.parser.TargetStateAndElement;
import org.unlaxer.util.collection.TreeNode;

public class BlockHierarchyResolver implements AddressProcessor{

	@Override
	public ParsingState targetState() {
		return ParsingState.町名から丁目の階層種類をDBを用いて求める;
	}

	@Override
	public TargetStateAndElement process(ParsingTarget parsingTarget) {

		AddressContext addressContext = parsingTarget.addressContext();
		IntermediateResult intermediateResult = parsingTarget.intermediateResult();
		DataAccessContext dataAccessContext = parsingTarget.dataAccessContext();
		BlockPatternResolver resolver = dataAccessContext.getBlockPatternResolver();


		//ここのadressElementの内容(町名)から丁目階層を求める

		Optional findLike町名 = findLike町名(addressContext);

		BlockPatternResolverResult result = findLike町名.map(like町名->{
			return resolver.resolve(addressContext.zip(), dataAccessContext , like町名);
		})
		.orElse(BlockPatternResolverResult.DEFAULT);

		intermediateResult.setBlockPatternResolverResult(result);

		return new TargetStateAndElement(ParsingState.丁目以降を分割する , target階層要素(parsingTarget));
	}

	Optional findLike町名(AddressContext addressContext) {
		Optional findFirst = addressContext.addressTree().stream()
			.map(TreeNode::get)
			.filter(addressElement->false == addressElement.singleOrRange階層要素().isRange())
			.sorted(AddressElement.big階層要素OrdinalIsTop)
			.findFirst();
		return findFirst;
	}

	public interface BlockPatternResolver{

		public BlockPatternResolverResult resolve(郵便番号 zip , DataAccessContext dataAccessContext , AddressElement town);
	}


	public static class SimpleBlockPatternResolver implements BlockPatternResolver{
		@Override
		public BlockPatternResolverResult resolve(郵便番号 zip, DataAccessContext dataAccessContext , AddressElement town) {
			
			BlockPatternResolverResult blockPatternResolverResult = new BlockPatternResolverResult();
			
//			boolean 丁目を有する町域 = dataAccessContext.is丁目を有する町域(zip, town.asString());
			
			boolean  丁目を有する町域 = Stream.of(addTownNameSuffix(town.asString()))
					.map(townName->dataAccessContext.is丁目を有する町域(zip, townName))
					.anyMatch(match->match);

			if(false == 丁目を有する町域) {
				blockPatternResolverResult.remove(階層要素.町域Top1);
			}

			//〒541-0056 大阪府大阪市中央区久太郎町4丁目渡辺3
			if(zip.value.equals("5410056") && "久太郎町".equals(town.asString())) {
				//地番に渡辺が入る可能性があるので、normal(漢字)を追加する
				blockPatternResolverResult.add(
					階層要素.町域Top2,
					new TripletCharacterKinds(
						CharacterKinds.EMPTY,
						new CharacterKinds(CharacterKind.normal),
						CharacterKinds.EMPTY
					)
				);
			}
			return blockPatternResolverResult;
		}
	}
	
	static String[] addTownNameSuffix(String townName) {
		if(townName.endsWith("町") || townName.endsWith("村")) {
			return new String[] {townName , townName.substring(0,townName.length()-1)};
		}
		return new String[] {townName+"町" , townName +"村" , townName };
	}


	public static class BlockPatternResolverResult{

		SortedMap<階層要素,TripletCharacterKinds> characterKindsBy階層要素;

		TripletCharacterKinds 丁目 = new TripletCharacterKinds(
			CharacterKinds.EMPTY,
			new CharacterKinds(
				CharacterKind.arabicNumber,
				CharacterKind.japaneseAddressNumber
			),
			new CharacterKinds(
				CharacterKind.suffix丁目
			)
		);

		TripletCharacterKinds 番地 = new TripletCharacterKinds(
			CharacterKinds.EMPTY,
			new CharacterKinds(
				CharacterKind.arabicNumber,
				CharacterKind.japaneseAddressNumber
			),
			new CharacterKinds(
				CharacterKind.suffix地番
			)
		);
		TripletCharacterKinds 号 = new TripletCharacterKinds(
			CharacterKinds.EMPTY,
			new CharacterKinds(
				CharacterKind.arabicNumber,
				CharacterKind.japaneseAddressNumber
			),
			new CharacterKinds(
				CharacterKind.suffix号
			)
		);
		TripletCharacterKinds 枝番 = new TripletCharacterKinds(
			CharacterKinds.EMPTY,
			new CharacterKinds(
				CharacterKind.arabicNumber,
				CharacterKind.japaneseAddressNumber
			),
			CharacterKinds.EMPTY
		);

		public static final BlockPatternResolverResult DEFAULT =
				new BlockPatternResolverResult();

		public BlockPatternResolverResult() {
			super();
			this.characterKindsBy階層要素 =
				new TreeMap<階層要素, TripletCharacterKinds>((x,y)->x.ordinal() - y.ordinal());

			add(階層要素.町域Top1, 丁目);
			add(階層要素.町域Top2, 番地);
			add(階層要素.町域Top3, 号);
			add(階層要素.町域Top4, 枝番);
			
		}

		public void add(階層要素 _階層要素 ,TripletCharacterKinds characterKinds) {
			characterKindsBy階層要素
				.compute(_階層要素 , (key,value)->
					value == null ?
						characterKinds:
						value.add(characterKinds)
				);
		}

		public void remove(階層要素 _階層要素) {
			characterKindsBy階層要素.remove(_階層要素);
		}

		public SortedMap<階層要素,TripletCharacterKinds> characterKindsBy階層要素(){
			return characterKindsBy階層要素;
		}

		@Override
		public String toString() {
			String collect = characterKindsBy階層要素.entrySet().stream()
				.map(entry->"'"+entry.getKey().name() + "' : " +entry.getValue().toString())
				.collect(Collectors.joining(",", "{", "}"));
			return collect;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy