diff --git a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/CheCodeFormatterInitializer.java b/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/CheCodeFormatterInitializer.java deleted file mode 100644 index 10198f00e9..0000000000 --- a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/CheCodeFormatterInitializer.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * ***************************************************************************** Copyright (c) - * 2012-2015 Red Hat, Inc. All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - * - *

Contributors: Red Hat, Inc. - initial API and implementation - * ***************************************************************************** - */ -package org.eclipse.jdt.internal.corext.format; - -import java.util.Hashtable; -import java.util.Map; -import org.eclipse.jdt.internal.core.JavaModelManager; - -/** @author Roman Nikitenko */ -public class CheCodeFormatterInitializer { - - @SuppressWarnings("unchecked") - public void initializeDefaultPreferences() { - Map codeFormatterDefaultSettings = - CheCodeFormatterOptions.getDefaultFormatSettings(); - Hashtable options = JavaModelManager.getJavaModelManager().getOptions(); - options.putAll(codeFormatterDefaultSettings); - JavaModelManager.getJavaModelManager().setOptions(options); - } -} diff --git a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/CheCodeFormatterOptions.java b/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/CheCodeFormatterOptions.java deleted file mode 100644 index 9f2c5434be..0000000000 --- a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/CheCodeFormatterOptions.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * ***************************************************************************** Copyright (c) - * 2012-2015 Red Hat, Inc. All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - * - *

Contributors: Red Hat, Inc. - initial API and implementation - * ***************************************************************************** - */ -package org.eclipse.jdt.internal.corext.format; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.util.Map; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.xml.sax.SAXException; - -/** @author Roman Nikitenko */ -public class CheCodeFormatterOptions { - private static final Logger LOG = LoggerFactory.getLogger(CheCodeFormatterInitializer.class); - private static final String DEFAULT_CODESTYLE = "che-codestyle-eclipse_.xml"; - private static Map formatSettings; - - public static Map getDefaultFormatSettings() { - if (formatSettings != null && !formatSettings.isEmpty()) { - return formatSettings; - } - - formatSettings = new CheCodeFormatterOptions().getCheDefaultSettings(); - if (formatSettings != null && !formatSettings.isEmpty()) { - return formatSettings; - } - return DefaultCodeFormatterConstants.getEclipseDefaultSettings(); - } - - /** - * Parses code formatter file. - * - * @param file file which describes formatting settings - * @return map with formatting settings - */ - public static Map getFormatSettingsFromFile(File file) { - SAXParserFactory factory = SAXParserFactory.newInstance(); - XMLParser parserXML = new XMLParser(); - try (FileInputStream fis = new FileInputStream(file)) { - SAXParser parser = factory.newSAXParser(); - parser.parse(fis, parserXML); - } catch (ParserConfigurationException | SAXException | IOException e) { - LOG.error("It is not possible to parse file " + file.getName(), e); - } - return parserXML.getSettings(); - } - - private Map getCheDefaultSettings() { - SAXParserFactory factory = SAXParserFactory.newInstance(); - XMLParser parserXML = new XMLParser(); - try { - SAXParser parser = factory.newSAXParser(); - parser.parse(getClass().getResourceAsStream(DEFAULT_CODESTYLE), parserXML); - } catch (ParserConfigurationException | SAXException | IOException e) { - LOG.error("It is not possible to parse file " + DEFAULT_CODESTYLE, e); - } - return parserXML.getSettings(); - } -} diff --git a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/Formatter.java b/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/Formatter.java deleted file mode 100644 index c919bc4973..0000000000 --- a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/Formatter.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * ***************************************************************************** Copyright (c) - * 2012-2015 Red Hat, Inc. All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - * - *

