123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- /*
- * Copyright 2000-2016 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
- package com.vaadin.shared.util;
-
- import java.io.Serializable;
- import java.util.Arrays;
- import java.util.HashSet;
- import java.util.LinkedHashSet;
- import java.util.Locale;
-
- /**
- * Misc internal utility methods used by both the server and the client package.
- *
- * @author Vaadin Ltd
- * @since 7.1
- *
- */
- public class SharedUtil implements Serializable {
- /**
- * Checks if a and b are equals using {@link #equals(Object)}. Handles null
- * values as well. Does not ensure that objects are of the same type.
- * Assumes that the first object's equals method handle equals properly.
- *
- * @param o1
- * The first value to compare
- * @param o2
- * The second value to compare
- * @return true if the objects are equal, false otherwise
- */
- public static boolean equals(Object o1, Object o2) {
- if (o1 == null) {
- return o2 == null;
- }
-
- return o1.equals(o2);
- }
-
- /**
- * Trims trailing slashes (if any) from a string.
- *
- * @param value
- * The string value to be trimmed. Cannot be null.
- * @return String value without trailing slashes.
- */
- public static String trimTrailingSlashes(String value) {
- return value.replaceAll("/*$", "");
- }
-
- /**
- * RegEx pattern to extract the width/height values.
- */
- public static final String SIZE_PATTERN = "^(-?\\d*(?:\\.\\d+)?)(%|px|em|rem|ex|in|cm|mm|pt|pc)?$";
-
- /**
- * Splits a camelCaseString into an array of words with the casing
- * preserved.
- *
- * @since 7.4
- * @param camelCaseString
- * The input string in camelCase format
- * @return An array with one entry per word in the input string
- */
- public static String[] splitCamelCase(String camelCaseString) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < camelCaseString.length(); i++) {
- char c = camelCaseString.charAt(i);
- if (Character.isUpperCase(c)
- && isWordComplete(camelCaseString, i)) {
- sb.append(' ');
- }
- sb.append(c);
- }
- return sb.toString().split(" ");
- }
-
- private static boolean isWordComplete(String camelCaseString, int i) {
- if (i == 0) {
- // Word can't end at the beginning
- return false;
- } else if (!Character.isUpperCase(camelCaseString.charAt(i - 1))) {
- // Word ends if previous char wasn't upper case
- return true;
- }
- // Word ends if next char isn't upper case
- return i + 1 < camelCaseString.length()
- && !Character.isUpperCase(camelCaseString.charAt(i + 1));
- }
-
- /**
- * Converts a camelCaseString to a human friendly format (Camel case
- * string).
- * <p>
- * In general splits words when the casing changes but also handles special
- * cases such as consecutive upper case characters. Examples:
- * <p>
- * {@literal MyBeanContainer} becomes {@literal My Bean Container}
- * {@literal AwesomeURLFactory} becomes {@literal Awesome URL Factory}
- * {@literal SomeUriAction} becomes {@literal Some Uri Action}
- *
- * @since 7.4
- * @param camelCaseString
- * The input string in camelCase format
- * @return A human friendly version of the input
- */
- public static String camelCaseToHumanFriendly(String camelCaseString) {
- String[] parts = splitCamelCase(camelCaseString);
- for (int i = 0; i < parts.length; i++) {
- parts[i] = capitalize(parts[i]);
- }
- return join(parts, " ");
- }
-
- /**
- * Converts an UPPER_CASE_STRING to a human friendly format (Upper Case
- * String).
- * <p>
- * Splits words on {@code _}. Examples:
- * <p>
- * {@literal MY_BEAN_CONTAINER} becomes {@literal My Bean Container}
- * {@literal AWESOME_URL_FACTORY} becomes {@literal Awesome Url Factory}
- * {@literal SOMETHING} becomes {@literal Something}
- *
- * @since 7.7.4
- * @param upperCaseUnderscoreString
- * The input string in UPPER_CASE_UNDERSCORE format
- * @return A human friendly version of the input
- */
- public static String upperCaseUnderscoreToHumanFriendly(
- String upperCaseUnderscoreString) {
- String[] parts = upperCaseUnderscoreString.replaceFirst("^_*", "")
- .split("_");
- for (int i = 0; i < parts.length; i++) {
- parts[i] = capitalize(parts[i].toLowerCase(Locale.ENGLISH));
- }
- return join(parts, " ");
- }
-
- /**
- * Joins the words in the input array together into a single string by
- * inserting the separator string between each word.
- *
- * @since 7.4
- * @param parts
- * The array of words
- * @param separator
- * The separator string to use between words
- * @return The constructed string of words and separators
- */
- public static String join(String[] parts, String separator) {
- if (parts.length == 0) {
- return "";
- }
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < parts.length; i++) {
- sb.append(parts[i]);
- sb.append(separator);
- }
- return sb.substring(0, sb.length() - separator.length());
- }
-
- /**
- * Capitalizes the first character in the given string in a way suitable for
- * use in code (methods, properties etc)
- *
- * @since 7.4
- * @param string
- * The string to capitalize
- * @return The capitalized string
- */
- public static String capitalize(String string) {
- if (string == null) {
- return null;
- }
-
- if (string.length() <= 1) {
- return string.toUpperCase(Locale.ENGLISH);
- }
-
- return string.substring(0, 1).toUpperCase(Locale.ENGLISH)
- + string.substring(1);
- }
-
- /**
- * Converts a property id to a human friendly format. Handles nested
- * properties by only considering the last part, e.g. "address.streetName"
- * is equal to "streetName" for this method.
- *
- * @since 7.4
- * @param propertyId
- * The propertyId to format
- * @return A human friendly version of the property id
- */
- public static String propertyIdToHumanFriendly(Object propertyId) {
- String string = propertyId.toString();
- if (string.isEmpty()) {
- return "";
- }
-
- // For nested properties, only use the last part
- int dotLocation = string.lastIndexOf('.');
- if (dotLocation > 0 && dotLocation < string.length() - 1) {
- string = string.substring(dotLocation + 1);
- }
-
- if (string.matches("^[0-9A-Z_]+$")) {
- // Deal with UPPER_CASE_PROPERTY_IDS
- return upperCaseUnderscoreToHumanFriendly(string);
- }
-
- return camelCaseToHumanFriendly(string);
- }
-
- /**
- * Adds the get parameters to the uri and returns the new uri that contains
- * the parameters.
- *
- * @param uri
- * The uri to which the parameters should be added.
- * @param extraParams
- * One or more parameters in the format "a=b" or "c=d&e=f". An
- * empty string is allowed but will not modify the url.
- * @return The modified URI with the get parameters in extraParams added.
- */
- public static String addGetParameters(String uri, String extraParams) {
- if (extraParams == null || extraParams.isEmpty()) {
- return uri;
- }
- // RFC 3986: The query component is indicated by the first question
- // mark ("?") character and terminated by a number sign ("#") character
- // or by the end of the URI.
- String fragment = null;
- int hashPosition = uri.indexOf('#');
- if (hashPosition != -1) {
- // Fragment including "#"
- fragment = uri.substring(hashPosition);
- // The full uri before the fragment
- uri = uri.substring(0, hashPosition);
- }
-
- if (uri.contains("?")) {
- uri += "&";
- } else {
- uri += "?";
- }
- uri += extraParams;
-
- if (fragment != null) {
- uri += fragment;
- }
-
- return uri;
- }
-
- /**
- * Converts a dash ("-") separated string into camelCase.
- * <p>
- * Examples:
- * <p>
- * {@literal foo} becomes {@literal foo} {@literal foo-bar} becomes
- * {@literal fooBar} {@literal foo--bar} becomes {@literal fooBar}
- *
- * @since 7.5
- * @param dashSeparated
- * The dash separated string to convert
- * @return a camelCase version of the input string
- */
- public static String dashSeparatedToCamelCase(String dashSeparated) {
- if (dashSeparated == null) {
- return null;
- }
- String[] parts = dashSeparated.split("-");
- for (int i = 1; i < parts.length; i++) {
- parts[i] = capitalize(parts[i]);
- }
-
- return join(parts, "");
- }
-
- /**
- * Checks if the given array contains duplicates (according to
- * {@link Object#equals(Object)}.
- *
- * @param values
- * the array to check for duplicates
- * @return <code>true</code> if the array contains duplicates,
- * <code>false</code> otherwise
- */
- public static boolean containsDuplicates(Object[] values) {
- int uniqueCount = new HashSet<Object>(Arrays.asList(values)).size();
- return uniqueCount != values.length;
- }
-
- /**
- * Return duplicate values in the given array in the format
- * "duplicateValue1, duplicateValue2".
- *
- * @param values
- * the values to check for duplicates
- * @return a comma separated string of duplicates or an empty string if no
- * duplicates were found
- */
- public static String getDuplicates(Object[] values) {
- HashSet<Object> set = new HashSet<Object>();
- LinkedHashSet<String> duplicates = new LinkedHashSet<String>();
- for (Object o : values) {
- if (!set.add(o)) {
- duplicates.add(String.valueOf(o));
- }
-
- }
- return join(duplicates.toArray(new String[duplicates.size()]), ", ");
- }
-
- }
|