PageRenderTime 21ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/branch/EclipseFormatter_1.6/src/java/krasa/formatter/eclipse/JavaCodeFormatterFacade.java

http://eclipse-code-formatter-intellij-plugin.googlecode.com/
Java | 138 lines | 79 code | 14 blank | 45 comment | 11 complexity | 72ee35011af778092c9231df0867b647 MD5 | raw file
  1. package krasa.formatter.eclipse;
  2. import krasa.formatter.plugin.Notifier;
  3. import org.eclipse.jdt.core.ToolFactory;
  4. import org.eclipse.jdt.core.formatter.CodeFormatter;
  5. import org.eclipse.jface.text.BadLocationException;
  6. import org.eclipse.jface.text.Document;
  7. import org.eclipse.jface.text.IDocument;
  8. import org.eclipse.text.edits.TextEdit;
  9. import java.io.File;
  10. import java.util.Properties;
  11. /**
  12. * @author Vojtech Krasa
  13. */
  14. public class JavaCodeFormatterFacade extends CodeFormatterFacade {
  15. protected final String pathToConfigFile;
  16. protected CodeFormatter codeFormatter;
  17. private long lastModified;
  18. public JavaCodeFormatterFacade(String pathToConfigFile) {
  19. this.pathToConfigFile = pathToConfigFile;
  20. }
  21. private CodeFormatter getCodeFormatter() throws InvalidPathToConfigFileException {
  22. File file = checkIfExists(this.pathToConfigFile);
  23. if (codeFormatter == null || configFileWasChanged(file)) {
  24. return newCodeFormatter(file);
  25. }
  26. return codeFormatter;
  27. }
  28. private CodeFormatter newCodeFormatter(File file) throws InvalidPathToConfigFileException {
  29. lastModified = file.lastModified();
  30. Properties properties = readConfig(file);
  31. if (properties.isEmpty()) {
  32. throw new InvalidPathToConfigFileException("incorrect properties file");
  33. }
  34. codeFormatter = ToolFactory.createCodeFormatter(properties);
  35. return codeFormatter;
  36. }
  37. private boolean configFileWasChanged(File file) {
  38. return file.lastModified() > lastModified;
  39. }
  40. protected String formatInternal(String text, int startOffset, int endOffset, String lineSeparator) throws InvalidPathToConfigFileException {
  41. if (endOffset > text.length()) {
  42. endOffset = text.length();
  43. }
  44. IDocument doc = new Document();
  45. try {
  46. doc.set(text);
  47. /**
  48. * Format <code>source</code>,
  49. * and returns a text edit that correspond to the difference between the given
  50. * string and the formatted string.
  51. * <p>
  52. * It returns null if the given string cannot be formatted.
  53. * </p><p>
  54. * If the offset position is matching a whitespace, the result can include
  55. * whitespaces. It would be up to the caller to get rid of preceding
  56. * whitespaces.
  57. * </p>
  58. *
  59. * @param kind Use to specify the kind of the code snippet to format. It can
  60. * be any of these:
  61. * <ul>
  62. * <li>{@link #K_EXPRESSION}</li>
  63. * <li>{@link #K_STATEMENTS}</li>
  64. * <li>{@link #K_CLASS_BODY_DECLARATIONS}</li>
  65. * <li>{@link #K_COMPILATION_UNIT}<br>
  66. * <b>Since 3.4</b>, the comments can be formatted on the fly while
  67. * using this kind of code snippet<br>
  68. * (see {@link #F_INCLUDE_COMMENTS} for more detailed explanation on
  69. * this flag)
  70. * </li>
  71. * <li>{@link #K_UNKNOWN}</li>
  72. * <li>{@link #K_SINGLE_LINE_COMMENT}</li>
  73. * <li>{@link #K_MULTI_LINE_COMMENT}</li>
  74. * <li>{@link #K_JAVA_DOC}</li>
  75. * </ul>
  76. * @param source the source to format
  77. * @param offset the given offset to start recording the edits (inclusive).
  78. * @param length the given length to stop recording the edits (exclusive).
  79. * @param indentationLevel the initial indentation level, used
  80. * to shift left/right the entire source fragment. An initial indentation
  81. * level of zero or below has no effect.
  82. * @param lineSeparator the line separator to use in formatted source,
  83. * if set to <code>null</code>, then the platform default one will be used.
  84. * @return the text edit
  85. * @throws IllegalArgumentException if offset is lower than 0, length is lower than 0 or
  86. * length is greater than source length.
  87. */
  88. TextEdit edit = getCodeFormatter().format(CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, text,
  89. startOffset, endOffset - startOffset, 0, lineSeparator);
  90. if (edit != null) {
  91. edit.apply(doc);
  92. } else {
  93. throw new RuntimeException(Notifier.FORMATTING_FAILED_PROBABLY_DUE_TO_NOT_COMPILABLE_CODE_OR_WRONG_CONFIG_FILE);
  94. }
  95. return doc.get();
  96. } catch (BadLocationException e) {
  97. throw new RuntimeException(e);
  98. }
  99. }
  100. @Override
  101. protected Properties createDefaultConfig() {
  102. Properties defaultConfig = new Properties();
  103. // TODO: Ideally, the IntelliJ project's language level should be the default value.
  104. defaultConfig.setProperty("org.eclipse.jdt.core.compiler.source", "1.5");
  105. return defaultConfig;
  106. }
  107. @Override
  108. protected void validateConfig(Properties config) {
  109. String sourceVersionString = config.getProperty("org.eclipse.jdt.core.compiler.source");
  110. if (sourceVersionString != null) {
  111. float sourceVersion = 0;
  112. try {
  113. sourceVersion = Float.parseFloat(sourceVersionString);
  114. } catch (NumberFormatException e) {
  115. throw new RuntimeException("Illegal value for org.eclipse.jdt.core.compiler.source property ("
  116. + sourceVersionString + ") - supported Java source versions are 1.5, 1.6, 1.7, or 1.8.");
  117. }
  118. if (sourceVersion < 1.5) {
  119. throw new RuntimeException("Illegal value for org.eclipse.jdt.core.compiler.source property ("
  120. + sourceVersionString + ") - Eclipse formatter requires a Java source version >= 1.5.");
  121. }
  122. }
  123. }
  124. }