org.jboss.tools.maven.ui.wizard.ConfigureMavenRepositoriesWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.tools.maven.ui.wizard.ConfigureMavenRepositoriesWizardPage.java

Source

/*************************************************************************************
 * Copyright (c) 2010-2012 Red Hat, Inc. and others.
 * 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:
 *     JBoss by Red Hat - Initial implementation.
 ************************************************************************************/
package org.jboss.tools.maven.ui.wizard;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.maven.cli.MavenCli;
import org.apache.maven.settings.Profile;
import org.apache.maven.settings.Repository;
import org.apache.maven.settings.RepositoryPolicy;
import org.apache.maven.settings.Settings;
import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.IEncodedStreamContentAccessor;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.compare.structuremergeviewer.Differencer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IPageChangeProvider;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.embedder.ArtifactKey;
import org.eclipse.m2e.core.embedder.IMaven;
import org.eclipse.m2e.core.embedder.IMavenConfiguration;
import org.eclipse.m2e.core.internal.index.IndexManager;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.MavenUpdateRequest;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.jboss.tools.maven.core.MavenCoreActivator;
import org.jboss.tools.maven.ui.Activator;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;

/**
 * 
 * @author snjeza
 *
 */
public class ConfigureMavenRepositoriesWizardPage extends WizardPage implements IPageChangedListener {

    private static final String ACTIVE_PROFILE = "activeProfile"; //$NON-NLS-1$

    private static final String ACTIVE_PROFILES = "activeProfiles"; //$NON-NLS-1$

    private static final String REPOSITORY_APACHE_ORG_ID = "repository-apache-org"; //$NON-NLS-1$

    private static final String REPOSITORY_APACHE_ORG_PROFILE_ID = REPOSITORY_APACHE_ORG_ID;

    private static final String COM_SPRINGSOURCE_REPOSITORY_BUNDLES_EXTERNAL_ID = "com-springsource-repository-bundles-external"; //$NON-NLS-1$

    private static final String COM_SPRINGSOURCE_REPOSITORY_BUNDLES_EXTERNAL_PROFILE_ID = COM_SPRINGSOURCE_REPOSITORY_BUNDLES_EXTERNAL_ID;

    private static final String COM_SPRINGSOURCE_REPOSITORY_BUNDLES_RELEASE_ID = "com-springsource-repository-bundles-release"; //$NON-NLS-1$

    private static final String COM_SPRINGSOURCE_REPOSITORY_BUNDLES_RELEASE_PROFILE_ID = COM_SPRINGSOURCE_REPOSITORY_BUNDLES_RELEASE_ID;

    private static final String JAVA_NET_PUBLIC_ID = "java-net-public"; //$NON-NLS-1$

    private static final String JAVA_NET_PUBLIC_PROFILE_ID = JAVA_NET_PUBLIC_ID;

    private static final String JBOSS_PUBLIC_REPOSITORY_ID = "jboss-public-repository"; //$NON-NLS-1$

    private static final String JBOSS_PUBLIC_REPOSITORY_PROFILE_ID = JBOSS_PUBLIC_REPOSITORY_ID;

    private static final String RED_HAT_TECHPREVIEW_ALL_REPOSITORY_ID = "redhat-techpreview-all-repository";//$NON-NLS-1$

    private static final String RED_HAT_TECHPREVIEW_ALL_REPOSITORY_PROFILE_ID = RED_HAT_TECHPREVIEW_ALL_REPOSITORY_ID;

    private static final String ERROR_TITLE = "Error";//$NON-NLS-1$

    private static final String SNAPSHOTS_ELEMENT = "snapshots"; //$NON-NLS-1$

    private static final String UPDATE_POLICY_ELEMENT = "updatePolicy"; //$NON-NLS-1$

    private static final String ENABLED_ELEMENT = "enabled"; //$NON-NLS-1$

    private static final String RELEASES_ELEMENT = "releases"; //$NON-NLS-1$

    private static final String LAYOUT_ELEMENT = "layout"; //$NON-NLS-1$

    private static final String POLICY_NEVER = "never"; //$NON-NLS-1$

    private static final String LAYOUT_DEFAULT = "default"; //$NON-NLS-1$

    private static final String NAME_ELEMENT = "name"; //$NON-NLS-1$

    private static final String URL_ELEMENT = "url"; //$NON-NLS-1$

    private static final String REPOSITORY_ELEMENT = "repository"; //$NON-NLS-1$

    private static final String PLUGIN_REPOSITORIES_ELEMENT = "pluginRepositories"; //$NON-NLS-1$

    private static final String PLUGIN_REPOSITORY_ELEMENT = "pluginRepository"; //$NON-NLS-1$

    private static final String REPOSITORIES_ELEMENT = "repositories"; //$NON-NLS-1$

