@@ -81,6 +81,11 @@ public static AlephFormatter template(String str, Map<String, Object> args) {
8181
8282 public static AlephFormatter fromFile (String strPath , Charset encoding , Map <String , Object > args ) { return template (readFromFile (strPath , encoding ), args ); }
8383
84+ public void failIfArgExists (String argName ) {
85+ if (arguments .containsKey (argName ))
86+ throw argumentAlreadyExist (argName );
87+ }
88+
8489 public static String readFromFile (String strPath , Charset encoding ) {
8590 try {
8691 byte [] encodedBytes = readAllBytes (Paths .get (strPath ));
@@ -91,19 +96,18 @@ public static String readFromFile(String strPath, Charset encoding) {
9196 }
9297
9398 public static String readFromFile (String strPath ) {
94- //TODO validate strPath
9599 return readFromFile (strPath , Charset .forName ("UTF8" ));
96100 }
97101
98102 public AlephFormatter arg (String argName , Object object ) {
103+ failIfArgExists (argName );
99104 this .arguments .put (argName , object );
100105 return this ;
101106 }
102107
103108 public AlephFormatter args (Map <String , Object > args ) {
104109 for (Map .Entry <String , Object > entry : args .entrySet ()) {
105- if (this .arguments .containsKey (entry .getKey ()))
106- throw argumentAlreadyExist (entry .getKey ());
110+ failIfArgExists (entry .getKey ());
107111 this .arguments .put (entry .getKey (), entry .getValue ());
108112 }
109113 return this ;
@@ -114,15 +118,11 @@ public AlephFormatter args(Object... args) {
114118 if (args .length % 2 == 1 )
115119 throw invalidNumberOfArguments (args .length );
116120
121+ String key ;
117122 for (int i = 0 ; i < args .length ; i +=2 ) {
118- String key = (String ) args [i ];
119-
120- // If the argument exists throw an error
121- if (this .arguments .containsKey (key ))
122- throw argumentAlreadyExist (key );
123-
124- Object value = args [i +1 ];
125- this .arguments .put (key , value );
123+ key = (String ) args [i ];
124+ failIfArgExists (key );
125+ this .arguments .put (key , args [i +1 ]);
126126 }
127127
128128 return this ;
@@ -132,29 +132,26 @@ public AlephFormatter args(Object... args) {
132132 */
133133 public String fmt () {
134134
135- StringBuilder result = new StringBuilder (str .length ());
136- StringBuilder param = new StringBuilder (16 );
135+ final StringBuilder result = new StringBuilder (str .length ());
136+ final StringBuilder param = new StringBuilder (16 );
137137
138138 State state = FREE_TEXT ;
139139
140140 int i = 0 ;
141+ char chr ;
141142 while (i < str .length ()) {
142- char chr = str .charAt (i );
143+ chr = str .charAt (i );
143144 state = nextState (state , i );
144145 switch (state ) {
145146 // In this state we just add the character to the
146147 // resulting buffer. No need to perform any processing.
147- case FREE_TEXT : result .append (chr ); break ;
148-
148+ case FREE_TEXT : { result .append (chr ); break ; }
149149 // We identify '#'. We skip the following '{'.
150- case PARAM_START : i ++; break ;
151-
150+ case PARAM_START : { i ++; break ; }
152151 // We append the character to the param chain buffer
153152 case PARAM : { validateParamChar (chr , i ); param .append (chr ); break ; }
154-
155153 // We append and replace the param with the correct value
156- case PARAM_END : appendParamValue (param , result ); break ;
157-
154+ case PARAM_END : { appendParamValue (param , result ); break ; }
158155 // Escape character
159156 case ESCAPE_CHAR : break ;
160157 }
@@ -168,12 +165,13 @@ public String fmt() {
168165 // in the string and the current value of the character
169166 private State nextState (State currentState , int i ) {
170167 switch (currentState ) {
171- case FREE_TEXT : return jumpFromFreText (str , i );
168+ case FREE_TEXT : return jumpFromFreeText (str , i );
172169 case PARAM_START : return jumpFromParamStart (str , i );
173170 case PARAM : return jumpFromParam (str , i );
174171 case PARAM_END : return jumpFromParamEnd (str , i );
175172 case ESCAPE_CHAR : return FREE_TEXT ;
176- default : throw new IllegalArgumentException ("Invalid state exception when parsing string." );
173+ // Should never go here
174+ default : throw invalidStateException (currentState );
177175 }
178176 }
179177
@@ -186,20 +184,27 @@ private State nextState(State currentState, int i) {
186184 // in this case it is obtained by calling recursively the methods on the last obtained object
187185 private void appendParamValue (StringBuilder param , StringBuilder result ) {
188186
189- if (param == null ) {
190- throw new IllegalArgumentException ("Invalid parameter name to append (NULL)." );
191- }
187+ if (param == null )
188+ throw invalidArgumentName (param );
192189
193190 // Object name is the parameter that should be found in the map.
194191 // If it's followed by points, the points remain in the "param" buffer.
195- String objectName = takeUntilDotOrEnd (param );
196- Object objectValue = arguments .get (objectName );
192+ final String objectName = takeUntilDotOrEnd (param );
193+ final Object objectValue = arguments .get (objectName );
194+
197195
196+ Object toAppend ;
197+ if (param .length () != 0 ) {
198+ // If this is a chain object.method1.method2.method3
199+ // we recurse
200+ toAppend = valueInChain (objectValue , param );
201+ } else {
202+ // We evaluate if the obejct is an array
203+ // If it's an array we print it nicely
204+ toAppend = evaluateIfArray (objectValue );
205+ }
198206
199- result .append (
200- (param .length () != 0 ) ?
201- valueInChain (objectValue , param ) :
202- evaluateIfArray (objectValue ));
207+ result .append (toAppend );
203208 }
204209
205210 private static Object evaluateIfArray (Object o ) {
@@ -209,7 +214,7 @@ private static Object evaluateIfArray(Object o) {
209214 }
210215
211216 private static String arrayToString (Object array ) {
212- StringBuilder buff = new StringBuilder ("[" );
217+ final StringBuilder buff = new StringBuilder ("[" );
213218
214219 for (int i = 0 ; i < getLength (array ); ++i )
215220 buff .append (get (array , i )).append (", " );
@@ -219,16 +224,19 @@ private static String arrayToString(Object array) {
219224
220225 private static StringBuilder clearLastComma (StringBuilder buff ) {
221226 int lastComma = buff .lastIndexOf (", " );
227+
228+ // No comma found, take everything
222229 if (-1 != lastComma )
223230 buff .delete (lastComma , buff .length ());
231+
224232 return buff ;
225233 }
226234
227235 // This method takes the section until the end of the buff or
228236 // until it finds the first dot ".".
229237 private static String takeUntilDotOrEnd (StringBuilder buff ) {
230238
231- int firstPointIdx = buff .indexOf ("." );
239+ final int firstPointIdx = buff .indexOf ("." );
232240 String result ;
233241
234242 if (-1 == firstPointIdx ) {
@@ -252,14 +260,16 @@ private static Object valueInChain(Object object, StringBuilder paramBuffer) {
252260 return evaluateIfArray (object );
253261 }
254262
255- String methodName = takeUntilDotOrEnd (paramBuffer );
263+ final String methodName = takeUntilDotOrEnd (paramBuffer );
256264
257265 Object newObject ;
258266 try {
259267 // Try with the given method or with the getter as a fallback
260268 Method method = getMethodOrGetter (object , methodName );
269+
261270 if (null == method )
262271 return null ;
272+
263273 newObject = method .invoke (object );
264274 return valueInChain (newObject , paramBuffer );
265275 } catch (IllegalAccessException | InvocationTargetException e ) {
@@ -275,8 +285,8 @@ public static Method getMethodOrGetter(Object object, String methodName) {
275285 } catch (NoSuchMethodException e ) {
276286 try {
277287 // Maybe improve this
278- String capital = methodName .substring (0 , 1 ).toUpperCase ();
279- String nameCapitalized = "get" + capital + methodName .substring (1 );
288+ final String capital = methodName .substring (0 , 1 ).toUpperCase ();
289+ final String nameCapitalized = "get" + capital + methodName .substring (1 );
280290 method = object .getClass ().getMethod (nameCapitalized );
281291 } catch (NoSuchMethodException e1 ) {
282292 return null ;
@@ -285,25 +295,31 @@ public static Method getMethodOrGetter(Object object, String methodName) {
285295 return method ;
286296 }
287297
288- private static State jumpFromFreText (String fmt , int idx ) {
289- if (isEscapeChar (fmt , idx )) return ESCAPE_CHAR ;
290- if (isParamStart (fmt , idx )) return PARAM_START ;
298+ private static State jumpFromFreeText (String fmt , int idx ) {
299+ if (isEscapeChar (fmt , idx ))
300+ return ESCAPE_CHAR ;
301+ if (isParamStart (fmt , idx ))
302+ return PARAM_START ;
291303 return FREE_TEXT ;
292304 }
293305
294306 private static State jumpFromParamStart (String fmt , int idx ) {
295- if (isParamEnd (fmt , idx )) return PARAM_END ;
307+ if (isParamEnd (fmt , idx ))
308+ return PARAM_END ;
296309 return PARAM ;
297310 }
298311
299312 private static State jumpFromParam (String fmt , int idx ) {
300- if (isParamEnd (fmt , idx )) return PARAM_END ;
313+ if (isParamEnd (fmt , idx ))
314+ return PARAM_END ;
301315 return PARAM ;
302316 }
303317
304318 private static State jumpFromParamEnd (String fmt , int idx ) {
305- if (isEscapeChar (fmt , idx )) return ESCAPE_CHAR ;
306- if (isParamStart (fmt , idx )) return PARAM_START ;
319+ if (isEscapeChar (fmt , idx ))
320+ return ESCAPE_CHAR ;
321+ if (isParamStart (fmt , idx ))
322+ return PARAM_START ;
307323 return FREE_TEXT ;
308324 }
309325
0 commit comments