001/* 002 * Copyright c 2018 Rusi Popov, MDA Tools.net All rights reserved. 003 * 004 * This program and the accompanying materials are made available under the terms of the 005 * Eclipse Public License v2.0 which accompanies this distribution, and is available at 006 * http://www.eclipse.org/legal/epl-v20.html 007 */ 008package net.mdatools.modelant.core.operation.format; 009 010import java.util.Iterator; 011 012import net.mdatools.modelant.core.api.Operation; 013import net.mdatools.modelant.core.util.NameTokenizer; 014 015/** 016 * Extract the words from the string, format them ad concatenate them according 017 * @author Rusi Popov (popovr@mdatools.net) 018 */ 019public abstract class FormatWordsString implements Operation<String> { 020 021 private final String separator; 022 023 /** 024 * @param separator not null, possibly empty string to use as a separator between the result words 025 */ 026 protected FormatWordsString(String separator) { 027 if ( separator == null) { 028 throw new IllegalArgumentException("Expected a non-null separator string"); 029 } 030 this.separator = separator; 031 } 032 033 034 /** 035 * @param source not null string to parse 036 * @return string of the formatted words from the source string, concatenated with the separator string provided 037 * @throws RuntimeException 038 * @throws IllegalArgumentException 039 * @see net.mdatools.modelant.core.api.Function#execute(java.lang.Object) 040 */ 041 public final String execute(String source) throws RuntimeException, IllegalArgumentException { 042 StringBuilder result; 043 Iterator<String> wordIterator; 044 String word; 045 046 assert source != null : "Expected a non-null source"; 047 048 result = new StringBuilder(source.length()); 049 050 source = prepare(source); 051 052 wordIterator = new NameTokenizer( source ); 053 while ( wordIterator.hasNext() ) { 054 word = wordIterator.next(); 055 056 if ( result.length() == 0 ) { 057 formatFirstWord( result, word, wordIterator.hasNext() ); 058 059 } else { 060 result.append( separator ); 061 formatNextWord( result, word, wordIterator.hasNext() ); 062 } 063 } 064 return result.toString(); 065 } 066 067 /** 068 * Implement any pre-processing of the source string, before parsing it into words 069 * @param source the not-null string to format 070 * @return the sanitized string to parse into words 071 */ 072 protected abstract String prepare(String source); 073 074 075 /** 076 * Concatenate the formatted word into the result builder 077 * @param result non null store of the produced word, result.lenght() = 0 078 * @param word not null, not empty word of letters and digits, which is NOT the first word identified in the source string 079 * @param nextWordExists true, if there are more words to be formatted, false when this is the only word to format 080 */ 081 protected abstract void formatFirstWord(StringBuilder result, String word, boolean nextWordExists); 082 083 084 /** 085 * Concatenate the formatted word into the result builder 086 * @param result non null store of the produced word, result.lenght() != 0 087 * @param word not null, not empty word of letters and digits, which is the first word identified in the source string 088 * @param nextWordExists true, if there are more words to be formatted, false when this is the last word to format 089 */ 090 protected abstract void formatNextWord(StringBuilder result, String word, boolean nextWordExists); 091 092 093 /** 094 * Append to result the string provided, with first letter capitalized and all next in lower case 095 * 096 * @param name not null to capitalize 097 * @param result not null result/output parameter 098 */ 099 protected final void formatFirstCapitalAllLower(StringBuilder result, String name) { 100 if ( name.length() > 0 ) { 101 result.append(Character.toUpperCase( name.charAt( 0 ) ) ); 102 result.append(name.substring( 1 ).toLowerCase() ); 103 } 104 } 105}