    private static final String ID_ELEMENT = "id"; //$NON-NLS-1$

    private static final String PROFILE_ELEMENT = "profile"; //$NON-NLS-1$

    private static final String PROFILES_ELEMENT = "profiles"; //$NON-NLS-1$

    private static final String UTF_8 = "UTF-8"; //$NON-NLS-1$

    private static final String PAGE_NAME = "org.jboss.tools.maven.ui.wizard.page"; //$NON-NLS-1$
    private static final String ADD_REPOSITORY = " Add Repository..."; //$NON-NLS-1$
    private static final String REMOVE_ALL = " Remove All "; //$NON-NLS-1$
    private static final String REMOVE = " Remove "; //$NON-NLS-1$

    private Button removeButton;
    private Button removeAllButton;
    private Button addRepositoryButton;
    private IMaven maven;
    private TableViewer includedRepositoriesViewer;
    private Set<RepositoryWrapper> includedRepositories;
    private Set<RepositoryWrapper> availableRepositories;
    private Set<RepositoryWrapper> selectedIncludedRepositories = new HashSet<RepositoryWrapper>();

    private Document document;

    private CompareConfiguration compareConfiguration;

    private TextMergeViewer previewViewer;

    private String newSettings;

    private String oldSettings;

    private ArtifactKey artifactKey;

    private String preSelectedProfileId;

    public ConfigureMavenRepositoriesWizardPage(ArtifactKey artifactKey) {
        this(artifactKey, null);
    }

    public ConfigureMavenRepositoriesWizardPage(ArtifactKey artifactKey, String profileId) {
        super(PAGE_NAME);
        setTitle("Configure Maven Repositories");//$NON-NLS-1$
        maven = MavenPlugin.getMaven();
        this.artifactKey = artifactKey;
        this.preSelectedProfileId = profileId;
    }

    public void createControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        composite.setLayout(new GridLayout(1, false));
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        composite.setLayoutData(gd);
        Dialog.applyDialogFont(composite);
        setControl(composite);

        Label userSettingsLabel = new Label(composite, SWT.NONE);
        gd = new GridData(SWT.FILL, SWT.FILL, true, false);
        userSettingsLabel.setLayoutData(gd);

        String userSettings = getUserSettings();
        userSettingsLabel.setText("User settings: " + userSettings);//$NON-NLS-1$

