001    package org.nakedobjects.applib.util;
002    
003    import org.nakedobjects.applib.Identifier;
004    
005    
006    /**
007     * Not public API, provides a number of utilities to represent formal {@link Identifier} names more naturally.
008     */
009    public class NameUtils {
010        private static final char SPACE = ' ';
011    
012        /**
013         * Returns a word spaced version of the specified name, so there are spaces between the words, where each
014         * word starts with a capital letter. E.g., "NextAvailableDate" is returned as "Next Available Date".
015         */
016        public static String naturalName(final String name) {
017    
018            final int length = name.length();
019    
020            if (length <= 1) {
021                return name.toUpperCase();// ensure first character is upper case
022            }
023    
024            final StringBuffer naturalName = new StringBuffer(length);
025    
026            char previousCharacter;
027            char character = Character.toUpperCase(name.charAt(0));// ensure first character is upper case
028            naturalName.append(character);
029            char nextCharacter = name.charAt(1);
030    
031            for (int pos = 2; pos < length; pos++) {
032                previousCharacter = character;
033                character = nextCharacter;
034                nextCharacter = name.charAt(pos);
035    
036                if (previousCharacter != SPACE) {
037                    if (Character.isUpperCase(character) && !Character.isUpperCase(previousCharacter)) {
038                        naturalName.append(SPACE);
039                    }
040                    if (Character.isUpperCase(character) && Character.isLowerCase(nextCharacter)
041                            && Character.isUpperCase(previousCharacter)) {
042                        naturalName.append(SPACE);
043                    }
044                    if (Character.isDigit(character) && !Character.isDigit(previousCharacter)) {
045                        naturalName.append(SPACE);
046                    }
047                }
048                naturalName.append(character);
049            }
050            naturalName.append(nextCharacter);
051            return naturalName.toString();
052        }
053    
054        public static String[] naturalNames(final String[] names) {
055            final String[] naturalNames = new String[names.length];
056            int i = 0;
057            for (final String name : names) {
058                naturalNames[i++] = NameUtils.naturalName(name);
059            }
060            return naturalNames;
061        }
062    
063    }
064    // Copyright (c) Naked Objects Group Ltd.