Contributors: Red Hat, Inc. - initial API and implementation - * ***************************************************************************** - */ -package org.eclipse.jdt.internal.corext.format; - -import java.io.File; -import java.util.List; -import java.util.Map; -import org.eclipse.che.ide.ext.java.shared.dto.Change; -import org.eclipse.jdt.core.formatter.CodeFormatter; -import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; -import org.eclipse.jface.text.BadLocationException; -import org.eclipse.jface.text.Document; -import org.eclipse.jface.text.IDocument; -import org.eclipse.text.edits.TextEdit; - -/** @author Roman Nikitenko */ -public class Formatter { - - /** - * Creates edits that describe how to format the given string. Returns the changes required to - * format source. - * - * @param formatter The file with custom formatter settings - * @param content The content to format - * @param offset The given offset to start recording the edits (inclusive). - * @param length the given length to stop recording the edits (exclusive). - * @return List describing the changes required to format source - * @throws IllegalArgumentException If the offset and length are not inside the string, a - * IllegalArgumentException is thrown. - */ - public List getFormatChanges(File formatter, String content, int offset, int length) - throws BadLocationException, IllegalArgumentException { - IDocument document = new Document(content); - DocumentChangeListener documentChangeListener = new DocumentChangeListener(document); - Map options = null; - if (formatter != null && formatter.exists()) { - options = CheCodeFormatterOptions.getFormatSettingsFromFile(formatter); - } - TextEdit textEdit = - CodeFormatterUtil.format2( - CodeFormatter.K_COMPILATION_UNIT, content, offset, length, 0, null, options); - textEdit.apply(document); - return documentChangeListener.getChanges(); - } -} diff --git a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/ui/JavaPlugin.java b/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/ui/JavaPlugin.java index 781bbd4992..a286002995 100644 --- a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/ui/JavaPlugin.java +++ b/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/ui/JavaPlugin.java @@ -26,7 +26,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.internal.core.JavaCorePreferenceInitializer; -import org.eclipse.jdt.internal.corext.format.CheCodeFormatterInitializer; import org.eclipse.jdt.internal.corext.template.java.AbstractJavaContextType; import org.eclipse.jdt.internal.corext.template.java.CodeTemplateContextType; import org.eclipse.jdt.internal.corext.template.java.JavaContextType; @@ -210,7 +209,6 @@ public class JavaPlugin { fMembersOrderPreferenceCache = new MembersOrderPreferenceCache(); PreferenceConstants.initializeDefaultValues(PreferenceConstants.getPreferenceStore()); new JavaCorePreferenceInitializer().initializeDefaultPreferences(); - new CheCodeFormatterInitializer().initializeDefaultPreferences(); } @PreDestroy diff --git a/plugins/plugin-java/che-plugin-java-ext-lang-server/src/main/java/org/eclipse/che/plugin/java/server/rest/JavaFormatterService.java b/plugins/plugin-java/che-plugin-java-ext-lang-server/src/main/java/org/eclipse/che/plugin/java/server/rest/JavaFormatterService.java index 448bf98537..6f326ef6e2 100644 --- a/plugins/plugin-java/che-plugin-java-ext-lang-server/src/main/java/org/eclipse/che/plugin/java/server/rest/JavaFormatterService.java +++ b/plugins/plugin-java/che-plugin-java-ext-lang-server/src/main/java/org/eclipse/che/plugin/java/server/rest/JavaFormatterService.java @@ -18,82 +18,31 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; -import java.io.File; -import java.util.List; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; -import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import org.eclipse.che.api.core.ConflictException; import org.eclipse.che.api.core.NotFoundException; import org.eclipse.che.api.core.ServerException; import org.eclipse.che.api.fs.server.FsManager; -import org.eclipse.che.api.fs.server.PathTransformer; -import org.eclipse.che.ide.ext.java.shared.dto.Change; -import org.eclipse.core.resources.IFile; -import org.eclipse.jdt.core.IJavaProject; -import org.eclipse.jdt.internal.core.JavaModel; -import org.eclipse.jdt.internal.core.JavaModelManager; -import org.eclipse.jdt.internal.corext.format.Formatter; -import org.eclipse.jface.text.BadLocationException; /** - * Java formatter service. Have a functionality to format java code and update formatter - * configuration for the project or for whole workspace. + * Java formatter service. Updates formatter's configuration for the project or for whole workspace. */ @Path("java/formatter/") public class JavaFormatterService { - private static final String CHE_FOLDER = ".che"; - private static final String CHE_FORMATTER_XML = "che-formatter.xml"; - private static final JavaModel model = JavaModelManager.getJavaModelManager().getJavaModel(); + public static final String CHE_FOLDER = ".che"; + public static final String CHE_FORMATTER_XML = "che-formatter.xml"; private final FsManager fsManager; - private final PathTransformer pathTransformer; - private Formatter formatter; @Inject - public JavaFormatterService( - FsManager fsManager, PathTransformer pathTransformer, Formatter formatter) { + public JavaFormatterService(FsManager fsManager) { this.fsManager = fsManager; - this.pathTransformer = pathTransformer; - this.formatter = formatter; - } - - @POST - @Path("/format") - @Consumes(MediaType.TEXT_PLAIN) - @Produces({MediaType.APPLICATION_JSON}) - @ApiOperation(value = "Creates edits that describe how to format the given string") - @ApiResponses({ - @ApiResponse(code = 200, message = "The response contains all changes after formating"), - @ApiResponse(code = 500, message = "Internal server error occurred") - }) - public List getFormatChanges( - @ApiParam(value = "Path to the root project") @QueryParam("projectpath") String projectPath, - @ApiParam(value = "The given offset to start recording the edits (inclusive)") - @QueryParam("offset") - int offset, - @ApiParam(value = "The given length to stop recording the edits (exclusive)") - @QueryParam("length") - int length, - @ApiParam(value = "The content to format. Java code formatting is supported only") - String content) - throws BadLocationException, IllegalArgumentException { - IJavaProject javaProject = model.getJavaProject(projectPath); - String formatterPath = CHE_FOLDER + '/' + CHE_FORMATTER_XML; - File file = null; - IFile iFile = javaProject.getProject().getFile(formatterPath); - if (iFile != null) { - file = iFile.getLocation().toFile(); - } - if (file == null || !file.exists()) { - file = getFormatterFromRootFolder(formatterPath); - } - return formatter.getFormatChanges(file, content, offset, length); } @POST @@ -161,9 +110,4 @@ public class JavaFormatterService { throw new ServerException(e); } } - - private File getFormatterFromRootFolder(String formatterPath) { - - return fsManager.toIoFile(absolutize(formatterPath)); - } } diff --git a/plugins/plugin-java/che-plugin-java-server/pom.xml b/plugins/plugin-java/che-plugin-java-server/pom.xml index 5249b5ea6d..e95fc3c3d0 100644 --- a/plugins/plugin-java/che-plugin-java-server/pom.xml +++ b/plugins/plugin-java/che-plugin-java-server/pom.xml @@ -89,6 +89,10 @@ org.eclipse.che.ls.jdt jdt.ls.extension.api + + org.eclipse.che.plugin + che-plugin-java-ext-lang-server + org.eclipse.che.plugin che-plugin-java-ext-lang-shared diff --git a/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaTextDocumentServiceWraper.java b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaTextDocumentServiceWraper.java index 1c7ebea586..55cbc8a13c 100644 --- a/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaTextDocumentServiceWraper.java +++ b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/JavaTextDocumentServiceWraper.java @@ -10,13 +10,39 @@ */ package org.eclipse.che.plugin.java.languageserver; +import static org.eclipse.che.api.fs.server.WsPathUtils.SEPARATOR; +import static org.eclipse.che.api.languageserver.service.LanguageServiceUtils.PROJECTS; +import static org.eclipse.che.api.languageserver.service.LanguageServiceUtils.extractProjectPath; +import static org.eclipse.che.plugin.java.server.rest.JavaFormatterService.CHE_FOLDER; +import static org.eclipse.che.plugin.java.server.rest.JavaFormatterService.CHE_FORMATTER_XML; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import org.eclipse.che.api.fs.server.WsPathUtils; +import org.eclipse.che.api.languageserver.exception.LanguageServerException; import org.eclipse.lsp4j.CodeActionParams; import org.eclipse.lsp4j.Command; +import org.eclipse.lsp4j.DocumentFormattingParams; +import org.eclipse.lsp4j.FormattingOptions; +import org.eclipse.lsp4j.TextEdit; import org.eclipse.lsp4j.services.TextDocumentService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; public class JavaTextDocumentServiceWraper { + private static final Logger LOG = LoggerFactory.getLogger(JavaTextDocumentServiceWraper.class); + private TextDocumentService wrapped; public JavaTextDocumentServiceWraper(TextDocumentService wrapped) { @@ -36,4 +62,51 @@ public class JavaTextDocumentServiceWraper { return commands; }); } + + public CompletableFuture> formatting(DocumentFormattingParams params) + throws LanguageServerException { + + String fileUri = params.getTextDocument().getUri(); + FormattingOptions options = params.getOptions(); + if (options == null) { + options = new FormattingOptions(); + params.setOptions(options); + } + + updateFormatterOptions(params, fileUri); + + return wrapped.formatting(params); + } + + private void updateFormatterOptions(DocumentFormattingParams params, String fileUri) + throws LanguageServerException { + String projectPath = WsPathUtils.absolutize(extractProjectPath(fileUri)); + String formatterPathSuffix = CHE_FOLDER + SEPARATOR + CHE_FORMATTER_XML; + Path projectFormatterPath = Paths.get(projectPath, formatterPathSuffix); + Path wsFormatterPath = Paths.get(PROJECTS, formatterPathSuffix); + if (Files.exists(projectFormatterPath)) { + updateFormatterOptions(params, getFormatSettingsFromFile(projectFormatterPath.toFile())); + } else if (Files.exists(wsFormatterPath)) { + updateFormatterOptions(params, getFormatSettingsFromFile(wsFormatterPath.toFile())); + } + } + + private void updateFormatterOptions( + DocumentFormattingParams params, Map options) { + for (String key : options.keySet()) { + params.getOptions().putString(key, options.get(key)); + } + } + + private static Map getFormatSettingsFromFile(File file) { + SAXParserFactory factory = SAXParserFactory.newInstance(); + XMLParser parserXML = new XMLParser(); + try (FileInputStream fis = new FileInputStream(file)) { + SAXParser parser = factory.newSAXParser(); + parser.parse(fis, parserXML); + } catch (ParserConfigurationException | SAXException | IOException e) { + LOG.error("It is not possible to parse file " + file.getName(), e); + } + return parserXML.getSettings(); + } } diff --git a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/XMLParser.java b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/XMLParser.java similarity index 57% rename from plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/XMLParser.java rename to plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/XMLParser.java index b9e5623321..7d25ca5311 100644 --- a/plugins/plugin-java/che-plugin-java-ext-jdt/org-eclipse-jdt-ui/src/main/java/org/eclipse/jdt/internal/corext/format/XMLParser.java +++ b/plugins/plugin-java/che-plugin-java-server/src/main/java/org/eclipse/che/plugin/java/languageserver/XMLParser.java @@ -1,13 +1,14 @@ -/** - * ***************************************************************************** Copyright (c) - * 2012-2015 Red Hat, Inc. All rights reserved. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html +/* + * Copyright (c) 2012-2018 Red Hat, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html * - *

Contributors: Red Hat, Inc. - initial API and implementation - * ***************************************************************************** + * Contributors: + * Red Hat, Inc. - initial API and implementation */ -package org.eclipse.jdt.internal.corext.format; +package org.eclipse.che.plugin.java.languageserver; import java.util.HashMap; import java.util.Map; diff --git a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/LanguageServiceUtils.java b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/LanguageServiceUtils.java index f87dd0b2ad..6e007cdb56 100644 --- a/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/LanguageServiceUtils.java +++ b/wsagent/che-core-api-languageserver/src/main/java/org/eclipse/che/api/languageserver/LanguageServiceUtils.java @@ -30,8 +30,8 @@ import org.eclipse.lsp4j.Location; */ public class LanguageServiceUtils { - private static final String PROJECTS = "/projects"; - private static final String FILE_PROJECTS = "file:///projects"; + public static final String PROJECTS = "/projects"; + public static final String FILE_PROJECTS = "file:///projects"; public static String prefixURI(String uri) { return uri.startsWith("/") ? FILE_PROJECTS + uri : uri;