diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form new file mode 100644 index 000000000000..d0b545c1100a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.form @@ -0,0 +1,65 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java new file mode 100644 index 000000000000..78ed30a9e5c2 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/ImportSchemeChooserDialog.java @@ -0,0 +1,100 @@ +package com.intellij.application.options; + +import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.openapi.options.Scheme; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.components.JBList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ImportSchemeChooserDialog extends DialogWrapper { + private JPanel contentPane; + private JBList mySchemeList; + private JTextField myTargetNameField; + private JCheckBox myUseCurrentScheme; + private String mySelectedName; + private final static String UNNAMED_SCHEME_ITEM = "<" + ApplicationBundle.message("code.style.scheme.import.unnamed") + ">"; + private final List myNames = new ArrayList(); + + public ImportSchemeChooserDialog(@NotNull Component parent, + String[] schemeNames, + final @Nullable String currScheme) { + super(parent, false); + if (schemeNames.length > 0) { + myNames.addAll(Arrays.asList(schemeNames)); + } + else { + myNames.add(UNNAMED_SCHEME_ITEM); + } + mySchemeList.setModel(new DefaultListModel() { + @Override + public int getSize() { + return myNames.size(); + } + + @Override + public Object getElementAt(int index) { + return myNames.get(index); + } + }); + mySchemeList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + mySchemeList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + int index = mySchemeList.getSelectedIndex(); + if (index >= 0) { + mySelectedName = myNames.get(index); + if (!myUseCurrentScheme.isSelected() && !UNNAMED_SCHEME_ITEM.equals(mySelectedName)) myTargetNameField.setText(mySelectedName); + } + } + }); + myUseCurrentScheme.setEnabled(currScheme != null); + myUseCurrentScheme.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (myUseCurrentScheme.isSelected()) { + myTargetNameField.setEnabled(false); + if (currScheme != null) { + myTargetNameField.setText(currScheme); + } + } + else { + myTargetNameField.setEnabled(true); + if (mySelectedName != null) myTargetNameField.setText(mySelectedName); + } + } + }); + mySchemeList.getSelectionModel().setSelectionInterval(0,0); + init(); + } + + public String getSelectedName() { + return UNNAMED_SCHEME_ITEM.equals(mySelectedName) ? null : mySelectedName; + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return contentPane; + } + + public boolean isUseCurrentScheme() { + return myUseCurrentScheme.isSelected(); + } + + @Nullable + public String getTargetName() { + String name = myTargetNameField.getText(); + return name != null && !name.trim().isEmpty() ? name : null; + } +} diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form new file mode 100644 index 000000000000..9e4261125fad --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.form @@ -0,0 +1,38 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java new file mode 100644 index 000000000000..067c86877201 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/application/options/ImportSourceChooserDialog.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * 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.intellij.application.options; + +import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.openapi.options.Scheme; +import com.intellij.openapi.options.SchemeImporterEP; +import com.intellij.openapi.options.SchemesManager; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.components.JBCheckBox; +import com.intellij.ui.components.JBList; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ImportSourceChooserDialog extends DialogWrapper { + private JPanel myContentPane; + private JBList mySourceList; + + private String mySelectedSourceName; + private final ListModel myListModel; + + private final static String SHARED_IMPORT_SOURCE = ApplicationBundle.message("import.scheme.shared"); + + public ImportSourceChooserDialog(JComponent parent, Class schemeClass, SchemesManager schemesManager) { + super(parent, true); + setTitle(ApplicationBundle.message("title.import.scheme.from")); + myListModel = new SourceListModel(SchemeImporterEP.getExtensions(schemeClass), schemesManager.isImportAvailable()); + initSourceList(); + init(); + } + + private void initSourceList() { + mySourceList.setModel(myListModel); + mySourceList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + mySourceList.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + int index = mySourceList.getSelectedIndex(); + if (index >= 0) { + setSelectedSourceName((String)myListModel.getElementAt(index)); + } + } + }); + mySourceList.setSelectedIndex(0); + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return myContentPane; + } + + private void setSelectedSourceName(String name) { + mySelectedSourceName = name; + } + + @Nullable + public String getSelectedSourceName() { + return mySelectedSourceName; + } + + public boolean isImportFromSharedSelected() { + return SHARED_IMPORT_SOURCE.equals(mySelectedSourceName); + } + + private class SourceListModel extends DefaultListModel { + private List mySourceNames = new ArrayList(); + + public SourceListModel(Collection> extensions, boolean isSharedImportAvailable) { + for (SchemeImporterEP extension : extensions) { + mySourceNames.add(extension.name); + } + if (isSharedImportAvailable) { + mySourceNames.add(SHARED_IMPORT_SOURCE); + } + } + + @Override + public int getSize() { + return mySourceNames.size(); + } + + @Override + public Object getElementAt(int index) { + return mySourceNames.get(index); + } + } + +} diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java index 91d078293b02..4b2764b5e504 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleSchemesModel.java @@ -209,6 +209,10 @@ public class CodeStyleSchemesModel { myDispatcher.getMulticaster().currentSettingsChanged(); } + public void fireSchemeChanged(CodeStyleScheme scheme) { + myDispatcher.getMulticaster().schemeChanged(scheme); + } + public CodeStyleScheme getSelectedGlobalScheme() { return myGlobalSelected; } diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java index a4c5d97da8b6..151a92f5616b 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/ManageCodeStyleSchemesDialog.java @@ -15,18 +15,31 @@ */ package com.intellij.application.options.codeStyle; -import com.intellij.application.options.ExportSchemeAction; -import com.intellij.application.options.SaveSchemeDialog; -import com.intellij.application.options.SchemesToImportPopup; +import com.intellij.application.options.*; import com.intellij.openapi.application.ApplicationBundle; +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDialog; +import com.intellij.openapi.fileChooser.FileChooserFactory; +import com.intellij.openapi.options.SchemeImportException; +import com.intellij.openapi.options.SchemeImporter; +import com.intellij.openapi.options.SchemeImporterEP; import com.intellij.openapi.options.SchemesManager; +import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.popup.Balloon; +import com.intellij.openapi.ui.popup.BalloonBuilder; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.codeStyle.CodeStyleScheme; import com.intellij.psi.codeStyle.CodeStyleSchemes; import com.intellij.psi.impl.source.codeStyle.CodeStyleSchemeImpl; +import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.table.JBTable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.ListSelectionEvent; @@ -35,6 +48,8 @@ import javax.swing.table.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.IOException; +import java.io.InputStream; import java.util.*; import java.util.List; @@ -54,6 +69,7 @@ public class ManageCodeStyleSchemesDialog extends DialogWrapper { private final MySchemesTableModel mySchemesTableModel; private final CodeStyleSchemesModel myModel; private final Component myParent; + private final SchemesManager mySchemesManager; protected ManageCodeStyleSchemesDialog(final Component parent, CodeStyleSchemesModel schemesModel) { @@ -98,15 +114,15 @@ public class ManageCodeStyleSchemesDialog extends DialogWrapper { } }); - final SchemesManager schemesManager = CodeStyleSchemesModel.getSchemesManager(); + mySchemesManager = CodeStyleSchemesModel.getSchemesManager(); - if (schemesManager.isExportAvailable()) { + if (mySchemesManager.isExportAvailable()) { myExportButton.setVisible(true); myExportButton.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { CodeStyleScheme selected = getSelectedScheme(); - ExportSchemeAction.doExport((CodeStyleSchemeImpl)selected, schemesManager); + ExportSchemeAction.doExport((CodeStyleSchemeImpl)selected, mySchemesManager); } }); myExportButton.setMnemonic('S'); @@ -115,21 +131,12 @@ public class ManageCodeStyleSchemesDialog extends DialogWrapper { myExportButton.setVisible(false); } - if (schemesManager.isImportAvailable()) { + if (mySchemesManager.isImportAvailable() || SchemeImporterEP.getExtensions(CodeStyleScheme.class).size() > 0) { myImportButton.setVisible(true); myImportButton.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { - SchemesToImportPopup popup = - new SchemesToImportPopup(parent) { - @Override - protected void onSchemeSelected(final CodeStyleSchemeImpl scheme) { - if (scheme != null) { - myModel.addScheme(scheme, true); - } - } - }; - popup.show(schemesManager, myModel.getSchemes()); + chooseAndImport(); } }); } @@ -140,6 +147,138 @@ public class ManageCodeStyleSchemesDialog extends DialogWrapper { init(); } + + private void chooseAndImport() { + ImportSourceChooserDialog importSourceChooserDialog = + new ImportSourceChooserDialog(myContentPane, CodeStyleScheme.class, mySchemesManager); + importSourceChooserDialog.show(); + if (importSourceChooserDialog.isOK()) { + if (importSourceChooserDialog.isImportFromSharedSelected()) { + SchemesToImportPopup popup = + new SchemesToImportPopup(myContentPane) { + @Override + protected void onSchemeSelected(final CodeStyleSchemeImpl scheme) { + if (scheme != null) { + myModel.addScheme(scheme, true); + } + } + }; + popup.show(mySchemesManager, myModel.getSchemes()); + } + else { + String selectedImporterName = importSourceChooserDialog.getSelectedSourceName(); + if (selectedImporterName != null) { + try { + String schemeName = importExternalCodeStyle(selectedImporterName); + if (schemeName != null) { + showStatus(myImportButton, + ApplicationBundle.message("message.code.style.scheme.import.success", selectedImporterName, schemeName), + MessageType.INFO); + } + } + catch (SchemeImportException e) { + showStatus(myImportButton, + ApplicationBundle.message("message.code.style.scheme.import.failure", selectedImporterName, e.getMessage()), + MessageType.ERROR); + } + } + } + } + } + + private static void showStatus(final Component component, final String message, MessageType messageType) { + BalloonBuilder balloonBuilder = JBPopupFactory.getInstance() + .createHtmlTextBalloonBuilder(message, messageType.getDefaultIcon(), + messageType.getPopupBackground(), null); + balloonBuilder.setFadeoutTime(5000); + final Balloon balloon = balloonBuilder.createBalloon(); + final Rectangle rect = component.getBounds(); + final Point p = new Point(rect.x, rect.y + rect.height); + final RelativePoint point = new RelativePoint(component, p); + balloon.show(point, Balloon.Position.below); + Disposer.register(ProjectManager.getInstance().getDefaultProject(), balloon); + } + + @Nullable + private String importExternalCodeStyle(String importerName) throws SchemeImportException { + final SchemeImporter importer = SchemeImporterEP.getImporter(importerName, CodeStyleScheme.class); + if (importer != null) { + FileChooserDialog fileChooser = FileChooserFactory.getInstance() + .createFileChooser(new FileChooserDescriptor(true, false, false, false, false, false) { + @Override + public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) { + return file.isDirectory() || importer.getSourceExtension().equals(file.getExtension()); + } + @Override + public boolean isFileSelectable(VirtualFile file) { + return !file.isDirectory() && importer.getSourceExtension().equals(file.getExtension()); + } + }, null, myContentPane); + VirtualFile[] selection = fileChooser.choose(null, null); + if (selection.length == 1) { + VirtualFile selectedFile = selection[0]; + try { + InputStream nameInputStream = selectedFile.getInputStream(); + String[] schemeNames; + try { + schemeNames = importer.readSchemeNames(nameInputStream); + } + finally { + nameInputStream.close(); + } + CodeStyleScheme currScheme = myModel.getSelectedScheme(); + ImportSchemeChooserDialog schemeChooserDialog = + new ImportSchemeChooserDialog(myContentPane, schemeNames, !currScheme.isDefault() ? currScheme.getName() : null); + schemeChooserDialog.show(); + if (schemeChooserDialog.isOK()) { + String schemeName = schemeChooserDialog.getSelectedName(); + String targetName = schemeChooserDialog.getTargetName(); + CodeStyleScheme targetScheme = null; + if (schemeChooserDialog.isUseCurrentScheme()) { + targetScheme = myModel.getSelectedScheme(); + } + else { + if (targetName == null) targetName = ApplicationBundle.message("code.style.scheme.import.unnamed"); + for (CodeStyleScheme scheme : myModel.getSchemes()) { + if (targetName.equals(scheme.getName())) { + targetScheme = scheme; + break; + } + } + if (targetScheme == null) { + int row = mySchemesTableModel.createNewScheme(getSelectedScheme(), targetName); + mySchemesTable.getSelectionModel().setSelectionInterval(row, row); + targetScheme = mySchemesTableModel.getSchemeAt(row); + } + else { + int result = Messages.showYesNoDialog(myContentPane, + ApplicationBundle.message("message.code.style.scheme.already.exists", targetName), + ApplicationBundle.message("title.code.style.settings.import"), + Messages.getQuestionIcon()); + if (result != Messages.OK) { + return null; + } + } + } + InputStream dataInputStream = selectedFile.getInputStream(); + try { + importer.importScheme(dataInputStream, schemeName, targetScheme); + myModel.fireSchemeChanged(targetScheme); + } + finally { + dataInputStream.close(); + } + return targetScheme.getName(); + } + } + catch (IOException e) { + throw new SchemeImportException(e); + } + } + } + return null; + } + private void updateActions() { CodeStyleScheme selectedScheme = getSelectedScheme(); myDeleteButton.setEnabled(!(selectedScheme.isDefault() || mySchemesTableModel.isProjectScheme(selectedScheme))); diff --git a/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java b/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java new file mode 100644 index 000000000000..96835f1c501a --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/options/SchemeImportException.java @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * 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.intellij.openapi.options; + +/** + * Thrown from SchemeImporter when a scheme can't be read for some reason. + * + * @see com.intellij.openapi.options.SchemeImporter + * @author Rustam Vishnyakov + */ +public class SchemeImportException extends Exception { + public SchemeImportException(String message) { + super(message); + } + + public SchemeImportException(Throwable cause) { + super(cause); + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java b/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java new file mode 100644 index 000000000000..8bb8456b90ea --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/options/SchemeImporter.java @@ -0,0 +1,39 @@ +package com.intellij.openapi.options; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.InputStream; + +/** + * Provides functionality to import a scheme from another non-IntelliJ IDEA format. + * + * @author Rustam Vishnyakov + */ +public interface SchemeImporter { + + /** + * @return An extension of a source file which can be imported, for example, "xml". + */ + String getSourceExtension(); + + /** + * Attempts to read scheme names from the given stream. The stream may contain several schemes in which case all the available + * names are returned. + * + * @param inputStream The input stream to read the name from. + * @return Either scheme name or null if the scheme doesn't have a name. + * @throws SchemeImportException + */ + @NotNull + String[] readSchemeNames(@NotNull InputStream inputStream) throws SchemeImportException; + + /** + * Import a scheme from the given stream and source scheme name. + * + * @param inputStream The input stream to import from. + * @param sourceScheme The source scheme name (one of returned by readSchemeNames method). + * @param scheme The target scheme receiving data. + */ + void importScheme(@NotNull InputStream inputStream, @Nullable String sourceScheme, T scheme) throws SchemeImportException; +} diff --git a/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java b/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java new file mode 100644 index 000000000000..4202ee4d7e68 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/options/SchemeImporterEP.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * 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.intellij.openapi.options; + +import com.intellij.openapi.extensions.AbstractExtensionPointBean; +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.util.LazyInstance; +import com.intellij.util.xmlb.annotations.Attribute; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author Rustam Vishnyakov + */ +public class SchemeImporterEP extends AbstractExtensionPointBean { + + public static ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.schemeImporter"); + + @Attribute("name") + public String name; + + @Attribute("schemeClass") + public String schemeClass; + + @Attribute("implementationClass") + public String implementationClass; + + private final LazyInstance> myImporterInstance = new LazyInstance>() { + @Override + protected Class> getInstanceClass() throws ClassNotFoundException { + return findClass(implementationClass); + } + }; + + public SchemeImporter getInstance() { + return myImporterInstance.getValue(); + } + + /** + * Finds extensions supporting the given schemeClass + * @param schemeClass The class of the scheme to search extensions for. + * @return A collection of importers capable of importing schemes of the given class. An empty collection is returned if there are + * no matching importers. + */ + @NotNull + public static Collection> getExtensions(Class schemeClass) { + List> importers = new ArrayList>(); + for (SchemeImporterEP importerEP : EP_NAME.getExtensions()) { + if (schemeClass.getName().equals(importerEP.schemeClass)) { + //noinspection unchecked + importers.add((SchemeImporterEP)importerEP); + } + } + return importers; + } + + + /** + * Find an importer for the given name and scheme class. It is allowed for importers to have the same name but different scheme classes. + * @param name The importer name as defined in plug-in configuration. + * @param schemeClass The scheme class the importer has to support. + * @return The found importer or null if there are no importers for the given name and scheme class. + */ + @Nullable + public static SchemeImporter getImporter(@NotNull String name, Class schemeClass) { + for (SchemeImporterEP importerEP : getExtensions(schemeClass)) { + if (name.equals(importerEP.name)) { + return importerEP.getInstance(); + } + } + return null; + } + +} diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 520aeaa5b89d..ecf970302280 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -460,6 +460,14 @@ button.export=Export... button.edit.global.settings=Edit Global Settings... label.edit.per.project.or.global.code.style=Check option above on for per-project code style configuration
or use global code style. Global code style settings can be configured
in IDE Settings/Global Code Style title.project.code.style=Project\nCode Style +title.code.style.settings.import=Settings Import +title.import.scheme.from=Import From +import.scheme.shared=Shared Scheme +message.code.style.scheme.already.exists=Scheme {0} already exists. Overwrite settings? +code.style.scheme.import.unnamed=Unnamed +message.code.style.scheme.import.success={0} settings were imported to {1} scheme. +message.code.style.scheme.import.failure={0} import failed with error message: {1} + label.name=Name: error.scheme.must.have.a.name=Scheme must have a name error.illegal.scheme.name=Illegal scheme name diff --git a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml index 16336236b9e5..a689fbc7c4f4 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensionPoints.xml @@ -196,5 +196,10 @@ + + + + + diff --git a/plugins/eclipse/resources/META-INF/plugin.xml b/plugins/eclipse/resources/META-INF/plugin.xml index a17e668f79d5..5145ea58bda6 100644 --- a/plugins/eclipse/resources/META-INF/plugin.xml +++ b/plugins/eclipse/resources/META-INF/plugin.xml @@ -13,6 +13,10 @@ + diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java new file mode 100644 index 000000000000..c3d99b97bd70 --- /dev/null +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseCodeStyleSchemeImporter.java @@ -0,0 +1,220 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * 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 org.jetbrains.idea.eclipse.importer; + + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.openapi.options.SchemeImportException; +import com.intellij.openapi.options.SchemeImporter; +import com.intellij.psi.codeStyle.CodeStyleScheme; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.util.ArrayUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.InputStream; +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Rustam Vishnyakov + */ +public class EclipseCodeStyleSchemeImporter implements SchemeImporter, EclipseXmlProfileElements { + + private static final Logger LOG = Logger.getInstance("#" + EclipseCodeStyleSchemeImporter.class.getName()); + + private final static String PROGRAMMATIC_IMPORT_KEY = ""; + + private final EclipseImportMap myImportMap; + + public EclipseCodeStyleSchemeImporter() { + myImportMap = new EclipseImportMap(); + myImportMap.load(); + } + + @Override + public String getSourceExtension() { + return "xml"; + } + + @NotNull + @Override + public String[] readSchemeNames(@NotNull InputStream inputStream) throws SchemeImportException { + final Set names = new HashSet(); + EclipseXmlProfileReader reader = new EclipseXmlProfileReader(new EclipseXmlProfileReader.OptionHandler() { + @Override + public void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException { + // Ignore + } + @Override + public void handleName(String name) { + names.add(name); + } + }); + reader.readSettings(inputStream); + return ArrayUtil.toStringArray(names); + } + + @Override + public void importScheme(@NotNull InputStream inputStream, final @Nullable String sourceScheme, final CodeStyleScheme scheme) + throws SchemeImportException { + final CodeStyleSettings settings = scheme.getCodeStyleSettings(); + EclipseXmlProfileReader reader = new EclipseXmlProfileReader(new EclipseXmlProfileReader.OptionHandler() { + private String myCurrScheme; + + @Override + public void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException { + if (sourceScheme == null || myCurrScheme != null && myCurrScheme.equals(sourceScheme)) { + setCodeStyleOption(settings, eclipseKey, value); + } + } + @Override + public void handleName(String name) { + myCurrScheme = name; + } + }); + reader.readSettings(inputStream); + } + + private void setCodeStyleOption(@NotNull CodeStyleSettings settings, @NotNull String key, @NotNull String value) + throws SchemeImportException { + EclipseImportMap.ImportDescriptor importDescriptor = myImportMap.getImportDescriptor(key); + if (importDescriptor != null) { + try { + if (importDescriptor.isLanguageSpecific()) { + CommonCodeStyleSettings languageSettings = settings.getCommonSettings(importDescriptor.getLanguage()); + if (languageSettings != null) { + if (importDescriptor.isIndentOptions()) { + CommonCodeStyleSettings.IndentOptions indentOptions = languageSettings.getIndentOptions(); + if (indentOptions != null) { + setValue(indentOptions, key, importDescriptor.getFieldName(), value); + } + } + else { + setValue(languageSettings, key, importDescriptor.getFieldName(), value); + } + } + } + else { + setValue(settings, key, importDescriptor.getFieldName(), value); + } + } + catch (Exception e) { + throw new SchemeImportException(e); + } + } + } + + private static void setValue(Object object, String key, String fieldName, String value) throws SchemeImportException { + if (PROGRAMMATIC_IMPORT_KEY.equalsIgnoreCase(fieldName)) { + setProgrammatically(object, key, value); + return; + } + try { + Field targetField = object.getClass().getField(fieldName); + Class fieldType = targetField.getType(); + if (fieldType.isPrimitive()) { + if (Boolean.TYPE.equals(fieldType)) { + targetField.setBoolean(object, valueToBoolean(key, value)); + } + else if (Integer.TYPE.equals(fieldType)) { + targetField.setInt(object, valueToInt(value)); + } + } + else if (fieldType.equals(String.class)) { + targetField.set(object, value); + } + } + catch (IllegalAccessException e) { + LOG.error(e); + } + catch (NoSuchFieldException e) { + LOG.error("Field '" + fieldName + "' does not exist in " + object.getClass().getName(), e); + } + } + + private static boolean valueToBoolean(@NotNull String key, @NotNull String value) throws SchemeImportException { + if (VALUE_INSERT.equals(value) || + VALUE_TRUE.equals(value)) { + return true; + } + if (key.contains("alignment") && value.matches("\\d*")) { + return isAlignmentOn(value); + } + if (!(VALUE_DO_NOT_INSERT.equals(value) || + VALUE_FALSE.equals(value))) { + throw new SchemeImportException("Unrecognized boolean value: " + value + ", key: " + key); + } + return false; + } + + private static int valueToInt(@NotNull String value) { + if (VALUE_END_OF_LINE.equals(value)) return CommonCodeStyleSettings.END_OF_LINE; + if (VALUE_NEXT_LINE.equals(value)) return CommonCodeStyleSettings.NEXT_LINE; + if (VALUE_NEXT_LINE_SHIFTED.equals(value)) return CommonCodeStyleSettings.NEXT_LINE_SHIFTED; + if (VALUE_NEXT_LINE_IF_WRAPPED.equals(value)) return CommonCodeStyleSettings.NEXT_LINE_IF_WRAPPED; + return Integer.parseInt(value); + } + + private static boolean isAlignmentOn(@NotNull String value) { + int packed = valueToInt(value); + return (packed & 2) != 0; + } + + private static void setProgrammatically(@NotNull Object object, @NotNull String key, @NotNull String value) throws SchemeImportException { + if (object instanceof CodeStyleSettings) { + CodeStyleSettings settings = (CodeStyleSettings)object; + if (OPTION_REMOVE_JAVADOC_BLANK_LINES.equals(key)) { + settings.JD_KEEP_EMPTY_LINES = !valueToBoolean(key, value); + } + else if (OPTION_NEW_LINE_AT_EOF.equals(key)) { + EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance(); + editorSettings.setEnsureNewLineAtEOF(valueToBoolean(key, value)); + } + } + else if (object instanceof CommonCodeStyleSettings) { + CommonCodeStyleSettings commonSettings = (CommonCodeStyleSettings)object; + if (OPTION_SPACE_AFTER_BINARY_OPERATOR.equals(key)) { + boolean addSpace = valueToBoolean(key, value); + commonSettings.SPACE_AROUND_ADDITIVE_OPERATORS = + commonSettings.SPACE_AROUND_BITWISE_OPERATORS = + commonSettings.SPACE_AROUND_LOGICAL_OPERATORS = + commonSettings.SPACE_AROUND_MULTIPLICATIVE_OPERATORS = + commonSettings.SPACE_AROUND_RELATIONAL_OPERATORS = + commonSettings.SPACE_AROUND_SHIFT_OPERATORS = + commonSettings.SPACE_AROUND_EQUALITY_OPERATORS = + addSpace; + } + else if (OPTION_INDENT_CLASS_BODY_DECL.equals(key)) { + commonSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = !valueToBoolean(key, value); + } + } + else if (object instanceof CommonCodeStyleSettings.IndentOptions) { + CommonCodeStyleSettings.IndentOptions indentOptions = (CommonCodeStyleSettings.IndentOptions)object; + if (OPTION_TAB_CHAR.equals(key)) { + if (TAB_CHAR_TAB.equals(value) || TAB_CHAR_MIXED.equals(value)) { + indentOptions.USE_TAB_CHARACTER = true; + } + else if (TAB_CHAR_SPACE.equals(value)) { + indentOptions.USE_TAB_CHARACTER = false; + } + } + } + } +} diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java new file mode 100644 index 000000000000..35dde4d0fcad --- /dev/null +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * 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 org.jetbrains.idea.eclipse.importer; + +import com.intellij.openapi.diagnostic.Logger; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * @author Rustam Vishnyakov + */ +public class EclipseImportMap { + private Properties myProperties; + private final static String MAP_PROPERTIES = "EclipseImportMap.properties"; + private static final Logger LOG = Logger.getInstance("#" + EclipseImportMap.class.getName()); + + public EclipseImportMap() { + myProperties = new Properties(); + } + + public void load() { + try { + InputStream sourceStream = getClass().getResourceAsStream(MAP_PROPERTIES); + try { + myProperties.load(sourceStream); + } + finally { + sourceStream.close(); + } + } + catch (IOException e) { + LOG.error(e); + } + } + + @Nullable + public ImportDescriptor getImportDescriptor(String name) { + String rawData = myProperties.getProperty(name); + if (rawData != null && !rawData.trim().isEmpty()) { + if (rawData.contains(":")) { + String[] parameters = rawData.split(":"); + if (parameters.length == 2) { + return new ImportDescriptor(parameters[0].trim(), parameters[1].trim()); + } + else if (parameters.length == 3) { + boolean indentOptions = "indentOptions".equalsIgnoreCase(parameters[1].trim()); + return new ImportDescriptor(parameters[0].trim(), parameters[2], indentOptions); + } + } + else { + return new ImportDescriptor(rawData.trim()); + } + } + return null; + } + + public static class ImportDescriptor { + private String myLanguage; + private String myFieldName; + private boolean myIndentOptions; + + public ImportDescriptor(String language, String fieldName, boolean indentOptions) { + myLanguage = language; + myFieldName = fieldName; + myIndentOptions = indentOptions; + } + + public ImportDescriptor(String language, String fieldName) { + this(language, fieldName, false); + } + + public ImportDescriptor(String fieldName) { + this(null, fieldName); + } + + public String getLanguage() { + return myLanguage; + } + + public String getFieldName() { + return myFieldName; + } + + public boolean isIndentOptions() { + return myIndentOptions; + } + + public boolean isLanguageSpecific() { + return myLanguage != null; + } + } +} diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties new file mode 100644 index 000000000000..e4ac52c48126 --- /dev/null +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseImportMap.properties @@ -0,0 +1,289 @@ +# suppress inspection "UnusedProperty" for whole file +# +# A set of properties describing a map from Eclipse settings to equivalent Intellij IDEA ones. +# Property value format: +# [Language:[IndentOptions:]]OPTION_NAME +# +# If Language is omitted, root CodeStyleSettings are used, otherwise CommonCodeStyleSettings for the specified Language. +# OPTION_NAME = means that the value is set programmatically, probably for many target options at a time. +# + +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration= +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=Java:SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS +#org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration= +#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case= +org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES +#org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries= +#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration= +org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=Java:ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=Java:SPACE_WITHIN_ANNOTATION_PARENTHESES +org.eclipse.jdt.core.formatter.blank_lines_before_field=Java:BLANK_LINES_AROUND_FIELD +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES +#org.eclipse.jdt.core.formatter.use_on_off_tags= +#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration= +org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=Java:ELSE_ON_NEW_LINE +#org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator= +#org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line= +#org.eclipse.jdt.core.formatter.insert_space_after_ellipsis= +#org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration= +#org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases= +#org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation= +org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=Java:ALIGN_GROUP_FIELD_DECLARATIONS +org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=Java:ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION +#org.eclipse.jdt.core.formatter.alignment_for_conditional_expression= +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=Java:SPACE_BEFORE_FOR_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=Java: +#org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard= +#org.eclipse.jdt.core.formatter.brace_position_for_array_initializer= +#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant= +org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=Java:FINALLY_ON_NEW_LINE +#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable= +org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=Java:CATCH_ON_NEW_LINE +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=Java:SPACE_BEFORE_WHILE_PARENTHESES +org.eclipse.jdt.core.formatter.blank_lines_after_package=Java:BLANK_LINES_AFTER_PACKAGE +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters= +org.eclipse.jdt.core.formatter.continuation_indentation=Java:IndentOptions:CONTINUATION_INDENT_SIZE +#org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator= +org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS +#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces= +#org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk= +#org.eclipse.jdt.core.formatter.insert_space_before_binary_operator= +org.eclipse.jdt.core.formatter.blank_lines_before_package=Java:BLANK_LINES_BEFORE_PACKAGE +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments= +#org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration= +#org.eclipse.jdt.core.formatter.comment.format_line_comments= +#org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations= +#org.eclipse.jdt.core.formatter.join_wrapped_lines= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block= +#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call= +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=Java:SPACE_BEFORE_COMMA +#org.eclipse.jdt.core.formatter.blank_lines_before_member_type= +#org.eclipse.jdt.core.formatter.align_type_members_on_columns= +#org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=Java:SPACE_WITHIN_FOR_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES +#org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=Java:SPACE_WITHIN_SWITCH_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=Java:SPACE_AROUND_UNARY_OPERATOR +#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case= +#org.eclipse.jdt.core.formatter.comment.indent_parameter_description= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=Java:SPACE_WITHIN_METHOD_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=Java:SPACE_WITHIN_SWITCH_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters= +#org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment= +#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration= +org.eclipse.jdt.core.formatter.lineSplit=RIGHT_MARGIN +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=Java:SPACE_BEFORE_IF_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=Java:SPACE_WITHIN_BRACKETS +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=Java:SPACE_WITHIN_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaratio n= +#org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration= +#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method= +org.eclipse.jdt.core.formatter.indentation.size=Java:IndentOptions:INDENT_SIZE +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=Java:SPACE_WITHIN_EMPTY_METHOD_PARENTHESES +#org.eclipse.jdt.core.formatter.enabling_tag= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant= +org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=Java:ALIGN_MULTILINE_EXTENDS_LIST +org.eclipse.jdt.core.formatter.alignment_for_assignment=Java:ALIGN_MULTILINE_ASSIGNMENT +org.eclipse.jdt.core.formatter.tabulation.char=Java:IndentOptions: +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters= +#org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources= +#org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator= +#org.eclipse.jdt.core.formatter.indent_statements_compare_to_body= +org.eclipse.jdt.core.formatter.blank_lines_before_method=Java:BLANK_LINES_AROUND_METHOD +#org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested= +#org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line= +#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for= +#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast= +#org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration= +#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement= +#org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration= +#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body= +org.eclipse.jdt.core.formatter.alignment_for_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS_IN_CALLS +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=Java:SPACE_WITHIN_METHOD_CALL_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation= +#org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=Java:SPACE_WITHIN_IF_PARENTHESES +#org.eclipse.jdt.core.formatter.brace_position_for_switch= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws= +#org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation= +org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=Java:SPACE_AFTER_QUEST +#org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=Java:SPACE_WITHIN_TRY_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression= +#org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments= +#org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments= +org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=Java:INDENT_CASE_FROM_SWITCH +#org.eclipse.jdt.core.formatter.insert_space_before_ellipsis= +org.eclipse.jdt.core.formatter.brace_position_for_block=Java:BRACE_STYLE +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits= +org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=Java:METHOD_BRACE_STYLE +org.eclipse.jdt.core.formatter.compact_else_if=Java:SPECIAL_ELSE_IF_TREATMENT +#org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments= +#org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column= +org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=Java:SPACE_WITHIN_BRACKETS +#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field= +#org.eclipse.jdt.core.formatter.comment.indent_root_tags= +#org.eclipse.jdt.core.formatter.brace_position_for_enum_constant= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations= +#org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments= +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=Java:SPACE_BEFORE_SWITCH_LBRACE +org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=Java:SPACE_BEFORE_COMMA +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression= +org.eclipse.jdt.core.formatter.tabulation.size=Java:IndentOptions:TAB_SIZE +#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference= +org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=Java:ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE +#org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference= +#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant= +#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=Java:SPACE_WITHIN_IF_PARENTHESES +org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment= +#org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration= +org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=Java:SPACE_AROUND_ASSIGNMENT_OPERATORS +org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=Java:SPACE_AROUND_ASSIGNMENT_OPERATORS +#org.eclipse.jdt.core.formatter.indent_empty_lines= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=Java:SPACE_WITHIN_SYNCHRONIZED_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=Java:SPACE_AFTER_TYPE_CAST +org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=Java:SPACE_AFTER_COMMA +#org.eclipse.jdt.core.formatter.brace_position_for_block_in_case= +org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=Java:KEEP_BLANK_LINES_IN_CODE +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=Java:SPACE_BEFORE_METHOD_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=Java:SPACE_WITHIN_CATCH_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration= +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=Java:SPACE_BEFORE_METHOD_CALL_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=Java:SPACE_WITHIN_BRACKETS +#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression= +#org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter= +#org.eclipse.jdt.core.compiler.compliance= +#org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer= +#org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression= +#org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration= +#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=Java:SPACE_WITHIN_CAST_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=Java:SPACE_AROUND_UNARY_OPERATOR +#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration= +#org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line= +#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration= +org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=Java:KEEP_SIMPLE_BLOCKS_IN_ONE_LINE +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters= +#org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters= +org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing= +#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for= +#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference= +#org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration= +org.eclipse.jdt.core.formatter.alignment_for_binary_expression=Java:ALIGN_MULTILINE_BINARY_OPERATION +#org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration= +#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=Java:SPACE_WITHIN_WHILE_PARENTHESES +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=Java:SPACE_BEFORE_TRY_PARENTHESES +#org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line= +#org.eclipse.jdt.core.formatter.insert_new_line_after_label= +#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter= +#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters= +org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=Java:SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES +org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=Java:WHILE_ON_NEW_LINE +#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant= +org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=ENABLE_JAVADOC_FORMATTING +#org.eclipse.jdt.core.formatter.comment.line_length= +#org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package= +#org.eclipse.jdt.core.formatter.blank_lines_between_import_groups= +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments= +org.eclipse.jdt.core.formatter.insert_space_before_semicolon=Java:SPACE_BEFORE_SEMICOLON +#org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration= +org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=Java:BLANK_LINES_BEFORE_METHOD_BODY +org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=Java:SPACE_BEFORE_COLON +org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=Java: +#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration= +org.eclipse.jdt.core.formatter.wrap_before_binary_operator=Java:BINARY_OPERATION_SIGN_ON_NEXT_LINE +#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header= +#org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=Java:SPACE_WITHIN_SYNCHRONIZED_PARENTHESES +#org.eclipse.jdt.core.formatter.indent_statements_compare_to_block= +#org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration= +#org.eclipse.jdt.core.formatter.join_lines_in_comments= +org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=Java:SPACE_BEFORE_QUEST +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations= +#org.eclipse.jdt.core.formatter.alignment_for_compact_if= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits= +#org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer= +#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default= +#org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter= +#org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration= +org.eclipse.jdt.core.formatter.blank_lines_before_imports=Java:BLANK_LINES_BEFORE_IMPORTS +#org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert= +#org.eclipse.jdt.core.formatter.comment.format_html= +org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=Java:ALIGN_MULTILINE_THROWS_LIST +#org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression= +#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration= +org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=Java:SPACE_AFTER_COLON +#org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=Java:SPACE_WITHIN_FOR_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator= +#org.eclipse.jdt.core.formatter.comment.format_source_code= +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=Java:SPACE_BEFORE_SYNCHRONIZED_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws= +org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=Java:ALIGN_MULTILINE_PARAMETERS +org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=Java:SPACE_WITHIN_ARRAY_INITIALIZER_BRACES +org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=Java:ALIGN_MULTILINE_RESOURCES +org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=Java:IndentOptions:SMART_TABS +#org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation= +#org.eclipse.jdt.core.formatter.comment.format_header= +#org.eclipse.jdt.core.formatter.comment.format_block_comments= +#org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant= +#org.eclipse.jdt.core.formatter.alignment_for_enum_constants= +#org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block= +#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=Java:SPACE_WITHIN_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=Java:SPACE_WITHIN_CATCH_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations= +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=Java:SPACE_BEFORE_SWITCH_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=Java:SPACE_WITHIN_METHOD_CALL_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert= +org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=Java:CLASS_BRACE_STYLE +org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=Java:SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE +#org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer= +org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=Java:SPACE_WITHIN_METHOD_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for= +org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=Java:SPACE_BEFORE_CATCH_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations= +org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=Java:SPACE_WITHIN_ANNOTATION_PARENTHESES +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference= +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments= +#org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries= +org.eclipse.jdt.core.formatter.blank_lines_after_imports=Java:BLANK_LINES_AFTER_IMPORTS +#org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations= +#org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header= +#org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for= +org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=Java:KEEP_FIRST_COLUMN_COMMENT +#org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources= +#org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments= +#org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column= +org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=Java:KEEP_CONTROL_STATEMENT_IN_ONE_LINE diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java new file mode 100644 index 000000000000..b30a3a8af472 --- /dev/null +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileElements.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * 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 org.jetbrains.idea.eclipse.importer; + +/** + * @author Rustam Vishnyakov + */ +@SuppressWarnings("UnusedDeclaration") +public interface EclipseXmlProfileElements { + String PROFILES_TAG = "profiles"; + String PROFILE_TAG = "profile"; + String NAME_ATTR = "name"; + String SETTING_TAG = "setting"; + String ID_ATTR = "id"; + String VALUE_ATTR = "value"; + + String VALUE_INSERT = "insert"; + String VALUE_DO_NOT_INSERT = "do not insert"; + String VALUE_FALSE = "false"; + String VALUE_TRUE = "true"; + + String VALUE_NEXT_LINE = "next_line"; + String VALUE_NEXT_LINE_SHIFTED = "next_line_shifted"; + String VALUE_END_OF_LINE = "end_of_line"; + String VALUE_NEXT_LINE_IF_WRAPPED = "next_line_on_wrap"; + + String TAB_CHAR_TAB = "tab"; + String TAB_CHAR_SPACE = "space"; + String TAB_CHAR_MIXED = "mixed"; + + String OPTION_SPACE_AFTER_BINARY_OPERATOR = "org.eclipse.jdt.core.formatter.insert_space_after_binary_operator"; + String OPTION_REMOVE_JAVADOC_BLANK_LINES = "org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment"; + String OPTION_NEW_LINE_AT_EOF = "org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing"; + String OPTION_INDENT_CLASS_BODY_DECL = "org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header"; + String OPTION_TAB_CHAR = "org.eclipse.jdt.core.formatter.tabulation.char"; +} diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java new file mode 100644 index 000000000000..4216e58cec14 --- /dev/null +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/EclipseXmlProfileReader.java @@ -0,0 +1,91 @@ +/* + * Copyright 2000-2013 JetBrains s.r.o. + * + * 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 org.jetbrains.idea.eclipse.importer; + +import com.intellij.openapi.options.SchemeImportException; +import org.jetbrains.annotations.NotNull; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.InputStream; + +/** + * Reads settings from Eclipse XML profile. The actual work is done by an implementor of handleOption() method. + * + * @author Rustam Vishnyakov + */ +public class EclipseXmlProfileReader extends DefaultHandler implements EclipseXmlProfileElements { + + private OptionHandler myOptionHandler; + + protected EclipseXmlProfileReader(OptionHandler optionHandler) { + myOptionHandler = optionHandler; + } + + /** + * Reads either basic profile info (name) or all the settings depending on whether settings parameter is null. + * + * @param input The input stream to read from. + * @throws SchemeImportException + */ + protected void readSettings(InputStream input) throws SchemeImportException { + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setValidating(false); + SAXParser parser; + try { + parser = spf.newSAXParser(); + parser.parse(input, this); + } + catch (Exception e) { + throw new SchemeImportException(e); + } + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + if (PROFILE_TAG.equals(qName)) { + myOptionHandler.handleName(attributes.getValue(NAME_ATTR)); + } + else if (SETTING_TAG.equals(qName)) { + String key = attributes.getValue(ID_ATTR); + String value = attributes.getValue(VALUE_ATTR); + if (key != null && value != null) { + try { + myOptionHandler.handleOption(key, value); + } + catch (SchemeImportException e) { + throw new SAXException(e); + } + } + } + else //noinspection StatementWithEmptyBody + if (PROFILES_TAG.equals(qName)) { + // Ignore + } + else { + throw new SAXException("Unknown XML element: " + qName); + } + } + + + interface OptionHandler { + void handleOption(@NotNull String eclipseKey, @NotNull String value) throws SchemeImportException; + void handleName(String name); + } +} diff --git a/plugins/eclipse/testData/import/settings/eclipse_exported.xml b/plugins/eclipse/testData/import/settings/eclipse_exported.xml new file mode 100644 index 000000000000..813c43bd86ca --- /dev/null +++ b/plugins/eclipse/testData/import/settings/eclipse_exported.xml @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java new file mode 100644 index 000000000000..30c309e7ea81 --- /dev/null +++ b/plugins/eclipse/testSources/org/jetbrains/idea/eclipse/EclipseSettingsImportTest.java @@ -0,0 +1,168 @@ +package org.jetbrains.idea.eclipse; + +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable; +import com.intellij.psi.codeStyle.CodeStyleScheme; +import com.intellij.psi.codeStyle.CodeStyleSchemes; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.testFramework.PlatformTestCase; +import org.jetbrains.idea.eclipse.importer.EclipseCodeStyleSchemeImporter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; + +/** + * @author Rustam Vishnyakov + */ +public class EclipseSettingsImportTest extends PlatformTestCase { + + private static String getTestDataPath() { + return PluginPathManager.getPluginHomePath("eclipse") + "/testData/import/settings/"; + } + + public void testImportCodeStyleSettingsFromXmlProfile() throws Exception { + File input = new File(getTestDataPath() + "eclipse_exported.xml"); + EclipseCodeStyleSchemeImporter codeStyleSchemeImporter = new EclipseCodeStyleSchemeImporter(); + CodeStyleSchemes schemes = CodeStyleSchemes.getInstance(); + CodeStyleScheme scheme = schemes.createNewScheme(getTestName(false), null); + CodeStyleSettings settings = scheme.getCodeStyleSettings(); + + CommonCodeStyleSettings javaSettings = settings.getCommonSettings("Java"); + CommonCodeStyleSettings.IndentOptions indentOptions = javaSettings.getIndentOptions(); + javaSettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS = false; + javaSettings.SPACE_WITHIN_ARRAY_INITIALIZER_BRACES = false; + javaSettings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE = true; + javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES = true; + javaSettings.BLANK_LINES_AROUND_FIELD = -1; + javaSettings.SPACE_WITHIN_WHILE_PARENTHESES = true; + javaSettings.ELSE_ON_NEW_LINE = true; + javaSettings.ALIGN_GROUP_FIELD_DECLARATIONS = true; + javaSettings.SPACE_BEFORE_FOR_PARENTHESES = false; + javaSettings.SPACE_AROUND_ADDITIVE_OPERATORS = false; + javaSettings.SPACE_AROUND_BITWISE_OPERATORS = false; + javaSettings.SPACE_AROUND_EQUALITY_OPERATORS = false; + javaSettings.SPACE_AROUND_LOGICAL_OPERATORS = false; + javaSettings.FINALLY_ON_NEW_LINE = true; + javaSettings.CATCH_ON_NEW_LINE = true; + javaSettings.SPACE_BEFORE_WHILE_PARENTHESES = false; + javaSettings.BLANK_LINES_AFTER_PACKAGE = -1; + javaSettings.getIndentOptions().CONTINUATION_INDENT_SIZE = 0; + javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true; + javaSettings.BLANK_LINES_BEFORE_PACKAGE = -1; + javaSettings.SPACE_WITHIN_FOR_PARENTHESES = true; + javaSettings.ALIGN_MULTILINE_ASSIGNMENT = true; + javaSettings.SPACE_BEFORE_METHOD_PARENTHESES = true; + javaSettings.SPACE_WITHIN_CATCH_PARENTHESES = true; + javaSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES = true; + javaSettings.SPACE_WITHIN_CAST_PARENTHESES = true; + javaSettings.SPACE_AROUND_UNARY_OPERATOR = true; + javaSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE = false; + EditorSettingsExternalizable editorSettings = EditorSettingsExternalizable.getInstance(); + boolean currAddLineFeed = editorSettings.isEnsureNewLineAtEOF(); + editorSettings.setEnsureNewLineAtEOF(true); + javaSettings.ALIGN_MULTILINE_BINARY_OPERATION = true; + javaSettings.SPACE_WITHIN_TRY_PARENTHESES = true; + javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES = true; + javaSettings.WHILE_ON_NEW_LINE = true; + settings.ENABLE_JAVADOC_FORMATTING = false; + javaSettings.SPACE_BEFORE_SEMICOLON = true; + javaSettings.BLANK_LINES_BEFORE_METHOD_BODY = -1; + javaSettings.SPACE_BEFORE_COLON = false; + javaSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS = true; + javaSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE = false; + javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES = true; + javaSettings.SPACE_BEFORE_QUEST = false; + javaSettings.BLANK_LINES_BEFORE_IMPORTS = 0; + javaSettings.ALIGN_MULTILINE_THROWS_LIST = true; + javaSettings.SPACE_AFTER_COLON = false; + javaSettings.SPACE_WITHIN_FOR_PARENTHESES = true; + javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES = false; + javaSettings.ALIGN_MULTILINE_PARAMETERS = true; + javaSettings.ALIGN_MULTILINE_RESOURCES = true; + javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES = false; + javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES = true; + javaSettings.CLASS_BRACE_STYLE = CommonCodeStyleSettings.NEXT_LINE; + javaSettings.SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE = false; + javaSettings.SPACE_WITHIN_METHOD_PARENTHESES = true; + javaSettings.SPACE_BEFORE_CATCH_PARENTHESES = false; + javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES = true; + javaSettings.BLANK_LINES_AFTER_IMPORTS = -1; + javaSettings.KEEP_FIRST_COLUMN_COMMENT = true; + javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE = true; + indentOptions.USE_TAB_CHARACTER = false; + indentOptions.SMART_TABS = false; + + InputStream inputStream = new FileInputStream(input); + try { + codeStyleSchemeImporter.importScheme(inputStream, null, scheme); + + assertTrue(javaSettings.SPACE_AFTER_COMMA_IN_TYPE_ARGUMENTS); + assertTrue(javaSettings.SPACE_WITHIN_ARRAY_INITIALIZER_BRACES); + assertFalse(javaSettings.ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE); + assertFalse(javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES); + assertEquals(0, javaSettings.BLANK_LINES_AROUND_FIELD); + assertFalse(javaSettings.SPACE_WITHIN_WHILE_PARENTHESES); + assertFalse(javaSettings.ELSE_ON_NEW_LINE); + assertFalse(javaSettings.ALIGN_GROUP_FIELD_DECLARATIONS); + assertTrue(javaSettings.SPACE_BEFORE_FOR_PARENTHESES); + assertTrue(javaSettings.SPACE_AROUND_ADDITIVE_OPERATORS); + assertTrue(javaSettings.SPACE_AROUND_BITWISE_OPERATORS); + assertTrue(javaSettings.SPACE_AROUND_EQUALITY_OPERATORS); + assertTrue(javaSettings.SPACE_AROUND_LOGICAL_OPERATORS); + assertFalse(javaSettings.FINALLY_ON_NEW_LINE); + assertFalse(javaSettings.CATCH_ON_NEW_LINE); + assertTrue(javaSettings.SPACE_BEFORE_WHILE_PARENTHESES); + assertEquals(1, javaSettings.BLANK_LINES_AFTER_PACKAGE); + assertEquals(2, javaSettings.getIndentOptions().CONTINUATION_INDENT_SIZE); + assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS); + assertEquals(0, javaSettings.BLANK_LINES_BEFORE_PACKAGE); + assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES); + assertFalse(javaSettings.ALIGN_MULTILINE_ASSIGNMENT); + assertFalse(javaSettings.SPACE_BEFORE_METHOD_PARENTHESES); + assertFalse(javaSettings.SPACE_WITHIN_CATCH_PARENTHESES); + assertFalse(javaSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES); + assertFalse(javaSettings.SPACE_WITHIN_CATCH_PARENTHESES); + assertFalse(javaSettings.SPACE_AROUND_UNARY_OPERATOR); + assertTrue(javaSettings.KEEP_SIMPLE_BLOCKS_IN_ONE_LINE); + assertFalse(editorSettings.isEnsureNewLineAtEOF()); + assertFalse(javaSettings.ALIGN_MULTILINE_BINARY_OPERATION); + assertFalse(javaSettings.SPACE_WITHIN_TRY_PARENTHESES); + assertFalse(javaSettings.SPACE_WITHIN_EMPTY_METHOD_CALL_PARENTHESES); + assertFalse(javaSettings.WHILE_ON_NEW_LINE); + assertTrue(settings.ENABLE_JAVADOC_FORMATTING); + assertFalse(javaSettings.SPACE_BEFORE_SEMICOLON); + assertEquals(0, javaSettings.BLANK_LINES_BEFORE_METHOD_BODY); + assertTrue(javaSettings.SPACE_BEFORE_COLON); + assertFalse(javaSettings.DO_NOT_INDENT_TOP_LEVEL_CLASS_MEMBERS); + assertTrue(javaSettings.BINARY_OPERATION_SIGN_ON_NEXT_LINE); + assertFalse(javaSettings.SPACE_WITHIN_SYNCHRONIZED_PARENTHESES); + assertTrue(javaSettings.SPACE_BEFORE_QUEST); + assertEquals(1, javaSettings.BLANK_LINES_BEFORE_IMPORTS); + assertFalse(javaSettings.ALIGN_MULTILINE_THROWS_LIST); + assertTrue(javaSettings.SPACE_AFTER_COLON); + assertFalse(javaSettings.SPACE_WITHIN_FOR_PARENTHESES); + assertTrue(javaSettings.SPACE_BEFORE_SYNCHRONIZED_PARENTHESES); + assertFalse(javaSettings.ALIGN_MULTILINE_PARAMETERS); + assertFalse(javaSettings.ALIGN_MULTILINE_RESOURCES); + assertTrue(javaSettings.SPACE_BEFORE_SWITCH_PARENTHESES); + assertFalse(javaSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES); + assertEquals(CommonCodeStyleSettings.END_OF_LINE, javaSettings.CLASS_BRACE_STYLE); + assertTrue(javaSettings.SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE); + assertFalse(javaSettings.SPACE_WITHIN_METHOD_PARENTHESES); + assertTrue(javaSettings.SPACE_BEFORE_CATCH_PARENTHESES); + assertFalse(javaSettings.SPACE_WITHIN_ANNOTATION_PARENTHESES); + assertEquals(1, javaSettings.BLANK_LINES_AFTER_IMPORTS); + assertFalse(javaSettings.KEEP_FIRST_COLUMN_COMMENT); + assertFalse(javaSettings.KEEP_CONTROL_STATEMENT_IN_ONE_LINE); + assertTrue(indentOptions.USE_TAB_CHARACTER); + assertTrue(indentOptions.SMART_TABS); + } + finally { + inputStream.close(); + schemes.deleteScheme(scheme); + editorSettings.setEnsureNewLineAtEOF(currAddLineFeed); + } + } +}