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

org.unlaxer.jaddress.parser.Phrase Maven / Gradle / Ivy

package org.unlaxer.jaddress.parser;

import static org.unlaxer.jaddress.parser.CharacterKind.alphabet;
import static org.unlaxer.jaddress.parser.CharacterKind.arabicNumber;
import static org.unlaxer.jaddress.parser.CharacterKind.japaneseAddressNumber;
import static org.unlaxer.jaddress.parser.CharacterKind.normal;
import static org.unlaxer.jaddress.parser.CharacterKind.suffix丁目;
import static org.unlaxer.jaddress.parser.CharacterKind.suffix号;
import static org.unlaxer.jaddress.parser.CharacterKind.suffix号室;
import static org.unlaxer.jaddress.parser.CharacterKind.suffix地番;
import static org.unlaxer.jaddress.parser.CharacterKind.suffix棟;
import static org.unlaxer.jaddress.parser.CharacterKind.suffix階;
import static org.unlaxer.jaddress.parser.CharacterKind._堂;
import static org.unlaxer.jaddress.parser.TopOrBottom.BOTTOM;
import static org.unlaxer.jaddress.parser.TopOrBottom.TOP;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

import org.unlaxer.jaddress.entity.standard.階層要素;

import io.vavr.Function3;


public enum Phrase {
	
	丁目(階層要素.町域Top1,TOP,
		List.of(
			toPredicates(arabicNumber ,suffix丁目),
			toPredicates(japaneseAddressNumber,suffix丁目)
	)),
	
	地番(階層要素.町域Top2,TOP,
		List.of(
			toPredicates(arabicNumber ,suffix地番),
			toPredicates(japaneseAddressNumber,suffix地番)
	)),
	
	支号(階層要素.町域Top3,TOP,
		List.of(
			toPredicates(arabicNumber ,suffix号),
			toPredicates(japaneseAddressNumber,suffix号)
	)),
	
	
	棟(階層要素.建物Bottom3,BOTTOM,
		List.of(
			toPredicates(arabicNumber ,suffix棟),
			toPredicates(japaneseAddressNumber,suffix棟),
			toPredicates(alphabet ,suffix棟),
			toPredicates(alphabet ,arabicNumber ,suffix棟),
			toPredicates(alphabet ,japaneseAddressNumber,suffix棟),
			toPredicates(arabicNumber ,alphabet ,suffix棟),
			toPredicates(japaneseAddressNumber, alphabet ,suffix棟)
	)),
	
	階数(階層要素.建物Bottom2,BOTTOM,
		List.of(
			List.of(
					toPredicate(arabicNumber ),
					toPredicate(suffix階) , 
					PredicateForNotConsumed.of(kind->kind != _堂)),//二階は良いが二階堂はダメ
			List.of(
					toPredicate(japaneseAddressNumber ),
					toPredicate(suffix階) , 
					PredicateForNotConsumed.of(kind->kind != _堂))
//			toPredicates(arabicNumber ,suffix階),
//			toPredicates(japaneseAddressNumber,suffix階)
	)),

	部屋番号(階層要素.建物Bottom1,BOTTOM,
		List.of(
			//TODO parser combinator
			toPredicates(arabicNumber ,suffix号室),
			toPredicates(japaneseAddressNumber,suffix号室),
			toPredicates(arabicNumber , alphabet, suffix号室),
			toPredicates(japaneseAddressNumber, alphabet, suffix号室),
			toPredicates(alphabet , arabicNumber , suffix号室),
			toPredicates(arabicNumber ,suffix号),
			toPredicates(japaneseAddressNumber,suffix号),
			toPredicates(arabicNumber , alphabet, suffix号),
			toPredicates(japaneseAddressNumber, alphabet, suffix号),
			toPredicates(alphabet , arabicNumber , suffix号),
			toPredicates(alphabet , japaneseAddressNumber, suffix号),
			toPredicates(alphabet , japaneseAddressNumber, suffix号)
	)),
	
	建物(階層要素.建物,BOTTOM,
		List.of(
			toPredicates(normal)
	)),
	
	数字のみ(
		TOP,
		List.of(
			toPredicates(arabicNumber),
			List.of(
				PredicateForNotConsumed.of(chracterKind->false == chracterKind.isNormal()), 
				toPredicate(japaneseAddressNumber ) , 
				PredicateForNotConsumed.of(chracterKind->false == chracterKind.isNormal())
			)
	)),
	
