eu.esdihumboldt.hale.ui.io.source.URLSource.java Source code

Java tutorial

Introduction

Here is the source code for eu.esdihumboldt.hale.ui.io.source.URLSource.java

Source

/*
 * Copyright (c) 2012 Data Harmonisation Panel
 * 
 * All rights reserved. This program and the accompanying materials are made
 * available under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution. If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     HUMBOLDT EU Integrated Project #030962
 *     Data Harmonisation Panel <http://www.dhpanel.eu>
 */

package eu.esdihumboldt.hale.ui.io.source;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.PlatformUI;

import eu.esdihumboldt.hale.common.core.io.HaleIO;
import eu.esdihumboldt.hale.common.core.io.IOProvider;
import eu.esdihumboldt.hale.common.core.io.ImportProvider;
import eu.esdihumboldt.hale.common.core.io.extension.IOProviderDescriptor;
import eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier;
import eu.esdihumboldt.hale.common.core.io.supplier.LocatableInputSupplier;
import eu.esdihumboldt.hale.ui.internal.HALEUIPlugin;
import eu.esdihumboldt.hale.ui.io.ImportSource;

/**
 * URL import source
 * 
 * @param <P> the supported {@link IOProvider} type
 * 
 * @author Simon Templer
 * @since 2.5
 */
public class URLSource<P extends ImportProvider> extends AbstractProviderSource<P> {

    /**
     * The file field editor for the source URL
     */
    private URLSourceURIFieldEditor sourceURL;

    /**
     * The set of supported content types
     */
    private Set<IContentType> supportedTypes;

    private ComboViewer types;

    private Button detect;

    private Image detectImage;

    /**
     * @see ImportSource#createControls(Composite)
     */
    @Override
    public void createControls(Composite parent) {
        parent.setLayout(new GridLayout(3, false));

        detectImage = HALEUIPlugin.getImageDescriptor("icons/find_obj.gif").createImage();

        // source file
        sourceURL = new URLSourceURIFieldEditor("sourceURL", "Source URL:", parent) {

            @Override
            protected void onHistorySelected(URI location, IContentType contentType) {
                // select the content type associated with the recent URL
                types.setSelection(new StructuredSelection(contentType));
                updateState(false);
            }

        };
        sourceURL.setPage(getPage());

        // set content types for file field
        Collection<IOProviderDescriptor> factories = getConfiguration().getFactories();
        supportedTypes = new HashSet<IContentType>();
        for (IOProviderDescriptor factory : factories) {
            supportedTypes.addAll(factory.getSupportedTypes());
        }

        sourceURL.setContentTypes(supportedTypes);

        sourceURL.setPropertyChangeListener(new IPropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent event) {
                if (event.getProperty().equals(FieldEditor.IS_VALID)) {
                    getPage().setMessage(null);
                    updateState(false);
                } else if (event.getProperty().equals(FieldEditor.VALUE)) {
                    getPage().setMessage(null);
                    updateState(false);
                }
            }
        });

        // content type selection

        // label
        Label typesLabel = new Label(parent, SWT.NONE);
        typesLabel.setText("Content type");

        // types combo
        Composite group = new Composite(parent, SWT.NONE);
        group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1));
        group.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());

        types = new ComboViewer(group, SWT.DROP_DOWN | SWT.READ_ONLY);
        types.getControl().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        types.setContentProvider(ArrayContentProvider.getInstance());
        types.setLabelProvider(new LabelProvider() {

            @Override
            public String getText(Object element) {
                if (element instanceof IContentType) {
                    return ((IContentType) element).getName();
                }
                return super.getText(element);
            }

        });
        types.setInput(supportedTypes);

        // process selection changes
        types.addSelectionChangedListener(new ISelectionChangedListener() {

            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                updateState(true);
            }
        });

        // detect button
        detect = new Button(group, SWT.PUSH);
        detect.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
        detect.setText("Detect");
        detect.setImage(detectImage);
        detect.addSelectionListener(new SelectionAdapter() {

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

        // provider selection

        // label
        Label providerLabel = new Label(parent, SWT.NONE);
        providerLabel.setText("Import as");

        // create provider combo
        ComboViewer providers = createProviders(parent);
        providers.getControl().setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false, 2, 1));

        // initial state update
        updateState(true);
    }

    /**
     * Run content type detection.
     */
    protected void runDetectContentType() {
        try {
            getPage().getWizard().getContainer().run(false, false, new IRunnableWithProgress() {

                @Override
                public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                    monitor.beginTask("Detect content type", IProgressMonitor.UNKNOWN);

                    final IContentType detected = detectContentType();

                    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {

                        @Override
                        public void run() {
                            if (detected != null) {
                                types.setSelection(new StructuredSelection(detected));
                                getPage().setMessage(
                                        MessageFormat.format("Detected {0} as content type", detected.getName()),
                                        DialogPage.INFORMATION);
                                updateState(true);
                            } else {
                                types.setSelection(new StructuredSelection());
                                getPage().setMessage(
                                        "Could not detect content type. The resource might be not available or it has no matching content type.",
                                        DialogPage.WARNING);
                                updateState(true);
                            }
                        }
                    });

                    monitor.done();
                }
            });
        } catch (Throwable t) {
            getPage().setErrorMessage("Starting the task to detect the content type failed");
        }
    }

    /**
     * Detect the content type
     * 
     * @return the detected content type or <code>null</code>
     */
    private IContentType detectContentType() {
        final Display display = PlatformUI.getWorkbench().getDisplay();
        final AtomicReference<String> sourceString = new AtomicReference<String>();
        final AtomicReference<URI> sourceURI = new AtomicReference<URI>();

        display.syncExec(new Runnable() {

            @Override
            public void run() {
                if (sourceURL.isValid() && sourceURL.getURI() != null) {
                    sourceString.set(sourceURL.getStringValue());
                    try {
                        sourceURI.set(sourceURL.getURI());
                    } catch (Throwable e) {
                        getPage().setErrorMessage(e.getLocalizedMessage());
                    }
                }
            }
        });

        if (sourceURI.get() != null && sourceString.get() != null) {
            // determine content type
            Collection<IContentType> filteredTypes;
            filteredTypes = HaleIO.findContentTypesFor(supportedTypes, new DefaultInputSupplier(sourceURI.get()),
                    sourceString.get());

            if (!filteredTypes.isEmpty()) {
                return filteredTypes.iterator().next();
            }
        }

        return null;
    }

    /**
     * @see AbstractProviderSource#updateContentType()
     */
    @Override
    protected void updateContentType() {
        IContentType ct = null;
        ISelection typeSel = types.getSelection();
        if (!typeSel.isEmpty() && typeSel instanceof IStructuredSelection) {
            ct = (IContentType) ((IStructuredSelection) typeSel).getFirstElement();
        }

        getConfiguration().setContentType(ct);

        super.updateContentType();
    }

    /**
     * @see AbstractProviderSource#updateState(boolean)
     */
    @Override
    protected void updateState(boolean updateContentType) {
        boolean enableSelection = sourceURL.isValid() && sourceURL.getURI() != null;

        detect.setEnabled(enableSelection);
        types.getControl().setEnabled(enableSelection);

        if (!enableSelection && types.getSelection() != null && !types.getSelection().isEmpty()) {
            types.setSelection(new StructuredSelection());
            updateContentType = true;
        }

        super.updateState(updateContentType);
    }

    /**
     * @see AbstractProviderSource#isValidSource()
     */
    @Override
    protected boolean isValidSource() {
        return sourceURL.isValid() && sourceURL.getURI() != null;
    }

    /**
     * @see AbstractProviderSource#getSource()
     */
    @Override
    protected LocatableInputSupplier<? extends InputStream> getSource() {
        URI uri = sourceURL.getURI();
        if (uri != null) {
            return new DefaultInputSupplier(uri);
        }

        return null;
    }

    /**
     * @see AbstractSource#dispose()
     */
    @Override
    public void dispose() {
        if (detectImage != null) {
            detectImage.dispose();
        }
    }

    /**
     * @see AbstractSource#onActivate()
     */
    @Override
    public void onActivate() {
        sourceURL.setFocus();
    }

}