        File settingsFile = new File(userSettings);
        try {
            if (!settingsFile.exists()) {
                createDefaultSettings();
                maven.reloadSettings();
                oldSettings = ""; //$NON-NLS-1$
            } else {
                oldSettings = readFile(settingsFile);
                newSettings = oldSettings;
            }
        } catch (Exception e) {
            Activator.log(e);
            MessageDialog.openError(getShell(), ERROR_TITLE, e.getMessage());
            throw new RuntimeException(e);
        }
        DocumentBuilder builder;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            builder = factory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            Activator.log(e);
            MessageDialog.openError(getShell(), ERROR_TITLE, e.getMessage());
            throw new RuntimeException(e);
        }
        try {
            document = builder.parse(new InputSource(new StringReader(newSettings)));
        } catch (Exception e) {
            Activator.log(e);
            try {
                createDefaultSettings();
            } catch (Exception e1) {
                Activator.log(e1);
                MessageDialog.openError(getShell(), ERROR_TITLE, e1.getMessage());
                throw new RuntimeException(e1);
            }
            try {
                document = builder.parse(new InputSource(new StringReader(newSettings)));
            } catch (Exception e1) {
                Activator.log(e1);
                MessageDialog.openError(getShell(), ERROR_TITLE, e1.getMessage());
                throw new RuntimeException(e1);
            }
        }

        Group repositoriesGroup = new Group(composite, SWT.NONE);
        gd = new GridData(SWT.FILL, SWT.FILL, true, false);
        GridLayout layout = new GridLayout(3, false);
        repositoriesGroup.setLayout(layout);
        repositoriesGroup.setLayoutData(gd);
        repositoriesGroup.setText("Repositories"); //$NON-NLS-1$

        Composite includedRepositoriesComposite = new Composite(repositoriesGroup, SWT.NONE);
        gd = new GridData(SWT.FILL, SWT.FILL, true, false);
        includedRepositoriesComposite.setLayoutData(gd);
        includedRepositoriesComposite.setLayout(new GridLayout(1, false));

        includedRepositoriesViewer = new TableViewer(includedRepositoriesComposite,
                SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        gd = new GridData(SWT.FILL, SWT.FILL, true, false);
        gd.widthHint = 500;
        gd.heightHint = 150;
        includedRepositoriesViewer.getTable().setLayoutData(gd);
        includedRepositoriesViewer.getTable().setLinesVisible(false);
        includedRepositoriesViewer.getTable().setHeaderVisible(false);
        TableViewerColumn c = new TableViewerColumn(includedRepositoriesViewer, SWT.NONE);
        c.getColumn().setText("Repository"); //$NON-NLS-1$
        c.getColumn().setResizable(true);
        TableLayout includedLayout = new AutoResizeTableLayout(includedRepositoriesViewer.getTable());
        ColumnLayoutData columnLayoutData = new ColumnWeightData(350, 350);
        includedLayout.addColumnData(columnLayoutData);

        includedRepositoriesViewer.setContentProvider(new ArrayContentProvider());
        includedRepositoriesViewer.setLabelProvider(new RepositoryLabelProvider());
        ColumnViewerToolTipSupport.enableFor(includedRepositoriesViewer, ToolTip.NO_RECREATE);

        createButtons(repositoriesGroup);

        includedRepositories = getIncludedRepositories();
        availableRepositories = getAvailableRepositories();
        List<RepositoryWrapper> remove = new ArrayList<RepositoryWrapper>();
        for (RepositoryWrapper availableRepository : availableRepositories) {
            if (includedRepositories.contains(availableRepository)) {
                remove.add(availableRepository);
            }
        }
        for (RepositoryWrapper repository : remove) {
            availableRepositories.remove(repository);
        }

        includedRepositoriesViewer.addSelectionChangedListener(new ISelectionChangedListener() {

            public void selectionChanged(SelectionChangedEvent event) {
                ISelection sel = event.getSelection();
                selectedIncludedRepositories.clear();
                if (sel instanceof IStructuredSelection) {
                    IStructuredSelection selection = (IStructuredSelection) sel;
                    Iterator iterator = selection.iterator();
                    while (iterator.hasNext()) {
                        Object object = iterator.next();
                        if (object instanceof RepositoryWrapper) {
                            selectedIncludedRepositories.add((RepositoryWrapper) object);
                        }
                    }
                }
                configureButtons();
            }
        });
        removeButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                boolean ok = getMessageDialog(selectedIncludedRepositories);
                if (ok) {
                    for (RepositoryWrapper wrapper : selectedIncludedRepositories) {
                        includedRepositories.remove(wrapper);
                        availableRepositories.add(wrapper);
                        removeRepository(wrapper);
                    }
                    setPageComplete(true);
                    refreshRepositories();
                }
            }

        });
        removeAllButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                boolean ok = getMessageDialog(includedRepositories);
                if (!ok) {
                    return;
                }
                List<RepositoryWrapper> list = new ArrayList<RepositoryWrapper>();
                for (RepositoryWrapper wrapper : includedRepositories) {
                    list.add(wrapper);
                    removeRepository(wrapper);
                }
                includedRepositories.removeAll(list);
                availableRepositories.addAll(list);
                setPageComplete(true);
                refreshRepositories();
            }

        });
        addRepositoryButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                openAddRepositoryDialog();
            }

        });

        Label separator = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
        separator.setVisible(false);

        Label previewLabel = new Label(composite, SWT.NULL);
        previewLabel.setText("Preview:"); //$NON-NLS-1$

        createPreviewer(composite);

        refreshRepositories();
        setPageComplete(false);
    }

    protected void createButtons(Composite parent) {
        GridData gd;
        Composite buttonsComposite = new Composite(parent, SWT.NONE);
        gd = new GridData(SWT.FILL, SWT.TOP, false, false);
        buttonsComposite.setLayoutData(gd);
        buttonsComposite.setLayout(new GridLayout(1, false));

        removeButton = createButton(buttonsComposite, REMOVE);
        removeAllButton = createButton(buttonsComposite, REMOVE_ALL);
        addRepositoryButton = createButton(buttonsComposite, ADD_REPOSITORY);
    }

    private void createDefaultSettings() throws CoreException, UnsupportedEncodingException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        maven.writeSettings(new Settings(), out);
        newSettings = new String(out.toByteArray(), UTF_8);
    }

    private void addRepository(RepositoryWrapper wrapper, boolean activeByDefault) {
        if (wrapper == null || wrapper.getProfileId() == null || wrapper.getRepository() == null) {
            return;
        }
        String profileId = wrapper.getProfileId();
        Element profile = getProfile(profileId);
        Element repositoriesElement = getElement(profile, REPOSITORIES_ELEMENT);
        if (repositoriesElement != null) {
            addRepository(wrapper, repositoriesElement, false);
        }
        Element pluginRepositoriesElement = getElement(profile, PLUGIN_REPOSITORIES_ELEMENT);
        if (pluginRepositoriesElement != null) {
            addRepository(wrapper, pluginRepositoriesElement, true);
        }

        if (activeByDefault) {

            NodeList activeProfilesList = document.getElementsByTagName(ACTIVE_PROFILES);
            Element activeProfiles = null;
            if (activeProfilesList.getLength() > 0) {
                activeProfiles = (Element) activeProfilesList.item(0);
            }
            if (activeProfiles == null) {
                activeProfiles = document.createElement(ACTIVE_PROFILES);
                document.getDocumentElement().appendChild(activeProfiles);
            }
            NodeList activeProfileList = activeProfiles.getChildNodes();
            boolean activated = false;
            for (int i = 0; i < activeProfileList.getLength(); i++) {
                Node node = activeProfileList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE && ACTIVE_PROFILE.equals(node.getNodeName())) {
                    String id = node.getTextContent();
                    if (id != null) {
                        id = id.trim();
                    }
                    if (profileId.equals(id)) {
                        activated = true;
                        break;
                    }
                }
            }
            if (!activated) {
                addElement(activeProfiles, ACTIVE_PROFILE, profileId);
            }
        }
    }

    private Element getElement(Element element, String name) {
        NodeList elements = element.getChildNodes();
        int len = elements.getLength();
        for (int i = 0; i < len; i++) {
            Node node = elements.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE && name.equals(node.getNodeName())) {
                return (Element) node;
            }
        }
        return null;
    }

    private Element getProfile(String profileId) {
        NodeList profilesList = document.getElementsByTagName(PROFILES_ELEMENT);
        Node profiles;
        Element profileElement = null;
        if (profilesList.getLength() > 0) {
            profiles = profilesList.item(0);
            NodeList profileNodes = profiles.getChildNodes();
            int length = profileNodes.getLength();

            for (int i = 0; i < length; i++) {
                Node profile = profileNodes.item(i);
                if (profile.getNodeType() == Node.ELEMENT_NODE && PROFILE_ELEMENT.equals(profile.getNodeName())) {
                    NodeList profileElements = profile.getChildNodes();
                    for (int j = 0; j < profileElements.getLength(); j++) {
                        Node node = profileElements.item(j);
                        if (node.getNodeType() == Node.ELEMENT_NODE && ID_ELEMENT.equals(node.getNodeName())) {
                            String id = node.getTextContent();
                            if (id != null) {
                                id = id.trim();
                            }
                            if (profileId.equals(id)) {
                                profileElement = (Element) profile;
                                break;
                            }
                        }
                    }
                }
                if (profileElement != null) {
                    break;
                }
            }
        } else {
            profiles = document.createElement(PROFILES_ELEMENT);
            document.getDocumentElement().appendChild(profiles);
        }

        if (profileElement == null) {
            profileElement = createProfile(profiles, profileId);
        }
        configureProfile(profileElement);
        return profileElement;

    }

    private Element createProfile(Node profiles, String profileId) {
        Element profile = document.createElement(PROFILE_ELEMENT);
        profiles.appendChild(profile);
        Element id = document.createElement(ID_ELEMENT);
        id.setTextContent(profileId);
        profile.appendChild(id);
        return profile;
    }

    private void configureProfile(Element profileElement) {
        NodeList nodeList = profileElement.getChildNodes();
        int len = nodeList.getLength();
        Element repositoriesElement = null;
        Element pluginRepositoriesElement = null;
        for (int i = 0; i < len; i++) {
            Node node = nodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE && REPOSITORIES_ELEMENT.equals(node.getNodeName())) {
                repositoriesElement = (Element) node;
            }
            if (node.getNodeType() == Node.ELEMENT_NODE && PLUGIN_REPOSITORIES_ELEMENT.equals(node.getNodeName())) {
                pluginRepositoriesElement = (Element) node;
            }
            if (repositoriesElement != null && pluginRepositoriesElement != null) {
                return;
            }
        }
        if (repositoriesElement == null) {
            repositoriesElement = document.createElement(REPOSITORIES_ELEMENT);
            profileElement.appendChild(repositoriesElement);
        }
        if (pluginRepositoriesElement == null) {
            pluginRepositoriesElement = document.createElement(PLUGIN_REPOSITORIES_ELEMENT);
            profileElement.appendChild(pluginRepositoriesElement);
        }
    }

    private void addRepository(RepositoryWrapper wrapper, Element repos, boolean isPluginRepository) {
        Element repository;
        if (isPluginRepository) {
            repository = document.createElement(PLUGIN_REPOSITORY_ELEMENT);
        } else {
            repository = document.createElement(REPOSITORY_ELEMENT);
        }
        repos.appendChild(repository);
        addElement(repository, ID_ELEMENT, wrapper.getRepository().getId());
        addElement(repository, NAME_ELEMENT, wrapper.getRepository().getName());
        addElement(repository, URL_ELEMENT, wrapper.getRepository().getUrl());
        addElement(repository, LAYOUT_ELEMENT, LAYOUT_DEFAULT);
        RepositoryPolicy policy = wrapper.getRepository().getReleases();
        if (policy != null) {
            Element releases = addElement(repository, RELEASES_ELEMENT, null);
            addElement(releases, ENABLED_ELEMENT, policy.isEnabled() ? "true" : "false"); //$NON-NLS-1$//$NON-NLS-2$
            addElement(releases, UPDATE_POLICY_ELEMENT, POLICY_NEVER);
            repository.appendChild(releases);
        }
        policy = wrapper.getRepository().getSnapshots();
        if (policy != null) {
            Element snapshots = addElement(repository, SNAPSHOTS_ELEMENT, null);
            addElement(snapshots, ENABLED_ELEMENT, policy.isEnabled() ? "true" : "false"); //$NON-NLS-1$//$NON-NLS-2$
            addElement(snapshots, UPDATE_POLICY_ELEMENT, POLICY_NEVER);
            repository.appendChild(snapshots);
        }
    }

    protected Element addElement(Element element, String name, String value) {
        Element child = document.createElement(name);
        if (value != null) {
            Text textNode = document.createTextNode(value);
            child.appendChild(textNode);
        }
        element.appendChild(child);
        return child;
    }

    protected void removeRepository(RepositoryWrapper wrapper) {
        if (wrapper == null || wrapper.getProfileId() == null || wrapper.getRepository() == null
                || wrapper.getRepository().getUrl() == null) {
            return;
        }
        String url = wrapper.getRepository().getUrl();
        String profileId = wrapper.getProfileId();
        Element profile = getProfile(profileId);
        if (profile == null) {
            return;
        }
        Element repositoriesElement = getElement(profile, REPOSITORIES_ELEMENT);
        if (repositoriesElement != null) {
            removeRepository(url, repositoriesElement, false);
        }
        Element pluginRepositoriesElement = getElement(profile, PLUGIN_REPOSITORIES_ELEMENT);
        if (pluginRepositoriesElement != null) {
            removeRepository(url, pluginRepositoriesElement, true);
        }

        // remove profile ?
        if (repositoriesElement != null) {
            NodeList nodeList = repositoriesElement.getChildNodes();
            int len = nodeList.getLength();
            for (int i = 0; i < len; i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE && REPOSITORY_ELEMENT.equals(node.getNodeName())) {
                    return;
                }
            }
        }
        if (pluginRepositoriesElement != null) {
            NodeList nodeList = pluginRepositoriesElement.getChildNodes();
            int len = nodeList.getLength();
            for (int i = 0; i < len; i++) {
                Node node = nodeList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE
                        && PLUGIN_REPOSITORY_ELEMENT.equals(node.getNodeName())) {
                    return;
                }
            }
        }
        NodeList profilesList = document.getElementsByTagName(PROFILES_ELEMENT);
        Element profiles = (Element) profilesList.item(0);
        profiles.removeChild(profile);

        NodeList activeProfilesList = document.getElementsByTagName(ACTIVE_PROFILES);
        Element activeProfiles = null;
        if (activeProfilesList.getLength() > 0) {
            activeProfiles = (Element) activeProfilesList.item(0);
        }
        if (activeProfiles != null) {
            NodeList activeProfileList = activeProfiles.getChildNodes();
            Node profileNode = null;
            for (int i = 0; i < activeProfileList.getLength(); i++) {
                Node node = activeProfileList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE && ACTIVE_PROFILE.equals(node.getNodeName())) {
                    String id = node.getTextContent();
                    if (id != null) {
                        id = id.trim();
                    }
                    if (profileId.equals(id)) {
                        profileNode = node;
                        break;
                    }
                }
            }
            if (profileNode != null) {
                activeProfiles.removeChild(profileNode);
            }
        }
    }

    protected void removeRepository(String url, Element repos, boolean isPluginRepository) {
        NodeList repositoryNodeList = repos.getChildNodes();
        int len = repositoryNodeList.getLength();
        String name;
        if (isPluginRepository) {
            name = PLUGIN_REPOSITORY_ELEMENT;
        } else {
            name = REPOSITORY_ELEMENT;
        }
        Node repository = null;
        for (int i = 0; i < len; i++) {
            Node node = repositoryNodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE && name.equals(node.getNodeName())) {
                String urlNode = getRepositoryUrl(node);
                if (urlNode != null && urlNode.equals(url)) {
                    repository = node;
                    break;
                }
            }
        }
        if (repository != null) {
            repos.removeChild(repository);
        }
    }

    private String getRepositoryUrl(Node repository) {
        NodeList nodeList = repository.getChildNodes();
        int len = nodeList.getLength();
        for (int i = 0; i < len; i++) {
            Node node = nodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE && URL_ELEMENT.equals(node.getNodeName())) {
                String value = node.getTextContent();
                if (value != null) {
                    value = value.trim();
                    if (!value.endsWith(RepositoryWrapper.SEPARATOR)) {
                        value = value + RepositoryWrapper.SEPARATOR;
                    }
                }
                return value;
            }
        }
        return null;
    }

    private void createPreviewer(Composite composite) {
        compareConfiguration = new CompareConfiguration();
        compareConfiguration.setAncestorLabel("Preview:"); //$NON-NLS-1$

        compareConfiguration.setLeftLabel("Old settings"); //$NON-NLS-1$
        compareConfiguration.setLeftEditable(false);

        compareConfiguration.setRightLabel("New settings"); //$NON-NLS-1$
        compareConfiguration.setRightEditable(false);

        previewViewer = new TextMergeViewer(composite, SWT.BORDER, compareConfiguration);

        previewViewer.setInput(new DiffNode(Differencer.CHANGE, null, new StringPreviewerInput(oldSettings),
                new PreviewerInput()));

        Control control = previewViewer.getControl();
        GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
        gd.minimumHeight = 200;
        control.setLayoutData(gd);
        control.addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                if (compareConfiguration != null)
                    compareConfiguration.dispose();
            }
        });

    }

    private String getNewSettings() {
        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            factory.setAttribute("indent-number", 2); //$NON-NLS-1$
            Transformer transformer = factory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$

            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
            DOMSource source = new DOMSource(document);
            transformer.transform(source, result);
            return writer.toString();
        } catch (Exception e) {
            Activator.log(e);
        }
        return null;
    }

    private String readFile(File file) throws FileNotFoundException {
        StringBuilder text = new StringBuilder();
        String NL = System.getProperty("line.separator"); //$NON-NLS-1$
        Scanner scanner = new Scanner(new FileInputStream(file), "UTF-8"); //$NON-NLS-1$
        try {
            while (scanner.hasNextLine()) {
                text.append(scanner.nextLine()).append(NL);
            }
        } finally {
            scanner.close();
        }
        return text.toString();
    }

    public static String getUserSettings() {
        String userSettings = MavenPlugin.getMavenConfiguration().getUserSettingsFile();
        if (userSettings == null || userSettings.length() == 0) {
            userSettings = MavenCli.DEFAULT_USER_SETTINGS_FILE.getAbsolutePath();
        }
        return userSettings;
    }

    private void configureButtons() {
        removeAllButton.setEnabled(includedRepositories.size() > 0);
        removeButton.setEnabled(selectedIncludedRepositories.size() > 0);
    }

    private void refreshRepositories() {
        includedRepositoriesViewer.setInput(includedRepositories.toArray(new RepositoryWrapper[0]));
        previewViewer.refresh();
        selectedIncludedRepositories.clear();
        includedRepositoriesViewer.setSelection(
                new StructuredSelection(selectedIncludedRepositories.toArray(new RepositoryWrapper[0])));
        configureButtons();
    }

    private Set<RepositoryWrapper> getIncludedRepositories() {
        Set<RepositoryWrapper> repositories = new TreeSet<RepositoryWrapper>();
        try {
            List<Profile> activeProfiles = getActiveProfiles();
            for (Profile profile : activeProfiles) {
                List<Repository> repos = profile.getRepositories();
                for (Repository repository : repos) {
                    String profileId = profile.getId() == null ? "" : profile.getId(); //$NON-NLS-1$
                    repositories.add(new RepositoryWrapper(repository, profileId));
                }
            }
        } catch (CoreException e) {
            Activator.log(e);
        }
        return repositories;
    }

    private Set<RepositoryWrapper> getAvailableRepositories() {
        Set<RepositoryWrapper> repositories = new TreeSet<RepositoryWrapper>();

        Repository repository = getDefaultRepository();
        repository.setId(JBOSS_PUBLIC_REPOSITORY_ID);
        repository.setName("JBoss Public"); //$NON-NLS-1$
        repository.setUrl("https://repository.jboss.org/nexus/content/groups/public-jboss/"); //$NON-NLS-1$
        repositories.add(new RepositoryWrapper(repository, JBOSS_PUBLIC_REPOSITORY_PROFILE_ID));

        repository = getDefaultRepository();
        repository.setId(RED_HAT_TECHPREVIEW_ALL_REPOSITORY_ID);
        repository.setName("Red Hat Tech Preview repository (all)"); //$NON-NLS-1$
        repository.setUrl("http://maven.repository.redhat.com/techpreview/all/"); //$NON-NLS-1$
        repositories.add(new RepositoryWrapper(repository, RED_HAT_TECHPREVIEW_ALL_REPOSITORY_PROFILE_ID));

        repository = getDefaultRepository();
        repository.setId(JAVA_NET_PUBLIC_ID);
        repository.setName("Java Net Public"); //$NON-NLS-1$
        repository.setUrl("https://maven.java.net/content/groups/public/"); //$NON-NLS-1$
        repositories.add(new RepositoryWrapper(repository, JAVA_NET_PUBLIC_PROFILE_ID));

        repository = getDefaultRepository();
        repository.setId(COM_SPRINGSOURCE_REPOSITORY_BUNDLES_RELEASE_ID);
        repository.setName("EBR Spring Release"); //$NON-NLS-1$
        repository.setUrl("http://repository.springsource.com/maven/bundles/release/"); //$NON-NLS-1$
        repositories.add(new RepositoryWrapper(repository, COM_SPRINGSOURCE_REPOSITORY_BUNDLES_RELEASE_PROFILE_ID));

        repository = getDefaultRepository();
        repository.setId(COM_SPRINGSOURCE_REPOSITORY_BUNDLES_EXTERNAL_ID);
        repository.setName("EBR External Release"); //$NON-NLS-1$
        repository.setUrl("http://repository.springsource.com/maven/bundles/external/"); //$NON-NLS-1$
        repositories
                .add(new RepositoryWrapper(repository, COM_SPRINGSOURCE_REPOSITORY_BUNDLES_EXTERNAL_PROFILE_ID));

        repository = getDefaultRepository();
        repository.setId(REPOSITORY_APACHE_ORG_ID);
        repository.setName("Apache Repository"); //$NON-NLS-1$
        repository.setUrl("https://repository.apache.org/content/groups/public/"); //$NON-NLS-1$
        repositories.add(new RepositoryWrapper(repository, REPOSITORY_APACHE_ORG_PROFILE_ID));

        return repositories;
    }

    public static Repository getDefaultRepository() {
        Repository repository = new Repository();
        repository.setLayout(LAYOUT_DEFAULT);
        RepositoryPolicy releases = new RepositoryPolicy();
        releases.setEnabled(true);
        releases.setUpdatePolicy(POLICY_NEVER); //$NON-NLS-1$
        repository.setReleases(releases);
        RepositoryPolicy snapshots = new RepositoryPolicy();
        snapshots.setEnabled(false);
        snapshots.setUpdatePolicy(POLICY_NEVER); //$NON-NLS-1$
        repository.setSnapshots(snapshots);
        return repository;
    }

    private List<Profile> getActiveProfiles() throws CoreException {
        Settings settings = maven.getSettings();
        List<String> activeProfilesIds = settings.getActiveProfiles();
        List<Profile> activeProfiles = new ArrayList<Profile>();
        for (Profile profile : settings.getProfiles()) {
            if ((profile.getActivation() != null && profile.getActivation().isActiveByDefault())
                    || activeProfilesIds.contains(profile.getId())) {
                activeProfiles.add(profile);
            }
        }
        return activeProfiles;
    }

    private Button createButton(Composite parent, String text) {
        GridData gd;
        Button button = new Button(parent, SWT.NONE | SWT.LEFT);
        gd = new GridData(GridData.FILL, GridData.FILL, false, false);
        button.setLayoutData(gd);
        button.setText(text);
        return button;
    }

    class RepositoryLabelProvider extends CellLabelProvider {

        public String getToolTipText(Object element) {
            if (element instanceof RepositoryWrapper) {
                return ((RepositoryWrapper) element).getDisplayName();
            }
            return null;
        }

        public Point getToolTipShift(Object object) {
            return new Point(10, 10);
        }

        public int getToolTipDisplayDelayTime(Object object) {
            return 1000;
        }

        public int getToolTipTimeDisplayed(Object object) {
            return 5000;
        }

        public Image getImage(Object element) {
            return null;
        }

        public String getText(Object element) {
            if (element instanceof RepositoryWrapper) {
                return ((RepositoryWrapper) element).getDisplayName();
            }
            return null;
        }

        @Override
        public void update(ViewerCell cell) {
            Object element = cell.getElement();
            if (element instanceof RepositoryWrapper) {
                cell.setText(((RepositoryWrapper) element).getDisplayName());
            }
        }
    }

    class StringPreviewerInput extends PreviewerInput {
        String fContent;

        StringPreviewerInput(String content) {
            if (content == null) {
                content = "<null>"; //$NON-NLS-1$
            }
            fContent = content;
        }

        public InputStream getContents() {
            return new ByteArrayInputStream(getBytes(fContent, UTF_8));
        }
    }

    class PreviewerInput implements ITypedElement, IEncodedStreamContentAccessor {

        PreviewerInput() {
        }

        public Image getImage() {
            return null;
        }

        public String getName() {
            return "no name"; //$NON-NLS-1$
        }

        public String getType() {
            return "xml"; //$NON-NLS-1$
        }

        public InputStream getContents() {
            return new ByteArrayInputStream(getBytes(getNewSettings(), UTF_8));
        }

        public String getCharset() {
            return UTF_8;
        }
    }

    public static byte[] getBytes(String s, String encoding) {
        byte[] bytes = null;
        if (s != null) {
            try {
                bytes = s.getBytes(encoding);
            } catch (UnsupportedEncodingException e) {
                bytes = s.getBytes();
            }
        }
        return bytes;
    }

    public boolean finishPage() {
        String userSettings = getUserSettings();
        File file = new File(userSettings);
        boolean ok = MessageDialog.openQuestion(getShell(), "Confirm File Update", //$NON-NLS-1$
                "Are you sure you want to update the file '" + userSettings + "'?"); //$NON-NLS-1$ //$NON-NLS-2$
        if (!ok) {
            return false;
        }
        String outputString = getNewSettings();
        FileOutputStream out = null;

        try {
            out = new FileOutputStream(file);
            byte[] bytes = outputString.getBytes(UTF_8);
            out.write(bytes);
            out.flush();
            updateSettings();
        } catch (Exception e) {
            MessageDialog.openError(getShell(), ERROR_TITLE, e.getMessage());
            Activator.log(e);
            return false;
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    // ignore
                }
            }
        }
        return true;
    }

    protected void updateSettings() {
        final String userSettings = getUserSettings();

        Job job = new Job("Updating Maven settings...") { //$NON-NLS-1$
            protected IStatus run(IProgressMonitor monitor) {
                try {
                    MavenPlugin.getMaven().reloadSettings();
                    final File localRepositoryDir = new File(maven.getLocalRepository().getBasedir());

                    IMavenConfiguration mavenConfiguration = MavenPlugin.getMavenConfiguration();
                    if (userSettings.length() > 0) {
                        mavenConfiguration.setUserSettingsFile(userSettings);
                    } else {
                        mavenConfiguration.setUserSettingsFile(null);
                    }

                    MavenCoreActivator.getDefault().notifyMavenSettingsChanged();

                    File newRepositoryDir = new File(maven.getLocalRepository().getBasedir());
                    if (!newRepositoryDir.equals(localRepositoryDir)) {
                        IndexManager indexManager = MavenPlugin.getIndexManager();
                        indexManager.getWorkspaceIndex().updateIndex(true, monitor);
                    }

                    List<IMavenProjectFacade> facades = new ArrayList<IMavenProjectFacade>();
                    IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();

                    if (projects != null && projects.length > 0) {
                        MavenUpdateRequest updateRequest = new MavenUpdateRequest(projects,
                                mavenConfiguration.isOffline(), true);
                        MavenPlugin.getMavenProjectRegistry().refresh(updateRequest);
                    }
                    return Status.OK_STATUS;
                } catch (CoreException e) {
                    Activator.log(e);
                    return e.getStatus();
                }
            }
        };
        job.schedule();
    }

    private boolean getMessageDialog(Set<RepositoryWrapper> repos) {
        if (repos.size() == 0) {
            return false;
        }
        StringBuilder builder = new StringBuilder();
        if (repos.size() == 1) {
            builder.append("Are you sure you want to delete the '"); //$NON-NLS-1$
            builder.append(repos.iterator().next().getRepository().getUrl());
            builder.append("' repository?"); //$NON-NLS-1$
        } else {
            builder.append("Are you sure you want to delete the following repositories:\n\n"); //$NON-NLS-1$
            for (RepositoryWrapper wrapper : repos) {
                builder.append(wrapper.getRepository().getUrl());
                builder.append("\n"); //$NON-NLS-1$
            }
            builder.append("\n"); //$NON-NLS-1$
        }
        return MessageDialog.openQuestion(getShell(), "Question?", builder.toString()); //$NON-NLS-1$
    }

    @Override
    public void pageChanged(PageChangedEvent event) {
        //When page is selected, if a profileId was preselected, then open the "Add Repository..." dialog 
        if (this.equals(event.getSelectedPage()) && preSelectedProfileId != null) {
            for (RepositoryWrapper repo : availableRepositories) {
                if (preSelectedProfileId.equals(repo.getProfileId())) {
                    openAddRepositoryDialog();
                    break;
                }
            }
            preSelectedProfileId = null;
        }
    }

    private void openAddRepositoryDialog() {
        AddRepositoryDialog dialog = new AddRepositoryDialog(getShell(), availableRepositories,
                includedRepositories, maven, artifactKey);
        dialog.setPreSelectedProfile(preSelectedProfileId);
        int ok = dialog.open();
        if (ok == Window.OK) {
            RepositoryWrapper wrapper = dialog.getRepositoryWrapper();
            includedRepositories.add(wrapper);
            availableRepositories.remove(wrapper);
            addRepository(wrapper, dialog.isActiveByDefault());
            setPageComplete(true);
            refreshRepositories();
        }
    }

}