001/******************************************************************************* 002 * Copyright (c) 2017, 2018 Red Hat Inc 003 * All rights reserved. This program and the accompanying materials 004 * are made available under the terms of the Eclipse Public License v1.0 005 * which accompanies this distribution, and is available at 006 * http://www.eclipse.org/legal/epl-v10.html 007 * 008 * Contributors: 009 * Jens Reimann - initial API and implementation 010 *******************************************************************************/ 011package de.dentrassi.varlink.generator.util; 012 013import java.util.LinkedList; 014import java.util.List; 015import java.util.function.Function; 016import java.util.stream.Collectors; 017 018public final class Names { 019 private Names() { 020 } 021 022 @FunctionalInterface 023 private interface CharMapper { 024 char map(char in); 025 } 026 027 @FunctionalInterface 028 private interface CharConsumer { 029 void consume(char in); 030 } 031 032 public static String toCamelCase(final String text, final boolean firstUpper) { 033 return toFormat(text, words -> joinCamel(firstUpper, words)); 034 } 035 036 public static String toLowerDash(final String text) { 037 return toFormat(text, words -> joinDelimiter(words, String::toLowerCase, "-")); 038 } 039 040 public static String toUpperUnderscore(final String text) { 041 return toFormat(text, words -> joinDelimiter(words, String::toUpperCase, "_")); 042 } 043 044 private static enum Type { 045 UPPER, LOWER, NUMERIC, OTHER; 046 } 047 048 public static String toFormat(final String text, final Function<List<String>, String> target) { 049 if (text == null) { 050 return null; 051 } 052 053 final List<String> words = new LinkedList<>(); 054 final int len = text.length(); 055 056 Type lastType = Type.UPPER; 057 StringBuilder sb = new StringBuilder(); 058 059 for (int i = 0; i < len; i++) { 060 final char c = text.charAt(i); 061 062 final Type type = typeOf(c); 063 064 if (lastType == Type.LOWER && (type == Type.UPPER || type == Type.NUMERIC)) { 065 sb = split(sb, words); 066 sb = append(sb, c); 067 } else if (lastType == Type.NUMERIC && (type == Type.UPPER || type == Type.LOWER)) { 068 sb = split(sb, words); 069 sb = append(sb, c); 070 } else if (type != Type.OTHER) { 071 sb = append(sb, c); 072 } else { 073 // unknown type: split and ignore 074 sb = split(sb, words); 075 } 076 077 lastType = type; 078 } 079 080 split(sb, words); 081 082 return target.apply(words); 083 } 084 085 private static StringBuilder append(StringBuilder sb, final char c) { 086 if (sb == null) { 087 sb = new StringBuilder(); 088 } 089 sb.append(c); 090 return sb; 091 } 092 093 private static StringBuilder split(StringBuilder sb, final List<String> words) { 094 if (sb != null) { 095 words.add(sb.toString()); 096 sb = null; 097 } 098 return sb; 099 } 100 101 private static Type typeOf(final char c) { 102 if (Character.isUpperCase(c)) { 103 return Type.UPPER; 104 } else if (Character.isDigit(c)) { 105 return Type.NUMERIC; 106 } else if (Character.isAlphabetic(c)) { 107 return Type.LOWER; 108 } 109 return Type.OTHER; 110 } 111 112 private static String joinDelimiter(final List<String> words, Function<String, String> conversion, 113 final String delimiter) { 114 if (conversion == null) { 115 conversion = str -> str; 116 } 117 118 return words.stream().map(conversion).collect(Collectors.joining(delimiter)); 119 } 120 121 private static String joinCamel(final boolean firstUpper, final List<String> words) { 122 CharMapper mapper = firstUpper ? Character::toUpperCase : Character::toLowerCase; 123 final StringBuilder result = new StringBuilder(); 124 for (final String word : words) { 125 126 final int wlen = word.length(); 127 if (wlen < 1) { 128 continue; 129 } 130 131 result.append(mapper.map(word.charAt(0))); 132 133 if (wlen > 1) { 134 result.append(word.substring(1).toLowerCase()); 135 } 136 137 mapper = Character::toUpperCase; 138 } 139 return result.toString(); 140 } 141 142 public static String makeVersion(final String version) { 143 return "v" + version.replace(".", "_"); 144 } 145 146 public static String toUpperFirst(final String string) { 147 if (string.length() < 2) { 148 return string.toUpperCase(); 149 } 150 151 return Character.toUpperCase(string.charAt(0)) + string.substring(1); 152 } 153 154 public static String toLowerFirst(final String string) { 155 if (string.length() < 2) { 156 return string.toLowerCase(); 157 } 158 159 return Character.toLowerCase(string.charAt(0)) + string.substring(1); 160 } 161 162}