	数字アルファベット(
		TOP,
		List.of(
			toPredicates(arabicNumber , alphabet)//,
//			toPredicates(japaneseAddressNumber  , alphabet)
	)),
	
	アルファベット数字(
		TOP,
		List.of(
			toPredicates(alphabet , arabicNumber)
//			List.of(toPredicate(alphabet) , toPredicate(japaneseAddressNumber ) , chracterKind->false == chracterKind.isNormal() )
	)),
	
	;
	Optional<階層要素> target階層要素;
	List>> predicates;
	TopOrBottom scanFrom;
	
	ResolverResultKindOfBoolean whenMatch;
	
	boolean withSuffix;
	
	static int replaceOffset(List> predicates) {
		int offset =0;
		for (Predicate predicate : predicates) {
			if(predicate instanceof PredicateForNotConsumed) {
				offset++;
				continue;
			}
			break;
		}
		return offset;
	}
	
	static int replaceSize(List> predicates) {
		int size =0;
		for (Predicate predicate : predicates) {
			if(predicate instanceof PredicateForNotConsumed) {
				continue;
			}
			size++;
		}
		return size;
	}

	
	Function3<
		BlockAndBuildings, 
		ListIndex, 
		List>,
		List> 
			extractorWhenMatch = (blockAndBuildings, listIndex, matchedPredicates)->{ 
				
				int replaceOffset = replaceOffset(matchedPredicates);
				int replaceSize = replaceSize(matchedPredicates);
				
				return blockAndBuildings.subStringAndCharacterKinds(listIndex.plus(replaceOffset) , replaceSize);
			};
			
	Function3> , Void> 
		replaceerWhenMatch = 
			(blockAndBuildings, listIndex, matchedPredicates)-> {
				StringAndCharacterKinds stringAndCharacterKinds = extract(blockAndBuildings ,  listIndex , matchedPredicates);
				
				int replaceOffset = replaceOffset(matchedPredicates);
				int replaceSize = replaceSize(matchedPredicates);
				
				blockAndBuildings.replace(
						listIndex.plus(replaceOffset), 
						replaceSize, 
						new PhraseAndStrings(this, stringAndCharacterKinds)
				);
				return null;
			};

	private Phrase(階層要素 target階層要素, TopOrBottom scanFrom ,
			List>> predicates) {
		this .target階層要素 = Optional.of(target階層要素);
		this.scanFrom = scanFrom;
		this.predicates = predicates;
		this.withSuffix = true;
	}
	
	private Phrase(TopOrBottom scanFrom , 
			List>> predicates) {
		this .target階層要素 = Optional.empty();
		this.scanFrom = scanFrom;
		this.predicates = predicates;
		this.withSuffix = false;
	}
	
	public boolean withSuffix() {
		return withSuffix;
	}
	
	public Optional<階層要素> target階層要素(){
		return target階層要素;
	}
	public List>> predicates(){
		return predicates;
	}
	public TopOrBottom scanFrom() {
		return scanFrom;
	}
	
	public StringAndCharacterKinds extract(
		BlockAndBuildings blockAndBuildings, ListIndex listIndex, List> predicates) {
		
		List stringAndCharacterKinds =
				extractorWhenMatch.apply(blockAndBuildings, listIndex , predicates);
		return new StringAndCharacterKinds(stringAndCharacterKinds);
	}
	
	public void replace(
		BlockAndBuildings blockAndBuildings, ListIndex listIndex , List> predicates) {
		
		replaceerWhenMatch.apply(blockAndBuildings, listIndex , predicates);
	}
	
	static List> toPredicates(CharacterKind... checkKinds){
		
		List> results = new ArrayList<>();
		
		for (CharacterKind characterKind : checkKinds) {
			results.add(parameterCharacterKind -> parameterCharacterKind == characterKind);
		}
		return results;
	}
	
	static Predicate toPredicate(CharacterKind characterKind){
		
		return parameterCharacterKind -> parameterCharacterKind == characterKind;
	}
	
	static PredicateForNotConsumed toPredicateForNotConsumed(CharacterKind characterKind){
		
		return parameterCharacterKind -> parameterCharacterKind == characterKind;
	}

	static PredicateForNotConsumed notJapanese = chracterKind->false == chracterKind.isNormal();
	
	public interface PredicateForNotConsumed extends Predicate{
		static PredicateForNotConsumed of(Predicate predicate){
			return new PredicateForNotConsumed() {
				@Override
				public boolean test(T t) {
					return predicate.test(t);
				}
			};
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy