All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.speedment.common.codegen.util.Formatting Maven / Gradle / Ivy

Go to download

A Speedment bundle that shades all dependencies into one jar. This is useful when deploying an application on a server.

There is a newer version: 3.1.6
Show newest version
/**
 *
 * Copyright (c) 2006-2017, Speedment, Inc. All Rights Reserved.
 *
 * 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.speedment.common.codegen.util;

import static com.speedment.common.codegen.internal.util.NullUtil.requireNonNullElements;
import static com.speedment.common.codegen.internal.util.StaticClassUtil.instanceNotAllowed;
import java.util.Arrays;
import java.util.List;
import static java.util.Objects.requireNonNull;
import java.util.Optional;
import java.util.function.Function;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
import java.util.stream.Stream;

/**
 * Common formatting methods used when generating code.
 * 
 * @author Emil Forslund
 */
public final class Formatting {
    
    /**
     * Returns a string consisting of the specified blocks concatenated
     * and separated by the specified separator.
     * 
     * @param separator The separator.
     * @param blocks All the blocks.
     * @return The concatenated string.
     */
    public static String separate(String separator, String... blocks) {
        requireNonNullElements(blocks);
        return Stream.of(blocks)
            .collect(joining(separator));
    }

    /**
     * Returns the specified text but with the first character lowercase.
     *
     * @param input The text.
     * @return The resulting text.
     */
    public static String lcfirst(String input) {
        return withFirst(input, (first) -> String.valueOf(Character.toLowerCase(first)));
    }

    /**
     * Returns the specified text but with the first character uppercase.
     *
     * @param input The text.
     * @return The resulting text.
     */
    public static String ucfirst(String input) {
        return withFirst(input, (first) -> String.valueOf(Character.toUpperCase(first)));
    }

    /**
     * Does something with the first character in the specified String.
     *
     * @param input The String.
     * @param callback The something.
     * @return The new String.
     */
    public static String withFirst(String input, Function callback) {
        if (input == null) {
            return null;
        } else if (input.length() == 0) {
            return "";
        } else {
            return String.join("",
                callback.apply(input.charAt(0)),
                input.subSequence(1, input.length())
            );
        }
    }
	
	/**
	 * Repeats the specified substring count times.
	 * @param str The string to repeat.
	 * @param count The number of times to repeat it.
	 * @return The new String.
	 */
	public static String repeat(String str, int count) {
		final StringBuilder result = new StringBuilder();

		for (int i = 0; i < count; i++) {
			result.append(str);
		}
		
		return result.toString();
	}

    /**
     * Indents the specified text, surrounds it with brackets and put the
     * content on a separate line.
     *
     * @param text The text to surround.
     * @return The text with a '{\n' before and a '\n}' afterwards.
     */
    public static String block(String text) {
        return "{" + nl + indent(text) + nl + "}";
    }
	
	/**
     * Indents the specified text, surrounds it with brackets and put the
     * content on a separate line.
     * 
	 * @param row   the first row of the text.
	 * @param rows  the rest of the rows.
     * @return      the text with a '{\n' before and a '\n}' afterwards.
     */
    public static String block(String row, String... rows) {
        requireNonNull(row);
        requireNonNullElements(rows);
        return block(
			Arrays.stream(rows).collect(joining(
				nl(), row + nl(), "")
			)
		);
    }
    
    /**
     * Indents the specified text, surrounds it with brackets and put the
     * content on a separate line.
     * 
	 * @param rows  the rest of the rows.
     * @return      the text with a '{\n' before and a '\n}' afterwards.
     */
    public static String block(Stream rows) {
        return block(rows.collect(joining(nl())));
    }

    /**
     * Indents one level after each new-line-character as defined by
     * nl().
     *
     * @param text  the text to indent.
     * @return      the indented text.
     */
    public static String indent(String text) {
        return indent + text.replaceAll("\\r?\\n", nl + indent);
    }
    
    /**
     * Indents one level after each new-line-character as defined by
     * nl(). If multiple strings are specified, new-line characters
     * will be added between them.
     *
     * @param text  the text to indent.
     * @return      the indented text.
     */
    public static String indent(String... text) {
        return indent + String.join(nl(), text).replaceAll("\\r?\\n", nl + indent);
    }
    
    /**
     * Indents one level after each new-line-character as defined by
     * nl(). f multiple strings are specified, new-line characters
     * will be added between them.
     *
     * @param text  the text to indent.
     * @return      the indented text.
     */
    public static String indent(Stream text) {
        return indent(text.toArray(String[]::new));
    }
    
    /**
     * Indents a variable number of levels level after each new-line-character 
     * as defined by nl().
     *
     * @param text   the text to indent
     * @param steps  the number of steps to indent
     * @return       the indented text
     */
    public static String indent(String text, int steps) {
        switch (steps) {
            case 0  : return text;
            case 1  : return indent(text);
            default : return indent(indent(text, steps - 1));
        }
    }
	
