org.eclipse.xtext.ui.resource.Storage2UriMapperImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.xtext.ui.resource.Storage2UriMapperImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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
 *******************************************************************************/
package org.eclipse.xtext.ui.resource;

import static com.google.common.collect.Maps.*;

import java.util.Collections;
import java.util.Map;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceVisitor;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.xtext.ui.shared.contribution.ISharedStateContributionRegistry;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.Tuples;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * @author Sven Efftinge - Initial contribution and API
 * @noextend This class is not intended to be subclassed by clients.
 */
@Singleton
public class Storage2UriMapperImpl implements IStorage2UriMapperExtension {

    private final static Logger log = Logger.getLogger(Storage2UriMapperImpl.class);

    @Inject
    private UriValidator uriValidator;

    private IStorage2UriMapperContribution contribution = new IStorage2UriMapperContribution() {
        @Override
        public void initializeCache() {
            // nothing to do
        }

        @Override
        public boolean isRejected(/* @NonNull */ IFolder folder) {
            return false;
        }

        /* @NonNull */
        @Override
        public Iterable<Pair<IStorage, IProject>> getStorages(/* @NonNull */ URI uri) {
            return Collections.emptyList();
        }

        @Override
        public URI getUri(/* @NonNull */ IStorage storage) {
            return null;
        }
    };

    /**
     * @since 2.4
     */
    public final void setUriValidator(UriValidator uriValidator) {
        this.uriValidator = uriValidator;
    }

    /**
     * Public for testing purpose
     * 
     * @since 2.5
     * @nooverride This method is not intended to be re-implemented or extended by clients.
     * @noreference This method is not intended to be referenced by clients.
     */
    public void setContribution(IStorage2UriMapperContribution contribution) {
        this.contribution = contribution;
    }

    /**
     * Public for testing purpose
     * 
     * @since 2.5
     * @nooverride This method is not intended to be re-implemented or extended by clients.
     * @noreference This method is not intended to be referenced by clients.
     */
    public IStorage2UriMapperContribution getContribution() {
        return contribution;
    }

    @Inject
    private void initializeContributions(ISharedStateContributionRegistry registry) {
        final ImmutableList<? extends IStorage2UriMapperContribution> allContributions = registry
                .getContributedInstances(IStorage2UriMapperContribution.class);
        final int size = allContributions.size();
        switch (size) {
        case 0:
            // nothing to do
            break;
        case 1:
            contribution = allContributions.get(0);
            break;
        default:
            contribution = new IStorage2UriMapperContribution() {
                @Override
                public void initializeCache() {
                    for (IStorage2UriMapperContribution contribution : allContributions) {
                        contribution.initializeCache();
                    }
                }

                @Override
                public boolean isRejected(/* @NonNull */ IFolder folder) {
                    for (int i = 0; i < size; i++) {
                        if (allContributions.get(i).isRejected(folder)) {
                            return true;
                        }
                    }
                    return false;
                }

                /* @NonNull */
                @Override
                public Iterable<Pair<IStorage, IProject>> getStorages(/* @NonNull */ final URI uri) {
                    return Iterables.concat(Lists.transform(allContributions,
                            new Function<IStorage2UriMapperContribution, Iterable<Pair<IStorage, IProject>>>() {
                                /* @NonNull */
                                @Override
                                public Iterable<Pair<IStorage, IProject>> apply(
                                        IStorage2UriMapperContribution contribution) {
                                    return contribution.getStorages(uri);
                                }
                            }));
                }

                /* @Nullable */
                @Override
                public URI getUri(/* @NonNull */ IStorage storage) {
                    for (int i = 0; i < size; i++) {
                        URI result = allContributions.get(i).getUri(storage);
                        if (result != null) {
                            return result;
                        }
                    }
                    return null;
                }
            };
        }
    }

    /**
     * @since 2.5
     */
    @Override
    public void initializeCache() {
        contribution.initializeCache();
    }

    /**
     * @since 2.4
     */
    @Override
    public Map<URI, IStorage> getAllEntries(IContainer container) {
        final Map<URI, IStorage> result = newLinkedHashMap();
        try {
            container.accept(new IResourceVisitor() {
                @Override
                public boolean visit(IResource resource) throws CoreException {
                    if (resource instanceof IFile) {
                        final IFile storage = (IFile) resource;
                        URI uri = getUri(storage);
                        if (uri != null)
                            result.put(uri, storage);
                    }
                    if (resource instanceof IFolder) {
                        return isHandled((IFolder) resource);
                    }
                    return true;
                }
            });
        } catch (CoreException e) {
            log.error(e.getMessage(), e);
        }
        return result;
    }

    /**
     * Return <code>true</code> if the folder should be traversed. <code>False</code> otherwise.
     * Defaults to <code>true</code> for all folders.
     * @return <code>true</code> if the folder should be traversed. <code>False</code> otherwise.
     * @since 2.4
     */
    protected boolean isHandled(IFolder folder) {
        return !contribution.isRejected(folder);
    }

    @Override
    public Iterable<Pair<IStorage, IProject>> getStorages(URI uri) {
        if (!uri.isPlatformResource()) {
            // support storage lookup by absolute file URI as it is possibly resolved by importURI references
            if (uri.isFile()) {
                IPath path = new Path(uri.toFileString());
                if (path.isAbsolute()) {
                    IFile file = getWorkspaceRoot().getFileForLocation(path);
                    return getStorages(uri, file);
                }
            }
            return contribution.getStorages(uri);
        }
        IFile file = getWorkspaceRoot().getFile(new Path(uri.toPlatformString(true)));
        return getStorages(uri, file);
    }

    private Iterable<Pair<IStorage, IProject>> getStorages(/* @NonNull */ URI uri, IFile file) {
        if (file == null || !file.isAccessible()) {
            return contribution.getStorages(uri);
        }
        return Collections.singleton(Tuples.<IStorage, IProject>create(file, file.getProject()));
    }

    protected IWorkspaceRoot getWorkspaceRoot() {
        return ResourcesPlugin.getWorkspace().getRoot();
    }

    @Override
    public URI getUri(IStorage storage) {
        if (!uriValidator.isPossiblyManaged(storage))
            return null;
        URI uri = internalGetUri(storage);
        if (uri != null && isValidUri(uri, storage))
            return uri;
        return null;
    }

    private URI internalGetUri(/* @NonNull */ IStorage storage) {
        if (storage instanceof IFile) {
            return URI.createPlatformResourceURI(storage.getFullPath().toString(), true);
        }
        return contribution.getUri(storage);
    }

    public boolean isValidUri(URI uri, IStorage storage) {
        boolean valid = uriValidator.isValid(uri, storage);
        return valid;
    }

}