de.crowdcode.kissmda.cartridges.simplejava.JavaCodeFormatter.java Source code

Java tutorial

Introduction

Here is the source code for de.crowdcode.kissmda.cartridges.simplejava.JavaCodeFormatter.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 de.crowdcode.kissmda.cartridges.simplejava;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;

/**
 * Java Code Formatter. Part of this code is taken from Maven Java Formatter
 * Plugin: https://code.google.com/p/maven-java-formatter-plugin.
 * 
 * @author Lofi Dewanto
 * @version 1.1.0
 * @since 1.1.0
 */
public class JavaCodeFormatter {

    private static final String JAVA_VERSION = "1.5";

    private static final Logger logger = Logger.getLogger(JavaCodeFormatter.class.getName());

    private static final String LINE_ENDING_AUTO = "AUTO";
    private static final String LINE_ENDING_KEEP = "KEEP";
    private static final String LINE_ENDING_LF = "LF";
    private static final String LINE_ENDING_CRLF = "CRLF";
    private static final String LINE_ENDING_CR = "CR";

    private static final String LINE_ENDING_LF_CHAR = "\n";
    private static final String LINE_ENDING_CRLF_CHARS = "\r\n";
    private static final String LINE_ENDING_CR_CHAR = "\r";

    private final String lineEnding = LINE_ENDING_AUTO;

    private CodeFormatter codeFormatter;

    private void createCodeFormatter() {
        Map<String, String> options = getFormattingOptions();
        codeFormatter = ToolFactory.createCodeFormatter(options);
    }

    private Map<String, String> getFormattingOptions() {
        Map<String, String> options = new HashMap<String, String>();
        options.put(JavaCore.COMPILER_SOURCE, JAVA_VERSION);
        options.put(JavaCore.COMPILER_COMPLIANCE, JAVA_VERSION);
        options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JAVA_VERSION);
        return options;
    }

    /**
     * Format the given code.
     * 
     * @param compilationUnit
     *            Compilation Unit as unformatted code
     * @return formatted code
     */
    public String format(String compilationUnit) {
        createCodeFormatter();
        String lineSeparator = getLineEnding(compilationUnit);

        TextEdit te = codeFormatter.format(CodeFormatter.K_COMPILATION_UNIT + CodeFormatter.F_INCLUDE_COMMENTS,
                compilationUnit, 0, compilationUnit.length(), 0, lineSeparator);
        IDocument doc = new Document(compilationUnit);
        try {
            te.apply(doc);
        } catch (MalformedTreeException e) {
            logger.log(Level.SEVERE, ExceptionUtils.getStackTrace(e));
        } catch (BadLocationException e) {
            logger.log(Level.SEVERE, ExceptionUtils.getStackTrace(e));
        }
        String formattedCode = doc.get();
        return formattedCode;
    }

    /**
     * Returns the lineEnding parameter as characters when the value is known
     * (LF, CRLF, CR) or can be determined from the file text (KEEP). Otherwise
     * null is returned.
     * 
     * @return String
     */
    private String getLineEnding(String fileDataString) {
        String lineEnd = null;
        if (LINE_ENDING_KEEP.equals(lineEnding)) {
            lineEnd = determineLineEnding(fileDataString);
        } else if (LINE_ENDING_LF.equals(lineEnding)) {
            lineEnd = LINE_ENDING_LF_CHAR;
        } else if (LINE_ENDING_CRLF.equals(lineEnding)) {
            lineEnd = LINE_ENDING_CRLF_CHARS;
        } else if (LINE_ENDING_CR.equals(lineEnding)) {
            lineEnd = LINE_ENDING_CR_CHAR;
        }
        return lineEnd;
    }

    /**
     * Returns the most occurring line-ending characters in the file text or
     * null if no line-ending occurs the most.
     * 
     * @return String
     */
    private String determineLineEnding(String fileDataString) {
        int lfCount = 0;
        int crCount = 0;
        int crlfCount = 0;

        for (int i = 0; i < fileDataString.length(); i++) {
            char c = fileDataString.charAt(i);
            if (c == '\r') {
                if ((i + 1) < fileDataString.length() && fileDataString.charAt(i + 1) == '\n') {
                    crlfCount++;
                    i++;
                } else {
                    crCount++;
                }
            } else if (c == '\n') {
                lfCount++;
            }
        }
        if (lfCount > crCount && lfCount > crlfCount) {
            return LINE_ENDING_LF_CHAR;
        } else if (crlfCount > lfCount && crlfCount > crCount) {
            return LINE_ENDING_CRLF_CHARS;
        } else if (crCount > lfCount && crCount > crlfCount) {
            return LINE_ENDING_CR_CHAR;
        }
        return null;
    }
}