	/**
	 * If the condition is present, the true-function will be called
	 * with its value and the result will be returned. Else the
	 * false-value will be returned.
	 * @param  The inner type of the condition.
	 * @param  The result type.
	 * @param condition The condition to be evaluated for presence.
	 * @param trueMap The function that will be called if present.
	 * @param falseValue The value returned if the condition is not present.
	 * @return The value.
	 */
	public static  R ifelse(Optional condition, Function trueMap, R falseValue) {
		if (condition.isPresent()) {
			return trueMap.apply(condition.get());
		} else {
			return falseValue;
		}
	}

    /**
     * Returns the new-line-character as defined in nl(String).
     *
     * @return The new-line character.
     */
    public static String nl() {
        return nl;
    }

    /**
     * Sets which new-line-character to use. Should be set before any code
     * generation happens for indentation to work as expected.
     *
     * @param nl The new character to use.
     */
    public static void nl(String nl) {
        Formatting.nl  = nl;
        Formatting.dnl = nl + nl;
    }

    /**
     * Returns two new-line-characters as defined in nl(String).
     *
     * @return The new-line character.
     */
    public static String dnl() {
        return dnl;
    }

    /**
     * Returns the current tab character. This can be defined by using
     * tab(String).
     *
     * @return The current tab character.
     */
    public static String tab() {
        return indent;
    }

    /**
     * Sets the tab character to use when generating code. This should only be
     * called before any indentation occurs to prevent errors.
     *
     * @param tab The new tab character.
     */
    public static void tab(String tab) {
        Formatting.indent = tab;
    }

    /**
     * Returns the 'name' part of a long name. This is everything after the last
     * dot.
     *
     * @param longName The long name.
     * @return The name part.
     */
    public static String shortName(String longName) {
        final String temp = longName.replace('$', '.');
        if (temp.contains(".")) {
            return temp.substring(temp.lastIndexOf(".") + 1);
        } else {
            return temp;
        }
    }

    /**
     * Returns the 'package' part of a long name. This is everything before the
     * last dot.
     *
     * @param longName The long name.
     * @return The package part.
     */
    public static Optional packageName(String longName) {
		if (longName.contains(".")) {
			return Optional.of(longName.substring(0,
				longName.lastIndexOf(".")
			));
		} else {
			return Optional.empty();
		}
    }
	
	public static Optional fileToClassName(String fileName) {
		Optional result = Optional.empty();
		if (fileName.endsWith(".java")) {
			String className = fileName;
			className = className.replace('/', '.');
			className = className.replace('\\', '.');
			className = className.substring(0, className.length() - 5);
			result = Optional.of(className);
		}
		return result;
	}
    
    public static String classToJavaFileName(String longName) {
        return longName.replace('.', '/') + ".java";
	}
    
    /**
     * Removes the generics and array parts of a class name.
     * 
     * @param className  the full class name
     * @return           class name with decorations stripped
     */
    public static String stripGenerics(String className) {
        String name = className;
        
        if (name.contains("<")) {
            name = name.substring(0, name.indexOf("<"));
        }
        
        if (name.contains("[")) {
            name = name.substring(0, name.indexOf("["));
        }
        
        return name;
    }
    
    /**
     * Replaces every tab character ({@code \t}) in the specified rows with a
     * number spaces so that the character indexes align. This is called 
     * recursively until all tab characters have been replaced. If there are no
     * tabs in the text, the method has no effect.
     * 

* This implementation will begin by splitting the specified string into * rows, then apply the alignment. Otherwise it is the same as * {@link #alignTabs(List)}. * * @param rows a single string with all the rows to align * @return the same string but with tabs replaced with aligning spaces */ public static String alignTabs(String rows) { final List list = Stream.of(rows.split(nl())).collect(toList()); alignTabs(list); return list.stream().collect(joining(nl())); } /** * Replaces every tab character ({@code \t}) in the specified rows with a * number spaces so that the character indexes align. This is called * recursively until all tab characters have been replaced. If there are no * tabs in the text, the method has no effect. *

* Example: * If you call the method on the following code: * {@code * this.firstname\t = firstname;\t // Nullable * this.lastname\t = lastname;\t // Nullable * this.email\t = email;\t // Nullable * this.age\t = age; * } * * You will get the following result: * {@code * this.firstname = firstname; // Nullable * this.lastname = lastname; // Nullable * this.email = email; // Nullable * this.age = age; * } * * @param rows list of rows to operate on */ public static void alignTabs(List rows) { while (true) { int maxIndex = -1; for (final String row : rows) { final int index = row.indexOf('\t'); if (index > maxIndex) { maxIndex = index; } } if (maxIndex > -1) { for (int i = 0; i < rows.size(); i++) { final String row = rows.get(i); final int index = row.indexOf('\t'); if (index > -1) { rows.set(i, row.replaceFirst("\t", Formatting.repeat(" ", maxIndex - index))); } } } else { break; } } } private static String nl = "\n", dnl = "\n\n", indent = " "; /** * Utility classes should not be instantiated. */ private Formatting() { instanceNotAllowed(getClass()); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy